diff --git a/Cargo.lock b/Cargo.lock index 6ef9034..db3a046 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -133,9 +133,9 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] @@ -239,9 +239,9 @@ dependencies = [ [[package]] name = "serde-wasm-bindgen" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ba92964781421b6cef36bf0d7da26d201e96d84e1b10e7ae6ed416e516906d" +checksum = "b9b713f70513ae1f8d92665bbbbda5c295c2cf1da5542881ae5eefe20c9af132" dependencies = [ "js-sys", "serde", @@ -353,9 +353,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -363,9 +363,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", @@ -378,9 +378,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-cli-support" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf8226e223e2dfbe8f921b7f20b82d1b5d86a6b143e9d6286cca8edd16695583" +checksum = "a875870b7b39024cbca8f61a0e1fc8edfe7ac02b484e5a9bcea64374050a850e" dependencies = [ "anyhow", "base64", @@ -400,9 +400,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-externref-xform" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a719be856d8b0802c7195ca26ee6eb02cb9639a12b80be32db960ce9640cb8" +checksum = "04c5d468dc79cfd824d181c386f34c2e7ea521ea5855ddd95af8f4cf3fa676f4" dependencies = [ "anyhow", "walrus", @@ -410,9 +410,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -420,9 +420,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", @@ -433,9 +433,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-multi-value-xform" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12766255d4b9026700376cc81894eeb62903e4414cbc94675f6f9babd9cfb76" +checksum = "65f10c037dad45759d53b598d4737acdced90a0945023c8c6cd8d67b4b3e4eaf" dependencies = [ "anyhow", "walrus", @@ -443,15 +443,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "wasm-bindgen-threads-xform" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2b14c5b9c2c7aa9dd1eb7161857de9783f40e98582e7f41f2d7c04ffdc155" +checksum = "16ddf1a4beb1bceb2b73c2325581901ca2cd92af628f24389a678854dcd65b24" dependencies = [ "anyhow", "walrus", @@ -460,9 +460,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-wasm-conventions" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaedf88769cb23c6fd2e3bfed65bcbff6c5d92c8336afbd80d2dfcc8eb5cf047" +checksum = "93f13ed8ccdac31eadcfd4c9b2ec7bd43e77454b14acb1f43189f2875a9b0391" dependencies = [ "anyhow", "walrus", @@ -470,9 +470,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-wasm-interpreter" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a79039df1e0822e6d66508ec86052993deac201e26060f62abcd85e1daf951" +checksum = "c4282a271772a3063d4057c1144e118254f207fbbc1381b8d50b23c25585d893" dependencies = [ "anyhow", "log", diff --git a/lib/versions.ts b/lib/versions.ts index 06456d6..c66e833 100644 --- a/lib/versions.ts +++ b/lib/versions.ts @@ -4,10 +4,10 @@ interface WasmCrate { } export const versions = { - wasmBindgen: "0.2.89", - wasmBindgenFutures: "0.4.39", - jsSys: "0.3.66", - webSys: "0.3.66", + wasmBindgen: "0.2.90", + wasmBindgenFutures: "0.4.40", + jsSys: "0.3.67", + webSys: "0.3.67", }; export function verifyVersions(crate: WasmCrate) { diff --git a/lib/wasmbuild.generated.js b/lib/wasmbuild.generated.js index a012ed9..eff63ef 100644 --- a/lib/wasmbuild.generated.js +++ b/lib/wasmbuild.generated.js @@ -2,7 +2,7 @@ // @ts-nocheck: generated // deno-lint-ignore-file // deno-fmt-ignore-file -// source-hash: 5bc24f8aa37e22f50b7574e0f9b7626c33201586 +// source-hash: 8c7ebcf7a9b868d06cf54e54fbd4be1f8b919979 let wasm; const heap = new Array(128).fill(undefined); @@ -157,21 +157,25 @@ export function generate_bindgen(name, wasm_bytes) { const imports = { __wbindgen_placeholder__: { - __wbg_new_9fb8d994e1c0aaac: function () { + __wbg_new_3a66822ed076951c: function (arg0, arg1) { + const ret = new Error(getStringFromWasm0(arg0, arg1)); + return addHeapObject(ret); + }, + __wbg_new_87d841e70661f6e9: function () { const ret = new Object(); return addHeapObject(ret); }, - __wbg_set_8761474ad72b9bf1: function (arg0, arg1, arg2) { + __wbg_set_9182712abebf82ef: function (arg0, arg1, arg2) { getObject(arg0)[takeObject(arg1)] = takeObject(arg2); }, - __wbg_new_ffc6d4d085022169: function () { + __wbg_new_34c624469fb1d4fd: function () { const ret = new Array(); return addHeapObject(ret); }, - __wbg_set_f2740edb12e318cd: function (arg0, arg1, arg2) { + __wbg_set_379b27f1d5f1bf9c: function (arg0, arg1, arg2) { getObject(arg0)[arg1 >>> 0] = takeObject(arg2); }, - __wbg_set_d257c6f2da008627: function (arg0, arg1, arg2) { + __wbg_set_83e83bc2428e50ab: function (arg0, arg1, arg2) { const ret = getObject(arg0).set(getObject(arg1), getObject(arg2)); return addHeapObject(ret); }, @@ -179,7 +183,7 @@ const imports = { const ret = arg0; return addHeapObject(ret); }, - __wbg_String_917f38a1211cf44b: function (arg0, arg1) { + __wbg_String_389b54bd9d25375f: function (arg0, arg1) { const ret = String(getObject(arg1)); const ptr1 = passStringToWasm0( ret, @@ -190,10 +194,6 @@ const imports = { getInt32Memory0()[arg0 / 4 + 1] = len1; getInt32Memory0()[arg0 / 4 + 0] = ptr1; }, - __wbg_new_a64e3f2afc2cf2f8: function (arg0, arg1) { - const ret = new Error(getStringFromWasm0(arg0, arg1)); - return addHeapObject(ret); - }, __wbindgen_string_new: function (arg0, arg1) { const ret = getStringFromWasm0(arg0, arg1); return addHeapObject(ret); @@ -213,7 +213,7 @@ const imports = { const ret = getObject(arg0); return addHeapObject(ret); }, - __wbg_new_bfd4534b584a9593: function () { + __wbg_new_ad4df4628315a892: function () { const ret = new Map(); return addHeapObject(ret); }, @@ -223,21 +223,182 @@ const imports = { }, }; -import { Loader } from "../loader/mod.js"; -import { cacheToLocalDir } from "../loader/cache.ts"; +/** @param {URL | string} url */ +export async function fetchWithRetries(url, maxRetries = 5) { + let sleepMs = 250; + let iterationCount = 0; + while (true) { + iterationCount++; + try { + const res = await fetch(url); + if (res.ok || iterationCount > maxRetries) { + return res; + } + } catch (err) { + if (iterationCount > maxRetries) { + throw err; + } + } + console.warn(`Failed fetching. Retrying in ${sleepMs}ms...`); + await new Promise((resolve) => setTimeout(resolve, sleepMs)); + sleepMs = Math.min(sleepMs * 2, 10_000); + } +} -const loader = new Loader({ - imports, - cache: cacheToLocalDir, -}); /** - * Decompression callback - * * @callback DecompressCallback * @param {Uint8Array} compressed - * @return {Uint8Array} decompressed + * @returns {Uint8Array} decompressed + */ + +/** + * @callback CacheCallback + * @param {URL} url + * @param {DecompressCallback | undefined} decompress + * @returns {Promise} */ +/** + * @typedef LoaderOptions + * @property {WebAssembly.Imports | undefined} imports - The Wasm module's imports. + * @property {CacheCallback} [cache] - A function that caches the Wasm module to + * a local path so that a network request isn't required on every load. + * + * Returns an ArrayBuffer with the bytes on download success, but cache save failure. + */ + +export class Loader { + /** @type {LoaderOptions} */ + #options; + /** @type {Promise | undefined} */ + #lastLoadPromise; + /** @type {WebAssembly.WebAssemblyInstantiatedSource | undefined} */ + #instantiated; + + /** @param {LoaderOptions} options */ + constructor(options) { + this.#options = options; + } + + /** @returns {WebAssembly.Instance | undefined} */ + get instance() { + return this.#instantiated?.instance; + } + + /** @returns {WebAssembly.Module | undefined} */ + get module() { + return this.#instantiated?.module; + } + + /** + * @param {URL} url + * @param {DecompressCallback | undefined} decompress + * @returns {Promise} + */ + load( + url, + decompress, + ) { + if (this.#instantiated) { + return Promise.resolve(this.#instantiated); + } else if (this.#lastLoadPromise == null) { + this.#lastLoadPromise = (async () => { + try { + this.#instantiated = await this.#instantiate(url, decompress); + return this.#instantiated; + } finally { + this.#lastLoadPromise = undefined; + } + })(); + } + return this.#lastLoadPromise; + } + + /** + * @param {URL} url + * @param {DecompressCallback | undefined} decompress + */ + async #instantiate(url, decompress) { + const imports = this.#options.imports; + if (this.#options.cache != null && url.protocol !== "file:") { + try { + const result = await this.#options.cache( + url, + decompress ?? ((bytes) => bytes), + ); + if (result instanceof URL) { + url = result; + decompress = undefined; // already decompressed + } else if (result != null) { + return WebAssembly.instantiate(result, imports); + } + } catch { + // ignore if caching ever fails (ex. when on deploy) + } + } + + const isFile = url.protocol === "file:"; + + // make file urls work in Node via dnt + const isNode = + (/** @type {any} */ (globalThis)).process?.versions?.node != null; + if (isFile && typeof Deno !== "object") { + throw new Error( + "Loading local files are not supported in this environment", + ); + } + if (isNode && isFile) { + // the deno global will be shimmed by dnt + const wasmCode = await Deno.readFile(url); + return WebAssembly.instantiate( + decompress ? decompress(wasmCode) : wasmCode, + imports, + ); + } + + switch (url.protocol) { + case "file:": + case "https:": + case "http:": { + const wasmResponse = await fetchWithRetries(url); + if (decompress) { + const wasmCode = new Uint8Array(await wasmResponse.arrayBuffer()); + return WebAssembly.instantiate(decompress(wasmCode), imports); + } + if ( + isFile || + wasmResponse.headers.get("content-type")?.toLowerCase() + .startsWith("application/wasm") + ) { + return WebAssembly.instantiateStreaming( + // Cast to any so there's no type checking issues with dnt + // (https://github.com/denoland/wasmbuild/issues/92) + /** @type {any} */ (wasmResponse), + imports, + ); + } else { + return WebAssembly.instantiate( + await wasmResponse.arrayBuffer(), + imports, + ); + } + } + default: + throw new Error(`Unsupported protocol: ${url.protocol}`); + } + } +} + +const isNodeOrDeno = typeof Deno === "object" || + (typeof process !== "undefined" && process.versions != null && + process.versions.node != null); + +const loader = new Loader({ + imports, + cache: isNodeOrDeno + ? (await import("../loader/cache.ts")).cacheToLocalDir + : undefined, +}); /** * Options for instantiating a Wasm instance. * @typedef {Object} InstantiateOptions diff --git a/lib/wasmbuild_bg.wasm b/lib/wasmbuild_bg.wasm index dee8051..dcb230f 100644 Binary files a/lib/wasmbuild_bg.wasm and b/lib/wasmbuild_bg.wasm differ diff --git a/rs_lib/Cargo.toml b/rs_lib/Cargo.toml index 346f686..c91dde7 100644 --- a/rs_lib/Cargo.toml +++ b/rs_lib/Cargo.toml @@ -8,9 +8,9 @@ crate_type = ["cdylib"] [dependencies] anyhow = "1.0.75" -js-sys = "0.3.66" +js-sys = "0.3.67" serde = { version = "1.0.193", features = ["derive", "rc"] } # make sure to update the version in lib/versions.ts to match this version -wasm-bindgen = "0.2.89" -wasm-bindgen-cli-support = "0.2.89" -serde-wasm-bindgen = "0.6.1" \ No newline at end of file +wasm-bindgen = "0.2.90" +wasm-bindgen-cli-support = "0.2.90" +serde-wasm-bindgen = "0.6.3" \ No newline at end of file diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 5369ff0..76958ae 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.74.0" +channel = "1.75.0" components = [ "clippy", "rustfmt" ] diff --git a/tests/Cargo.toml b/tests/Cargo.toml index b6efe89..24c012c 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -6,7 +6,7 @@ authors = ["the Deno authors"] license = "MIT" [dependencies] -wasm-bindgen = "0.2.89" +wasm-bindgen = "0.2.90" [lib] name = "deno_test"