Use rollup to bundle the web worker script to support more downstream bundlers
The WASM bundle is embedded as a base64 encoded resource and loaded synchronously, because this is the only mechanism widely supported to load WASM inside a web worker currently. Hopefully in the future this can be changed to pure modules.
This commit is contained in:
@@ -54,6 +54,7 @@
|
||||
"scripts": {
|
||||
"prestart": "yarn build:dependencies",
|
||||
"start": "webpack serve --progress --port 3000",
|
||||
"start:only-this": "webpack serve --progress --port 3000",
|
||||
"build:dependencies": "run-s build:dependencies:nym-client-wasm build:dependencies:ts-packages build:dependencies:sdk",
|
||||
"build:dependencies:nym-client-wasm": "../../packages/nym-client-wasm/scripts/build.sh",
|
||||
"build:dependencies:ts-packages": "cd ../../../.. && yarn && yarn build",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { NymMixnetClient } from '@nymproject/sdk';
|
||||
import { NymMixnetClient, MimeTypes } from '@nymproject/sdk';
|
||||
|
||||
/**
|
||||
* Create a Sphinx packet and send it to the mixnet through the gateway node.
|
||||
@@ -8,11 +8,11 @@ import { NymMixnetClient } from '@nymproject/sdk';
|
||||
* @param {Client} nymClient the nym client to use for message sending
|
||||
*/
|
||||
export async function sendMessageTo(nym: NymMixnetClient) {
|
||||
const payload = (document.getElementById('message') as HTMLFormElement).value;
|
||||
const message = (document.getElementById('message') as HTMLFormElement).value;
|
||||
const recipient = (document.getElementById('recipient') as HTMLFormElement).value;
|
||||
|
||||
await nym.client.sendMessage({ payload, recipient });
|
||||
displaySend(payload);
|
||||
await nym.client.send({ payload: { message, mimeType: MimeTypes.TextPlain }, recipient });
|
||||
displaySend(message);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,13 +14,8 @@ async function main() {
|
||||
return;
|
||||
}
|
||||
|
||||
// // mixnet v1
|
||||
// const nymApiUrl = 'https://validator.nymtech.net/api';
|
||||
// const preferredGatewayIdentityKey = 'E3mvZTHQCdBvhfr178Swx9g4QG3kkRUun7YnToLMcMbM';
|
||||
|
||||
// mixnet v2
|
||||
const nymApiUrl = 'https://qwerty-validator-api.qa.nymte.ch/api'; // "http://localhost:8081";
|
||||
const preferredGatewayIdentityKey = undefined; // '36vfvEyBzo5cWEFbnP7fqgY39kFw9PQhvwzbispeNaxL';
|
||||
const nymApiUrl = 'https://validator.nymtech.net/api';
|
||||
const preferredGatewayIdentityKey = 'E3mvZTHQCdBvhfr178Swx9g4QG3kkRUun7YnToLMcMbM';
|
||||
|
||||
// subscribe to connect event, so that we can show the client's address
|
||||
nym.events.subscribeToConnected((e) => {
|
||||
|
||||
@@ -13,8 +13,8 @@ rm nym_client_wasm* package.json || true
|
||||
|
||||
# let wasm-pack build the files and put them in the output location rather than `./pkg`
|
||||
cd ../../../../clients/webassembly
|
||||
wasm-pack build --scope nymproject --target no-modules --out-dir ../../sdk/typescript/packages/nym-client-wasm
|
||||
wasm-pack build --scope nymproject --target web --out-dir ../../sdk/typescript/packages/nym-client-wasm
|
||||
|
||||
# clean up some files that come with the build
|
||||
cd ../../sdk/typescript/packages/nym-client-wasm
|
||||
rm README.md LICENSE_APACHE
|
||||
rm README.md LICENSE_APACHE
|
||||
|
||||
@@ -27,10 +27,13 @@
|
||||
"build:dependencies:ts-packages": "cd ../../../.. && yarn && yarn build",
|
||||
"build:dependencies:nym-client-wasm": "../nym-client-wasm/scripts/build.sh",
|
||||
"prebuild": "yarn build:dependencies",
|
||||
"build": "tsc",
|
||||
"postbuild": "cp ../nym-client-wasm/nym_client_wasm* dist/mixnet/wasm && yarn copy:readme",
|
||||
"build:only-this": "tsc",
|
||||
"postbuild:only-this": "cp ../nym-client-wasm/nym_client_wasm* dist/mixnet/wasm",
|
||||
"build": "yarn build:only-this",
|
||||
"build:only-this": "run-s build:worker build:tsc build:worker:move",
|
||||
"postbuild:only-this": "yarn copy:readme",
|
||||
"build:tsc": "tsc",
|
||||
"build:worker": "rollup src/mixnet/wasm/worker.ts -c rollup.config.mjs",
|
||||
"postbuild:worker": "rm -rf dist/index.d.ts dist/coconut dist/mixnet && mkdir -p dist/mixnet/wasm",
|
||||
"build:worker:move": "rm dist/mixnet/wasm/worker.js && mv dist/worker.js dist/mixnet/wasm",
|
||||
"copy:readme": "cp README.md dist"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -38,10 +41,13 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nymproject/eslint-config-react-typescript": "^1.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@rollup/plugin-terser": "^0.2.1",
|
||||
"@rollup/plugin-typescript": "^10.0.1",
|
||||
"@rollup/plugin-wasm": "^6.1.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.13.0",
|
||||
"@typescript-eslint/parser": "^5.13.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"typescript": "^4.8.4",
|
||||
"eslint": "^8.10.0",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-airbnb-typescript": "^16.1.0",
|
||||
@@ -52,6 +58,11 @@
|
||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.29.2",
|
||||
"eslint-plugin-react-hooks": "^4.3.0"
|
||||
"eslint-plugin-react-hooks": "^4.3.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^3.9.1",
|
||||
"rollup-plugin-base64": "^1.0.1",
|
||||
"rollup-plugin-web-worker-loader": "^1.6.1",
|
||||
"typescript": "^4.8.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import typescript from '@rollup/plugin-typescript';
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
import { wasm } from '@rollup/plugin-wasm';
|
||||
import replace from '@rollup/plugin-replace';
|
||||
|
||||
const extensions = [
|
||||
'.js', '.jsx', '.ts', '.tsx',
|
||||
];
|
||||
|
||||
export default {
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
dir: 'dist',
|
||||
format: 'es',
|
||||
},
|
||||
plugins: [
|
||||
resolve({ extensions }),
|
||||
// this is some nasty monkey patching that removes the WASM URL (because it is handled by the `wasm` plugin)
|
||||
replace({
|
||||
values: { 'input = new URL(\'nym_client_wasm_bg.wasm\', import.meta.url);': 'input = undefined;' },
|
||||
delimiters: ['', ''],
|
||||
preventAssignment: true,
|
||||
}),
|
||||
// force the wasm plugin to embed the wasm bundle - this means no downstream bundlers have to worry about handling it
|
||||
wasm({ maxFileSize: 10000000, targetEnv: 'browser' }),
|
||||
typescript(),
|
||||
],
|
||||
};
|
||||
@@ -1,11 +1,30 @@
|
||||
/* eslint-disable no-console,no-restricted-globals */
|
||||
/// <reference path="../../../../nym-client-wasm/nym_client_wasm.d.ts" />
|
||||
/**
|
||||
* NB: URL syntax is used so that bundlers like webpack can load this package's code when inside the final bundle
|
||||
* the files from ../../../../nym-client-wasm will be copied into the dist directory of this package, so all import
|
||||
* paths are _relative to the output directory_ of this package (`dist`) - don't get confused!
|
||||
*/
|
||||
import * as Comlink from 'comlink';
|
||||
|
||||
//
|
||||
// Rollup will replace wasmBytes with a function that loads the WASM bundle from a base64 string embedded in the output.
|
||||
//
|
||||
// Doing it this way, saves having to support a large variety of bundlers and their quirks.
|
||||
//
|
||||
// @ts-ignore
|
||||
import wasmBytes from '@nymproject/nym-client-wasm/nym_client_wasm_bg.wasm';
|
||||
|
||||
import init, {
|
||||
NymClient,
|
||||
NymClientBuilder,
|
||||
Config,
|
||||
get_gateway,
|
||||
default_debug,
|
||||
decode_payload,
|
||||
parse_utf8_string,
|
||||
utf8_string_to_byte_array,
|
||||
encode_payload_with_headers,
|
||||
} from '@nymproject/nym-client-wasm';
|
||||
|
||||
import type {
|
||||
BinaryMessageReceivedEvent,
|
||||
ConnectedEvent,
|
||||
@@ -18,13 +37,11 @@ import type {
|
||||
import { EventKinds, MimeTypes } from './types';
|
||||
|
||||
// web workers are only allowed to load external scripts as the load
|
||||
importScripts(new URL('./nym_client_wasm.js', import.meta.url));
|
||||
// importScripts(new URL('./nym_client_wasm.js', import.meta.url));
|
||||
// eslint-disable-next-line import/extensions
|
||||
|
||||
console.log('[Nym WASM client] Starting Nym WASM web worker...');
|
||||
|
||||
// again, construct a URL that can be used by a bundler to repackage the WASM binary
|
||||
const wasmUrl = new URL('./nym_client_wasm_bg.wasm', import.meta.url);
|
||||
|
||||
/**
|
||||
* Helper method to send typed messages.
|
||||
* @param event The strongly typed message to send back to the calling thread.
|
||||
@@ -35,7 +52,11 @@ const postMessageWithType = <E>(event: E) => self.postMessage(event);
|
||||
* This class holds the state of the Nym WASM client and provides any interop needed.
|
||||
*/
|
||||
class ClientWrapper {
|
||||
client: wasm_bindgen.NymClient | null = null;
|
||||
client: NymClient | null = null;
|
||||
|
||||
builder: NymClientBuilder | null = null;
|
||||
|
||||
mimeTypes: string[] = [MimeTypes.TextPlain, MimeTypes.ApplicationJson];
|
||||
|
||||
/**
|
||||
* Creates the WASM client and initialises it.
|
||||
@@ -127,8 +148,8 @@ class ClientWrapper {
|
||||
}
|
||||
|
||||
// load WASM binary
|
||||
wasm_bindgen(wasmUrl)
|
||||
.then((importResult) => {
|
||||
init(wasmBytes())
|
||||
.then((importResult: any) => {
|
||||
// sets up better stack traces in case of in-rust panics
|
||||
importResult.set_panic_hook();
|
||||
|
||||
@@ -137,27 +158,14 @@ wasm_bindgen(wasmUrl)
|
||||
|
||||
const startHandler = async (config: NymClientConfig) => {
|
||||
// fetch the gateway details (randomly chosen if no preferred gateway is set)
|
||||
const gatewayEndpoint = await wasm_bindgen.get_gateway(
|
||||
config.nymApiUrl,
|
||||
config.preferredGatewayIdentityKey,
|
||||
);
|
||||
const gatewayEndpoint = await get_gateway(config.nymApiUrl, config.preferredGatewayIdentityKey);
|
||||
|
||||
// set a different gatewayListener in order to avoid workaround ws over https error
|
||||
if (config.gatewayListener)
|
||||
gatewayEndpoint.gateway_listener = config.gatewayListener;
|
||||
if (config.gatewayListener) gatewayEndpoint.gateway_listener = config.gatewayListener;
|
||||
|
||||
// create the client, passing handlers for events
|
||||
wrapper.init(
|
||||
new wasm_bindgen.Config(
|
||||
config.clientId,
|
||||
config.nymApiUrl,
|
||||
gatewayEndpoint,
|
||||
config.debug || wasm_bindgen.default_debug(),
|
||||
),
|
||||
() => {
|
||||
console.log();
|
||||
},
|
||||
undefined,
|
||||
new Config(config.clientId, config.nymApiUrl, gatewayEndpoint, config.debug || default_debug()),
|
||||
async (message) => {
|
||||
try {
|
||||
const decodedPayload = decode_payload(message);
|
||||
|
||||
Reference in New Issue
Block a user