-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
121 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,42 @@ | ||
#!/bin/bash | ||
# | ||
# Build the JavaScript modules | ||
# | ||
# This script is really a workaround for https://github.com/rustwasm/wasm-pack/issues/1074. | ||
# | ||
# Currently, the only reliable way to load WebAssembly in all the JS | ||
# environments we want to target (web-via-webpack, web-via-browserify, jest) | ||
# seems to be to pack the WASM into base64, and then unpack it and instantiate | ||
# it at runtime. | ||
# | ||
# Hopefully one day, https://github.com/rustwasm/wasm-pack/issues/1074 will be | ||
# fixed and this will be unnecessary. | ||
|
||
set -e | ||
|
||
cd $(dirname "$0")/.. | ||
|
||
wasm-pack build --target web --no-pack --scope shadowylab --weak-refs --out-dir pkg "${WASM_PACK_ARGS[@]}" | ||
wasm-pack build --target nodejs --no-pack --scope shadowylab --weak-refs --out-dir pkg "${WASM_PACK_ARGS[@]}" | ||
|
||
# Shrinking .wasm Size | ||
wc -c pkg/webln_js_bg.wasm | ||
wc -c pkg/webln_js_bg.wasm | ||
|
||
# Convert the Wasm into a JS file that exports the base64'ed Wasm. | ||
{ | ||
printf 'module.exports = `' | ||
base64 < pkg/webln_js_bg.wasm | ||
printf '`;' | ||
} > pkg/webln_js_bg.wasm.js | ||
|
||
# In the JavaScript: | ||
# 1. Strip out the lines that load the WASM, and our new epilogue. | ||
# 2. Remove the imports of `TextDecoder` and `TextEncoder`. We rely on the global defaults. | ||
{ | ||
sed -e '/Text..coder.*= require(.util.)/d' \ | ||
-e '/^const path = /,$d' pkg/webln_js.js | ||
cat scripts/epilogue.js | ||
} > pkg/webln_js.js.new | ||
mv pkg/webln_js.js.new pkg/webln_js.js | ||
|
||
# also extend the typescript | ||
cat scripts/epilogue.d.ts >> pkg/webln_js.d.ts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/** | ||
* Load the WebAssembly module in the background, if it has not already been loaded. | ||
* | ||
* Returns a promise which will resolve once the other methods are ready. | ||
* | ||
* @returns {Promise<void>} | ||
*/ | ||
export function loadWasmAsync(): Promise<void>; | ||
|
||
export function loadWasmSync(): void; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
let inited = false; | ||
module.exports.loadWasmSync = function () { | ||
if (inited) { | ||
return; | ||
} | ||
if (initPromise) { | ||
throw new Error("Asynchronous initialisation already in progress: cannot initialise synchronously"); | ||
} | ||
const bytes = unbase64(require("./webln_js_bg.wasm.js")); | ||
const mod = new WebAssembly.Module(bytes); | ||
const instance = new WebAssembly.Instance(mod, imports); | ||
wasm = instance.exports; | ||
wasm.__wbindgen_start(); | ||
inited = true; | ||
}; | ||
|
||
let initPromise = null; | ||
|
||
/** | ||
* Load the WebAssembly module in the background, if it has not already been loaded. | ||
* | ||
* Returns a promise which will resolve once the other methods are ready. | ||
* | ||
* @returns {Promise<void>} | ||
*/ | ||
module.exports.loadWasmAsync = function () { | ||
if (inited) { | ||
return Promise.resolve(); | ||
} | ||
if (!initPromise) { | ||
initPromise = Promise.resolve() | ||
.then(() => require("./webln_js_bg.wasm.js")) | ||
.then((b64) => WebAssembly.instantiate(unbase64(b64), imports)) | ||
.then((result) => { | ||
wasm = result.instance.exports; | ||
wasm.__wbindgen_start(); | ||
inited = true; | ||
}); | ||
} | ||
return initPromise; | ||
}; | ||
|
||
const b64lookup = new Uint8Array([ | ||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 62, 0, 62, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, | ||
8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, | ||
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, | ||
]); | ||
|
||
// base64 decoder, based on the code at https://developer.mozilla.org/en-US/docs/Glossary/Base64#solution_2_%E2%80%93_rewriting_atob_and_btoa_using_typedarrays_and_utf-8 | ||
function unbase64(sBase64) { | ||
const sB64Enc = sBase64.replace(/[^A-Za-z0-9+/]/g, ""); | ||
const nInLen = sB64Enc.length; | ||
const nOutLen = (nInLen * 3 + 1) >> 2; | ||
const taBytes = new Uint8Array(nOutLen); | ||
|
||
let nMod3; | ||
let nMod4; | ||
let nUint24 = 0; | ||
let nOutIdx = 0; | ||
for (let nInIdx = 0; nInIdx < nInLen; nInIdx++) { | ||
nMod4 = nInIdx & 3; | ||
nUint24 |= b64lookup[sB64Enc.charCodeAt(nInIdx)] << (6 * (3 - nMod4)); | ||
if (nMod4 === 3 || nInLen - nInIdx === 1) { | ||
nMod3 = 0; | ||
while (nMod3 < 3 && nOutIdx < nOutLen) { | ||
taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; | ||
nMod3++; | ||
nOutIdx++; | ||
} | ||
nUint24 = 0; | ||
} | ||
} | ||
|
||
return taBytes; | ||
} |