Skip to content

Commit

Permalink
feat: SDK-713 npm package structure for userlib (dfinity#370) (dfinit…
Browse files Browse the repository at this point in the history
  • Loading branch information
Hans authored Feb 28, 2020
1 parent 9358889 commit 4cc4643
Show file tree
Hide file tree
Showing 15 changed files with 215 additions and 212 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ target/
# Mac Temporary Files
.DS_Store
**/.DS_Store

# Node Modules
**/node_modules/
5 changes: 4 additions & 1 deletion dfx.nix
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ let
cp ${pkgs.motoko.didc}/bin/didc $out
cp ${pkgs.motoko.rts}/rts/mo-rts.wasm $out
mkdir $out/stdlib && cp -R ${pkgs.motoko.stdlib}/. $out/stdlib
mkdir $out/js-user-library && cp -R ${userlib-js}/. $out/js-user-library
mkdir $out/js-user-library
tar xvzf ${userlib-js.out}/internet-computer-*.tgz --strip-component 1 --directory $out/js-user-library
cp -R ${userlib-js.lib}/node_modules $out/js-user-library
'';
}
)
Expand Down
2 changes: 1 addition & 1 deletion src/dfx/assets/new_project_node_files/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const aliases = Object.entries(dfxJson.canisters).reduce((acc, [name,value]) =>
process.env["HOME"],
".cache/dfinity/versions",
dfxJson.dfx || process.env["DFX_VERSION"],
"js-user-library/dist/lib.prod.js",
"js-user-library/",
),
});

Expand Down
10 changes: 8 additions & 2 deletions src/userlib/js/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
dist/
out/
build_info.json
node_modules/
dist/
**/*.js
**/*.js.map
**/*.d.ts

# Cannot ignore candid.js, the last bastion of JS code in our app.
bootstrap/candid/candid.js
13 changes: 13 additions & 0 deletions src/userlib/js/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# We work with a safelist here, so block everything that's not permitted, and add packages
# that are.
**

!dist/**
!src/**/*.d.ts
!src/**/*.js
!types/**/*.d.ts
!package.json
!README.md

# The following line further removes all test files (which matches .js and .d.ts).
src/**/*.test.*
28 changes: 28 additions & 0 deletions src/userlib/js/INTERNAL.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
= JavaScript User Library

This is an internal document and is not published to NPM. The public facing README is in
`./README.md`. This file can be safely removed once we are open sourced.

Package: `@internet-computer/userlib`

== Development

=== How to build and use locally

In this repo:

[source,bash]
cd src/userlib/js # You are here
npm install
npm run build
pwd # Keep this
cp -rf . $(dfx cache show)

Alternatively, it might be easier to simply create a symlink;

[source,bash]
rm -rf $(dfx cache show)/js-user-library
ln -s src/userlib/js $(dfx cache show)/js-user-library

Then you just need to run `npm run build` when you change the code. You can also use
`npm run build -- --watch` for a quick watch mode.
5 changes: 0 additions & 5 deletions src/userlib/js/README.adoc

This file was deleted.

7 changes: 7 additions & 0 deletions src/userlib/js/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# JavaScript User Library

Package: `@internet-computer/userlib`

## API

TBD.
113 changes: 0 additions & 113 deletions src/userlib/js/bootstrap/index.js

This file was deleted.

118 changes: 118 additions & 0 deletions src/userlib/js/bootstrap/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import {
generateKeyPair,
HttpAgent,
IDL,
makeAuthTransform,
makeKeyPair,
makeNonceTransform,
} from '@internet-computer/userlib';

interface WindowWithInternetComputer extends Window {
icHttpAgent: HttpAgent;
ic: {
httpAgent: HttpAgent;
};
}
declare const window: WindowWithInternetComputer;

const localStorageIdentityKey = 'dfinity-ic-user-identity';
const localStorageCanisterIdKey = 'dfinity-ic-canister-id';
const localStorageHostKey = 'dfinity-ic-host';

function _getVariable(
queryName: string,
localStorageName: string,
defaultValue?: string,
): string | undefined {
const queryValue = window.location.search.match(new RegExp(`[?&]${queryName}=([^&]*)(?:&|$)`));
if (queryValue) {
return decodeURIComponent(queryValue[1]);
}
const lsValue = window.localStorage.getItem(localStorageName);
if (lsValue) {
return lsValue;
}
return defaultValue;
}

// Retrieve and execute a JavaScript file from the server.
async function _loadJs(canisterId: string, filename: string): Promise<any> {
const content = await window.icHttpAgent.retrieveAsset(canisterId, filename);
const js = new TextDecoder().decode(content);
const dataUri = 'data:text/javascript;base64,' + btoa(js);
return import(/* webpackIgnore: true */ dataUri);
}

const k = _getVariable('userIdentity', localStorageIdentityKey);
let keyPair;
if (k) {
keyPair = JSON.parse(k);
keyPair = makeKeyPair(
new Uint8Array(keyPair.publicKey.data),
new Uint8Array(keyPair.secretKey.data),
);
} else {
keyPair = generateKeyPair();
// TODO(eftycis): use a parser+an appropriate format to avoid
// leaking the key when constructing the string for
// localStorage.
window.localStorage.setItem(localStorageIdentityKey, JSON.stringify(keyPair));
}

// Figure out the host.
let host = _getVariable('host', localStorageHostKey, '');
if (host) {
try {
host = JSON.parse(host);

if (Array.isArray(host)) {
host = '' + host[Math.floor(Math.random() * host.length)];
} else {
host = '' + host;
}
} catch (_) {
host = '';
}
}

const agent = new HttpAgent({ host });
agent.addTransform(makeNonceTransform());
agent.addTransform(makeAuthTransform(keyPair));

window.icHttpAgent = agent;
window.ic = { httpAgent: agent };

async function _main() {
// Find the canister ID. Allow override from the url with 'canister_id=1234..'
const canisterId = _getVariable('canisterId', localStorageCanisterIdKey, '');
if (!canisterId) {
// Show an error.
const div = document.createElement('div');
div.innerText =
'Could not find the canister ID to use. Please provide one in the query parameters.';

document.body.replaceChild(div, document.body.getElementsByTagName('app').item(0)!);
} else {
if (window.location.pathname === '/candid') {
// Load candid.js from the canister.
const candid = await _loadJs(canisterId, 'candid.js');
const canister = window.icHttpAgent.makeActorFactory(candid.default)({ canisterId });
// @ts-ignore: Could not find a declaration file for module
const render: any = await import(/* webpackIgnore: true */ './candid/candid.js');
const actor = candid.default({ IDL });
render.render(canisterId, actor, canister);
} else {
// Load index.js from the canister and execute it.
await _loadJs(canisterId, 'index.js');
}
}
}

_main().catch(err => {
const div = document.createElement('div');
div.innerText = 'An error happened:';
const pre = document.createElement('pre');
pre.innerHTML = err.stack;
div.appendChild(pre);
document.body.replaceChild(div, document.body.getElementsByTagName('app').item(0)!);
});
18 changes: 13 additions & 5 deletions src/userlib/js/default.nix
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
{ pkgs }:

{ pkgs ? import ../../../nix { inherit system; }
, system ? builtins.currentSystem
}:
let
repoRoot = ../../..;
src = pkgs.lib.noNixFiles (pkgs.lib.gitOnlySource repoRoot ./.);
in
pkgs.napalm.buildPackage src {
root = ./.;
name = "dfinity-sdk-userlib-js";

outputs = [ "out" "lib" ];

# ci script now does everything CI should do. Bundle is needed because it's the output
# of the nix derivation.
npmCommands = [
Expand All @@ -16,9 +20,13 @@ pkgs.napalm.buildPackage src {
];

installPhase = ''
npm pack
mkdir -p $out
cp -R dist $out
cp package.json $out
cp README.adoc $out
cp internet-computer-*.tgz $out
# Copy node_modules to be reused elsewhere.
mkdir -p $lib
cp -R node_modules $lib
'';
}
4 changes: 2 additions & 2 deletions src/userlib/js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 4cc4643

Please sign in to comment.