diff --git a/.gitmodules b/.gitmodules index c9f05a1..2d9d707 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,7 @@ path = test/wasi-testsuite url = https://github.com/WebAssembly/wasi-testsuite branch = prod/testsuite-base +[submodule "examples/wasi_multi_threads_rustc/rust_wasm"] + path = examples/wasi_multi_threads_rustc/rust_wasm + url = https://github.com/oligamiq/rust_wasm + sharrow = true diff --git a/bun.lockb b/bun.lockb new file mode 100644 index 0000000..54a53eb Binary files /dev/null and b/bun.lockb differ diff --git a/examples/bun.lockb b/examples/bun.lockb new file mode 100644 index 0000000..d2ee58d Binary files /dev/null and b/examples/bun.lockb differ diff --git a/examples/package-lock.json b/examples/package-lock.json index 9dd8988..c665358 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -1,7 +1,7 @@ { "name": "browser_wasi_shim_examples", "version": "0.0.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -9,35 +9,39 @@ "version": "0.0.0", "license": "MIT OR Apache-2.0", "dependencies": { + "@oligami/shared-object": "^0.1.0", + "browser_wasi_shim_examples": "file:", "xterm": "^4.18.0", "xterm-addon-fit": "^0.5.0" } }, + "node_modules/@oligami/shared-object": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@oligami/shared-object/-/shared-object-0.1.0.tgz", + "integrity": "sha512-MxF1UN6R8oUwlfFWL85eACM8M4nqqeLk7nN+JK5K+Qte5nILT5haGW0DquniVK3la+h45rFKYZB2S6jgyUPq4Q==", + "license": "MIT", + "dependencies": { + "shared-object": "file:" + } + }, + "node_modules/browser_wasi_shim_examples": { + "resolved": "", + "link": true + }, + "node_modules/shared-object": { + "resolved": "node_modules/@oligami/shared-object", + "link": true + }, "node_modules/xterm": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/xterm/-/xterm-4.18.0.tgz", - "integrity": "sha512-JQoc1S0dti6SQfI0bK1AZvGnAxH4MVw45ZPFSO6FHTInAiau3Ix77fSxNx3mX4eh9OL4AYa8+4C8f5UvnSfppQ==" + "version": "4.19.0", + "license": "MIT" }, "node_modules/xterm-addon-fit": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.5.0.tgz", - "integrity": "sha512-DsS9fqhXHacEmsPxBJZvfj2la30Iz9xk+UKjhQgnYNkrUIN5CYLbw7WEfz117c7+S86S/tpHPfvNxJsF5/G8wQ==", + "license": "MIT", "peerDependencies": { "xterm": "^4.0.0" } } - }, - "dependencies": { - "xterm": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/xterm/-/xterm-4.18.0.tgz", - "integrity": "sha512-JQoc1S0dti6SQfI0bK1AZvGnAxH4MVw45ZPFSO6FHTInAiau3Ix77fSxNx3mX4eh9OL4AYa8+4C8f5UvnSfppQ==" - }, - "xterm-addon-fit": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.5.0.tgz", - "integrity": "sha512-DsS9fqhXHacEmsPxBJZvfj2la30Iz9xk+UKjhQgnYNkrUIN5CYLbw7WEfz117c7+S86S/tpHPfvNxJsF5/G8wQ==", - "requires": {} - } } } diff --git a/examples/package.json b/examples/package.json index cd22ce6..a0d39e6 100644 --- a/examples/package.json +++ b/examples/package.json @@ -14,6 +14,8 @@ }, "homepage": "https://github.com/bjorn3/browser_wasi_shim#readme", "dependencies": { + "@oligami/shared-object": "^0.1.0", + "browser_wasi_shim_examples": "file:", "xterm": "^4.18.0", "xterm-addon-fit": "^0.5.0" } diff --git a/examples/wasi_multi_threads/index.html b/examples/wasi_multi_threads/index.html new file mode 100644 index 0000000..c3ae7e3 --- /dev/null +++ b/examples/wasi_multi_threads/index.html @@ -0,0 +1,38 @@ + + + + + +

+ #### +

+ + + + diff --git a/examples/wasi_multi_threads/main.rs b/examples/wasi_multi_threads/main.rs new file mode 100644 index 0000000..86d14dd --- /dev/null +++ b/examples/wasi_multi_threads/main.rs @@ -0,0 +1,13 @@ +fn main() { + println!("Hello, world!"); + + let _: std::thread::JoinHandle<()> = std::thread::spawn(|| { + for i in 1..1000 { + println!("hi number {} from the spawned thread!", i); + } + }); + + for i in 1..1000 { + println!("hi number {} from the main thread!", i); + } +} diff --git a/examples/wasi_multi_threads/multi_thread_echo.wasm b/examples/wasi_multi_threads/multi_thread_echo.wasm new file mode 100644 index 0000000..894878b Binary files /dev/null and b/examples/wasi_multi_threads/multi_thread_echo.wasm differ diff --git a/examples/wasi_multi_threads/thread_spawn.js b/examples/wasi_multi_threads/thread_spawn.js new file mode 100644 index 0000000..3761fb9 --- /dev/null +++ b/examples/wasi_multi_threads/thread_spawn.js @@ -0,0 +1,5 @@ +import { thread_spawn_on_worker } from "../../dist/wasi_farm/shared_array_buffer/thread_spawn.js"; + +self.onmessage = (event) => { + thread_spawn_on_worker(event.data); +} diff --git a/examples/wasi_multi_threads/worker.js b/examples/wasi_multi_threads/worker.js new file mode 100644 index 0000000..913a976 --- /dev/null +++ b/examples/wasi_multi_threads/worker.js @@ -0,0 +1,32 @@ +import { WASIFarmAnimal } from "../../dist/index.js"; + +self.onmessage = async (e) => { + const { wasi_ref } = e.data; + + const wasm = await WebAssembly.compileStreaming(fetch("./multi_thread_echo.wasm")); + + const wasi = new WASIFarmAnimal( + wasi_ref, + [], // args + [], // env + { + debug: true, + can_thread_spawn: true, + thread_spawn_worker_url: (new URL("./thread_spawn.js", import.meta.url)).href, + // thread_spawn_worker_url: "./thread_spawn.js", + thread_spawn_wasm: wasm, + } + ); + + await wasi.wait_worker_background_worker(); + + let inst = await WebAssembly.instantiate(wasm, { + "env": { + memory: wasi.get_share_memory(), + }, + "wasi": wasi.wasiThreadImport, + "wasi_snapshot_preview1": wasi.wasiImport, + }); + + wasi.start(inst); +} diff --git a/examples/wasi_multi_threads_channel/channel.wasm b/examples/wasi_multi_threads_channel/channel.wasm new file mode 100644 index 0000000..369c3b5 Binary files /dev/null and b/examples/wasi_multi_threads_channel/channel.wasm differ diff --git a/examples/wasi_multi_threads_channel/index.html b/examples/wasi_multi_threads_channel/index.html new file mode 100644 index 0000000..44539a0 --- /dev/null +++ b/examples/wasi_multi_threads_channel/index.html @@ -0,0 +1,28 @@ + + + + + +

+ #### +

+ + + + diff --git a/examples/wasi_multi_threads_channel/main.rs b/examples/wasi_multi_threads_channel/main.rs new file mode 100644 index 0000000..216800c --- /dev/null +++ b/examples/wasi_multi_threads_channel/main.rs @@ -0,0 +1,16 @@ +// https://doc.rust-lang.org/book/ch16-02-message-passing.html + +use std::sync::mpsc; +use std::thread; + +fn main() { + let (tx, rx) = mpsc::channel(); + + thread::spawn(move || { + let val = String::from("hi"); + tx.send(val).unwrap(); + }); + + let received = rx.recv().unwrap(); + println!("Got: {received}"); +} diff --git a/examples/wasi_multi_threads_channel/thread_spawn.js b/examples/wasi_multi_threads_channel/thread_spawn.js new file mode 100644 index 0000000..3761fb9 --- /dev/null +++ b/examples/wasi_multi_threads_channel/thread_spawn.js @@ -0,0 +1,5 @@ +import { thread_spawn_on_worker } from "../../dist/wasi_farm/shared_array_buffer/thread_spawn.js"; + +self.onmessage = (event) => { + thread_spawn_on_worker(event.data); +} diff --git a/examples/wasi_multi_threads_channel/worker.js b/examples/wasi_multi_threads_channel/worker.js new file mode 100644 index 0000000..c91ecb4 --- /dev/null +++ b/examples/wasi_multi_threads_channel/worker.js @@ -0,0 +1,32 @@ +import { WASIFarmAnimal } from "../../dist/index.js"; + +self.onmessage = async (e) => { + const { wasi_ref } = e.data; + + const wasm = await WebAssembly.compileStreaming(fetch("./channel.wasm")); + + const wasi = new WASIFarmAnimal( + wasi_ref, + [], // args + [], // env + { + debug: true, + can_thread_spawn: true, + thread_spawn_worker_url: (new URL("./thread_spawn.js", import.meta.url)).href, + // thread_spawn_worker_url: "./thread_spawn.js", + thread_spawn_wasm: wasm, + } + ); + + await wasi.wait_worker_background_worker(); + + let inst = await WebAssembly.instantiate(wasm, { + "env": { + memory: wasi.get_share_memory(), + }, + "wasi": wasi.wasiThreadImport, + "wasi_snapshot_preview1": wasi.wasiImport, + }); + + wasi.start(inst); +} diff --git a/examples/wasi_multi_threads_rustc/depend_files.js b/examples/wasi_multi_threads_rustc/depend_files.js new file mode 100644 index 0000000..b1ea3fe --- /dev/null +++ b/examples/wasi_multi_threads_rustc/depend_files.js @@ -0,0 +1,154 @@ +import { + PreopenDirectory, + WASIFarm, + Directory, + File, +} from "../../dist/index.js"; + +async function load_external_file(path) { + return new File(await (await (await fetch(path)).blob()).arrayBuffer()); +} + +const linux_libs_promise = (async () => { + const dir = new Map(); + for (const file of [ + "libaddr2line-b8754aeb03c02354.rlib", + "libadler-05c3545f6cd12159.rlib", + "liballoc-0dab879bc41cd6bd.rlib", + "libcfg_if-c7fd2cef50341546.rlib", + "libcompiler_builtins-a99947d020d809d6.rlib", + "libcore-4b8e8a815d049db3.rlib", + "libgetopts-bbb75529e85d129d.rlib", + "libgimli-598847d27d7a3cbf.rlib", + "libhashbrown-d2ff91fdf93cacb2.rlib", + "liblibc-dc63949c664c3fce.rlib", + "libmemchr-2d3a423be1a6cb96.rlib", + "libminiz_oxide-b109506a0ccc4c6a.rlib", + "libobject-7b48def7544c748b.rlib", + "libpanic_abort-c93441899b93b849.rlib", + "libpanic_unwind-11d9ba05b60bf694.rlib", + "libproc_macro-1a7f7840bb9983dc.rlib", + "librustc_demangle-59342a335246393d.rlib", + "librustc_std_workspace_alloc-552b185085090ff6.rlib", + "librustc_std_workspace_core-5d8a121daa7eeaa9.rlib", + "librustc_std_workspace_std-97f43841ce452f7d.rlib", + "libstd-bdedb7706a556da2.rlib", + "libstd-bdedb7706a556da2.so", + "libstd_detect-cca21eebc4281add.rlib", + "libsysroot-f654e185be3ffebd.rlib", + "libtest-f06fa3fbc201c558.rlib", + "libunicode_width-19a0dcd589fa0877.rlib", + "libunwind-747b693f90af9445.rlib", + ]) { + dir.set( + file, + await load_external_file( + `./rust_wasm/rustc_llvm/dist/lib/rustlib/x86_64-unknown-linux-gnu/lib/${file}`, + ), + ); + } + return dir; +})(); + +const threads_libs_promise = (async () => { + const dir = new Map(); + for (const file of [ + "libaddr2line-a47658bebc67c3a1.rlib", + "libadler-38ddbcf07afd45fc.rlib", + "liballoc-1fc4f6ca1d836e4c.rlib", + "libcfg_if-fd15f5d506df7899.rlib", + "libcompiler_builtins-3dc6223f56552b05.rlib", + "libcore-0ec7cb16e8553802.rlib", + "libgetopts-6248a91c42a854a0.rlib", + "libgimli-4425159eeeeb18dd.rlib", + "libhashbrown-243f98c4e4e641ea.rlib", + "liblibc-9149392e3841960d.rlib", + "libmemchr-9ac950afd37fa4c7.rlib", + "libminiz_oxide-91aaa0ee7402d39e.rlib", + "libobject-361b96ef5df8a7f9.rlib", + "libpanic_abort-f91052098501e46b.rlib", + "libpanic_unwind-fc376dcf47815f10.rlib", + "libproc_macro-9cab37e4d11f0e52.rlib", + "librustc_demangle-1af142f261139812.rlib", + "librustc_std_workspace_alloc-f0d62212c413dd0e.rlib", + "librustc_std_workspace_core-ea396731d16229a8.rlib", + "librustc_std_workspace_std-7434133be68a4a89.rlib", + "libstd_detect-083332b3c8180bc9.rlib", + "libstd-5ddf10249e9580fe.rlib", + "libsysroot-8b3608099dad3b42.rlib", + "libtest-8ebd431ae5608538.rlib", + "libunicode_width-7e2396fcd7049a8b.rlib", + "libunwind-e7408208cf4a3c79.rlib", + "libwasi-f0b9e157c50fe586.rlib", + ]) { + dir.set( + file, + await load_external_file( + `./rust_wasm/rustc_llvm/dist/lib/rustlib/wasm32-wasip1-threads/lib/${file}`, + ), + ); + } + return dir; +})(); + +const threads_self_contained_promise = (async () => { + const dir = new Map(); + for (const file of ["crt1-command.o", "crt1-reactor.o", "libc.a"]) { + dir.set( + file, + await load_external_file( + `./rust_wasm/rustc_llvm/dist/lib/rustlib/wasm32-wasip1-threads/lib/self-contained/${file}`, + ), + ); + } + return dir; +})(); + +const [linux_libs, threads_libs, threads_self_contained, components] = + await Promise.all([ + linux_libs_promise, + threads_libs_promise, + threads_self_contained_promise, + await load_external_file( + "./rust_wasm/rustc_llvm/dist/lib/rustlib/components", + ), + ]); + +threads_libs.set("self-contained", new Directory(threads_self_contained)); + +const farm = new WASIFarm( + undefined, + undefined, + undefined, + [ + new PreopenDirectory("/sysroot", [ + [ + "lib", + new Directory([ + [ + "rustlib", + new Directory([ + ["components", components], + [ + "wasm32-wasip1-threads", + new Directory([["lib", new Directory(threads_libs)]]), + ], + [ + "x86_64-unknown-linux-gnu", + new Directory([["lib", new Directory(linux_libs)]]), + ], + ]), + ], + ]), + ], + ]), + ], + { + allocator_size: 1024 * 1024 * 1024, + // debug: true, + }, +); + +const ret = await farm.get_ref(); + +postMessage({ wasi_ref: ret }); diff --git a/examples/wasi_multi_threads_rustc/index.html b/examples/wasi_multi_threads_rustc/index.html new file mode 100644 index 0000000..58d58e4 --- /dev/null +++ b/examples/wasi_multi_threads_rustc/index.html @@ -0,0 +1,75 @@ + + + + + +
+ + + + + + + + + + + diff --git a/examples/wasi_multi_threads_rustc/rust_wasm b/examples/wasi_multi_threads_rustc/rust_wasm new file mode 160000 index 0000000..b3114df --- /dev/null +++ b/examples/wasi_multi_threads_rustc/rust_wasm @@ -0,0 +1 @@ +Subproject commit b3114df16241f3f2d332bbf588f0ece0b7ddfe0f diff --git a/examples/wasi_multi_threads_rustc/rustc.js b/examples/wasi_multi_threads_rustc/rustc.js new file mode 100644 index 0000000..1dd1bf8 --- /dev/null +++ b/examples/wasi_multi_threads_rustc/rustc.js @@ -0,0 +1,48 @@ +import { WASIFarmAnimal } from "../../dist/index.js"; + +const { promise, resolve } = Promise.withResolvers(); +import("../node_modules/@oligami/shared-object/dist/index.js").then(resolve); + +let wasi; +let wasm; +let shared; + +onmessage = async function (e) { + const { wasi_refs } = e.data; + + if (wasi_refs) { + wasm = await WebAssembly.compileStreaming( + fetch("./rust_wasm/rustc_llvm/rustc_opt.wasm"), + ); + + wasi = new WASIFarmAnimal( + wasi_refs, + [], // args + ["RUST_MIN_STACK=16777216"], // env + { + // debug: true, + can_thread_spawn: true, + thread_spawn_worker_url: new URL("./thread_spawn.js", import.meta.url) + .href, + // thread_spawn_worker_url: "./thread_spawn.js", + thread_spawn_wasm: wasm, + }, + ); + + await wasi.wait_worker_background_worker(); + + wasi.get_share_memory().grow(200); + + console.log("Waiting for worker background worker..."); + + await promise; + + shared = new SharedObject.SharedObject((...args) => { + wasi.args = ["rustc", ...args]; + wasi.block_start_on_thread(); + console.log("wasi.start done"); + }, "rustc"); + + postMessage({ ready: true }); + } +}; diff --git a/examples/wasi_multi_threads_rustc/thread_spawn.js b/examples/wasi_multi_threads_rustc/thread_spawn.js new file mode 100644 index 0000000..bed9b51 --- /dev/null +++ b/examples/wasi_multi_threads_rustc/thread_spawn.js @@ -0,0 +1,5 @@ +import { thread_spawn_on_worker } from "../../dist/index.js"; + +self.onmessage = async (event) => { + await thread_spawn_on_worker(event.data); +}; diff --git a/examples/wasi_multi_threads_rustc/tmp_dir.js b/examples/wasi_multi_threads_rustc/tmp_dir.js new file mode 100644 index 0000000..4086095 --- /dev/null +++ b/examples/wasi_multi_threads_rustc/tmp_dir.js @@ -0,0 +1,58 @@ +import { + PreopenDirectory, + WASIFarm, + File, + Directory, +} from "../../dist/index.js"; + +const farm = new WASIFarm( + undefined, + undefined, + undefined, + [ + // new PreopenDirectory(".", [ + // ["tmp-tmp", new File(new TextEncoder("utf-8").encode("Hello World!"))], + // ["tmp-dir", new Directory([])], + // ]), + // new PreopenDirectory("tmp-dir", [ + // [ + // "tmp-dir_inner", + // new Directory([ + // [ + // "tmp-dir_inner-file", + // new File(new TextEncoder("utf-8").encode("Hello World!!!!!")), + // ], + // ]), + // ], + // ]), + new PreopenDirectory("/tmp", []), + new PreopenDirectory("/", [ + [ + "hello.rs", + new File( + new TextEncoder("utf-8").encode( + `fn main() { println!("Hello World!"); }`, + ), + ), + ], + ["sysroot", new Directory([])], + ["tmp", new Directory([])], + ]), + new PreopenDirectory("~", [ + [ + "####.rs", + new File( + new TextEncoder("utf-8").encode( + `fn main() { println!("Hello World!"); }`, + ), + ), + ], + ["sysroot", new Directory([])], + ]), + ], + // { debug: true }, +); + +const ret = await farm.get_ref(); + +postMessage({ wasi_ref: ret }); diff --git a/examples/wasi_multi_threads_rustc/tre_opt.wasm b/examples/wasi_multi_threads_rustc/tre_opt.wasm new file mode 100644 index 0000000..67f06df Binary files /dev/null and b/examples/wasi_multi_threads_rustc/tre_opt.wasm differ diff --git a/examples/wasi_multi_threads_rustc/tree.js b/examples/wasi_multi_threads_rustc/tree.js new file mode 100644 index 0000000..a2bc7e0 --- /dev/null +++ b/examples/wasi_multi_threads_rustc/tree.js @@ -0,0 +1,47 @@ +import { strace, WASIFarmAnimal } from "../../dist/index.js"; + +const { promise, resolve } = Promise.withResolvers(); +import("../node_modules/@oligami/shared-object/dist/index.js").then(resolve); + +let wasi; +let inst; +let wasm; + +let shared; + +onmessage = async function (e) { + const { wasi_refs } = e.data; + + if (wasi_refs) { + wasm = await WebAssembly.compileStreaming(fetch("./tre_opt.wasm")); + + wasi = new WASIFarmAnimal( + wasi_refs, + ["tre"], // args + [], // env + { + debug: false, + }, + ); + + // Memory is rewritten at this time. + inst = await WebAssembly.instantiate(wasm, { + wasi_snapshot_preview1: wasi.wasiImport, + }); + + await promise; + + const memory_reset = inst.exports.memory.buffer; + const memory_reset_view = new Uint8Array(memory_reset).slice(); + + shared = new SharedObject.SharedObject((...args) => { + // If I don't reset memory, I get some kind of error. + wasi.args = ["tre", ...args]; + const memory_view = new Uint8Array(inst.exports.memory.buffer); + memory_view.set(memory_reset_view); + wasi.start(inst); + }, "tree"); + + postMessage({ ready: true }); + } +}; diff --git a/examples/wasi_multi_threads_rustc/worker.js b/examples/wasi_multi_threads_rustc/worker.js new file mode 100644 index 0000000..d6fe3ae --- /dev/null +++ b/examples/wasi_multi_threads_rustc/worker.js @@ -0,0 +1,115 @@ +const { promise, resolve } = Promise.withResolvers(); +import("../node_modules/@oligami/shared-object/dist/index.js").then(resolve); + +let tree; +let term; +let rustc; + +self.onmessage = async (e) => { + const { wasi_ref } = e.data; + + const { promise: depend_files_promise, resolve: depend_files_resolve } = + Promise.withResolvers(); + const { promise: tmp_dir_promise, resolve: tmp_dir_resolve } = + Promise.withResolvers(); + + const depend_files_manage_worker = new Worker("depend_files.js", { + type: "module", + }); + depend_files_manage_worker.onmessage = (e) => { + depend_files_resolve(e.data); + }; + + const tmp_dir_manage_worker = new Worker("tmp_dir.js", { + type: "module", + }); + tmp_dir_manage_worker.onmessage = (e) => { + tmp_dir_resolve(e.data); + }; + + const [depend_files, tmp_dir] = await Promise.all([ + depend_files_promise, + tmp_dir_promise, + ]); + const { wasi_ref: wasi_ref_depend_files } = depend_files; + const { wasi_ref: wasi_ref_tmp_dir } = tmp_dir; + + const wasi_refs = [wasi_ref_depend_files, wasi_ref_tmp_dir, wasi_ref]; + + const { promise: tree_promise, resolve: tree_resolve } = + Promise.withResolvers(); + const { promise: rustc_promise, resolve: rustc_resolve } = + Promise.withResolvers(); + + const tree_worker = new Worker("tree.js", { + type: "module", + }); + tree_worker.onmessage = (e) => { + console.log("tree onmessage"); + tree_resolve(e.data); + }; + + const rustc_worker = new Worker("rustc.js", { + type: "module", + }); + rustc_worker.onmessage = (e) => { + console.log("rustc onmessage"); + rustc_resolve(e.data); + }; + + tree_worker.postMessage({ + wasi_refs, + }); + rustc_worker.postMessage({ + wasi_refs, + }); + + console.log("Waiting for tree and rustc to finish..."); + + await Promise.all([tree_promise, rustc_promise]); + + console.log("Sending run message..."); + + await promise; + + tree = new SharedObject.SharedObjectRef("tree").proxy(); + + term = new SharedObject.SharedObjectRef("term").proxy(); + + rustc = new SharedObject.SharedObjectRef("rustc").proxy(); + + // tree -h + await term.writeln("$ tree -h"); + await tree("-h"); + + // tree / + await term.writeln("\n$ tree /"); + await tree("/"); + + // rustc -h + await term.writeln("\n$ rustc -h"); + await rustc("-h"); + + // rustc /hello.rs --sysroot /sysroot --target wasm32-wasip1-threads -Csave-temps --out-dir /tmp + await term.writeln( + "\n$ rustc /hello.rs --sysroot /sysroot --target wasm32-wasip1-threads -Csave-temps --out-dir /tmp", + ); + try { + await rustc( + "/hello.rs", + "--sysroot", + "/sysroot", + "--target", + "wasm32-wasip1-threads", + "-Csave-temps", + "--out-dir", + "/tmp", + ); + } catch (e) { + console.error(e); + } + + // tree / + await term.writeln("\n$ tree /"); + await tree("/"); +}; diff --git a/examples/wasi_workers/echo_and_rewrite.wasm b/examples/wasi_workers/echo_and_rewrite.wasm old mode 100755 new mode 100644 diff --git a/examples/wasi_workers_single/echo_and_rewrite.wasm b/examples/wasi_workers_single/echo_and_rewrite.wasm old mode 100755 new mode 100644 diff --git a/package-lock.json b/package-lock.json index 67a7fd4..7967411 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "@bjorn3/browser_wasi_shim", "version": "0.3.0", "license": "MIT OR Apache-2.0", + "dependencies": { + "@bjorn3/browser_wasi_shim": "file:" + }, "devDependencies": { "@swc/cli": "^0.1.62", "@swc/core": "^1.3.37", @@ -16,13 +19,15 @@ "eslint": "^8.50.0", "playwright": "^1.40.1", "prettier": "^3.0.3", - "typescript": "^4.9.5" + "typescript": "^5.6.2" } }, + "node_modules/@bjorn3/browser_wasi_shim": { + "resolved": "", + "link": true + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, "license": "MIT", "dependencies": { @@ -36,9 +41,7 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "version": "4.11.1", "dev": true, "license": "MIT", "engines": { @@ -47,8 +50,6 @@ }, "node_modules/@eslint/eslintrc": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "license": "MIT", "dependencies": { @@ -69,21 +70,8 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -93,10 +81,17 @@ "node": "*" } }, + "node_modules/@eslint/eslintrc/node_modules/minimatch/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "8.57.1", "dev": true, "license": "MIT", "engines": { @@ -104,14 +99,11 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", + "version": "0.13.0", "dev": true, "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" }, @@ -119,21 +111,8 @@ "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -143,10 +122,17 @@ "node": "*" } }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -159,16 +145,11 @@ }, "node_modules/@humanwhocodes/object-schema": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@mole-inc/bin-wrapper": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@mole-inc/bin-wrapper/-/bin-wrapper-8.0.1.tgz", - "integrity": "sha512-sTGoeZnjI8N4KS+sW2AN95gDBErhAguvkw/tWdCjeM8bvxpz5lqrnd0vOJABA1A+Ic3zED7PYoLP/RANLgVotA==", "dev": true, "license": "MIT", "dependencies": { @@ -187,8 +168,6 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "license": "MIT", "dependencies": { @@ -201,8 +180,6 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "license": "MIT", "engines": { @@ -211,8 +188,6 @@ }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "license": "MIT", "dependencies": { @@ -225,8 +200,6 @@ }, "node_modules/@sindresorhus/is": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true, "license": "MIT", "engines": { @@ -238,8 +211,6 @@ }, "node_modules/@swc/cli": { "version": "0.1.65", - "resolved": "https://registry.npmjs.org/@swc/cli/-/cli-0.1.65.tgz", - "integrity": "sha512-4NcgsvJVHhA7trDnMmkGLLvWMHu2kSy+qHx6QwRhhJhdiYdNUrhdp+ERxen73sYtaeEOYeLJcWrQ60nzKi6rpg==", "dev": true, "license": "MIT", "dependencies": { @@ -270,9 +241,7 @@ } }, "node_modules/@swc/core": { - "version": "1.7.25", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.25.tgz", - "integrity": "sha512-EWTWdb0GD+Z9CByvW5j5b9d1cFr9P6hy7TkGgAwnhKxGwzGu8BHTG3ou28KY6P57yZXDVKB0exWmSNRIv6LYCg==", + "version": "1.7.26", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", @@ -288,16 +257,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.7.25", - "@swc/core-darwin-x64": "1.7.25", - "@swc/core-linux-arm-gnueabihf": "1.7.25", - "@swc/core-linux-arm64-gnu": "1.7.25", - "@swc/core-linux-arm64-musl": "1.7.25", - "@swc/core-linux-x64-gnu": "1.7.25", - "@swc/core-linux-x64-musl": "1.7.25", - "@swc/core-win32-arm64-msvc": "1.7.25", - "@swc/core-win32-ia32-msvc": "1.7.25", - "@swc/core-win32-x64-msvc": "1.7.25" + "@swc/core-darwin-arm64": "1.7.26", + "@swc/core-darwin-x64": "1.7.26", + "@swc/core-linux-arm-gnueabihf": "1.7.26", + "@swc/core-linux-arm64-gnu": "1.7.26", + "@swc/core-linux-arm64-musl": "1.7.26", + "@swc/core-linux-x64-gnu": "1.7.26", + "@swc/core-linux-x64-musl": "1.7.26", + "@swc/core-win32-arm64-msvc": "1.7.26", + "@swc/core-win32-ia32-msvc": "1.7.26", + "@swc/core-win32-x64-msvc": "1.7.26" }, "peerDependencies": { "@swc/helpers": "*" @@ -308,163 +277,8 @@ } } }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.7.25", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.25.tgz", - "integrity": "sha512-cbLNV4vsqSbll7kehJ58hZ9lt+nLlUPF+fmSRVsb4Qasnr0IRDtpT+3Rc87bDNXfkc15Ii80xdp7sU2MVgHn7A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.7.25", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.25.tgz", - "integrity": "sha512-kZswLBI8KWWV8VuGIJZd8GM7eWFY5srmlomiWw7j/OtRyRgr8qfX3EmxBAYYZqTEvWdooSc/y3I61lHn/a1tRg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.7.25", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.25.tgz", - "integrity": "sha512-DV/8BHwdtymoelC1KvefOoyXraIDK0rJIBqjPvtzW9YbkN1hepF7au1deiieJ6+A0smP+4fxtYhrnJ5EjPvylA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.7.25", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.25.tgz", - "integrity": "sha512-lIx8BeKzpulL2PbLyMUln5Hk164M/PHXquHt6y86sD7Spza6zbCme+/Zr17PRiElqrP8byKC09UZj0K6hONDqQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.7.25", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.25.tgz", - "integrity": "sha512-+/I7AzzY4066bvKLTyAZXLL0dPpWhRUh0ja4cZNZ+0Gpn8FmtWDwZKCriIWkDlD1gSuXm8+iOaaLGhEwIquOpQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.7.25", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.25.tgz", - "integrity": "sha512-BPtnKyiBVMZyN6ml7oHGX9wuSLHN06nT1x1TM9wcSKSx6y+BEKb8jSmzrKzM7K5LnfOiy4+ARCb4HrMkXIQjUg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-musl": { - "version": "1.7.25", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.25.tgz", - "integrity": "sha512-ZlZztuvy2hvfoYg5gYHYuc2mssgzGq1kKanF9kPdICsTmze6t7AvkSfmlTN7/YGuO//yDDJR1GR0EuXwOAJqPw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.7.25", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.25.tgz", - "integrity": "sha512-k3QsHJ+53BVhRUeC7NJOMxdMGexBIhFmL8Ex39vqWVvDZgnOepMFu9/G1pm04xBHSqcb0lioDj5WirAoy4VusQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.7.25", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.25.tgz", - "integrity": "sha512-3PW8LDgS7eIdjeGLNYhO1XLXyZJZ+aLjf79am8+HqfzVkmz+uIK39FcFxeF6A/LUsuQBMa3Geg++rS38kviMEA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.7.25", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.25.tgz", - "integrity": "sha512-iYpJNfIzPwahwPgddb9PHYichdFoS/2NR4Gaemv9s6nzTguS4vx/YT1oFGwuGMP0RyOdmAN2rEfPh7sJktqWfA==", + "version": "1.7.26", "cpu": [ "x64" ], @@ -480,15 +294,11 @@ }, "node_modules/@swc/counter": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", "dev": true, "license": "Apache-2.0" }, "node_modules/@swc/types": { "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.12.tgz", - "integrity": "sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -497,8 +307,6 @@ }, "node_modules/@szmarczak/http-timer": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "dev": true, "license": "MIT", "dependencies": { @@ -510,15 +318,11 @@ }, "node_modules/@tokenizer/token": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", "dev": true, "license": "MIT" }, "node_modules/@types/cacheable-request": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", "dev": true, "license": "MIT", "dependencies": { @@ -530,22 +334,16 @@ }, "node_modules/@types/http-cache-semantics": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", "dev": true, "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true, "license": "MIT" }, "node_modules/@types/keyv": { "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", "dev": true, "license": "MIT", "dependencies": { @@ -553,9 +351,7 @@ } }, "node_modules/@types/node": { - "version": "22.5.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", - "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "version": "22.5.5", "dev": true, "license": "MIT", "dependencies": { @@ -564,8 +360,6 @@ }, "node_modules/@types/responselike": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", - "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", "dev": true, "license": "MIT", "dependencies": { @@ -574,15 +368,11 @@ }, "node_modules/@types/semver": { "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true, "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", - "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", "dev": true, "license": "MIT", "dependencies": { @@ -617,8 +407,6 @@ }, "node_modules/@typescript-eslint/parser": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -646,8 +434,6 @@ }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "license": "MIT", "dependencies": { @@ -664,8 +450,6 @@ }, "node_modules/@typescript-eslint/type-utils": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", - "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", "dev": true, "license": "MIT", "dependencies": { @@ -692,8 +476,6 @@ }, "node_modules/@typescript-eslint/types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, "license": "MIT", "engines": { @@ -706,8 +488,6 @@ }, "node_modules/@typescript-eslint/typescript-estree": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -735,8 +515,6 @@ }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "license": "ISC", "dependencies": { @@ -751,8 +529,6 @@ }, "node_modules/@typescript-eslint/utils": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, "license": "MIT", "dependencies": { @@ -777,8 +553,6 @@ }, "node_modules/@typescript-eslint/visitor-keys": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "license": "MIT", "dependencies": { @@ -795,15 +569,11 @@ }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true, "license": "ISC" }, "node_modules/acorn": { "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, "license": "MIT", "bin": { @@ -815,8 +585,6 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -825,8 +593,6 @@ }, "node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", "dependencies": { @@ -842,8 +608,6 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { @@ -852,8 +616,6 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { @@ -868,8 +630,6 @@ }, "node_modules/arch": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", "dev": true, "funding": [ { @@ -889,15 +649,11 @@ }, "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, "license": "Python-2.0" }, "node_modules/array-union": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "license": "MIT", "engines": { @@ -906,15 +662,11 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, "license": "MIT" }, "node_modules/bin-check": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz", - "integrity": "sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA==", "dev": true, "license": "MIT", "dependencies": { @@ -927,8 +679,6 @@ }, "node_modules/bin-version": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-6.0.0.tgz", - "integrity": "sha512-nk5wEsP4RiKjG+vF+uG8lFsEn4d7Y6FVDamzzftSunXOoOcOOkzcWdKVlGgFFwlUQCj63SgnUkLLGF8v7lufhw==", "dev": true, "license": "MIT", "dependencies": { @@ -944,8 +694,6 @@ }, "node_modules/bin-version-check": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-5.1.0.tgz", - "integrity": "sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g==", "dev": true, "license": "MIT", "dependencies": { @@ -962,8 +710,6 @@ }, "node_modules/bin-version/node_modules/execa": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "license": "MIT", "dependencies": { @@ -984,10 +730,8 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/bin-version/node_modules/get-stream": { + "node_modules/bin-version/node_modules/execa/node_modules/get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, "license": "MIT", "engines": { @@ -997,10 +741,8 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-version/node_modules/is-stream": { + "node_modules/bin-version/node_modules/execa/node_modules/is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "license": "MIT", "engines": { @@ -1010,10 +752,8 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-version/node_modules/npm-run-path": { + "node_modules/bin-version/node_modules/execa/node_modules/npm-run-path": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "license": "MIT", "dependencies": { @@ -1025,8 +765,6 @@ }, "node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "license": "MIT", "dependencies": { @@ -1035,8 +773,6 @@ }, "node_modules/braces": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", "dependencies": { @@ -1048,8 +784,6 @@ }, "node_modules/cacheable-lookup": { "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", "dev": true, "license": "MIT", "engines": { @@ -1058,8 +792,6 @@ }, "node_modules/cacheable-request": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", - "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", "dev": true, "license": "MIT", "dependencies": { @@ -1077,8 +809,6 @@ }, "node_modules/cacheable-request/node_modules/get-stream": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "license": "MIT", "dependencies": { @@ -1093,8 +823,6 @@ }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", "engines": { @@ -1103,8 +831,6 @@ }, "node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { @@ -1120,8 +846,6 @@ }, "node_modules/clone-response": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", "dev": true, "license": "MIT", "dependencies": { @@ -1131,10 +855,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/clone-response/node_modules/mimic-response": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1146,15 +876,11 @@ }, "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, "license": "MIT" }, "node_modules/commander": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "dev": true, "license": "MIT", "engines": { @@ -1163,15 +889,11 @@ }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, "license": "MIT" }, "node_modules/content-disposition": { "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1183,8 +905,6 @@ }, "node_modules/cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "license": "MIT", "dependencies": { @@ -1198,8 +918,6 @@ }, "node_modules/debug": { "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1216,8 +934,6 @@ }, "node_modules/decompress-response": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1230,30 +946,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/deep-is": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true, "license": "MIT" }, "node_modules/defer-to-connect": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", "dev": true, "license": "MIT", "engines": { @@ -1262,8 +961,6 @@ }, "node_modules/dir-glob": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "license": "MIT", "dependencies": { @@ -1275,8 +972,6 @@ }, "node_modules/doctrine": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1288,8 +983,6 @@ }, "node_modules/end-of-stream": { "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "license": "MIT", "dependencies": { @@ -1298,8 +991,6 @@ }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", "engines": { @@ -1310,17 +1001,15 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "8.57.1", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -1367,8 +1056,6 @@ }, "node_modules/eslint-scope": { "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -1384,8 +1071,6 @@ }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1395,21 +1080,8 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -1419,10 +1091,17 @@ "node": "*" } }, + "node_modules/eslint/node_modules/minimatch/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/espree": { "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -1439,8 +1118,6 @@ }, "node_modules/esquery": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -1452,8 +1129,6 @@ }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -1465,8 +1140,6 @@ }, "node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -1475,8 +1148,6 @@ }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -1485,8 +1156,6 @@ }, "node_modules/execa": { "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", "dev": true, "license": "MIT", "dependencies": { @@ -1504,8 +1173,6 @@ }, "node_modules/execa/node_modules/cross-spawn": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", "dev": true, "license": "MIT", "dependencies": { @@ -1514,10 +1181,8 @@ "which": "^1.2.9" } }, - "node_modules/execa/node_modules/shebang-command": { + "node_modules/execa/node_modules/cross-spawn/node_modules/shebang-command": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, "license": "MIT", "dependencies": { @@ -1527,20 +1192,16 @@ "node": ">=0.10.0" } }, - "node_modules/execa/node_modules/shebang-regex": { + "node_modules/execa/node_modules/cross-spawn/node_modules/shebang-command/node_modules/shebang-regex": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/execa/node_modules/which": { + "node_modules/execa/node_modules/cross-spawn/node_modules/which": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "license": "ISC", "dependencies": { @@ -1552,8 +1213,6 @@ }, "node_modules/executable": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", - "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", "dev": true, "license": "MIT", "dependencies": { @@ -1565,8 +1224,6 @@ }, "node_modules/ext-list": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", - "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", "dev": true, "license": "MIT", "dependencies": { @@ -1578,8 +1235,6 @@ }, "node_modules/ext-name": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", - "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1592,15 +1247,11 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "license": "MIT", "dependencies": { @@ -1616,8 +1267,6 @@ }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "license": "ISC", "dependencies": { @@ -1629,22 +1278,16 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true, "license": "MIT" }, "node_modules/fastq": { "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "license": "ISC", "dependencies": { @@ -1653,8 +1296,6 @@ }, "node_modules/file-entry-cache": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "license": "MIT", "dependencies": { @@ -1666,8 +1307,6 @@ }, "node_modules/file-type": { "version": "17.1.6", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-17.1.6.tgz", - "integrity": "sha512-hlDw5Ev+9e883s0pwUsuuYNu4tD7GgpUnOvykjv1Gya0ZIjuKumthDRua90VUn6/nlRKAjcxLUnHNTIUWwWIiw==", "dev": true, "license": "MIT", "dependencies": { @@ -1684,8 +1323,6 @@ }, "node_modules/filename-reserved-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz", - "integrity": "sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==", "dev": true, "license": "MIT", "engines": { @@ -1697,8 +1334,6 @@ }, "node_modules/filenamify": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-5.1.1.tgz", - "integrity": "sha512-M45CbrJLGACfrPOkrTp3j2EcO9OBkKUYME0eiqOCa7i2poaklU0jhlIaMlr8ijLorT0uLAzrn3qXOp5684CkfA==", "dev": true, "license": "MIT", "dependencies": { @@ -1715,8 +1350,6 @@ }, "node_modules/fill-range": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "license": "MIT", "dependencies": { @@ -1728,8 +1361,6 @@ }, "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", "dependencies": { @@ -1745,8 +1376,6 @@ }, "node_modules/find-versions": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz", - "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==", "dev": true, "license": "MIT", "dependencies": { @@ -1761,8 +1390,6 @@ }, "node_modules/flat-cache": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "license": "MIT", "dependencies": { @@ -1776,37 +1403,16 @@ }, "node_modules/flatted": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true, "license": "ISC" }, "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true, "license": "ISC" }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/get-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", "dev": true, "license": "MIT", "engines": { @@ -1815,9 +1421,6 @@ }, "node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -1837,8 +1440,6 @@ }, "node_modules/glob-parent": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "license": "ISC", "dependencies": { @@ -1848,21 +1449,8 @@ "node": ">=10.13.0" } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/glob/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -1872,10 +1460,17 @@ "node": "*" } }, + "node_modules/glob/node_modules/minimatch/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/globals": { "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1890,8 +1485,6 @@ }, "node_modules/globby": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "license": "MIT", "dependencies": { @@ -1911,8 +1504,6 @@ }, "node_modules/got": { "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", "dev": true, "license": "MIT", "dependencies": { @@ -1937,15 +1528,11 @@ }, "node_modules/graphemer": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true, "license": "MIT" }, "node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", "engines": { @@ -1954,15 +1541,11 @@ }, "node_modules/http-cache-semantics": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "dev": true, "license": "BSD-2-Clause" }, "node_modules/http2-wrapper": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", "dev": true, "license": "MIT", "dependencies": { @@ -1975,8 +1558,6 @@ }, "node_modules/human-signals": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1985,8 +1566,6 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true, "funding": [ { @@ -2006,8 +1585,6 @@ }, "node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -2016,8 +1593,6 @@ }, "node_modules/import-fresh": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "license": "MIT", "dependencies": { @@ -2033,8 +1608,6 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", "engines": { @@ -2043,9 +1616,6 @@ }, "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, "license": "ISC", "dependencies": { @@ -2055,15 +1625,11 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, "license": "ISC" }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", "engines": { @@ -2072,8 +1638,6 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "license": "MIT", "dependencies": { @@ -2085,8 +1649,6 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "license": "MIT", "engines": { @@ -2095,8 +1657,6 @@ }, "node_modules/is-path-inside": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, "license": "MIT", "engines": { @@ -2105,8 +1665,6 @@ }, "node_modules/is-plain-obj": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true, "license": "MIT", "engines": { @@ -2115,8 +1673,6 @@ }, "node_modules/is-stream": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true, "license": "MIT", "engines": { @@ -2125,15 +1681,11 @@ }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, "license": "ISC" }, "node_modules/js-yaml": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "license": "MIT", "dependencies": { @@ -2145,29 +1697,21 @@ }, "node_modules/json-buffer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true, "license": "MIT" }, "node_modules/keyv": { "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "license": "MIT", "dependencies": { @@ -2176,8 +1720,6 @@ }, "node_modules/levn": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2190,8 +1732,6 @@ }, "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", "dependencies": { @@ -2206,15 +1746,11 @@ }, "node_modules/lodash.merge": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true, "license": "MIT" }, "node_modules/lowercase-keys": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "dev": true, "license": "MIT", "engines": { @@ -2223,8 +1759,6 @@ }, "node_modules/lru-cache": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, "license": "ISC", "dependencies": { @@ -2234,15 +1768,11 @@ }, "node_modules/merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true, "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, "license": "MIT", "engines": { @@ -2251,8 +1781,6 @@ }, "node_modules/micromatch": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { @@ -2265,8 +1793,6 @@ }, "node_modules/mime-db": { "version": "1.53.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", - "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", "dev": true, "license": "MIT", "engines": { @@ -2275,8 +1801,6 @@ }, "node_modules/mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, "license": "MIT", "engines": { @@ -2284,19 +1808,18 @@ } }, "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "version": "3.1.0", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/minimatch": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { @@ -2311,22 +1834,16 @@ }, "node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "license": "MIT" }, "node_modules/natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true, "license": "MIT" }, "node_modules/normalize-url": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "dev": true, "license": "MIT", "engines": { @@ -2338,8 +1855,6 @@ }, "node_modules/npm-run-path": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", "dev": true, "license": "MIT", "dependencies": { @@ -2351,8 +1866,6 @@ }, "node_modules/npm-run-path/node_modules/path-key": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "dev": true, "license": "MIT", "engines": { @@ -2361,8 +1874,6 @@ }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "license": "ISC", "dependencies": { @@ -2371,8 +1882,6 @@ }, "node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "license": "MIT", "dependencies": { @@ -2387,8 +1896,6 @@ }, "node_modules/optionator": { "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "license": "MIT", "dependencies": { @@ -2405,8 +1912,6 @@ }, "node_modules/os-filter-obj": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz", - "integrity": "sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg==", "dev": true, "license": "MIT", "dependencies": { @@ -2418,8 +1923,6 @@ }, "node_modules/p-cancelable": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", "dev": true, "license": "MIT", "engines": { @@ -2428,8 +1931,6 @@ }, "node_modules/p-finally": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", "dev": true, "license": "MIT", "engines": { @@ -2438,8 +1939,6 @@ }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2454,8 +1953,6 @@ }, "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", "dependencies": { @@ -2470,8 +1967,6 @@ }, "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "license": "MIT", "dependencies": { @@ -2483,8 +1978,6 @@ }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", "engines": { @@ -2493,8 +1986,6 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "license": "MIT", "engines": { @@ -2503,8 +1994,6 @@ }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", "engines": { @@ -2513,8 +2002,6 @@ }, "node_modules/path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, "license": "MIT", "engines": { @@ -2523,8 +2010,6 @@ }, "node_modules/peek-readable": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.2.0.tgz", - "integrity": "sha512-U94a+eXHzct7vAd19GH3UQ2dH4Satbng0MyYTMaQatL0pvYYL5CTPR25HBhKtecl+4bfu1/i3vC6k0hydO5Vcw==", "dev": true, "license": "MIT", "engines": { @@ -2537,8 +2022,6 @@ }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", "engines": { @@ -2550,8 +2033,6 @@ }, "node_modules/pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, "license": "MIT", "engines": { @@ -2559,13 +2040,11 @@ } }, "node_modules/playwright": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.0.tgz", - "integrity": "sha512-jOWiRq2pdNAX/mwLiwFYnPHpEZ4rM+fRSQpRHwEwZlP2PUANvL3+aJOF/bvISMhFD30rqMxUB4RJx9aQbfh4Ww==", + "version": "1.47.2", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.47.0" + "playwright-core": "1.47.2" }, "bin": { "playwright": "cli.js" @@ -2578,9 +2057,7 @@ } }, "node_modules/playwright-core": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.0.tgz", - "integrity": "sha512-1DyHT8OqkcfCkYUD9zzUTfg7EfTd+6a8MkD/NWOvjo0u/SCNd5YmY/lJwFvUZOxJbWNds+ei7ic2+R/cRz/PDg==", + "version": "1.47.2", "dev": true, "license": "Apache-2.0", "bin": { @@ -2592,8 +2069,6 @@ }, "node_modules/prelude-ls": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "license": "MIT", "engines": { @@ -2602,8 +2077,6 @@ }, "node_modules/prettier": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "license": "MIT", "bin": { @@ -2618,15 +2091,11 @@ }, "node_modules/pseudomap": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", "dev": true, "license": "ISC" }, "node_modules/pump": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.1.tgz", - "integrity": "sha512-2ynnAmUu45oUSq51AQbeugLkMSKaz8FqVpZ6ykTqzOVkzXe8u/ezkGsYrFJqKZx+D9cVxoDrSbR7CeAwxFa5cQ==", + "version": "3.0.2", "dev": true, "license": "MIT", "dependencies": { @@ -2636,8 +2105,6 @@ }, "node_modules/punycode": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", "engines": { @@ -2646,8 +2113,6 @@ }, "node_modules/queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -2667,8 +2132,6 @@ }, "node_modules/quick-lru": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "dev": true, "license": "MIT", "engines": { @@ -2680,8 +2143,6 @@ }, "node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "license": "MIT", "dependencies": { @@ -2695,8 +2156,6 @@ }, "node_modules/readable-web-to-node-stream": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", - "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", "dev": true, "license": "MIT", "dependencies": { @@ -2712,15 +2171,11 @@ }, "node_modules/resolve-alpn": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", "dev": true, "license": "MIT" }, "node_modules/resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "license": "MIT", "engines": { @@ -2729,8 +2184,6 @@ }, "node_modules/responselike": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "dev": true, "license": "MIT", "dependencies": { @@ -2742,8 +2195,6 @@ }, "node_modules/reusify": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, "license": "MIT", "engines": { @@ -2753,9 +2204,6 @@ }, "node_modules/rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -2770,8 +2218,6 @@ }, "node_modules/run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -2794,8 +2240,6 @@ }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { @@ -2815,8 +2259,6 @@ }, "node_modules/semver": { "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", "bin": { @@ -2828,8 +2270,6 @@ }, "node_modules/semver-regex": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", - "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", "dev": true, "license": "MIT", "engines": { @@ -2841,8 +2281,6 @@ }, "node_modules/semver-truncate": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-3.0.0.tgz", - "integrity": "sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg==", "dev": true, "license": "MIT", "dependencies": { @@ -2857,8 +2295,6 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "license": "MIT", "dependencies": { @@ -2870,8 +2306,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", "engines": { @@ -2880,15 +2314,11 @@ }, "node_modules/signal-exit": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true, "license": "ISC" }, "node_modules/slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", "engines": { @@ -2897,8 +2327,6 @@ }, "node_modules/sort-keys": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", "dev": true, "license": "MIT", "dependencies": { @@ -2910,8 +2338,6 @@ }, "node_modules/sort-keys-length": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", - "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", "dev": true, "license": "MIT", "dependencies": { @@ -2923,8 +2349,6 @@ }, "node_modules/source-map": { "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -2933,8 +2357,6 @@ }, "node_modules/string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "license": "MIT", "dependencies": { @@ -2943,8 +2365,6 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { @@ -2956,8 +2376,6 @@ }, "node_modules/strip-eof": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", "dev": true, "license": "MIT", "engines": { @@ -2966,8 +2384,6 @@ }, "node_modules/strip-final-newline": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, "license": "MIT", "engines": { @@ -2976,8 +2392,6 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", "engines": { @@ -2989,8 +2403,6 @@ }, "node_modules/strip-outer": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-2.0.0.tgz", - "integrity": "sha512-A21Xsm1XzUkK0qK1ZrytDUvqsQWict2Cykhvi0fBQntGG5JSprESasEyV1EZ/4CiR5WB5KjzLTrP/bO37B0wPg==", "dev": true, "license": "MIT", "engines": { @@ -3002,8 +2414,6 @@ }, "node_modules/strtok3": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.1.1.tgz", - "integrity": "sha512-mKX8HA/cdBqMKUr0MMZAFssCkIGoZeSCMXgnt79yKxNFguMLVFgRe6wB+fsL0NmoHDbeyZXczy7vEPSoo3rkzg==", "dev": true, "license": "MIT", "dependencies": { @@ -3020,8 +2430,6 @@ }, "node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { @@ -3033,15 +2441,11 @@ }, "node_modules/text-table": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true, "license": "MIT" }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3053,8 +2457,6 @@ }, "node_modules/token-types": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz", - "integrity": "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==", "dev": true, "license": "MIT", "dependencies": { @@ -3071,8 +2473,6 @@ }, "node_modules/trim-repeated": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-2.0.0.tgz", - "integrity": "sha512-QUHBFTJGdOwmp0tbOG505xAgOp/YliZP/6UgafFXYZ26WT1bvQmSMJUvkeVSASuJJHbqsFbynTvkd5W8RBTipg==", "dev": true, "license": "MIT", "dependencies": { @@ -3084,8 +2484,6 @@ }, "node_modules/trim-repeated/node_modules/escape-string-regexp": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, "license": "MIT", "engines": { @@ -3097,8 +2495,6 @@ }, "node_modules/ts-api-utils": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "license": "MIT", "engines": { @@ -3110,8 +2506,6 @@ }, "node_modules/type-check": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "license": "MIT", "dependencies": { @@ -3123,8 +2517,6 @@ }, "node_modules/type-fest": { "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { @@ -3135,9 +2527,7 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.6.2", "dev": true, "license": "Apache-2.0", "bin": { @@ -3145,20 +2535,16 @@ "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/undici-types": { "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true, "license": "MIT" }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -3167,15 +2553,11 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true, "license": "MIT" }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", "dependencies": { @@ -3190,8 +2572,6 @@ }, "node_modules/word-wrap": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "license": "MIT", "engines": { @@ -3200,22 +2580,16 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true, "license": "ISC" }, "node_modules/yallist": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", "dev": true, "license": "ISC" }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index f9610a1..5684b24 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,13 @@ "description": "A pure javascript shim for WASI", "type": "module", "scripts": { - "build": "swc src -d dist -s true && tsc --emitDeclarationOnly", + "build": "npm run worker && swc src -d dist -s true && tsc --emitDeclarationOnly", "prepare": "swc src -d dist && tsc --emitDeclarationOnly", "test:node": "./test/run-testsuite.sh node", "test:browser": "playwright-core install && ./test/run-testsuite.sh browser", "test": "npm run test:node && npm run test:browser", - "check": "tsc --noEmit && prettier src -c && eslint src/" + "check": "tsc --noEmit && prettier src -c && eslint src/", + "worker": "spack --config ./src/wasi_farm/shared_array_buffer/worker_background/spack.config.cjs && node src/wasi_farm/shared_array_buffer/worker_background/minify.js" }, "repository": { "type": "git", @@ -39,6 +40,9 @@ "eslint": "^8.50.0", "playwright": "^1.40.1", "prettier": "^3.0.3", - "typescript": "^4.9.5" + "typescript": "^5.6.2" + }, + "dependencies": { + "@bjorn3/browser_wasi_shim": "file:" } } diff --git a/src/fs_mem.ts b/src/fs_mem.ts index 261743c..dcfaf7d 100644 --- a/src/fs_mem.ts +++ b/src/fs_mem.ts @@ -128,7 +128,7 @@ export class OpenDirectory extends Fd { super(); this.dir = dir; } - + OpenDirectory; // eslint-disable-next-line @typescript-eslint/no-unused-vars fd_seek(offset: bigint, whence: number): { ret: number; offset: bigint } { return { ret: wasi.ERRNO_BADF, offset: 0n }; @@ -151,10 +151,10 @@ export class OpenDirectory extends Fd { ret: number; dirent: wasi.Dirent | null; } { - // if (debug.enabled) { + if (debug.enabled) { debug.log("readdir_single", cookie); debug.log(cookie, this.dir.contents.keys()); - // } + } if (cookie == 0n) { return { diff --git a/src/index.ts b/src/index.ts index d50418e..a3ed42a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,7 @@ import WASI, { WASIProcExit } from "./wasi.js"; export { WASI, WASIProcExit }; import { WASIFarm, WASIFarmRef, WASIFarmAnimal } from "./wasi_farm/index.js"; export { WASIFarm, WASIFarmRef, WASIFarmAnimal }; +export { thread_spawn_on_worker } from "./wasi_farm/index.js"; export { Fd, Inode } from "./fd.js"; export { File, diff --git a/src/serialize_error.ts b/src/serialize_error.ts new file mode 100644 index 0000000..0672412 --- /dev/null +++ b/src/serialize_error.ts @@ -0,0 +1,23 @@ +export type SerializedError = { + message: string; + name: string; + stack: string; + cause?: unknown; +}; + +export const serialize = (error: Error): SerializedError => { + return { + message: error.message, + name: error.name, + stack: error.stack, + cause: error.cause, + }; +}; + +export const deserialize = (serializedError: SerializedError): Error => { + const error = new Error(serializedError.message); + error.name = serializedError.name; + error.stack = serializedError.stack.replace(/.wasm:/g, ".wasm\n"); + error.cause = serializedError.cause; + return error; +}; diff --git a/src/wasi_farm/animals.ts b/src/wasi_farm/animals.ts index c0c06cb..96e5d40 100644 --- a/src/wasi_farm/animals.ts +++ b/src/wasi_farm/animals.ts @@ -1,24 +1,43 @@ import { debug } from "../debug.js"; -import { Options, WASIProcExit } from "../wasi.js"; -import { WASIFarmRef, WASIFarmRefObject } from "./ref.js"; +import { type Options, WASIProcExit } from "../wasi.js"; import * as wasi from "../wasi_defs.js"; -import { WASIFarmRefUseArrayBuffer, WASIFarmRefUseArrayBufferObject } from "./shared_array_buffer/ref.js"; -import { FdCloseSender } from "./sender.js"; +import type { WASIFarmRef } from "./ref.js"; +import type { WASIFarmRefObject } from "./ref.js"; +import type { FdCloseSender } from "./sender.js"; +import { WASIFarmRefUseArrayBuffer } from "./shared_array_buffer/index.js"; +import type { WASIFarmRefUseArrayBufferObject } from "./shared_array_buffer/index.js"; +import { ThreadSpawner } from "./shared_array_buffer/index.js"; export class WASIFarmAnimal { - private args: Array; - private env: Array; + args: Array; + env: Array; private wasi_farm_refs: WASIFarmRef[]; private id_in_wasi_farm_ref: Array; - private inst: { exports: { memory: WebAssembly.Memory } }; + inst: { exports: { memory: WebAssembly.Memory } }; // eslint-disable-next-line @typescript-eslint/no-explicit-any wasiImport: { [key: string]: (...args: Array) => unknown }; + wasiThreadImport: { + "thread-spawn": (start_arg: number) => number; + }; + private can_array_buffer; + private can_thread_spawn: boolean; + + private thread_spawner: ThreadSpawner; + + async wait_worker_background_worker(): Promise { + await this.thread_spawner.wait_worker_background_worker(); + } + + check_worker_background_worker(): void { + this.thread_spawner.check_worker_background_worker(); + } + // Each process has a specific fd that it can access. // If it does not exist in the map, it cannot be accessed. // child process can access parent process's fd. @@ -26,7 +45,9 @@ export class WASIFarmAnimal { // [fd, wasi_ref_n] protected fd_map: Array<[number, number]>; - protected get_fd_and_wasi_ref(fd: number): [number | undefined, WASIFarmRef | undefined] { + protected get_fd_and_wasi_ref( + fd: number, + ): [number | undefined, WASIFarmRef | undefined] { const mapped_fd_and_wasi_ref_n = this.fd_map[fd]; if (!mapped_fd_and_wasi_ref_n) { // console.log("fd", fd, "is not found"); @@ -37,7 +58,9 @@ export class WASIFarmAnimal { return [mapped_fd, this.wasi_farm_refs[wasi_ref_n]]; } - protected get_fd_and_wasi_ref_n(fd: number): [number | undefined, number | undefined] { + protected get_fd_and_wasi_ref_n( + fd: number, + ): [number | undefined, number | undefined] { const mapped_fd_and_wasi_ref_n = this.fd_map[fd]; if (!mapped_fd_and_wasi_ref_n) { // console.log("fd", fd, "is not found"); @@ -54,15 +77,107 @@ export class WASIFarmAnimal { exports: { memory: WebAssembly.Memory; _start: () => unknown }; }) { this.inst = instance; + try { instance.exports._start(); + + if (this.can_thread_spawn) { + this.thread_spawner.done_notify(0); + } + return 0; } catch (e) { if (e instanceof WASIProcExit) { + if (this.can_thread_spawn) { + this.thread_spawner.done_notify(e.code); + } + return e.code; - } else { - throw e; } + throw e; + } + } + + /// Start a WASI command on a thread + /// If a module has child threads and a child thread throws an error, + /// the main thread should also be stopped, + /// but there is no way to stop it, + /// so the entire worker is stopped. + /// If it is not necessary, do not use it. + /// Custom imports are not implemented, + /// function because it cannot be passed to other threads. + /// If the sharedObject library someday supports synchronization, it could be used to support this. + async async_start_on_thread(): Promise { + if (!this.can_thread_spawn) { + throw new Error("thread_spawn is not supported"); + } + + await this.wait_worker_background_worker(); + + if (this.inst) { + throw new Error("what happened?"); + } + + const view = new Uint8Array(this.get_share_memory().buffer); + view.fill(0); + + await this.thread_spawner.async_start_on_thread(this.args, this.env); + + const code = await this.thread_spawner.async_wait_done_or_error(); + + return code; + } + + block_start_on_thread(): number { + if (!this.can_thread_spawn) { + throw new Error("thread_spawn is not supported"); + } + + console.log("block_start_on_thread"); + + this.check_worker_background_worker(); + + console.log("block_start_on_thread"); + + if (this.inst) { + throw new Error("what happened?"); + } + + const view = new Uint8Array(this.get_share_memory().buffer); + view.fill(0); + + console.log("block_start_on_thread: start"); + + this.thread_spawner.block_start_on_thread(this.args, this.env); + + console.log("block_start_on_thread: wait"); + + const code = this.thread_spawner.block_wait_done_or_error(); + + console.log("block_start_on_thread: done"); + + return code; + } + + wasi_thread_start( + instance: { + exports: { + memory: WebAssembly.Memory; + wasi_thread_start: (thread_id: number, start_arg: number) => void; + }; + }, + thread_id: number, + start_arg: number, + ) { + this.inst = instance; + try { + instance.exports.wasi_thread_start(thread_id, start_arg); + return 0; + } catch (e) { + if (e instanceof WASIProcExit) { + return e.code; + } + throw e; } } @@ -81,27 +196,30 @@ export class WASIFarmAnimal { override_fd_maps?: Array, ) { this.fd_map = [undefined, undefined, undefined]; + // console.log("wasi_farm_refs", wasi_farm_refs); for (let i = 0; i < wasi_farm_refs.length; i++) { // console.log("fd_map", [...this.fd_map]); const wasi_farm_ref = wasi_farm_refs[i]; // console.log("override_fd_map", wasi_farm_ref.default_fds); - const override_fd_map = override_fd_maps ? override_fd_maps[i] : wasi_farm_ref.default_fds; + const override_fd_map = override_fd_maps + ? override_fd_maps[i] + : wasi_farm_ref.default_fds; // console.log("override_fd_map", override_fd_map); const stdin = wasi_farm_ref.get_stdin(); const stdout = wasi_farm_ref.get_stdout(); const stderr = wasi_farm_ref.get_stderr(); - console.log("stdin", stdin, "stdout", stdout, "stderr", stderr); + // console.log("stdin", stdin, "stdout", stdout, "stderr", stderr); if (stdin !== undefined) { if (override_fd_map.includes(stdin)) { this.fd_map[0] = [stdin, i]; } } if (stdout !== undefined) { - console.log("stdout", stdout, i, "override_fd_map", override_fd_map); + // console.log("stdout", stdout, i, "override_fd_map", override_fd_map); if (override_fd_map.includes(stdout)) { - console.log("stdout defined"); + // console.log("stdout defined"); this.fd_map[1] = [stdout, i]; } } @@ -120,6 +238,7 @@ export class WASIFarmAnimal { // console.log("fd_map", this.fd_map); } + if (this.fd_map[0] === undefined) { throw new Error("stdin is not found"); } @@ -196,18 +315,28 @@ export class WASIFarmAnimal { } } + get_share_memory(): WebAssembly.Memory { + return this.thread_spawner.get_share_memory(); + } + constructor( wasi_farm_refs: WASIFarmRefObject[] | WASIFarmRefObject, args: Array, env: Array, - options: Options = {}, + options: Options & { + can_thread_spawn?: boolean; + thread_spawn_worker_url?: string; + thread_spawn_wasm?: WebAssembly.Module; + } = {}, override_fd_maps?: Array, + thread_spawner?: ThreadSpawner, ) { debug.enable(options.debug); let wasi_farm_refs_tmp: WASIFarmRefObject[]; if (Array.isArray(wasi_farm_refs)) { - wasi_farm_refs_tmp = wasi_farm_refs as unknown as Array; + wasi_farm_refs_tmp = + wasi_farm_refs as unknown as Array; } else { wasi_farm_refs_tmp = [wasi_farm_refs as unknown as WASIFarmRefObject]; } @@ -223,17 +352,47 @@ export class WASIFarmAnimal { this.wasi_farm_refs = []; for (let i = 0; i < wasi_farm_refs_tmp.length; i++) { if (this.can_array_buffer) { - this.wasi_farm_refs.push(WASIFarmRefUseArrayBuffer.init_self(wasi_farm_refs_tmp[i] as WASIFarmRefUseArrayBufferObject)); + this.wasi_farm_refs.push( + WASIFarmRefUseArrayBuffer.init_self( + wasi_farm_refs_tmp[i] as WASIFarmRefUseArrayBufferObject, + ), + ); } else { throw new Error("Non SharedArrayBuffer is not supported yet"); } - this.id_in_wasi_farm_ref.push( - this.wasi_farm_refs[i].set_id(), - ) + this.id_in_wasi_farm_ref.push(this.wasi_farm_refs[i].set_id()); } // console.log("this.wasi_farm_refs", this.wasi_farm_refs); + if (options.can_thread_spawn) { + this.can_thread_spawn = options.can_thread_spawn; + + if (thread_spawner) { + if (!(thread_spawner instanceof ThreadSpawner)) { + throw new Error("thread_spawner is not ThreadSpawner"); + } + + this.thread_spawner = thread_spawner; + } else { + if (options.thread_spawn_worker_url === undefined) { + throw new Error("thread_spawn_worker_url is not defined"); + } + if (options.thread_spawn_wasm === undefined) { + throw new Error("thread_spawn_wasm is not defined"); + } + + this.thread_spawner = new ThreadSpawner( + options.thread_spawn_worker_url, + wasi_farm_refs_tmp, + undefined, + undefined, + undefined, + options.thread_spawn_wasm, + ); + } + } + this.mapping_fds(this.wasi_farm_refs, override_fd_maps); // console.log("this.fd_map", this.fd_map); @@ -272,12 +431,12 @@ export class WASIFarmAnimal { argv_buf += arg.length + 1; } // if (debug.enabled) { - debug.log( - "read args_get: args", - new TextDecoder("utf-8").decode( - buffer8.slice(orig_argv_buf, argv_buf), - ), - ); + debug.log( + "read args_get: args", + new TextDecoder("utf-8").decode( + buffer8.slice(orig_argv_buf, argv_buf), + ), + ); // } return 0; }, @@ -311,12 +470,12 @@ export class WASIFarmAnimal { environ_buf += e.length + 1; } // if (debug.enabled) { - debug.log( - "read environ_get: environ", - new TextDecoder("utf-8").decode( - buffer8.slice(orig_environ_buf, environ_buf), - ), - ); + debug.log( + "read environ_get: environ", + new TextDecoder("utf-8").decode( + buffer8.slice(orig_environ_buf, environ_buf), + ), + ); // } return 0; }, @@ -351,7 +510,7 @@ export class WASIFarmAnimal { BigInt(new Date().getTime()) * 1_000_000n, true, ); - } else if (id == wasi.CLOCKID_MONOTONIC) { + } else if (id === wasi.CLOCKID_MONOTONIC) { let monotonic_time: bigint; try { monotonic_time = BigInt(Math.round(performance.now() * 1000000)); @@ -383,11 +542,7 @@ export class WASIFarmAnimal { } return wasi_farm_ref.fd_advise(mapped_fd); }, - fd_allocate( - fd: number, - offset: bigint, - len: bigint, - ) { + fd_allocate(fd: number, offset: bigint, len: bigint) { self.check_fds(); const [mapped_fd, wasi_farm_ref] = self.get_fd_and_wasi_ref(fd); if (mapped_fd === undefined || wasi_farm_ref === undefined) { @@ -436,13 +591,21 @@ export class WASIFarmAnimal { } return wasi_farm_ref.fd_fdstat_set_flags(mapped_fd, flags); }, - fd_fdstat_set_rights(fd: number, fs_rights_base: bigint, fs_rights_inheriting: bigint) { + fd_fdstat_set_rights( + fd: number, + fs_rights_base: bigint, + fs_rights_inheriting: bigint, + ) { self.check_fds(); const [mapped_fd, wasi_farm_ref] = self.get_fd_and_wasi_ref(fd); if (mapped_fd === undefined || wasi_farm_ref === undefined) { return wasi.ERRNO_BADF; } - return wasi_farm_ref.fd_fdstat_set_rights(mapped_fd, fs_rights_base, fs_rights_inheriting); + return wasi_farm_ref.fd_fdstat_set_rights( + mapped_fd, + fs_rights_base, + fs_rights_inheriting, + ); }, fd_filestat_get(fd: number, filestat_ptr: number) { self.check_fds(); @@ -467,15 +630,31 @@ export class WASIFarmAnimal { } return wasi_farm_ref.fd_filestat_set_size(mapped_fd, size); }, - fd_filestat_set_times(fd: number, atim: bigint, mtim: bigint, fst_flags: number) { + fd_filestat_set_times( + fd: number, + atim: bigint, + mtim: bigint, + fst_flags: number, + ) { self.check_fds(); const [mapped_fd, wasi_farm_ref] = self.get_fd_and_wasi_ref(fd); if (mapped_fd === undefined || wasi_farm_ref === undefined) { return wasi.ERRNO_BADF; } - return wasi_farm_ref.fd_filestat_set_times(mapped_fd, atim, mtim, fst_flags); + return wasi_farm_ref.fd_filestat_set_times( + mapped_fd, + atim, + mtim, + fst_flags, + ); }, - fd_pread(fd: number, iovs_ptr: number, iovs_len: number, offset: bigint, nread_ptr: number) { + fd_pread( + fd: number, + iovs_ptr: number, + iovs_len: number, + offset: bigint, + nread_ptr: number, + ) { self.check_fds(); const [mapped_fd, wasi_farm_ref] = self.get_fd_and_wasi_ref(fd); if (mapped_fd === undefined || wasi_farm_ref === undefined) { @@ -483,8 +662,16 @@ export class WASIFarmAnimal { } const buffer = new DataView(self.inst.exports.memory.buffer); const buffer8 = new Uint8Array(self.inst.exports.memory.buffer); - const iovs_view = new Uint32Array(buffer.buffer, iovs_ptr, iovs_len * 2); - const [nerad_and_read_data, ret] = wasi_farm_ref.fd_pread(mapped_fd, iovs_view, offset); + const iovs_view = new Uint32Array( + buffer.buffer, + iovs_ptr, + iovs_len * 2, + ); + const [nerad_and_read_data, ret] = wasi_farm_ref.fd_pread( + mapped_fd, + iovs_view, + offset, + ); if (nerad_and_read_data) { const iovecs = wasi.Iovec.read_bytes_array( buffer, @@ -501,7 +688,7 @@ export class WASIFarmAnimal { } buffer8.set( read_data.slice(nreaded, nreaded + iovec.buf_len), - iovec.buf + iovec.buf, ); nreaded += iovec.buf_len; } @@ -530,7 +717,10 @@ export class WASIFarmAnimal { return [undefined, wasi.ERRNO_BADF]; } // console.log("fd_prestat_dir_name: fd", mapped_fd, "path_len", path_len); - const [path, ret] = wasi_farm_ref.fd_prestat_dir_name(mapped_fd, path_len); + const [path, ret] = wasi_farm_ref.fd_prestat_dir_name( + mapped_fd, + path_len, + ); if (path) { // console.log("fd_prestat_dir_name", new TextDecoder().decode(path)); // console.log("fd_prestat_dir_name", path); @@ -539,7 +729,13 @@ export class WASIFarmAnimal { } return ret; }, - fd_pwrite(fd: number, iovs_ptr: number, iovs_len: number, offset: bigint, nwritten_ptr: number) { + fd_pwrite( + fd: number, + iovs_ptr: number, + iovs_len: number, + offset: bigint, + nwritten_ptr: number, + ) { self.check_fds(); const [mapped_fd, wasi_farm_ref] = self.get_fd_and_wasi_ref(fd); if (mapped_fd === undefined || wasi_farm_ref === undefined) { @@ -547,15 +743,16 @@ export class WASIFarmAnimal { } const buffer = new DataView(self.inst.exports.memory.buffer); const buffer8 = new Uint8Array(self.inst.exports.memory.buffer); - const iovecs = wasi.Ciovec.read_bytes_array( - buffer, - iovs_ptr, - iovs_len, + const iovecs = wasi.Ciovec.read_bytes_array(buffer, iovs_ptr, iovs_len); + const data = new Uint8Array( + iovecs.reduce((acc, iovec) => acc + iovec.buf_len, 0), ); - const data = new Uint8Array(iovecs.reduce((acc, iovec) => acc + iovec.buf_len, 0)); let nwritten = 0; for (const iovec of iovecs) { - data.set(buffer8.slice(iovec.buf, iovec.buf + iovec.buf_len), nwritten); + data.set( + buffer8.slice(iovec.buf, iovec.buf + iovec.buf_len), + nwritten, + ); nwritten += iovec.buf_len; } const [written, ret] = wasi_farm_ref.fd_pwrite(mapped_fd, data, offset); @@ -564,7 +761,12 @@ export class WASIFarmAnimal { } return ret; }, - fd_read(fd: number, iovs_ptr: number, iovs_len: number, nread_ptr: number) { + fd_read( + fd: number, + iovs_ptr: number, + iovs_len: number, + nread_ptr: number, + ) { self.check_fds(); const [mapped_fd, wasi_farm_ref] = self.get_fd_and_wasi_ref(fd); if (mapped_fd === undefined || wasi_farm_ref === undefined) { @@ -572,9 +774,16 @@ export class WASIFarmAnimal { } const buffer = new DataView(self.inst.exports.memory.buffer); const buffer8 = new Uint8Array(self.inst.exports.memory.buffer); - const iovs_view = new Uint32Array(buffer.buffer, iovs_ptr, iovs_len * 2); + const iovs_view = new Uint32Array( + buffer.buffer, + iovs_ptr, + iovs_len * 2, + ); - const [nerad_and_read_data, ret] = wasi_farm_ref.fd_read(mapped_fd, iovs_view); + const [nerad_and_read_data, ret] = wasi_farm_ref.fd_read( + mapped_fd, + iovs_view, + ); if (nerad_and_read_data) { const iovecs = wasi.Iovec.read_bytes_array( buffer, @@ -597,14 +806,20 @@ export class WASIFarmAnimal { } buffer8.set( read_data.slice(nreaded, nreaded + iovec.buf_len), - iovec.buf + iovec.buf, ); nreaded += iovec.buf_len; } } return ret; }, - fd_readdir(fd: number, buf_ptr: number, buf_len: number, cookie: bigint, buf_used_ptr: number) { + fd_readdir( + fd: number, + buf_ptr: number, + buf_len: number, + cookie: bigint, + buf_used_ptr: number, + ) { self.check_fds(); const [mapped_fd, wasi_farm_ref] = self.get_fd_and_wasi_ref(fd); if (mapped_fd === undefined || wasi_farm_ref === undefined) { @@ -612,7 +827,11 @@ export class WASIFarmAnimal { } const buffer = new DataView(self.inst.exports.memory.buffer); const buffer8 = new Uint8Array(self.inst.exports.memory.buffer); - const [nerad_and_read_data, ret] = wasi_farm_ref.fd_readdir(mapped_fd, buf_len, cookie); + const [nerad_and_read_data, ret] = wasi_farm_ref.fd_readdir( + mapped_fd, + buf_len, + cookie, + ); if (nerad_and_read_data) { const [read_data, buf_used] = nerad_and_read_data; buffer.setUint32(buf_used_ptr, buf_used, true); @@ -626,14 +845,19 @@ export class WASIFarmAnimal { const [mapped_fd, wasi_farm_ref_n] = self.get_fd_and_wasi_ref_n(fd); const [mapped_to, wasi_farm_ref_to] = self.get_fd_and_wasi_ref(to); - if (mapped_fd === undefined || wasi_farm_ref_n === undefined || mapped_to === undefined || wasi_farm_ref_to === undefined) { + if ( + mapped_fd === undefined || + wasi_farm_ref_n === undefined || + mapped_to === undefined || + wasi_farm_ref_to === undefined + ) { return wasi.ERRNO_BADF; } const ret = wasi_farm_ref_to.fd_close(mapped_to); self.check_fds(); - if (ret != wasi.ERRNO_SUCCESS) { + if (ret !== wasi.ERRNO_SUCCESS) { return ret; } @@ -641,13 +865,22 @@ export class WASIFarmAnimal { return wasi.ERRNO_SUCCESS; }, - fd_seek(fd: number, offset: bigint, whence: number, newoffset_ptr: number) { + fd_seek( + fd: number, + offset: bigint, + whence: number, + newoffset_ptr: number, + ) { self.check_fds(); const [mapped_fd, wasi_farm_ref] = self.get_fd_and_wasi_ref(fd); if (mapped_fd === undefined || wasi_farm_ref === undefined) { return [undefined, wasi.ERRNO_BADF]; } - const [newoffset, ret] = wasi_farm_ref.fd_seek(mapped_fd, offset, whence); + const [newoffset, ret] = wasi_farm_ref.fd_seek( + mapped_fd, + offset, + whence, + ); if (newoffset) { const buffer = new DataView(self.inst.exports.memory.buffer); @@ -677,7 +910,12 @@ export class WASIFarmAnimal { } return ret; }, - fd_write(fd: number, iovs_ptr: number, iovs_len: number, nwritten_ptr: number) { + fd_write( + fd: number, + iovs_ptr: number, + iovs_len: number, + nwritten_ptr: number, + ) { self.check_fds(); const [mapped_fd, wasi_farm_ref] = self.get_fd_and_wasi_ref(fd); if (mapped_fd === undefined || wasi_farm_ref === undefined) { @@ -688,17 +926,18 @@ export class WASIFarmAnimal { const buffer = new DataView(self.inst.exports.memory.buffer); const buffer8 = new Uint8Array(self.inst.exports.memory.buffer); - const iovecs = wasi.Ciovec.read_bytes_array( - buffer, - iovs_ptr, - iovs_len, - ); + const iovecs = wasi.Ciovec.read_bytes_array(buffer, iovs_ptr, iovs_len); // console.log("iovecs", iovecs); - const data = new Uint8Array(iovecs.reduce((acc, iovec) => acc + iovec.buf_len, 0)); + const data = new Uint8Array( + iovecs.reduce((acc, iovec) => acc + iovec.buf_len, 0), + ); // console.log("data", data); let nwritten = 0; for (const iovec of iovecs) { - data.set(buffer8.slice(iovec.buf, iovec.buf + iovec.buf_len), nwritten); + data.set( + buffer8.slice(iovec.buf, iovec.buf + iovec.buf_len), + nwritten, + ); nwritten += iovec.buf_len; } @@ -723,7 +962,13 @@ export class WASIFarmAnimal { const path = buffer8.slice(path_ptr, path_ptr + path_len); return wasi_farm_ref.path_create_directory(mapped_fd, path); }, - path_filestat_get(fd: number, flags: number, path_ptr: number, path_len: number, filestat_ptr: number) { + path_filestat_get( + fd: number, + flags: number, + path_ptr: number, + path_len: number, + filestat_ptr: number, + ) { self.check_fds(); const [mapped_fd, wasi_farm_ref] = self.get_fd_and_wasi_ref(fd); if (mapped_fd === undefined || wasi_farm_ref === undefined) { @@ -732,13 +977,25 @@ export class WASIFarmAnimal { const buffer = new DataView(self.inst.exports.memory.buffer); const buffer8 = new Uint8Array(self.inst.exports.memory.buffer); const path = buffer8.slice(path_ptr, path_ptr + path_len); - const [filestat, ret] = wasi_farm_ref.path_filestat_get(mapped_fd, flags, path); + const [filestat, ret] = wasi_farm_ref.path_filestat_get( + mapped_fd, + flags, + path, + ); if (filestat) { filestat.write_bytes(buffer, filestat_ptr); } return ret; }, - path_filestat_set_times(fd: number, flags: number, path_ptr: number, path_len: number, atim: bigint, mtim: bigint, fst_flags: number) { + path_filestat_set_times( + fd: number, + flags: number, + path_ptr: number, + path_len: number, + atim: bigint, + mtim: bigint, + fst_flags: number, + ) { self.check_fds(); const [mapped_fd, wasi_farm_ref] = self.get_fd_and_wasi_ref(fd); if (mapped_fd === undefined || wasi_farm_ref === undefined) { @@ -746,25 +1003,68 @@ export class WASIFarmAnimal { } const buffer8 = new Uint8Array(self.inst.exports.memory.buffer); const path = buffer8.slice(path_ptr, path_ptr + path_len); - return wasi_farm_ref.path_filestat_set_times(mapped_fd, flags, path, atim, mtim, fst_flags); + return wasi_farm_ref.path_filestat_set_times( + mapped_fd, + flags, + path, + atim, + mtim, + fst_flags, + ); }, // TODO! Make it work with different wasi_farm_ref - path_link(old_fd: number, old_flags: number, old_path_ptr: number, old_path_len: number, new_fd: number, new_path_ptr: number, new_path_len: number) { + path_link( + old_fd: number, + old_flags: number, + old_path_ptr: number, + old_path_len: number, + new_fd: number, + new_path_ptr: number, + new_path_len: number, + ) { self.check_fds(); const [mapped_old_fd, wasi_farm_ref] = self.get_fd_and_wasi_ref(old_fd); - const [mapped_new_fd, wasi_farm_ref_new] = self.get_fd_and_wasi_ref(new_fd); - if (mapped_old_fd === undefined || wasi_farm_ref === undefined || mapped_new_fd === undefined || wasi_farm_ref_new === undefined) { + const [mapped_new_fd, wasi_farm_ref_new] = + self.get_fd_and_wasi_ref(new_fd); + if ( + mapped_old_fd === undefined || + wasi_farm_ref === undefined || + mapped_new_fd === undefined || + wasi_farm_ref_new === undefined + ) { return wasi.ERRNO_BADF; } if (wasi_farm_ref !== wasi_farm_ref_new) { return wasi.ERRNO_BADF; } const buffer8 = new Uint8Array(self.inst.exports.memory.buffer); - const old_path = buffer8.slice(old_path_ptr, old_path_ptr + old_path_len); - const new_path = buffer8.slice(new_path_ptr, new_path_ptr + new_path_len); - return wasi_farm_ref.path_link(mapped_old_fd, old_flags, old_path, mapped_new_fd, new_path); + const old_path = buffer8.slice( + old_path_ptr, + old_path_ptr + old_path_len, + ); + const new_path = buffer8.slice( + new_path_ptr, + new_path_ptr + new_path_len, + ); + return wasi_farm_ref.path_link( + mapped_old_fd, + old_flags, + old_path, + mapped_new_fd, + new_path, + ); }, - path_open(fd: number, dirflags: number, path_ptr: number, path_len: number, oflags: number, fs_rights_base: bigint, fs_rights_inheriting: bigint, fs_flags: number, opened_fd_ptr: number) { + path_open( + fd: number, + dirflags: number, + path_ptr: number, + path_len: number, + oflags: number, + fs_rights_base: bigint, + fs_rights_inheriting: bigint, + fs_flags: number, + opened_fd_ptr: number, + ) { self.check_fds(); const [mapped_fd, wasi_farm_ref_n] = self.get_fd_and_wasi_ref_n(fd); if (mapped_fd === undefined || wasi_farm_ref_n === undefined) { @@ -773,18 +1073,36 @@ export class WASIFarmAnimal { const wasi_farm_ref = self.wasi_farm_refs[wasi_farm_ref_n]; const buffer8 = new Uint8Array(self.inst.exports.memory.buffer); const path = buffer8.slice(path_ptr, path_ptr + path_len); - const [opened_fd, ret] = wasi_farm_ref.path_open(mapped_fd, dirflags, path, oflags, fs_rights_base, fs_rights_inheriting, fs_flags); + const [opened_fd, ret] = wasi_farm_ref.path_open( + mapped_fd, + dirflags, + path, + oflags, + fs_rights_base, + fs_rights_inheriting, + fs_flags, + ); if (opened_fd) { if (self.fd_map.includes([opened_fd, wasi_farm_ref_n])) { throw new Error("opened_fd already exists"); } - const mapped_opened_fd = self.map_new_fd_and_notify(opened_fd, wasi_farm_ref_n); + const mapped_opened_fd = self.map_new_fd_and_notify( + opened_fd, + wasi_farm_ref_n, + ); const buffer = new DataView(self.inst.exports.memory.buffer); buffer.setUint32(opened_fd_ptr, mapped_opened_fd, true); } return ret; }, - path_readlink(fd: number, path_ptr: number, path_len: number, buf_ptr: number, buf_len: number, buf_used_ptr: number) { + path_readlink( + fd: number, + path_ptr: number, + path_len: number, + buf_ptr: number, + buf_len: number, + buf_used_ptr: number, + ) { self.check_fds(); const [mapped_fd, wasi_farm_ref] = self.get_fd_and_wasi_ref(fd); if (mapped_fd === undefined || wasi_farm_ref === undefined) { @@ -792,7 +1110,11 @@ export class WASIFarmAnimal { } const buffer8 = new Uint8Array(self.inst.exports.memory.buffer); const path = buffer8.slice(path_ptr, path_ptr + path_len); - const [buf, ret] = wasi_farm_ref.path_readlink(mapped_fd, path, buf_len); + const [buf, ret] = wasi_farm_ref.path_readlink( + mapped_fd, + path, + buf_len, + ); if (buf) { const buffer = new DataView(self.inst.exports.memory.buffer); buffer.setUint32(buf_used_ptr, buf.length, true); @@ -811,30 +1133,66 @@ export class WASIFarmAnimal { return wasi_farm_ref.path_remove_directory(mapped_fd, path); }, // TODO! Make it work with different wasi_farm_ref - path_rename(old_fd: number, old_path_ptr: number, old_path_len: number, new_fd: number, new_path_ptr: number, new_path_len: number) { + path_rename( + old_fd: number, + old_path_ptr: number, + old_path_len: number, + new_fd: number, + new_path_ptr: number, + new_path_len: number, + ) { self.check_fds(); const [mapped_old_fd, wasi_farm_ref] = self.get_fd_and_wasi_ref(old_fd); - const [mapped_new_fd, wasi_farm_ref_new] = self.get_fd_and_wasi_ref(new_fd); - if (mapped_old_fd === undefined || wasi_farm_ref === undefined || mapped_new_fd === undefined || wasi_farm_ref_new === undefined) { + const [mapped_new_fd, wasi_farm_ref_new] = + self.get_fd_and_wasi_ref(new_fd); + if ( + mapped_old_fd === undefined || + wasi_farm_ref === undefined || + mapped_new_fd === undefined || + wasi_farm_ref_new === undefined + ) { return wasi.ERRNO_BADF; } if (wasi_farm_ref !== wasi_farm_ref_new) { return wasi.ERRNO_BADF; } const buffer8 = new Uint8Array(self.inst.exports.memory.buffer); - const old_path = buffer8.slice(old_path_ptr, old_path_ptr + old_path_len); - const new_path = buffer8.slice(new_path_ptr, new_path_ptr + new_path_len); - return wasi_farm_ref.path_rename(mapped_old_fd, old_path, mapped_new_fd, new_path); + const old_path = buffer8.slice( + old_path_ptr, + old_path_ptr + old_path_len, + ); + const new_path = buffer8.slice( + new_path_ptr, + new_path_ptr + new_path_len, + ); + return wasi_farm_ref.path_rename( + mapped_old_fd, + old_path, + mapped_new_fd, + new_path, + ); }, - path_symlink(old_path_ptr: number, old_path_len: number, fd: number, new_path_ptr: number, new_path_len: number) { + path_symlink( + old_path_ptr: number, + old_path_len: number, + fd: number, + new_path_ptr: number, + new_path_len: number, + ) { self.check_fds(); const [mapped_fd, wasi_farm_ref] = self.get_fd_and_wasi_ref(fd); if (mapped_fd === undefined || wasi_farm_ref === undefined) { return wasi.ERRNO_BADF; } const buffer8 = new Uint8Array(self.inst.exports.memory.buffer); - const old_path = buffer8.slice(old_path_ptr, old_path_ptr + old_path_len); - const new_path = buffer8.slice(new_path_ptr, new_path_ptr + new_path_len); + const old_path = buffer8.slice( + old_path_ptr, + old_path_ptr + old_path_len, + ); + const new_path = buffer8.slice( + new_path_ptr, + new_path_ptr + new_path_len, + ); return wasi_farm_ref.path_symlink(old_path, mapped_fd, new_path); }, path_unlink_file(fd: number, path_ptr: number, path_len: number) { @@ -858,7 +1216,7 @@ export class WASIFarmAnimal { }, proc_raise(sig: number) { self.check_fds(); - throw "raised signal " + sig; + throw `raised signal ${sig}`; }, sched_yield() { self.check_fds(); @@ -902,6 +1260,24 @@ export class WASIFarmAnimal { self.check_fds(); throw "sockets not supported"; }, - } + }; + + this.wasiThreadImport = { + "thread-spawn": (start_arg: number) => { + self.check_fds(); + if (!self.can_thread_spawn) { + throw new Error("thread_spawn is not allowed"); + } + + const thread_id = self.thread_spawner.thread_spawn( + start_arg, + self.args, + self.env, + self.fd_map, + ); + + return thread_id; + }, + }; } } diff --git a/src/wasi_farm/farm.ts b/src/wasi_farm/farm.ts index cca48fd..7966339 100644 --- a/src/wasi_farm/farm.ts +++ b/src/wasi_farm/farm.ts @@ -1,9 +1,9 @@ import { debug } from "../debug.js"; -import { Fd } from "../fd.js"; -import { Options } from "../wasi.js"; -import { WASIFarmPark } from "./park.js"; -import { WASIFarmRefObject } from "./ref.js"; -import { WASIFarmParkUseArrayBuffer } from "./shared_array_buffer/park.js"; +import type { Fd } from "../fd.js"; +import type { Options } from "../wasi.js"; +import type { WASIFarmPark } from "./park.js"; +import type { WASIFarmRefObject } from "./ref.js"; +import { WASIFarmParkUseArrayBuffer } from "./shared_array_buffer/index.js"; export class WASIFarm { private fds: Array; @@ -52,10 +52,17 @@ export class WASIFarm { // Failed to execute 'postMessage' on 'Worker': // SharedArrayBuffer transfer requires self.crossOriginIsolated. try { - new SharedArrayBuffer(4); - this.can_array_buffer = true; - } catch (_) { - this.can_array_buffer = false; + new SharedArrayBuffer(4); + this.can_array_buffer = true; + } catch (e) { + this.can_array_buffer = false; + console.warn("SharedArrayBuffer is not supported:", e); + + if (!crossOriginIsolated) { + console.warn( + "SharedArrayBuffer is not supported because crossOriginIsolated is not enabled.", + ); + } } if (this.can_array_buffer) { @@ -92,7 +99,7 @@ export class WASIFarm { // console.log("fds", prop, value); this.fds[prop] = value; return true; - } + }, }); return fds; diff --git a/src/wasi_farm/index.ts b/src/wasi_farm/index.ts index 9dc3946..76b6389 100644 --- a/src/wasi_farm/index.ts +++ b/src/wasi_farm/index.ts @@ -1,4 +1,5 @@ +import { WASIFarmAnimal } from "./animals.js"; import { WASIFarm } from "./farm.js"; import { WASIFarmRef } from "./ref.js"; -import { WASIFarmAnimal } from "./animals.js"; -export { WASIFarm, WASIFarmRef, WASIFarmAnimal }; +import { thread_spawn_on_worker } from "./shared_array_buffer/index.js"; +export { WASIFarm, WASIFarmRef, WASIFarmAnimal, thread_spawn_on_worker }; diff --git a/src/wasi_farm/park.ts b/src/wasi_farm/park.ts index 94e7600..03e6119 100644 --- a/src/wasi_farm/park.ts +++ b/src/wasi_farm/park.ts @@ -1,7 +1,7 @@ -import { Fd } from "../fd.js"; -import { WASIFarmRefObject } from "./ref.js"; -import * as wasi from "../wasi_defs.js"; import { debug } from "../debug.js"; +import type { Fd } from "../fd.js"; +import * as wasi from "../wasi_defs.js"; +import type { WASIFarmRefObject } from "./ref.js"; export abstract class WASIFarmPark { abstract get_ref(): WASIFarmRefObject; @@ -49,12 +49,12 @@ export abstract class WASIFarmPark { const len = this.get_new_fd_lock.push(async () => { let ret = -1; for (let i = 0; i < this.fds.length; i++) { - if (this.fds[i] == undefined) { + if (this.fds[i] === undefined) { ret = i; break; } } - if (ret == -1) { + if (ret === -1) { ret = this.fds.length; // console.log("push_fd", this.fds.length) this.fds.push(undefined); @@ -68,17 +68,20 @@ export abstract class WASIFarmPark { } // If it's assigned, it's resolved. - resolve([async () => { - this.get_new_fd_lock.shift(); - const fn = this.get_new_fd_lock[0]; - if (fn != undefined) { - fn(); - } - // assigned and notify - await this.notify_set_fd(ret); - }, ret]); + resolve([ + async () => { + this.get_new_fd_lock.shift(); + const fn = this.get_new_fd_lock[0]; + if (fn !== undefined) { + fn(); + } + // assigned and notify + await this.notify_set_fd(ret); + }, + ret, + ]); }); - if (len == 1) { + if (len === 1) { this.get_new_fd_lock[0](); } }); @@ -86,44 +89,40 @@ export abstract class WASIFarmPark { } protected fd_advise(fd: number): number { - if (this.fds[fd] != undefined) { + if (this.fds[fd] !== undefined) { return wasi.ERRNO_SUCCESS; - } else { - return wasi.ERRNO_BADF; } + return wasi.ERRNO_BADF; } protected fd_allocate(fd: number, offset: bigint, len: bigint): number { - if (this.fds[fd] != undefined) { + if (this.fds[fd] !== undefined) { return this.fds[fd].fd_allocate(offset, len); - } else { - return wasi.ERRNO_BADF; } + return wasi.ERRNO_BADF; } protected async fd_close(fd: number): Promise { - if (this.fds[fd] != undefined) { + if (this.fds[fd] !== undefined) { const ret = this.fds[fd].fd_close(); this.fds[fd] = undefined; // console.log("fd_close1", fd); await this.notify_rm_fd(fd); // console.log("fd_close2", fd); return ret; - } else { - return wasi.ERRNO_BADF; } + return wasi.ERRNO_BADF; } protected fd_datasync(fd: number): number { - if (this.fds[fd] != undefined) { + if (this.fds[fd] !== undefined) { return this.fds[fd].fd_sync(); - } else { - return wasi.ERRNO_BADF; } + return wasi.ERRNO_BADF; } protected fd_fdstat_get(fd: number): [wasi.Fdstat | undefined, number] { - if (this.fds[fd] != undefined) { + if (this.fds[fd] !== undefined) { const { ret, fdstat } = this.fds[fd].fd_fdstat_get(); if (fdstat != null) { return [fdstat, ret]; @@ -134,23 +133,28 @@ export abstract class WASIFarmPark { } protected fd_fdstat_set_flags(fd: number, flags: number): number { - if (this.fds[fd] != undefined) { + if (this.fds[fd] !== undefined) { return this.fds[fd].fd_fdstat_set_flags(flags); - } else { - return wasi.ERRNO_BADF; } + return wasi.ERRNO_BADF; } - protected fd_fdstat_set_rights(fd: number, fs_rights_base: bigint, fs_rights_inheriting: bigint): number { - if (this.fds[fd] != undefined) { - return this.fds[fd].fd_fdstat_set_rights(fs_rights_base, fs_rights_inheriting); - } else { - return wasi.ERRNO_BADF; + protected fd_fdstat_set_rights( + fd: number, + fs_rights_base: bigint, + fs_rights_inheriting: bigint, + ): number { + if (this.fds[fd] !== undefined) { + return this.fds[fd].fd_fdstat_set_rights( + fs_rights_base, + fs_rights_inheriting, + ); } + return wasi.ERRNO_BADF; } protected fd_filestat_get(fd: number): [wasi.Filestat | undefined, number] { - if (this.fds[fd] != undefined) { + if (this.fds[fd] !== undefined) { const { ret, filestat } = this.fds[fd].fd_filestat_get(); if (filestat != null) { return [filestat, ret]; @@ -161,29 +165,36 @@ export abstract class WASIFarmPark { } protected fd_filestat_set_size(fd: number, size: bigint): number { - if (this.fds[fd] != undefined) { + if (this.fds[fd] !== undefined) { return this.fds[fd].fd_filestat_set_size(size); - } else { - return wasi.ERRNO_BADF; } + return wasi.ERRNO_BADF; } - protected fd_filestat_set_times(fd: number, atim: bigint, mtim: bigint, fst_flags: number): number { - if (this.fds[fd] != undefined) { + protected fd_filestat_set_times( + fd: number, + atim: bigint, + mtim: bigint, + fst_flags: number, + ): number { + if (this.fds[fd] !== undefined) { return this.fds[fd].fd_filestat_set_times(atim, mtim, fst_flags); - } else { - return wasi.ERRNO_BADF; } + return wasi.ERRNO_BADF; } - protected fd_pread(fd: number, iovecs: Array, offset: bigint): [[number, Uint8Array] | undefined, number] { - if (this.fds[fd] != undefined) { + protected fd_pread( + fd: number, + iovecs: Array, + offset: bigint, + ): [[number, Uint8Array] | undefined, number] { + if (this.fds[fd] !== undefined) { let nread = 0; let buffer8 = new Uint8Array(0); for (const iovec of iovecs) { const { ret, data } = this.fds[fd].fd_pread(iovec.buf_len, offset); - if (ret != wasi.ERRNO_SUCCESS) { + if (ret !== wasi.ERRNO_SUCCESS) { return [[nread, buffer8], ret]; } const new_buffer = new Uint8Array(buffer8.byteLength + data.byteLength); @@ -191,18 +202,17 @@ export abstract class WASIFarmPark { new_buffer.set(data, buffer8.byteLength); buffer8 = new_buffer; nread += data.byteLength; - if (data.byteLength != iovec.buf_len) { + if (data.byteLength !== iovec.buf_len) { break; } } return [[nread, buffer8], wasi.ERRNO_SUCCESS]; - } else { - return [undefined, wasi.ERRNO_BADF]; } + return [undefined, wasi.ERRNO_BADF]; } protected fd_prestat_get(fd: number): [wasi.Prestat | undefined, number] { - if (this.fds[fd] != undefined) { + if (this.fds[fd] !== undefined) { const { ret, prestat } = this.fds[fd].fd_prestat_get(); if (prestat != null) { return [prestat, ret]; @@ -212,8 +222,11 @@ export abstract class WASIFarmPark { return [undefined, wasi.ERRNO_BADF]; } - protected fd_prestat_dir_name(fd: number, path_len: number): [Uint8Array | undefined, number] { - if (this.fds[fd] != undefined) { + protected fd_prestat_dir_name( + fd: number, + path_len: number, + ): [Uint8Array | undefined, number] { + if (this.fds[fd] !== undefined) { const { ret, prestat } = this.fds[fd].fd_prestat_get(); if (prestat) { const prestat_dir_name = prestat.inner.pr_name; @@ -238,17 +251,23 @@ export abstract class WASIFarmPark { return [undefined, wasi.ERRNO_BADF]; } - protected fd_pwrite(fd: number, write_data: Uint8Array, offset: bigint): [number | undefined, number] { - if (this.fds[fd] != undefined) { + protected fd_pwrite( + fd: number, + write_data: Uint8Array, + offset: bigint, + ): [number | undefined, number] { + if (this.fds[fd] !== undefined) { const { ret, nwritten } = this.fds[fd].fd_pwrite(write_data, offset); return [nwritten, ret]; - } else { - return [undefined, wasi.ERRNO_BADF]; } + return [undefined, wasi.ERRNO_BADF]; } - protected fd_read(fd: number, iovecs: Array): [[number, Uint8Array] | undefined, number] { - if (this.fds[fd] != undefined) { + protected fd_read( + fd: number, + iovecs: Array, + ): [[number, Uint8Array] | undefined, number] { + if (this.fds[fd] !== undefined) { let nread = 0; // console.log("fd_read: park: iovecs: ", iovecs); @@ -261,7 +280,7 @@ export abstract class WASIFarmPark { for (const iovec of iovecs) { const { ret, data } = this.fds[fd].fd_read(iovec.buf_len); // console.log("fd_read: park: data: ", data); - if (ret != wasi.ERRNO_SUCCESS) { + if (ret !== wasi.ERRNO_SUCCESS) { return [[nread, buffer8], ret]; } const new_buffer = new Uint8Array(buffer8.byteLength + data.byteLength); @@ -269,24 +288,24 @@ export abstract class WASIFarmPark { new_buffer.set(data, buffer8.byteLength); buffer8 = new_buffer; nread += data.byteLength; - if (data.byteLength != iovec.buf_len) { + if (data.byteLength !== iovec.buf_len) { break; } } // console.log("fd_read: park: nread: ", nread); - return [[ - nread, - buffer8, - ], wasi.ERRNO_SUCCESS]; - } else { - return [undefined, wasi.ERRNO_BADF]; + return [[nread, buffer8], wasi.ERRNO_SUCCESS]; } + return [undefined, wasi.ERRNO_BADF]; } - protected fd_readdir(fd: number, buf_len: number, cookie: bigint): [[Uint8Array, number] | undefined, number] { - if (this.fds[fd] != undefined) { + protected fd_readdir( + fd: number, + buf_len: number, + cookie: bigint, + ): [[Uint8Array, number] | undefined, number] { + if (this.fds[fd] !== undefined) { const array = new Uint8Array(buf_len); let buf_used = 0; @@ -295,7 +314,7 @@ export abstract class WASIFarmPark { // eslint-disable-next-line no-constant-condition while (true) { const { ret, dirent } = this.fds[fd].fd_readdir_single(cookie); - if (ret != wasi.ERRNO_SUCCESS) { + if (ret !== wasi.ERRNO_SUCCESS) { return [[array, buf_used], ret]; } if (dirent == null) { @@ -331,9 +350,8 @@ export abstract class WASIFarmPark { } return [[array, buf_used], wasi.ERRNO_SUCCESS]; - } else { - return [undefined, wasi.ERRNO_BADF]; } + return [undefined, wasi.ERRNO_BADF]; } // protected async fd_renumber(fd: number, to: number): Promise { @@ -351,51 +369,57 @@ export abstract class WASIFarmPark { // } // } - protected fd_seek(fd: number, offset: bigint, whence: number): [bigint | undefined, number] { - if (this.fds[fd] != undefined) { + protected fd_seek( + fd: number, + offset: bigint, + whence: number, + ): [bigint | undefined, number] { + if (this.fds[fd] !== undefined) { const { ret, offset: new_offset } = this.fds[fd].fd_seek(offset, whence); return [new_offset, ret]; - } else { - return [undefined, wasi.ERRNO_BADF]; } + return [undefined, wasi.ERRNO_BADF]; } protected fd_sync(fd: number): number { - if (this.fds[fd] != undefined) { + if (this.fds[fd] !== undefined) { return this.fds[fd].fd_sync(); - } else { - return wasi.ERRNO_BADF; } + return wasi.ERRNO_BADF; } protected fd_tell(fd: number): [bigint | undefined, number] { - if (this.fds[fd] != undefined) { + if (this.fds[fd] !== undefined) { const { ret, offset } = this.fds[fd].fd_tell(); return [offset, ret]; - } else { - return [undefined, wasi.ERRNO_BADF]; } + return [undefined, wasi.ERRNO_BADF]; } - protected fd_write(fd: number, write_data: Uint8Array): [number | undefined, number] { - if (this.fds[fd] != undefined) { + protected fd_write( + fd: number, + write_data: Uint8Array, + ): [number | undefined, number] { + if (this.fds[fd] !== undefined) { const { ret, nwritten } = this.fds[fd].fd_write(write_data); return [nwritten, ret]; - } else { - return [undefined, wasi.ERRNO_BADF]; } + return [undefined, wasi.ERRNO_BADF]; } protected path_create_directory(fd: number, path: string): number { - if (this.fds[fd] != undefined) { + if (this.fds[fd] !== undefined) { return this.fds[fd].path_create_directory(path); - } else { - return wasi.ERRNO_BADF; } + return wasi.ERRNO_BADF; } - protected path_filestat_get(fd: number, flags: number, path: string): [wasi.Filestat | undefined, number] { - if (this.fds[fd] != undefined) { + protected path_filestat_get( + fd: number, + flags: number, + path: string, + ): [wasi.Filestat | undefined, number] { + if (this.fds[fd] !== undefined) { const { ret, filestat } = this.fds[fd].path_filestat_get(flags, path); if (filestat != null) { return [filestat, ret]; @@ -405,16 +429,34 @@ export abstract class WASIFarmPark { return [undefined, wasi.ERRNO_BADF]; } - protected path_filestat_set_times(fd: number, flags: number, path: string, atim: bigint, mtim: bigint, fst_flags: number): number { - if (this.fds[fd] != undefined) { - return this.fds[fd].path_filestat_set_times(flags, path, atim, mtim, fst_flags); - } else { - return wasi.ERRNO_BADF; + protected path_filestat_set_times( + fd: number, + flags: number, + path: string, + atim: bigint, + mtim: bigint, + fst_flags: number, + ): number { + if (this.fds[fd] !== undefined) { + return this.fds[fd].path_filestat_set_times( + flags, + path, + atim, + mtim, + fst_flags, + ); } + return wasi.ERRNO_BADF; } - protected path_link(old_fd: number, old_flags: number, old_path: string, new_fd: number, new_path: string): number { - if (this.fds[old_fd] != undefined && this.fds[new_fd] != undefined) { + protected path_link( + old_fd: number, + old_flags: number, + old_path: string, + new_fd: number, + new_path: string, + ): number { + if (this.fds[old_fd] !== undefined && this.fds[new_fd] !== undefined) { const { ret, inode_obj } = this.fds[old_fd].path_lookup( old_path, old_flags, @@ -423,9 +465,8 @@ export abstract class WASIFarmPark { return ret; } return this.fds[new_fd].path_link(new_path, inode_obj, false); - } else { - return wasi.ERRNO_BADF; } + return wasi.ERRNO_BADF; } protected async path_open( @@ -437,7 +478,7 @@ export abstract class WASIFarmPark { fs_rights_inheriting: bigint, fs_flags: number, ): Promise<[number | undefined, number]> { - if (this.fds[fd] != undefined) { + if (this.fds[fd] !== undefined) { debug.log("path_open", path); const { ret, fd_obj } = this.fds[fd].path_open( dirflags, @@ -448,7 +489,7 @@ export abstract class WASIFarmPark { fs_flags, ); // console.log("path_open: park: ", ret, fd_obj); - if (ret != wasi.ERRNO_SUCCESS) { + if (ret !== wasi.ERRNO_SUCCESS) { return [undefined, ret]; } @@ -465,13 +506,16 @@ export abstract class WASIFarmPark { // console.log("path_open: park: ", opened_fd); return [opened_fd, wasi.ERRNO_SUCCESS]; - } else { - return [undefined, wasi.ERRNO_BADF]; } + return [undefined, wasi.ERRNO_BADF]; } - protected path_readlink(fd: number, path: string, buf_len: number): [Uint8Array | undefined, number] { - if (this.fds[fd] != undefined) { + protected path_readlink( + fd: number, + path: string, + buf_len: number, + ): [Uint8Array | undefined, number] { + if (this.fds[fd] !== undefined) { debug.log("path_readlink", path); const { ret, data } = this.fds[fd].path_readlink(path); if (data != null) { @@ -483,57 +527,59 @@ export abstract class WASIFarmPark { return [data_buf, ret]; } return [undefined, ret]; - } else { - return [undefined, wasi.ERRNO_BADF]; } + return [undefined, wasi.ERRNO_BADF]; } protected path_remove_directory(fd: number, path: string): number { - if (this.fds[fd] != undefined) { + if (this.fds[fd] !== undefined) { return this.fds[fd].path_remove_directory(path); - } else { - return wasi.ERRNO_BADF; } + return wasi.ERRNO_BADF; } - protected path_rename(old_fd: number, old_path: string, new_fd: number, new_path: string): number { - if (this.fds[old_fd] != undefined && this.fds[new_fd] != undefined) { + protected path_rename( + old_fd: number, + old_path: string, + new_fd: number, + new_path: string, + ): number { + if (this.fds[old_fd] !== undefined && this.fds[new_fd] !== undefined) { // eslint-disable-next-line prefer-const - let { ret, inode_obj } = this.fds[old_fd].path_unlink( - old_path, - ); + let { ret, inode_obj } = this.fds[old_fd].path_unlink(old_path); if (inode_obj == null) { return ret; } ret = this.fds[new_fd].path_link(new_path, inode_obj, true); - if (ret != wasi.ERRNO_SUCCESS) { + if (ret !== wasi.ERRNO_SUCCESS) { if ( - this.fds[old_fd].path_link(old_path, inode_obj, true) != + this.fds[old_fd].path_link(old_path, inode_obj, true) !== wasi.ERRNO_SUCCESS ) { throw "path_link should always return success when relinking an inode back to the original place"; } } return ret; - } else { - return wasi.ERRNO_BADF; } + return wasi.ERRNO_BADF; } // eslint-disable-next-line @typescript-eslint/no-unused-vars - protected path_symlink(old_path: string, fd: number, new_path: string): number { - if (this.fds[fd] != undefined) { + protected path_symlink( + old_path: string, + fd: number, + new_path: string, + ): number { + if (this.fds[fd] !== undefined) { return wasi.ERRNO_NOTSUP; - } else { - return wasi.ERRNO_BADF; } + return wasi.ERRNO_BADF; } protected path_unlink_file(fd: number, path: string): number { - if (this.fds[fd] != undefined) { + if (this.fds[fd] !== undefined) { return this.fds[fd].path_unlink_file(path); - } else { - return wasi.ERRNO_BADF; } + return wasi.ERRNO_BADF; } } diff --git a/src/wasi_farm/polyfill.js b/src/wasi_farm/polyfill.js index c468f91..bde01dd 100644 --- a/src/wasi_farm/polyfill.js +++ b/src/wasi_farm/polyfill.js @@ -33,111 +33,115 @@ * when possible. The worker communicates with its parent using postMessage. */ -(function () { - if (typeof Atomics.waitAsync === "function") - return; - - let helperCode = ` - onmessage = function (ev) { - try { - switch (ev.data[0]) { - case 'wait': { - let [_, ia, index, value, timeout] = ev.data; - let result = Atomics.wait(ia, index, value, timeout) - postMessage(['ok', result]); - break; - } - default: { - throw new Error("Bogus message sent to wait helper: " + ev.data.join(',')); - } +(() => { + if (typeof Atomics.waitAsync === "function") return; + + const helperCode = ` + onmessage = function (ev) { + try { + switch (ev.data[0]) { + case 'wait': { + let [_, ia, index, value, timeout] = ev.data; + let result = Atomics.wait(ia, index, value, timeout) + postMessage(['ok', result]); + break; } - } catch (e) { - console.log("Exception in wait helper"); - postMessage(['error', 'Exception']); - } - } - `; - - let helpers = []; - - function allocHelper() { - if (helpers.length > 0) - return helpers.pop(); - let h = new Worker("data:application/javascript," + encodeURIComponent(helperCode)); - return h; - } - - function freeHelper(h) { - helpers.push(h); - } - - // Atomics.waitAsync always returns a promise. Throws standard errors - // for parameter validation. The promise is resolved with a string as from - // Atomics.wait, or, in the case something went completely wrong, it is - // rejected with an error string. - - function waitAsync(ia, index_, value_, timeout_) { - if (typeof ia != "object" || !(ia instanceof Int32Array) || !(ia.buffer instanceof SharedArrayBuffer)) - throw new TypeError("Expected shared memory"); - - // These conversions only approximate the desired semantics but are - // close enough for the polyfill. - - let index = index_|0; - let value = value_|0; - let timeout = timeout_ === undefined ? Infinity : +timeout_; - - // Range checking for the index. - - ia[index]; - - // Optimization, avoid the helper thread in this common case. - - if (Atomics.load(ia, index) != value) - return Promise.resolve("not-equal"); - - // General case, we must wait. - - return new Promise(function (resolve, reject) { - let h = allocHelper(); - h.onmessage = function (ev) { - // Free the helper early so that it can be reused if the resolution - // needs a helper. - freeHelper(h); - switch (ev.data[0]) { - case 'ok': - resolve(ev.data[1]); - break; - case 'error': - // Note, rejection is not in the spec, it is an artifact of the polyfill. - // The helper already printed an error to the console. - reject(ev.data[1]); - break; - } + default: { + throw new Error("Bogus message sent to wait helper: " + ev.data.join(',')); } - - // It's possible to do better here if the ia is already known to the - // helper. In that case we can communicate the other data through - // shared memory and wake the agent. And it is possible to make ia - // known to the helper by waking it with a special value so that it - // checks its messages, and then posting the ia to the helper. Some - // caching / decay scheme is useful no doubt, to improve performance - // and avoid leaks. - // - // In the event we wake the helper directly, we can micro-wait here - // for a quick result. We'll need to restructure some code to make - // that work out properly, and some synchronization is necessary for - // the helper to know that we've picked up the result and no - // postMessage is necessary. - - h.postMessage(['wait', ia, index, value, timeout]); - }) - } - - Object.defineProperty(Atomics, 'waitAsync', { - value: waitAsync, - configurable: true, - enumerable: false, - writable: true, + } + } catch (e) { + console.log("Exception in wait helper"); + postMessage(['error', 'Exception']); + } + } + `; + + const helpers = []; + + function allocHelper() { + if (helpers.length > 0) return helpers.pop(); + const h = new Worker( + `data:application/javascript,${encodeURIComponent(helperCode)}`, + ); + return h; + } + + function freeHelper(h) { + helpers.push(h); + } + + // Atomics.waitAsync always returns a promise. Throws standard errors + // for parameter validation. The promise is resolved with a string as from + // Atomics.wait, or, in the case something went completely wrong, it is + // rejected with an error string. + + function waitAsync(ia, index_, value_, timeout_) { + if ( + typeof ia !== "object" || + !(ia instanceof Int32Array) || + !(ia.buffer instanceof SharedArrayBuffer) + ) + throw new TypeError("Expected shared memory"); + + // These conversions only approximate the desired semantics but are + // close enough for the polyfill. + + const index = index_ | 0; + const value = value_ | 0; + const timeout = + timeout_ === undefined ? Number.POSITIVE_INFINITY : +timeout_; + + // Range checking for the index. + + ia[index]; + + // Optimization, avoid the helper thread in this common case. + + if (Atomics.load(ia, index) !== value) return Promise.resolve("not-equal"); + + // General case, we must wait. + + return new Promise((resolve, reject) => { + const h = allocHelper(); + h.onmessage = (ev) => { + // Free the helper early so that it can be reused if the resolution + // needs a helper. + freeHelper(h); + switch (ev.data[0]) { + case "ok": + resolve(ev.data[1]); + break; + case "error": + // Note, rejection is not in the spec, it is an artifact of the polyfill. + // The helper already printed an error to the console. + reject(ev.data[1]); + break; + } + }; + + // It's possible to do better here if the ia is already known to the + // helper. In that case we can communicate the other data through + // shared memory and wake the agent. And it is possible to make ia + // known to the helper by waking it with a special value so that it + // checks its messages, and then posting the ia to the helper. Some + // caching / decay scheme is useful no doubt, to improve performance + // and avoid leaks. + // + // In the event we wake the helper directly, we can micro-wait here + // for a quick result. We'll need to restructure some code to make + // that work out properly, and some synchronization is necessary for + // the helper to know that we've picked up the result and no + // postMessage is necessary. + + h.postMessage(["wait", ia, index, value, timeout]); }); + } + + Object.defineProperty(Atomics, "waitAsync", { + value: waitAsync, + configurable: true, + enumerable: false, + writable: true, + }); })(); diff --git a/src/wasi_farm/ref.ts b/src/wasi_farm/ref.ts index aa5837c..1e86f03 100644 --- a/src/wasi_farm/ref.ts +++ b/src/wasi_farm/ref.ts @@ -1,6 +1,5 @@ -import { Options } from "../wasi.js"; -import * as wasi from "../wasi_defs.js"; -import { FdCloseSender } from "./sender.js"; +import type * as wasi from "../wasi_defs.js"; +import type { FdCloseSender } from "./sender.js"; export type WASIFarmRefObject = { stdin: number | undefined; @@ -8,7 +7,7 @@ export type WASIFarmRefObject = { stderr: number | undefined; fd_close_receiver: FdCloseSender; default_fds: Array; -} +}; export abstract class WASIFarmRef { abstract get_fds_len(): number; @@ -66,34 +65,122 @@ export abstract class WASIFarmRef { } abstract fd_advise(fd: number | undefined): number; - abstract fd_allocate(fd: number | undefined, offset: bigint, len: bigint): number; + abstract fd_allocate( + fd: number | undefined, + offset: bigint, + len: bigint, + ): number; abstract fd_close(fd: number | undefined): number; abstract fd_datasync(fd: number | undefined): number; - abstract fd_fdstat_get(fd: number | undefined): [wasi.Fdstat | undefined, number]; + abstract fd_fdstat_get( + fd: number | undefined, + ): [wasi.Fdstat | undefined, number]; abstract fd_fdstat_set_flags(fd: number | undefined, flags: number): number; - abstract fd_fdstat_set_rights(fd: number | undefined, fs_rights_base: bigint, fs_rights_inheriting: bigint): number; - abstract fd_filestat_get(fd: number | undefined): [wasi.Filestat | undefined, number]; + abstract fd_fdstat_set_rights( + fd: number | undefined, + fs_rights_base: bigint, + fs_rights_inheriting: bigint, + ): number; + abstract fd_filestat_get( + fd: number | undefined, + ): [wasi.Filestat | undefined, number]; abstract fd_filestat_set_size(fd: number | undefined, size: bigint): number; - abstract fd_filestat_set_times(fd: number | undefined, atim: bigint, mtim: bigint, fst_flags: number): number; - abstract fd_pread(fd: number | undefined, iovs: Uint32Array, offset: bigint): [[number, Uint8Array] | undefined, number]; - abstract fd_prestat_get(fd: number | undefined): [[number, number] | undefined, number]; - abstract fd_prestat_dir_name(fd: number | undefined, path_len: number): [Uint8Array | undefined, number]; - abstract fd_pwrite(fd: number | undefined, iovs: Uint8Array, offset: bigint): [number | undefined, number]; - abstract fd_read(fd: number | undefined, iovs: Uint32Array): [[number, Uint8Array] | undefined, number]; - abstract fd_readdir(fd: number | undefined, limit_buf_len: number, cookie: bigint): [[Uint8Array, number] | undefined, number] + abstract fd_filestat_set_times( + fd: number | undefined, + atim: bigint, + mtim: bigint, + fst_flags: number, + ): number; + abstract fd_pread( + fd: number | undefined, + iovs: Uint32Array, + offset: bigint, + ): [[number, Uint8Array] | undefined, number]; + abstract fd_prestat_get( + fd: number | undefined, + ): [[number, number] | undefined, number]; + abstract fd_prestat_dir_name( + fd: number | undefined, + path_len: number, + ): [Uint8Array | undefined, number]; + abstract fd_pwrite( + fd: number | undefined, + iovs: Uint8Array, + offset: bigint, + ): [number | undefined, number]; + abstract fd_read( + fd: number | undefined, + iovs: Uint32Array, + ): [[number, Uint8Array] | undefined, number]; + abstract fd_readdir( + fd: number | undefined, + limit_buf_len: number, + cookie: bigint, + ): [[Uint8Array, number] | undefined, number]; // abstract fd_renumber(fd: number | undefined, to: number): number; - abstract fd_seek(fd: number | undefined, offset: bigint, whence: number): [bigint | undefined, number]; + abstract fd_seek( + fd: number | undefined, + offset: bigint, + whence: number, + ): [bigint | undefined, number]; abstract fd_sync(fd: number | undefined): number; abstract fd_tell(fd: number | undefined): [bigint, number]; - abstract fd_write(fd: number | undefined, iovs: Uint8Array): [number | undefined, number]; - abstract path_create_directory(fd: number | undefined, path: Uint8Array): number; - abstract path_filestat_get(fd: number | undefined, flags: number, path: Uint8Array): [wasi.Filestat | undefined, number]; - abstract path_filestat_set_times(fd: number | undefined, flags: number, path: Uint8Array, st_atim: bigint, st_mtim: bigint, fst_flags: number): number - abstract path_link(old_fd: number | undefined, old_flags: number, old_path: Uint8Array, new_fd: number | undefined, new_path: Uint8Array): number; - abstract path_open(fd: number | undefined, dirflags: number, path: Uint8Array, oflags: number, fs_rights_base: bigint, fs_rights_inheriting: bigint, fs_flags: number): [number, number]; - abstract path_readlink(fd: number | undefined, path: Uint8Array, buf_len: number): [Uint8Array | undefined, number]; - abstract path_remove_directory(fd: number | undefined, path: Uint8Array): number; - abstract path_rename(old_fd: number | undefined, old_path: Uint8Array, new_fd: number | undefined, new_path: Uint8Array): number; - abstract path_symlink(old_path: Uint8Array, fd: number | undefined, new_path: Uint8Array): number; + abstract fd_write( + fd: number | undefined, + iovs: Uint8Array, + ): [number | undefined, number]; + abstract path_create_directory( + fd: number | undefined, + path: Uint8Array, + ): number; + abstract path_filestat_get( + fd: number | undefined, + flags: number, + path: Uint8Array, + ): [wasi.Filestat | undefined, number]; + abstract path_filestat_set_times( + fd: number | undefined, + flags: number, + path: Uint8Array, + st_atim: bigint, + st_mtim: bigint, + fst_flags: number, + ): number; + abstract path_link( + old_fd: number | undefined, + old_flags: number, + old_path: Uint8Array, + new_fd: number | undefined, + new_path: Uint8Array, + ): number; + abstract path_open( + fd: number | undefined, + dirflags: number, + path: Uint8Array, + oflags: number, + fs_rights_base: bigint, + fs_rights_inheriting: bigint, + fs_flags: number, + ): [number, number]; + abstract path_readlink( + fd: number | undefined, + path: Uint8Array, + buf_len: number, + ): [Uint8Array | undefined, number]; + abstract path_remove_directory( + fd: number | undefined, + path: Uint8Array, + ): number; + abstract path_rename( + old_fd: number | undefined, + old_path: Uint8Array, + new_fd: number | undefined, + new_path: Uint8Array, + ): number; + abstract path_symlink( + old_path: Uint8Array, + fd: number | undefined, + new_path: Uint8Array, + ): number; abstract path_unlink_file(fd: number | undefined, path: Uint8Array): number; } diff --git a/src/wasi_farm/shared_array_buffer/allocator.ts b/src/wasi_farm/shared_array_buffer/allocator.ts index 95f6ef4..8cd3edf 100644 --- a/src/wasi_farm/shared_array_buffer/allocator.ts +++ b/src/wasi_farm/shared_array_buffer/allocator.ts @@ -1,10 +1,10 @@ // @ts-ignore // import { debug } from "../../debug.js"; -import "../polyfill.js"; +// import "../polyfill.js"; export type AllocatorUseArrayBufferObject = { share_arrays_memory: SharedArrayBuffer; -} +}; export class AllocatorUseArrayBuffer { // Pass a !Sized type @@ -40,7 +40,9 @@ export class AllocatorUseArrayBuffer { // Since postMessage makes the class an object, // it must be able to receive and assign a SharedArrayBuffer. constructor( - share_arrays_memory: SharedArrayBuffer = new SharedArrayBuffer(10 * 1024 * 1024), + share_arrays_memory: SharedArrayBuffer = new SharedArrayBuffer( + 10 * 1024 * 1024, + ), ) { this.share_arrays_memory = share_arrays_memory; const view = new Int32Array(this.share_arrays_memory); @@ -51,9 +53,7 @@ export class AllocatorUseArrayBuffer { // Since postMessage converts classes to objects, // it must be able to convert objects to classes. - static init_self( - sl: AllocatorUseArrayBufferObject, - ): AllocatorUseArrayBuffer { + static init_self(sl: AllocatorUseArrayBufferObject): AllocatorUseArrayBuffer { return new AllocatorUseArrayBuffer(sl.share_arrays_memory); } @@ -64,7 +64,7 @@ export class AllocatorUseArrayBuffer { // ptr, len // Pass I32Array ret_ptr ret_ptr: number, - ): Promise { + ): Promise<[number, number]> { const view = new Int32Array(this.share_arrays_memory); // eslint-disable-next-line no-constant-condition while (true) { @@ -83,13 +83,13 @@ export class AllocatorUseArrayBuffer { continue; } - this.write_inner(data, memory, ret_ptr); + const ret = this.write_inner(data, memory, ret_ptr); // release lock Atomics.store(view, 0, 0); Atomics.notify(view, 0, 1); - break; + return ret; } } @@ -153,7 +153,9 @@ export class AllocatorUseArrayBuffer { // extend memory // support from es2024 // this.share_arrays_memory.grow(new_memory_len); - throw new Error("size is bigger than memory. \nTODO! fix memory limit. support big size another way."); + throw new Error( + "size is bigger than memory. \nTODO! fix memory limit. support big size another way.", + ); } let data8: Uint8Array; @@ -183,7 +185,7 @@ export class AllocatorUseArrayBuffer { // eslint-disable-next-line @typescript-eslint/no-unused-vars pointer: number, // eslint-disable-next-line @typescript-eslint/no-unused-vars - len: number + len: number, ) { Atomics.sub(new Int32Array(this.share_arrays_memory), 1, 1); @@ -191,10 +193,7 @@ export class AllocatorUseArrayBuffer { } // get memory from pointer and length - get_memory( - ptr: number, - len: number, - ): ArrayBuffer { + get_memory(ptr: number, len: number): ArrayBuffer { const data = new ArrayBuffer(len); const view = new Uint8Array(data); view.set(new Uint8Array(this.share_arrays_memory).slice(ptr, ptr + len)); @@ -203,12 +202,14 @@ export class AllocatorUseArrayBuffer { // Write again to the memory before releasing // Not used because the situation for using it does not exist. - use_defined_memory( - ptr: number, - len: number, - data: ArrayBufferLike, - ) { + use_defined_memory(ptr: number, len: number, data: ArrayBufferLike) { const memory = new Uint8Array(this.share_arrays_memory); memory.set(new Uint8Array(data).slice(0, len), ptr); } + + get_object(): AllocatorUseArrayBufferObject { + return { + share_arrays_memory: this.share_arrays_memory, + }; + } } diff --git a/src/wasi_farm/shared_array_buffer/fd_close_sender.ts b/src/wasi_farm/shared_array_buffer/fd_close_sender.ts index 2f4ec40..a137e77 100644 --- a/src/wasi_farm/shared_array_buffer/fd_close_sender.ts +++ b/src/wasi_farm/shared_array_buffer/fd_close_sender.ts @@ -1,5 +1,8 @@ -import { FdCloseSender } from "../sender.js"; -import { ToRefSenderUseArrayBuffer, ToRefSenderUseArrayBufferObject } from "./sender.js"; +import type { FdCloseSender } from "../sender.js"; +import { + ToRefSenderUseArrayBuffer, + type ToRefSenderUseArrayBufferObject, +} from "./sender.js"; export type FdCloseSenderUseArrayBufferObject = { max_share_arrays_memory?: number; @@ -9,7 +12,10 @@ export type FdCloseSenderUseArrayBufferObject = { // Object to tell other processes, // such as child processes, // that the file descriptor has been closed -export class FdCloseSenderUseArrayBuffer extends ToRefSenderUseArrayBuffer implements FdCloseSender { +export class FdCloseSenderUseArrayBuffer + extends ToRefSenderUseArrayBuffer + implements FdCloseSender +{ // Should be able to change the size of memory as it accumulates more and more on memory constructor( max_share_arrays_memory?: number, @@ -19,10 +25,7 @@ export class FdCloseSenderUseArrayBuffer extends ToRefSenderUseArrayBuffer imple } // Send the closed file descriptor to the target process - async send( - targets: Array, - fd: number, - ): Promise { + async send(targets: Array, fd: number): Promise { if (targets === undefined || targets.length === 0) { throw new Error("targets is empty"); } @@ -32,9 +35,7 @@ export class FdCloseSenderUseArrayBuffer extends ToRefSenderUseArrayBuffer imple } // Get the closed file descriptor from the target process - get( - id: number, - ): Array | undefined { + get(id: number): Array | undefined { const data = this.get_data(id); if (data === undefined) { return undefined; @@ -51,9 +52,7 @@ export class FdCloseSenderUseArrayBuffer extends ToRefSenderUseArrayBuffer imple } // Initialize the class from object - static init_self( - sl: FdCloseSenderUseArrayBufferObject, - ): FdCloseSender { + static init_self(sl: FdCloseSenderUseArrayBufferObject): FdCloseSender { const sel = ToRefSenderUseArrayBuffer.init_self_inner(sl); return new FdCloseSenderUseArrayBuffer( sel.max_share_arrays_memory, diff --git a/src/wasi_farm/shared_array_buffer/index.ts b/src/wasi_farm/shared_array_buffer/index.ts new file mode 100644 index 0000000..0e2d34a --- /dev/null +++ b/src/wasi_farm/shared_array_buffer/index.ts @@ -0,0 +1,13 @@ +import { WASIFarmParkUseArrayBuffer } from "./park.js"; +import { WASIFarmRefUseArrayBuffer } from "./ref.js"; +import type { WASIFarmRefUseArrayBufferObject } from "./ref.js"; +import { ThreadSpawner } from "./thread_spawn.js"; +import { thread_spawn_on_worker } from "./thread_spawn.js"; + +export { + WASIFarmRefUseArrayBuffer, + type WASIFarmRefUseArrayBufferObject, + WASIFarmParkUseArrayBuffer, + ThreadSpawner, + thread_spawn_on_worker, +}; diff --git a/src/wasi_farm/shared_array_buffer/park.ts b/src/wasi_farm/shared_array_buffer/park.ts index b242194..861b807 100644 --- a/src/wasi_farm/shared_array_buffer/park.ts +++ b/src/wasi_farm/shared_array_buffer/park.ts @@ -1,10 +1,10 @@ -import { Fd } from "../../fd.js"; +import type { Fd } from "../../fd.js"; import * as wasi from "../../wasi_defs.js"; -import { AllocatorUseArrayBuffer } from "./allocator.js"; import { WASIFarmPark } from "../park.js"; -import { WASIFarmRefUseArrayBufferObject } from "./ref.js"; -import { FdCloseSender } from "../sender.js"; +import type { FdCloseSender } from "../sender.js"; +import { AllocatorUseArrayBuffer } from "./allocator.js"; import { FdCloseSenderUseArrayBuffer } from "./fd_close_sender.js"; +import type { WASIFarmRefUseArrayBufferObject } from "./ref.js"; import { get_func_name_from_number } from "./util.js"; export const fd_func_sig_u32_size: number = 18; @@ -112,22 +112,20 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { default_allow_fds: Array, allocator_size?: number, ) { - super( - fds, - stdin, - stdout, - stderr, - default_allow_fds, - ); + super(fds, stdin, stdout, stderr, default_allow_fds); if (allocator_size === undefined) { this.allocator = new AllocatorUseArrayBuffer(); } else { - this.allocator = new AllocatorUseArrayBuffer(new SharedArrayBuffer(allocator_size)); + this.allocator = new AllocatorUseArrayBuffer( + new SharedArrayBuffer(allocator_size), + ); } const max_fds_len = 128; this.lock_fds = new SharedArrayBuffer(4 * max_fds_len * 3); - this.fd_func_sig = new SharedArrayBuffer(fd_func_sig_u32_size * 4 * max_fds_len); + this.fd_func_sig = new SharedArrayBuffer( + fd_func_sig_u32_size * 4 * max_fds_len, + ); this.fds_len_and_num = new SharedArrayBuffer(8); const view = new Int32Array(this.fds_len_and_num); @@ -159,7 +157,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { // received and listen the fd // and set fds.length async notify_set_fd(fd: number) { - if (this.fds[fd] == undefined) { + if (this.fds[fd] === undefined) { throw new Error("fd is not defined"); } if (fd >= 128) { @@ -185,7 +183,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { (async () => { await this.listen_fds[fd]; this.listen_fds[fd] = undefined; - })() + })(); // console.log("notify_rm_fd", fd); // console.log("fds", this.fds); @@ -206,9 +204,8 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { can_set_new_fd(fd: number): [boolean, Promise | undefined] { if (this.listen_fds[fd] instanceof Promise) { return [false, this.listen_fds[fd]]; - } else { - return [true, undefined]; } + return [true, undefined]; } // listen all fds and base @@ -232,12 +229,12 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { Atomics.store(lock_view, 1, 0); // eslint-disable-next-line no-constant-condition - while(true) { + while (true) { try { let lock: "not-equal" | "timed-out" | "ok"; const { value } = Atomics.waitAsync(lock_view, 1, 0); - if ( value instanceof Promise) { + if (value instanceof Promise) { lock = await value; } else { lock = value; @@ -248,7 +245,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const func_number = Atomics.load(lock_view, 2); - switcher: switch (func_number) { + switch (func_number) { // set_fds_map: (fds_ptr: u32, fds_len: u32); case 0: { // console.log("set_fds_map"); @@ -278,7 +275,10 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { // console.log("listen_base fds_map", this.fds_map); - break switcher; + // sleep 1000ms + await new Promise((resolve) => setTimeout(resolve, 1000)); + + break; } } @@ -292,7 +292,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { console.warn("notify failed, waiter is late"); continue; } - throw new Error("notify failed: " + num); + throw new Error(`notify failed: ${num}`); } } catch (e) { console.error("error", e); @@ -310,7 +310,10 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const func_sig_view_u16 = new Uint16Array(this.fd_func_sig, bytes_offset); const func_sig_view_i32 = new Int32Array(this.fd_func_sig, bytes_offset); const func_sig_view_u32 = new Int32Array(this.fd_func_sig, bytes_offset); - const func_sig_view_u64 = new BigUint64Array(this.fd_func_sig, bytes_offset); + const func_sig_view_u64 = new BigUint64Array( + this.fd_func_sig, + bytes_offset, + ); const errno_offset = fd_func_sig_u32_size - 1; Atomics.store(lock_view, 0, 0); Atomics.store(lock_view, 1, 0); @@ -322,7 +325,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { let lock: "not-equal" | "timed-out" | "ok"; const { value } = Atomics.waitAsync(lock_view, 1, 0); - if ( value instanceof Promise) { + if (value instanceof Promise) { // console.log("listen", fd_n, 1); lock = await value; } else { @@ -335,7 +338,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const func_lock = Atomics.load(lock_view, 1); if (func_lock !== 1) { - throw new Error("func_lock is already set: " + func_lock); + throw new Error(`func_lock is already set: ${func_lock}`); } // console.log("func_lock", func_lock); @@ -345,13 +348,13 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const set_error = (errno: number) => { // console.log("set_error", errno, "pointer", errno_offset); Atomics.store(func_sig_view_i32, errno_offset, errno); - } + }; const func_number = Atomics.load(func_sig_view_u32, 0); // console.log("called: func: ", get_func_name_from_number(func_number), "fd: ", fd_n); - switcher: switch (func_number) { + switch (func_number) { // fd_advise: (fd: u32) => errno; case 7: { const fd = Atomics.load(func_sig_view_u32, 1); @@ -359,7 +362,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const error = this.fd_advise(fd); set_error(error); - break switcher; + break; } // fd_allocate: (fd: u32, offset: u64, len: u64) => errno; case 8: { @@ -370,7 +373,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const error = this.fd_allocate(fd, offset, len); set_error(error); - break switcher; + break; } // fd_close: (fd: u32) => errno; case 9: { @@ -381,7 +384,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { // console.log("fd_close", fd, error); set_error(error); - break switcher; + break; } // fd_datasync: (fd: u32) => errno; case 10: { @@ -390,22 +393,22 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const error = this.fd_datasync(fd); set_error(error); - break switcher; + break; } // fd_fdstat_get: (fd: u32) => [wasi.Fdstat(u32 * 6)], errno]; case 11: { const fd = Atomics.load(func_sig_view_u32, 1); - const [ fdstat, ret ] = this.fd_fdstat_get(fd); + const [fdstat, ret] = this.fd_fdstat_get(fd); if (fdstat) { - Atomics.store(func_sig_view_u8, 0, fdstat.fs_filetype); - Atomics.store(func_sig_view_u16, 2, fdstat.fs_flags); - Atomics.store(func_sig_view_u64, 1, fdstat.fs_rights_base); - Atomics.store(func_sig_view_u64, 2, fdstat.fs_rights_inherited); + Atomics.store(func_sig_view_u8, 0, fdstat.fs_filetype); + Atomics.store(func_sig_view_u16, 2, fdstat.fs_flags); + Atomics.store(func_sig_view_u64, 1, fdstat.fs_rights_base); + Atomics.store(func_sig_view_u64, 2, fdstat.fs_rights_inherited); } set_error(ret); - break switcher; + break; } // fd_fdstat_set_flags: (fd: u32, flags: u16) => errno; case 12: { @@ -415,7 +418,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const error = this.fd_fdstat_set_flags(fd, flags); set_error(error); - break switcher; + break; } // fd_fdstat_set_rights: (fd: u32, fs_rights_base: u64, fs_rights_inheriting: u64) => errno; case 13: { @@ -423,30 +426,34 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const fs_rights_base = Atomics.load(func_sig_view_u64, 1); const fs_rights_inheriting = Atomics.load(func_sig_view_u64, 2); - const error = this.fd_fdstat_set_rights(fd, fs_rights_base, fs_rights_inheriting); + const error = this.fd_fdstat_set_rights( + fd, + fs_rights_base, + fs_rights_inheriting, + ); set_error(error); - break switcher; + break; } // fd_filestat_get: (fd: u32) => [wasi.Filestat(u32 * 16)], errno]; case 14: { const fd = Atomics.load(func_sig_view_u32, 1); - const [ filestat, ret ] = this.fd_filestat_get(fd); + const [filestat, ret] = this.fd_filestat_get(fd); if (filestat) { - Atomics.store(func_sig_view_u64, 0, filestat.dev); - Atomics.store(func_sig_view_u64, 1, filestat.ino); - Atomics.store(func_sig_view_u8, 16, filestat.filetype); - Atomics.store(func_sig_view_u64, 3, filestat.nlink); - Atomics.store(func_sig_view_u64, 4, filestat.size); - Atomics.store(func_sig_view_u64, 5, filestat.atim); - Atomics.store(func_sig_view_u64, 6, filestat.mtim); - Atomics.store(func_sig_view_u64, 7, filestat.ctim); + Atomics.store(func_sig_view_u64, 0, filestat.dev); + Atomics.store(func_sig_view_u64, 1, filestat.ino); + Atomics.store(func_sig_view_u8, 16, filestat.filetype); + Atomics.store(func_sig_view_u64, 3, filestat.nlink); + Atomics.store(func_sig_view_u64, 4, filestat.size); + Atomics.store(func_sig_view_u64, 5, filestat.atim); + Atomics.store(func_sig_view_u64, 6, filestat.mtim); + Atomics.store(func_sig_view_u64, 7, filestat.ctim); } set_error(ret); - break switcher; + break; } // fd_filestat_set_size: (fd: u32, size: u64) => errno; case 15: { @@ -456,7 +463,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const error = this.fd_filestat_set_size(fd, size); set_error(error); - break switcher; + break; } // fd_filestat_set_times: (fd: u32, atim: u64, mtim: u64, fst_flags: u16) => errno; case 16: { @@ -468,7 +475,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const error = this.fd_filestat_set_times(fd, atim, mtim, fst_flags); set_error(error); - break switcher; + break; } // fd_pread: (fd: u32, iovs_ptr: pointer, iovs_len: u32, offset: u64) => [u32, data_ptr, errno]; case 17: { @@ -476,7 +483,9 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const iovs_ptr = Atomics.load(func_sig_view_u32, 2); const iovs_ptr_len = Atomics.load(func_sig_view_u32, 3); const offset = Atomics.load(func_sig_view_u64, 2); - const data = new Uint32Array(this.allocator.get_memory(iovs_ptr, iovs_ptr_len)); + const data = new Uint32Array( + this.allocator.get_memory(iovs_ptr, iovs_ptr_len), + ); this.allocator.free(iovs_ptr, iovs_ptr_len); const iovecs = new Array(); @@ -493,40 +502,58 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { Atomics.store(func_sig_view_u32, 0, nread); } if (buffer8) { - await this.allocator.async_write(buffer8, this.fd_func_sig, fd * fd_func_sig_u32_size + 1); + await this.allocator.async_write( + buffer8, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 1, + ); } set_error(error); - break switcher; + break; } // fd_prestat_get: (fd: u32) => [wasi.Prestat(u32 * 2)], errno]; case 18: { const fd = Atomics.load(func_sig_view_u32, 1); - const [ prestat, ret ] = this.fd_prestat_get(fd); + const [prestat, ret] = this.fd_prestat_get(fd); // console.log("fd_prestat_get", prestat, ret); if (prestat) { Atomics.store(func_sig_view_u32, 0, prestat.tag); - Atomics.store(func_sig_view_u32, 1, prestat.inner.pr_name.byteLength); + Atomics.store( + func_sig_view_u32, + 1, + prestat.inner.pr_name.byteLength, + ); } set_error(ret); - break switcher; + break; } // fd_prestat_dir_name: (fd: u32, path_len: u32) => [path_ptr: pointer, path_len: u32, errno]; case 19: { const fd = Atomics.load(func_sig_view_u32, 1); const path_len = Atomics.load(func_sig_view_u32, 2); - const [ prestat_dir_name, ret ] = this.fd_prestat_dir_name(fd, path_len); + const [prestat_dir_name, ret] = this.fd_prestat_dir_name( + fd, + path_len, + ); // console.log("fd_prestat_dir_name: park: ", prestat_dir_name); - if (prestat_dir_name && (ret === wasi.ERRNO_SUCCESS || ret === wasi.ERRNO_NAMETOOLONG)) { - await this.allocator.async_write(prestat_dir_name, this.fd_func_sig, fd * fd_func_sig_u32_size); + if ( + prestat_dir_name && + (ret === wasi.ERRNO_SUCCESS || ret === wasi.ERRNO_NAMETOOLONG) + ) { + await this.allocator.async_write( + prestat_dir_name, + this.fd_func_sig, + fd * fd_func_sig_u32_size, + ); } set_error(ret); - break switcher; + break; } // fd_pwrite: (fd: u32, write_data: pointer, write_data_len: u32, offset: u64) => [u32, errno]; case 20: { @@ -535,7 +562,9 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const write_data_len = Atomics.load(func_sig_view_u32, 3); const offset = Atomics.load(func_sig_view_u64, 2); - const data = new Uint8Array(this.allocator.get_memory(write_data_ptr, write_data_len)); + const data = new Uint8Array( + this.allocator.get_memory(write_data_ptr, write_data_len), + ); this.allocator.free(write_data_ptr, write_data_len); const [nwritten, error] = this.fd_pwrite(fd, data, offset); @@ -544,7 +573,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { Atomics.store(func_sig_view_u32, 0, nwritten); } set_error(error); - break switcher; + break; } // fd_read: (fd: u32, iovs_ptr: pointer, iovs_len: u32) => [u32, data_ptr, errno]; case 21: { @@ -553,7 +582,9 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const iovs_ptr_len = Atomics.load(func_sig_view_u32, 3); // console.log("fd_read: park: iovs: Uint8Array", this.allocator.get_memory(iovs_ptr, iovs_ptr_len)); // console.log("ptr_len", iovs_ptr_len); - const iovs = new Uint32Array(this.allocator.get_memory(iovs_ptr, iovs_ptr_len)); + const iovs = new Uint32Array( + this.allocator.get_memory(iovs_ptr, iovs_ptr_len), + ); this.allocator.free(iovs_ptr, iovs_ptr_len); // console.log("fd_read: park: iovs", iovs); @@ -576,10 +607,14 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { Atomics.store(func_sig_view_u32, 0, nread); } if (buffer8) { - await this.allocator.async_write(buffer8, this.fd_func_sig, fd * fd_func_sig_u32_size + 1); + await this.allocator.async_write( + buffer8, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 1, + ); } set_error(error); - break switcher; + break; } // fd_readdir: (fd: u32, buf_len: u32, cookie: u64) => [buf_ptr: pointer, buf_len: u32, buf_used: u32, errno]; case 22: { @@ -587,22 +622,30 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const buf_len = Atomics.load(func_sig_view_u32, 2); const cookie = Atomics.load(func_sig_view_u64, 2); - const [[array, buf_used], error] = this.fd_readdir(fd, buf_len, cookie); + const [[array, buf_used], error] = this.fd_readdir( + fd, + buf_len, + cookie, + ); if (array) { - await this.allocator.async_write(array, this.fd_func_sig, fd * fd_func_sig_u32_size); + await this.allocator.async_write( + array, + this.fd_func_sig, + fd * fd_func_sig_u32_size, + ); } if (buf_used !== undefined) { Atomics.store(func_sig_view_u32, 2, buf_used); } set_error(error); - break switcher; + break; } // fd_seek: (fd: u32, offset: i64, whence: u8) => [u64, errno]; case 24: { const fd = Atomics.load(func_sig_view_u32, 1); const offset = Atomics.load(func_sig_view_u64, 1); - const whence = Atomics.load(func_sig_view_u8,16); + const whence = Atomics.load(func_sig_view_u8, 16); const [new_offset, error] = this.fd_seek(fd, offset, whence); @@ -610,7 +653,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { Atomics.store(func_sig_view_u64, 0, new_offset); } set_error(error); - break switcher; + break; } // fd_sync: (fd: u32) => errno; case 25: { @@ -619,7 +662,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const error = this.fd_sync(fd); set_error(error); - break switcher; + break; } // fd_tell: (fd: u32) => [u64, errno]; case 26: { @@ -631,7 +674,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { Atomics.store(func_sig_view_u64, 0, offset); } set_error(error); - break switcher; + break; } // fd_write: (fd: u32, write_data: pointer, write_data_len: u32) => [u32, errno]; case 27: { @@ -639,7 +682,9 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const write_data_ptr = Atomics.load(func_sig_view_u32, 2); const write_data_len = Atomics.load(func_sig_view_u32, 3); - const data = new Uint8Array(this.allocator.get_memory(write_data_ptr, write_data_len)); + const data = new Uint8Array( + this.allocator.get_memory(write_data_ptr, write_data_len), + ); this.allocator.free(write_data_ptr, write_data_len); // console.log("allocator", this.allocator); @@ -654,7 +699,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { Atomics.store(func_sig_view_u32, 0, nwritten); } set_error(error); - break switcher; + break; } // path_create_directory: (fd: u32, path_ptr: pointer, path_len: u32) => errno; case 28: { @@ -662,14 +707,16 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const path_ptr = Atomics.load(func_sig_view_u32, 2); const path_len = Atomics.load(func_sig_view_u32, 3); - const path = new Uint8Array(this.allocator.get_memory(path_ptr, path_len)); + const path = new Uint8Array( + this.allocator.get_memory(path_ptr, path_len), + ); const path_str = new TextDecoder().decode(path); this.allocator.free(path_ptr, path_len); const error = this.path_create_directory(fd, path_str); set_error(error); - break switcher; + break; } // path_filestat_get: (fd: u32, flags: u32, path_ptr: pointer, path_len: u32) => [wasi.Filestat(u32 * 16), errno]; case 29: { @@ -678,7 +725,9 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const path_ptr = Atomics.load(func_sig_view_u32, 3); const path_len = Atomics.load(func_sig_view_u32, 4); - const path = new Uint8Array(this.allocator.get_memory(path_ptr, path_len)); + const path = new Uint8Array( + this.allocator.get_memory(path_ptr, path_len), + ); const path_str = new TextDecoder().decode(path); this.allocator.free(path_ptr, path_len); @@ -687,7 +736,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { if (filestat) { Atomics.store(func_sig_view_u64, 0, filestat.dev); Atomics.store(func_sig_view_u64, 1, filestat.ino); - Atomics.store(func_sig_view_u8,16, filestat.filetype); + Atomics.store(func_sig_view_u8, 16, filestat.filetype); Atomics.store(func_sig_view_u64, 3, filestat.nlink); Atomics.store(func_sig_view_u64, 4, filestat.size); Atomics.store(func_sig_view_u64, 5, filestat.atim); @@ -695,7 +744,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { Atomics.store(func_sig_view_u64, 7, filestat.ctim); } set_error(ret); - break switcher; + break; } // path_filestat_set_times: (fd: u32, flags: u32, path_ptr: pointer, path_len: u32, atim: u64, mtim: u64, fst_flags: u16) => errno; case 30: { @@ -707,14 +756,23 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const mtim = Atomics.load(func_sig_view_u64, 4); const fst_flags = Atomics.load(func_sig_view_u16, 12); - const path = new Uint8Array(this.allocator.get_memory(path_ptr, path_len)); + const path = new Uint8Array( + this.allocator.get_memory(path_ptr, path_len), + ); const path_str = new TextDecoder().decode(path); this.allocator.free(path_ptr, path_len); - const error = this.path_filestat_set_times(fd, flags, path_str, atim, mtim, fst_flags); + const error = this.path_filestat_set_times( + fd, + flags, + path_str, + atim, + mtim, + fst_flags, + ); set_error(error); - break switcher; + break; } // path_link: (old_fd: u32, old_flags: u32, old_path_ptr: pointer, old_path_len: u32, new_fd: u32, new_path_ptr: pointer, new_path_len: u32) => errno; case 31: { @@ -726,17 +784,27 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const new_path_ptr = Atomics.load(func_sig_view_u32, 6); const new_path_len = Atomics.load(func_sig_view_u32, 7); - const old_path = new Uint8Array(this.allocator.get_memory(old_path_ptr, old_path_len)); + const old_path = new Uint8Array( + this.allocator.get_memory(old_path_ptr, old_path_len), + ); const old_path_str = new TextDecoder().decode(old_path); this.allocator.free(old_path_ptr, old_path_len); - const new_path = new Uint8Array(this.allocator.get_memory(new_path_ptr, new_path_len)); + const new_path = new Uint8Array( + this.allocator.get_memory(new_path_ptr, new_path_len), + ); const new_path_str = new TextDecoder().decode(new_path); this.allocator.free(new_path_ptr, new_path_len); - const error = this.path_link(old_fd, old_flags, old_path_str, new_fd, new_path_str); + const error = this.path_link( + old_fd, + old_flags, + old_path_str, + new_fd, + new_path_str, + ); set_error(error); - break switcher; + break; } // path_open: (fd: u32, dirflags: u32, path_ptr: pointer, path_len: u32, oflags: u32, fs_rights_base: u64, fs_rights_inheriting: u64, fdflags: u16) => [u32, errno]; case 32: { @@ -749,11 +817,21 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const fs_rights_inheriting = Atomics.load(func_sig_view_u64, 4); const fd_flags = Atomics.load(func_sig_view_u16, 20); - const path = new Uint8Array(this.allocator.get_memory(path_ptr, path_len)); + const path = new Uint8Array( + this.allocator.get_memory(path_ptr, path_len), + ); const path_str = new TextDecoder().decode(path); this.allocator.free(path_ptr, path_len); - const [opened_fd, error] = await this.path_open(fd, dirflags, path_str, oflags, fs_rights_base, fs_rights_inheriting, fd_flags); + const [opened_fd, error] = await this.path_open( + fd, + dirflags, + path_str, + oflags, + fs_rights_base, + fs_rights_inheriting, + fd_flags, + ); // console.log("path_open: opend_fd", opened_fd, error); @@ -761,7 +839,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { Atomics.store(func_sig_view_u32, 0, opened_fd); } set_error(error); - break switcher; + break; } // path_readlink: (fd: u32, path_ptr: pointer, path_len: u32, buf_len: u32) => [buf_len: u32, data_ptr: pointer, data_len: u32, errno]; case 33: { @@ -770,18 +848,24 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const path_len = Atomics.load(func_sig_view_u32, 3); const buf_len = Atomics.load(func_sig_view_u32, 4); - const path = new Uint8Array(this.allocator.get_memory(path_ptr, path_len)); + const path = new Uint8Array( + this.allocator.get_memory(path_ptr, path_len), + ); const path_str = new TextDecoder().decode(path); this.allocator.free(path_ptr, path_len); const [buf, error] = this.path_readlink(fd, path_str, buf_len); if (buf) { - await this.allocator.async_write(buf, this.fd_func_sig, fd * fd_func_sig_u32_size + 1); + await this.allocator.async_write( + buf, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 1, + ); Atomics.store(func_sig_view_u32, 0, buf.byteLength); } set_error(error); - break switcher; + break; } // path_remove_directory: (fd: u32, path_ptr: pointer, path_len: u32) => errno; case 34: { @@ -789,14 +873,16 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const path_ptr = Atomics.load(func_sig_view_u32, 2); const path_len = Atomics.load(func_sig_view_u32, 3); - const path = new Uint8Array(this.allocator.get_memory(path_ptr, path_len)); + const path = new Uint8Array( + this.allocator.get_memory(path_ptr, path_len), + ); const path_str = new TextDecoder().decode(path); this.allocator.free(path_ptr, path_len); const error = this.path_remove_directory(fd, path_str); set_error(error); - break switcher; + break; } // path_rename: (old_fd: u32, old_path_ptr: pointer, old_path_len: u32, new_fd: u32, new_path_ptr: pointer, new_path_len: u32) => errno; case 35: { @@ -807,17 +893,26 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const new_path_ptr = Atomics.load(func_sig_view_u32, 5); const new_path_len = Atomics.load(func_sig_view_u32, 6); - const old_path = new Uint8Array(this.allocator.get_memory(old_path_ptr, old_path_len)); + const old_path = new Uint8Array( + this.allocator.get_memory(old_path_ptr, old_path_len), + ); const old_path_str = new TextDecoder().decode(old_path); this.allocator.free(old_path_ptr, old_path_len); - const new_path = new Uint8Array(this.allocator.get_memory(new_path_ptr, new_path_len)); + const new_path = new Uint8Array( + this.allocator.get_memory(new_path_ptr, new_path_len), + ); const new_path_str = new TextDecoder().decode(new_path); this.allocator.free(new_path_ptr, new_path_len); - const error = this.path_rename(fd, old_path_str, new_fd, new_path_str); + const error = this.path_rename( + fd, + old_path_str, + new_fd, + new_path_str, + ); set_error(error); - break switcher; + break; } // path_symlink: (old_path_ptr: pointer, old_path_len: u32, fd: u32, new_path_ptr: pointer, new_path_len: u32) => errno; case 36: { @@ -827,15 +922,19 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const new_path_ptr = Atomics.load(func_sig_view_u32, 4); const new_path_len = Atomics.load(func_sig_view_u32, 5); - const old_path = new Uint8Array(this.allocator.get_memory(old_path_ptr, old_path_len)); + const old_path = new Uint8Array( + this.allocator.get_memory(old_path_ptr, old_path_len), + ); const old_path_str = new TextDecoder().decode(old_path); this.allocator.free(old_path_ptr, old_path_len); - const new_path = new Uint8Array(this.allocator.get_memory(new_path_ptr, new_path_len)); + const new_path = new Uint8Array( + this.allocator.get_memory(new_path_ptr, new_path_len), + ); const new_path_str = new TextDecoder().decode(new_path); this.allocator.free(new_path_ptr, new_path_len); set_error(this.path_symlink(old_path_str, fd, new_path_str)); - break switcher; + break; } // path_unlink_file: (fd: u32, path_ptr: pointer, path_len: u32) => errno; case 37: { @@ -843,21 +942,25 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { const path_ptr = Atomics.load(func_sig_view_u32, 2); const path_len = Atomics.load(func_sig_view_u32, 3); - const path = new Uint8Array(this.allocator.get_memory(path_ptr, path_len)); + const path = new Uint8Array( + this.allocator.get_memory(path_ptr, path_len), + ); const path_str = new TextDecoder().decode(path); this.allocator.free(path_ptr, path_len); set_error(this.path_unlink_file(fd, path_str)); - break switcher; + break; } default: { - throw new Error("Unknown function number: " + func_number); + throw new Error(`Unknown function number: ${func_number}`); } } const old_call_lock = Atomics.exchange(lock_view, 1, 0); if (old_call_lock !== 1) { - throw new Error("Call is already set: " + old_call_lock + "\nfunc: " + get_func_name_from_number(func_number) + "\nfd: " + fd_n); + throw new Error( + `Call is already set: ${old_call_lock}\nfunc: ${get_func_name_from_number(func_number)}\nfd: ${fd_n}`, + ); } // console.log("called end: func: ", get_func_name_from_number(func_number), "fd: ", fd_n); @@ -867,7 +970,7 @@ export class WASIFarmParkUseArrayBuffer extends WASIFarmPark { if (n === 0) { console.warn("notify number is 0. ref is late?"); } else { - console.warn("notify number is not 1: " + n); + console.warn(`notify number is not 1: ${n}`); } } diff --git a/src/wasi_farm/shared_array_buffer/ref.ts b/src/wasi_farm/shared_array_buffer/ref.ts index 7405a7c..acae92b 100644 --- a/src/wasi_farm/shared_array_buffer/ref.ts +++ b/src/wasi_farm/shared_array_buffer/ref.ts @@ -1,8 +1,14 @@ -import { WASIFarmRef, WASIFarmRefObject } from "../ref.js"; -import { AllocatorUseArrayBuffer, AllocatorUseArrayBufferObject } from "./allocator.js"; -import { fd_func_sig_bytes, fd_func_sig_u32_size } from "./park.js"; import * as wasi from "../../wasi_defs.js"; -import { FdCloseSenderUseArrayBuffer, FdCloseSenderUseArrayBufferObject } from "./fd_close_sender.js"; +import { WASIFarmRef, type WASIFarmRefObject } from "../ref.js"; +import { + AllocatorUseArrayBuffer, + type AllocatorUseArrayBufferObject, +} from "./allocator.js"; +import { + FdCloseSenderUseArrayBuffer, + type FdCloseSenderUseArrayBufferObject, +} from "./fd_close_sender.js"; +import { fd_func_sig_bytes, fd_func_sig_u32_size } from "./park.js"; export type WASIFarmRefUseArrayBufferObject = { allocator: AllocatorUseArrayBuffer; @@ -35,7 +41,13 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { stderr: number | undefined, default_fds: Array, ) { - super(stdin, stdout, stderr, FdCloseSenderUseArrayBuffer.init_self(fd_close_receiver), default_fds); + super( + stdin, + stdout, + stderr, + FdCloseSenderUseArrayBuffer.init_self(fd_close_receiver), + default_fds, + ); this.allocator = AllocatorUseArrayBuffer.init_self(allocator); this.lock_fds = lock_fds; this.fd_func_sig = fd_func_sig; @@ -216,7 +228,7 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { const view = new Int32Array(this.lock_fds, fd * 12 + 4); const old = Atomics.exchange(view, 0, 1); if (old === 1) { - console.error("invoke_fd_func already invoked\n" + "fd: " + fd); + console.error(`invoke_fd_func already invoked\nfd: ${fd}`); return; } const n = Atomics.notify(view, 0); @@ -231,10 +243,9 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { Atomics.notify(view, 0, 1); console.error("what happened?: len", len, "fd", fd); return true; - } else { - console.warn("invoke_func_loop is late"); - return true; } + console.warn("invoke_func_loop is late"); + return true; } console.error("invoke_fd_func notify failed:", n); return false; @@ -263,18 +274,22 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { } private get_error(fd: number): number { - const func_sig_view_i32 = new Int32Array(this.fd_func_sig, fd * fd_func_sig_bytes); + const func_sig_view_i32 = new Int32Array( + this.fd_func_sig, + fd * fd_func_sig_bytes, + ); const errno_offset = fd_func_sig_u32_size - 1; // console.log("get_error: offset", errno_offset); return Atomics.load(func_sig_view_i32, errno_offset); } - fd_advise( - fd: number, - ): number { + fd_advise(fd: number): number { this.lock_fd(fd); - const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, fd * fd_func_sig_bytes); + const func_sig_view_u32 = new Uint32Array( + this.fd_func_sig, + fd * fd_func_sig_bytes, + ); Atomics.store(func_sig_view_u32, 0, 7); Atomics.store(func_sig_view_u32, 1, fd); @@ -291,16 +306,15 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { return error; } - fd_allocate( - fd: number, - offset: bigint, - len: bigint, - ): number { + fd_allocate(fd: number, offset: bigint, len: bigint): number { this.lock_fd(fd); const bytes_offset = fd * fd_func_sig_bytes; const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, bytes_offset); - const func_sig_view_u64 = new BigUint64Array(this.fd_func_sig, bytes_offset); + const func_sig_view_u64 = new BigUint64Array( + this.fd_func_sig, + bytes_offset, + ); Atomics.store(func_sig_view_u32, 0, 8); Atomics.store(func_sig_view_u32, 1, fd); @@ -319,9 +333,7 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { return error; } - fd_close( - fd: number, - ): number { + fd_close(fd: number): number { this.lock_fd(fd); const bytes_offset = fd * fd_func_sig_bytes; @@ -348,9 +360,7 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { return error; } - fd_datasync( - fd: number, - ): number { + fd_datasync(fd: number): number { this.lock_fd(fd); const bytes_offset = fd * fd_func_sig_bytes; @@ -371,16 +381,17 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { return error; } - fd_fdstat_get( - fd: number, - ): [wasi.Fdstat | undefined, number] { + fd_fdstat_get(fd: number): [wasi.Fdstat | undefined, number] { this.lock_fd(fd); const bytes_offset = fd * fd_func_sig_bytes; const func_sig_view_u8 = new Uint8Array(this.fd_func_sig, bytes_offset); const func_sig_view_u16 = new Uint16Array(this.fd_func_sig, bytes_offset); const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, bytes_offset); - const func_sig_view_u64 = new BigUint64Array(this.fd_func_sig, bytes_offset); + const func_sig_view_u64 = new BigUint64Array( + this.fd_func_sig, + bytes_offset, + ); Atomics.store(func_sig_view_u32, 0, 11); Atomics.store(func_sig_view_u32, 1, fd); @@ -404,20 +415,14 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { this.release_fd(fd); - const fd_stat = new wasi.Fdstat( - fs_filetype, - fs_flags, - ); + const fd_stat = new wasi.Fdstat(fs_filetype, fs_flags); fd_stat.fs_rights_base = fs_rights_base; fd_stat.fs_rights_inherited = fs_rights_inheriting; return [fd_stat, error]; } - fd_fdstat_set_flags( - fd: number, - flags: number, - ): number { + fd_fdstat_set_flags(fd: number, flags: number): number { this.lock_fd(fd); const bytes_offset = fd * fd_func_sig_bytes; @@ -449,7 +454,10 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { const bytes_offset = fd * fd_func_sig_bytes; const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, bytes_offset); - const func_sig_view_u64 = new BigUint64Array(this.fd_func_sig, bytes_offset); + const func_sig_view_u64 = new BigUint64Array( + this.fd_func_sig, + bytes_offset, + ); Atomics.store(func_sig_view_u32, 0, 13); Atomics.store(func_sig_view_u32, 1, fd); @@ -468,15 +476,16 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { return error; } - fd_filestat_get( - fd: number, - ): [wasi.Filestat | undefined, number] { + fd_filestat_get(fd: number): [wasi.Filestat | undefined, number] { this.lock_fd(fd); const bytes_offset = fd * fd_func_sig_bytes; const func_sig_view_u8 = new Uint8Array(this.fd_func_sig, bytes_offset); const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, bytes_offset); - const func_sig_view_u64 = new BigUint64Array(this.fd_func_sig, bytes_offset); + const func_sig_view_u64 = new BigUint64Array( + this.fd_func_sig, + bytes_offset, + ); Atomics.store(func_sig_view_u32, 0, 14); Atomics.store(func_sig_view_u32, 1, fd); @@ -504,9 +513,7 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { this.release_fd(fd); - const file_stat = new wasi.Filestat( - fs_filetype, fs_size - ); + const file_stat = new wasi.Filestat(fs_filetype, fs_size); file_stat.dev = fs_dev; file_stat.ino = fs_ino; file_stat.nlink = fs_nlink; @@ -517,15 +524,15 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { return [file_stat, error]; } - fd_filestat_set_size( - fd: number, - size: bigint, - ): number { + fd_filestat_set_size(fd: number, size: bigint): number { this.lock_fd(fd); const bytes_offset = fd * fd_func_sig_bytes; const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, bytes_offset); - const func_sig_view_u64 = new BigUint64Array(this.fd_func_sig, bytes_offset); + const func_sig_view_u64 = new BigUint64Array( + this.fd_func_sig, + bytes_offset, + ); Atomics.store(func_sig_view_u32, 0, 15); Atomics.store(func_sig_view_u32, 1, fd); @@ -554,7 +561,10 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { const bytes_offset = fd * fd_func_sig_bytes; const func_sig_view_u16 = new Uint16Array(this.fd_func_sig, bytes_offset); const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, bytes_offset); - const func_sig_view_u64 = new BigUint64Array(this.fd_func_sig, bytes_offset); + const func_sig_view_u64 = new BigUint64Array( + this.fd_func_sig, + bytes_offset, + ); Atomics.store(func_sig_view_u32, 0, 16); Atomics.store(func_sig_view_u32, 1, fd); @@ -583,11 +593,18 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { const bytes_offset = fd * fd_func_sig_bytes; const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, bytes_offset); - const func_sig_view_u64 = new BigUint64Array(this.fd_func_sig, bytes_offset); + const func_sig_view_u64 = new BigUint64Array( + this.fd_func_sig, + bytes_offset, + ); Atomics.store(func_sig_view_u32, 0, 17); Atomics.store(func_sig_view_u32, 1, fd); - const [ptr, len] = this.allocator.block_write(iovs, this.fd_func_sig, fd * fd_func_sig_u32_size + 2); + const [ptr, len] = this.allocator.block_write( + iovs, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 2, + ); Atomics.store(func_sig_view_u64, 2, offset); if (!this.call_fd_func(fd)) { @@ -619,9 +636,7 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { return [[nread, buf], error]; } - fd_prestat_get( - fd: number, - ): [[number, number] | undefined, number] { + fd_prestat_get(fd: number): [[number, number] | undefined, number] { this.lock_fd(fd); const bytes_offset = fd * fd_func_sig_bytes; @@ -679,7 +694,9 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { return [undefined, error]; } - const ret_path = new Uint8Array(this.allocator.get_memory(ret_path_ptr, ret_path_len)); + const ret_path = new Uint8Array( + this.allocator.get_memory(ret_path_ptr, ret_path_len), + ); this.allocator.free(ret_path_ptr, ret_path_len); return [ret_path, error]; @@ -694,11 +711,18 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { const bytes_offset = fd * fd_func_sig_bytes; const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, bytes_offset); - const func_sig_view_u64 = new BigUint64Array(this.fd_func_sig, bytes_offset); + const func_sig_view_u64 = new BigUint64Array( + this.fd_func_sig, + bytes_offset, + ); Atomics.store(func_sig_view_u32, 0, 20); Atomics.store(func_sig_view_u32, 1, fd); - const [ptr, len] = this.allocator.block_write(write_data, this.fd_func_sig, fd * fd_func_sig_u32_size + 2); + const [ptr, len] = this.allocator.block_write( + write_data, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 2, + ); Atomics.store(func_sig_view_u64, 2, offset); if (!this.call_fd_func(fd)) { @@ -736,7 +760,11 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { // console.log("fd_read: ref: iovs", iovs); // console.log("iovs.buffer", iovs.buffer.slice(0, iovs.byteLength)); - const [ptr, len] = this.allocator.block_write(iovs, this.fd_func_sig, fd * fd_func_sig_u32_size + 2); + const [ptr, len] = this.allocator.block_write( + iovs, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 2, + ); // console.log("fd_read: ref: iovs", iovs); @@ -787,7 +815,10 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { const bytes_offset = fd * fd_func_sig_bytes; const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, bytes_offset); - const func_sig_view_u64 = new BigUint64Array(this.fd_func_sig, bytes_offset); + const func_sig_view_u64 = new BigUint64Array( + this.fd_func_sig, + bytes_offset, + ); Atomics.store(func_sig_view_u32, 0, 22); Atomics.store(func_sig_view_u32, 1, fd); @@ -854,7 +885,10 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { const bytes_offset = fd * fd_func_sig_bytes; const func_sig_view_u8 = new Uint8Array(this.fd_func_sig, bytes_offset); const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, bytes_offset); - const func_sig_view_u64 = new BigUint64Array(this.fd_func_sig, bytes_offset); + const func_sig_view_u64 = new BigUint64Array( + this.fd_func_sig, + bytes_offset, + ); Atomics.store(func_sig_view_u32, 0, 24); Atomics.store(func_sig_view_u32, 1, fd); @@ -880,9 +914,7 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { return [new_offset, error]; } - fd_sync( - fd: number, - ): number { + fd_sync(fd: number): number { this.lock_fd(fd); const bytes_offset = fd * fd_func_sig_bytes; @@ -903,14 +935,15 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { return error; } - fd_tell( - fd: number, - ): [bigint | undefined, number] { + fd_tell(fd: number): [bigint | undefined, number] { this.lock_fd(fd); const bytes_offset = fd * fd_func_sig_bytes; const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, bytes_offset); - const func_sig_view_u64 = new BigUint64Array(this.fd_func_sig, bytes_offset); + const func_sig_view_u64 = new BigUint64Array( + this.fd_func_sig, + bytes_offset, + ); Atomics.store(func_sig_view_u32, 0, 26); Atomics.store(func_sig_view_u32, 1, fd); @@ -934,10 +967,7 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { return [offset, error]; } - fd_write( - fd: number, - write_data: Uint8Array, - ): [number | undefined, number] { + fd_write(fd: number, write_data: Uint8Array): [number | undefined, number] { this.lock_fd(fd); // console.log("fd_write: ref: write_data", new TextDecoder().decode(write_data)); @@ -947,7 +977,11 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { Atomics.store(func_sig_view_u32, 0, 27); Atomics.store(func_sig_view_u32, 1, fd); - const [ptr, len] = this.allocator.block_write(write_data, this.fd_func_sig, fd * fd_func_sig_u32_size +2); + const [ptr, len] = this.allocator.block_write( + write_data, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 2, + ); if (!this.call_fd_func(fd)) { // console.log("fd_write: ref: error", "wasi.ERRNO_BADF"); @@ -975,10 +1009,7 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { return [nwritten, error]; } - path_create_directory( - fd: number, - path: Uint8Array, - ): number { + path_create_directory(fd: number, path: Uint8Array): number { this.lock_fd(fd); const bytes_offset = fd * fd_func_sig_bytes; @@ -986,7 +1017,11 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { Atomics.store(func_sig_view_u32, 0, 28); Atomics.store(func_sig_view_u32, 1, fd); - const [ptr, len] = this.allocator.block_write(path, this.fd_func_sig, fd * fd_func_sig_u32_size + 2); + const [ptr, len] = this.allocator.block_write( + path, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 2, + ); if (!this.call_fd_func(fd)) { this.allocator.free(ptr, len); @@ -1011,12 +1046,19 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { const bytes_offset = fd * fd_func_sig_bytes; const func_sig_view_u8 = new Uint8Array(this.fd_func_sig, bytes_offset); const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, bytes_offset); - const func_sig_view_u64 = new BigUint64Array(this.fd_func_sig, bytes_offset); + const func_sig_view_u64 = new BigUint64Array( + this.fd_func_sig, + bytes_offset, + ); Atomics.store(func_sig_view_u32, 0, 29); Atomics.store(func_sig_view_u32, 1, fd); Atomics.store(func_sig_view_u32, 2, flags); - const [ptr, len] = this.allocator.block_write(path, this.fd_func_sig, fd * fd_func_sig_u32_size + 3); + const [ptr, len] = this.allocator.block_write( + path, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 3, + ); if (!this.call_fd_func(fd)) { this.allocator.free(ptr, len); @@ -1042,9 +1084,7 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { this.release_fd(fd); - const file_stat = new wasi.Filestat( - fs_filetype, fs_size - ); + const file_stat = new wasi.Filestat(fs_filetype, fs_size); file_stat.dev = fs_dev; file_stat.ino = fs_ino; file_stat.nlink = fs_nlink; @@ -1068,12 +1108,19 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { const bytes_offset = fd * fd_func_sig_bytes; const func_sig_view_u16 = new Uint16Array(this.fd_func_sig, bytes_offset); const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, bytes_offset); - const func_sig_view_u64 = new BigUint64Array(this.fd_func_sig, bytes_offset); + const func_sig_view_u64 = new BigUint64Array( + this.fd_func_sig, + bytes_offset, + ); Atomics.store(func_sig_view_u32, 0, 30); Atomics.store(func_sig_view_u32, 1, fd); Atomics.store(func_sig_view_u32, 2, flags); - const [ptr, len] = this.allocator.block_write(path, this.fd_func_sig, fd * fd_func_sig_u32_size + 3); + const [ptr, len] = this.allocator.block_write( + path, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 3, + ); Atomics.store(func_sig_view_u64, 3, st_atim); Atomics.store(func_sig_view_u64, 4, st_mtim); Atomics.store(func_sig_view_u16, 12, fst_flags); @@ -1106,9 +1153,17 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { Atomics.store(func_sig_view_u32, 0, 31); Atomics.store(func_sig_view_u32, 1, old_fd); Atomics.store(func_sig_view_u32, 2, old_flags); - const [ptr1, len1] = this.allocator.block_write(old_path, this.fd_func_sig, old_fd * fd_func_sig_u32_size + 3); + const [ptr1, len1] = this.allocator.block_write( + old_path, + this.fd_func_sig, + old_fd * fd_func_sig_u32_size + 3, + ); Atomics.store(func_sig_view_u32, 5, new_fd); - const [ptr2, len2] = this.allocator.block_write(new_path, this.fd_func_sig, old_fd * fd_func_sig_u32_size + 6); + const [ptr2, len2] = this.allocator.block_write( + new_path, + this.fd_func_sig, + old_fd * fd_func_sig_u32_size + 6, + ); if (!this.call_fd_func(old_fd)) { this.allocator.free(ptr1, len1); @@ -1138,12 +1193,19 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { const bytes_offset = fd * fd_func_sig_bytes; const func_sig_view_u16 = new Uint16Array(this.fd_func_sig, bytes_offset); const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, bytes_offset); - const func_sig_view_u64 = new BigUint64Array(this.fd_func_sig, bytes_offset); + const func_sig_view_u64 = new BigUint64Array( + this.fd_func_sig, + bytes_offset, + ); Atomics.store(func_sig_view_u32, 0, 32); Atomics.store(func_sig_view_u32, 1, fd); Atomics.store(func_sig_view_u32, 2, dirflags); - const [ptr, len] = this.allocator.block_write(path, this.fd_func_sig, fd * fd_func_sig_u32_size + 3); + const [ptr, len] = this.allocator.block_write( + path, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 3, + ); Atomics.store(func_sig_view_u32, 5, oflags); Atomics.store(func_sig_view_u64, 3, fs_rights_base); Atomics.store(func_sig_view_u64, 4, fs_rights_inheriting); @@ -1180,7 +1242,11 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { Atomics.store(func_sig_view_u32, 0, 33); Atomics.store(func_sig_view_u32, 1, fd); - const [ptr, len] = this.allocator.block_write(path, this.fd_func_sig, fd * fd_func_sig_u32_size + 2); + const [ptr, len] = this.allocator.block_write( + path, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 2, + ); Atomics.store(func_sig_view_u32, 4, buf_len); if (!this.call_fd_func(fd)) { @@ -1201,16 +1267,15 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { return [undefined, error]; } - const ret_path = new Uint8Array(this.allocator.get_memory(ret_path_ptr, ret_path_len)); + const ret_path = new Uint8Array( + this.allocator.get_memory(ret_path_ptr, ret_path_len), + ); const ret_path_slice = ret_path.slice(0, nread); return [ret_path_slice, error]; } - path_remove_directory( - fd: number, - path: Uint8Array, - ): number { + path_remove_directory(fd: number, path: Uint8Array): number { this.lock_fd(fd); const bytes_offset = fd * fd_func_sig_bytes; @@ -1218,7 +1283,11 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { Atomics.store(func_sig_view_u32, 0, 34); Atomics.store(func_sig_view_u32, 1, fd); - const [ptr, len] = this.allocator.block_write(path, this.fd_func_sig, fd * fd_func_sig_u32_size + 2); + const [ptr, len] = this.allocator.block_write( + path, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 2, + ); if (!this.call_fd_func(fd)) { this.allocator.free(ptr, len); @@ -1246,9 +1315,17 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { Atomics.store(func_sig_view_u32, 0, 35); Atomics.store(func_sig_view_u32, 1, old_fd); - const [ptr1, len1] = this.allocator.block_write(old_path, this.fd_func_sig, old_fd * fd_func_sig_u32_size + 2); + const [ptr1, len1] = this.allocator.block_write( + old_path, + this.fd_func_sig, + old_fd * fd_func_sig_u32_size + 2, + ); Atomics.store(func_sig_view_u32, 4, new_fd); - const [ptr2, len2] = this.allocator.block_write(new_path, this.fd_func_sig, old_fd * fd_func_sig_u32_size + 5); + const [ptr2, len2] = this.allocator.block_write( + new_path, + this.fd_func_sig, + old_fd * fd_func_sig_u32_size + 5, + ); if (!this.call_fd_func(old_fd)) { this.allocator.free(ptr1, len1); @@ -1264,20 +1341,24 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { return error; } - path_symlink( - old_path: Uint8Array, - fd: number, - new_path: Uint8Array, - ): number { + path_symlink(old_path: Uint8Array, fd: number, new_path: Uint8Array): number { this.lock_fd(fd); const bytes_offset = fd * fd_func_sig_bytes; const func_sig_view_u32 = new Uint32Array(this.fd_func_sig, bytes_offset); Atomics.store(func_sig_view_u32, 0, 36); - const [ptr1, len1] = this.allocator.block_write(old_path, this.fd_func_sig, fd * fd_func_sig_u32_size + 1); + const [ptr1, len1] = this.allocator.block_write( + old_path, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 1, + ); Atomics.store(func_sig_view_u32, 3, fd); - const [ptr2, len2] = this.allocator.block_write(new_path, this.fd_func_sig, fd * fd_func_sig_u32_size + 4); + const [ptr2, len2] = this.allocator.block_write( + new_path, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 4, + ); if (!this.call_fd_func(fd)) { this.allocator.free(ptr1, len1); @@ -1293,10 +1374,7 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { return error; } - path_unlink_file( - fd: number, - path: Uint8Array, - ): number { + path_unlink_file(fd: number, path: Uint8Array): number { this.lock_fd(fd); const bytes_offset = fd * fd_func_sig_bytes; @@ -1304,7 +1382,11 @@ export class WASIFarmRefUseArrayBuffer extends WASIFarmRef { Atomics.store(func_sig_view_u32, 0, 37); Atomics.store(func_sig_view_u32, 1, fd); - const [ptr, len] = this.allocator.block_write(path, this.fd_func_sig, fd * fd_func_sig_u32_size + 2); + const [ptr, len] = this.allocator.block_write( + path, + this.fd_func_sig, + fd * fd_func_sig_u32_size + 2, + ); if (!this.call_fd_func(fd)) { this.allocator.free(ptr, len); diff --git a/src/wasi_farm/shared_array_buffer/sender.ts b/src/wasi_farm/shared_array_buffer/sender.ts index 42b54d1..252e36b 100644 --- a/src/wasi_farm/shared_array_buffer/sender.ts +++ b/src/wasi_farm/shared_array_buffer/sender.ts @@ -1,7 +1,7 @@ export type ToRefSenderUseArrayBufferObject = { data_size: number; share_arrays_memory?: SharedArrayBuffer; -} +}; // To ref sender abstract class export abstract class ToRefSenderUseArrayBuffer { @@ -53,12 +53,10 @@ export abstract class ToRefSenderUseArrayBuffer { Atomics.store(view, 2, 12); } - protected static init_self_inner( - sl: ToRefSenderUseArrayBufferObject, - ): { - data_size: number, - max_share_arrays_memory: number, - share_arrays_memory: SharedArrayBuffer, + protected static init_self_inner(sl: ToRefSenderUseArrayBufferObject): { + data_size: number; + max_share_arrays_memory: number; + share_arrays_memory: SharedArrayBuffer; } { return { data_size: sl.data_size, @@ -121,7 +119,7 @@ export abstract class ToRefSenderUseArrayBuffer { const used_len = Atomics.load(view, 2); const data_len = data.byteLength; if (data_len !== this.data_size) { - throw new Error("invalid data size: " + data_len + " !== " + this.data_size); + throw new Error(`invalid data size: ${data_len} !== ${this.data_size}`); } const new_used_len = used_len + data_len + 8 + targets.length * 4; if (new_used_len > this.share_arrays_memory.byteLength) { @@ -135,7 +133,10 @@ export abstract class ToRefSenderUseArrayBuffer { header[1] = targets.length; header.set(targets, 2); - const data_view = new Uint32Array(this.share_arrays_memory, used_len + 8 + targets.length * 4); + const data_view = new Uint32Array( + this.share_arrays_memory, + used_len + 8 + targets.length * 4, + ); data_view.set(data); // console.log("async_send send", targets, data); @@ -145,9 +146,7 @@ export abstract class ToRefSenderUseArrayBuffer { this.release_lock(); } - protected get_data( - id: number, - ): Array | undefined { + protected get_data(id: number): Array | undefined { const view = new Int32Array(this.share_arrays_memory); const data_num_tmp = Atomics.load(view, 1); if (data_num_tmp === 0) { @@ -166,10 +165,18 @@ export abstract class ToRefSenderUseArrayBuffer { // console.log("this.share_arrays_memory", this.share_arrays_memory); const header = new Int32Array(this.share_arrays_memory, offset); const target_num = header[1]; - const targets = new Int32Array(this.share_arrays_memory, offset + 8, target_num); + const targets = new Int32Array( + this.share_arrays_memory, + offset + 8, + target_num, + ); const data_len = this.data_size; if (targets.includes(id)) { - const data = new Uint32Array(this.share_arrays_memory, offset + 8 + target_num * 4, data_len / 4); + const data = new Uint32Array( + this.share_arrays_memory, + offset + 8 + target_num * 4, + data_len / 4, + ); // なぜかわからないが、上では正常に動作せず、以下のようにすると動作する // return_data.push(new Uint32Array(data)); @@ -185,7 +192,10 @@ export abstract class ToRefSenderUseArrayBuffer { const new_used_len = used_len - data_len - 8 - target_num * 4; Atomics.store(view, 2, new_used_len); const next_data_offset = offset + data_len + 8 + target_num * 4; - const next_tail = new Int32Array(this.share_arrays_memory, next_data_offset); + const next_tail = new Int32Array( + this.share_arrays_memory, + next_data_offset, + ); const now_tail = new Int32Array(this.share_arrays_memory, offset); now_tail.set(next_tail); // console.log("new_used_len", new_used_len); @@ -199,7 +209,7 @@ export abstract class ToRefSenderUseArrayBuffer { } if (offset !== Atomics.load(view, 2)) { - throw new Error("invalid offset: " + offset + " !== " + Atomics.load(view, 2)); + throw new Error(`invalid offset: ${offset} !== ${Atomics.load(view, 2)}`); } this.release_lock(); diff --git a/src/wasi_farm/shared_array_buffer/thread_spawn.ts b/src/wasi_farm/shared_array_buffer/thread_spawn.ts new file mode 100644 index 0000000..dc3ba3b --- /dev/null +++ b/src/wasi_farm/shared_array_buffer/thread_spawn.ts @@ -0,0 +1,410 @@ +// (export "wasi_thread_start" (func $61879)) +// (func $61879 (param $0 i32) (param $1 i32) +// (local $2 i32) +// (local $3 i32) +// (local $4 i32) +// (local $5 i32) +// (local $6 i32) +// (local $7 i32) +// (global.set $global$0 +// (i32.load +// (local.get $1) +// ) +// ) + +// (import "wasi" "thread-spawn" (func $fimport$27 (param i32) (result i32))) + +import { WASIFarmAnimal } from "../animals.js"; +import type { WASIFarmRefObject } from "../ref.js"; +import type { WorkerBackgroundRefObject } from "./worker_background/index.js"; +import { + WorkerBackgroundRef, + worker_background_worker_url, +} from "./worker_background/index.js"; +import { WorkerBackgroundRefObjectConstructor } from "./worker_background/worker_export.js"; + +type ThreadSpawnerObject = { + share_memory: WebAssembly.Memory; + wasi_farm_refs_object: Array; + worker_url: string; + worker_background_ref_object: WorkerBackgroundRefObject; + // inst_default_buffer_kept: WebAssembly.Memory; +}; + +export class ThreadSpawner { + private share_memory: WebAssembly.Memory; + private wasi_farm_refs_object: Array; + private worker_url: string; + private worker_background_ref: WorkerBackgroundRef; + private worker_background_ref_object: WorkerBackgroundRefObject; + // inst_default_buffer_kept: WebAssembly.Memory; + + // hold the worker to prevent GC. + private worker_background_worker?: Worker; + private worker_background_worker_promise?: Promise; + + // https://github.com/rustwasm/wasm-pack/issues/479 + + constructor( + worker_url: string, + wasi_farm_refs_object: Array, + share_memory?: WebAssembly.Memory, + // 16MB for the time being. + // https://users.rust-lang.org/t/what-is-the-size-limit-of-threads-stack-in-rust/11867/3 + MIN_STACK = 16777216, + worker_background_ref_object?: WorkerBackgroundRefObject, + thread_spawn_wasm?: WebAssembly.Module, + // inst_default_buffer_kept?: WebAssembly.Memory, + ) { + this.worker_url = worker_url; + this.wasi_farm_refs_object = wasi_farm_refs_object; + + const min_initial_size = 1048576 / 65536; // Rust's default stack size is 1MB. + const initial_size = MIN_STACK / 65536; + if (initial_size < min_initial_size) { + throw new Error( + `The stack size must be at least ${min_initial_size} bytes.`, + ); + } + const max_memory = 1073741824 / 65536; // Rust's default maximum memory size is 1GB. + + // this.inst_default_buffer_kept = + // inst_default_buffer_kept || + // new WebAssembly.Memory({ + // initial: 1, + // maximum: max_memory, + // shared: true, + // }); + + this.share_memory = + share_memory || + // WebAssembly.Memory's 1 page is 65536 bytes. + new WebAssembly.Memory({ + initial: initial_size, + maximum: max_memory, + shared: true, + }); + + if (worker_background_ref_object === undefined) { + const worker_background_worker_url__ = worker_background_worker_url(); + this.worker_background_worker = new Worker( + worker_background_worker_url__, + { type: "module" }, + ); + URL.revokeObjectURL(worker_background_worker_url__); + const { promise, resolve } = Promise.withResolvers(); + this.worker_background_worker_promise = promise; + this.worker_background_worker.onmessage = () => { + this.worker_background_worker_promise = undefined; + resolve(); + }; + this.worker_background_ref_object = + WorkerBackgroundRefObjectConstructor(); + this.worker_background_ref = WorkerBackgroundRef.init_self( + this.worker_background_ref_object, + ); + this.worker_background_worker.postMessage({ + override_object: { + sl_object: this.get_object(), + thread_spawn_wasm, + }, + worker_background_ref_object: this.worker_background_ref_object, + }); + } else { + this.worker_background_ref = WorkerBackgroundRef.init_self( + worker_background_ref_object, + ); + } + } + + // This cannot blocking. + async wait_worker_background_worker(): Promise { + if (this.worker_background_worker_promise) { + const promise = this.worker_background_worker_promise; + + await promise; + + return; + } + return; + } + + check_worker_background_worker(): void { + if (this.worker_background_worker_promise) { + throw new Error("worker_background_worker is not ready."); + } + } + + thread_spawn( + start_arg: number, + args: Array, + env: Array, + fd_map: Array<[number, number]>, + ): number { + const worker = this.worker_background_ref.new_worker( + this.worker_url, + { type: "module" }, + { + this_is_thread_spawn: true, + start_arg, + args, + env, + fd_map, + }, + ); + + const thread_id = worker.get_id(); + + return thread_id; + } + + async async_start_on_thread( + args: Array, + env: Array, + ): Promise { + if (!self.Worker.toString().includes("[native code]")) { + if (self.Worker.toString().includes("function")) { + console.warn("SubWorker(new Worker on Worker) is polyfilled maybe."); + } else { + throw new Error("SubWorker(new Worker on Worker) is not supported."); + } + } + + await this.worker_background_ref.async_start_on_thread( + this.worker_url, + { type: "module" }, + { + this_is_thread_spawn: true, + this_is_start: true, + args, + env, + }, + ); + } + + block_start_on_thread(args: Array, env: Array): void { + if (!self.Worker.toString().includes("[native code]")) { + if (self.Worker.toString().includes("function")) { + console.warn("SubWorker(new Worker on Worker) is polyfilled maybe."); + } else { + throw new Error("SubWorker(new Worker on Worker) is not supported."); + } + } + + this.worker_background_ref.block_start_on_thread( + this.worker_url, + { type: "module" }, + { + this_is_thread_spawn: true, + this_is_start: true, + args, + env, + }, + ); + } + + static init_self(sl: ThreadSpawnerObject): ThreadSpawner { + const thread_spawner = new ThreadSpawner( + sl.worker_url, + sl.wasi_farm_refs_object, + sl.share_memory, + undefined, + sl.worker_background_ref_object, + // undefined, + // sl.inst_default_buffer_kept, + ); + return thread_spawner; + } + + static init_self_with_worker_background_ref( + sl: ThreadSpawnerObject, + worker_background_ref_object: WorkerBackgroundRefObject, + ): ThreadSpawner { + const thread_spawner = new ThreadSpawner( + sl.worker_url, + sl.wasi_farm_refs_object, + sl.share_memory, + undefined, + worker_background_ref_object, + // undefined, + // sl.inst_default_buffer_kept, + ); + return thread_spawner; + } + + get_share_memory(): WebAssembly.Memory { + return this.share_memory; + } + + get_object(): ThreadSpawnerObject { + return { + share_memory: this.share_memory, + wasi_farm_refs_object: this.wasi_farm_refs_object, + worker_url: this.worker_url, + worker_background_ref_object: this.worker_background_ref_object, + // inst_default_buffer_kept: this.inst_default_buffer_kept, + }; + } + + done_notify(code: number): void { + this.worker_background_ref.done_notify(code); + } + + async async_wait_done_or_error(): Promise { + if (this.worker_background_worker === undefined) { + throw new Error("worker_background_worker is undefined."); + } + + return await this.worker_background_ref.async_wait_done_or_error(); + } + + block_wait_done_or_error(): number { + if (this.worker_background_worker === undefined) { + throw new Error("worker_background_worker is undefined."); + } + + return this.worker_background_ref.block_wait_done_or_error(); + } +} + +// send fd_map is not implemented yet. +// issue: the fd passed to the child process is different from the parent process. +export const thread_spawn_on_worker = async (msg: { + this_is_thread_spawn: boolean; + worker_id?: number; + start_arg: number; + worker_background_ref: WorkerBackgroundRefObject; + sl_object: ThreadSpawnerObject; + thread_spawn_wasm: WebAssembly.Module; + args: Array; + env: Array; + fd_map: Array; + this_is_start?: boolean; +}): Promise => { + if (msg.this_is_thread_spawn) { + if (msg.this_is_start) { + const thread_spawner = ThreadSpawner.init_self_with_worker_background_ref( + msg.sl_object, + msg.worker_background_ref, + ); + + const wasi = new WASIFarmAnimal( + msg.sl_object.wasi_farm_refs_object, + msg.args, + msg.env, + { + can_thread_spawn: true, + thread_spawn_worker_url: msg.sl_object.worker_url, + }, + undefined, + thread_spawner, + ); + + const inst = await WebAssembly.instantiate(msg.thread_spawn_wasm, { + env: { + memory: wasi.get_share_memory(), + }, + wasi: wasi.wasiThreadImport, + wasi_snapshot_preview1: wasi.wasiImport, + }); + + wasi.start( + inst as unknown as { + exports: { + memory: WebAssembly.Memory; + _start: () => unknown; + }; + }, + ); + + globalThis.postMessage({ + msg: "done", + }); + + return wasi; + } + + const { + worker_id: thread_id, + start_arg, + args, + env, + sl_object, + thread_spawn_wasm, + } = msg; + + console.log(`thread_spawn worker ${thread_id} start`); + + const thread_spawner = ThreadSpawner.init_self_with_worker_background_ref( + sl_object, + msg.worker_background_ref, + ); + + const override_fd_map: Array = new Array( + sl_object.wasi_farm_refs_object.length, + ); + + // Possibly null (undefined) + for (const fd_and_wasi_ref_n of msg.fd_map) { + // biome-ignore lint/suspicious/noDoubleEquals: + if (fd_and_wasi_ref_n == undefined) { + continue; + } + const [fd, wasi_ref_n] = fd_and_wasi_ref_n; + if (override_fd_map[wasi_ref_n] === undefined) { + override_fd_map[wasi_ref_n] = []; + } + override_fd_map[wasi_ref_n].push(fd); + } + + const wasi = new WASIFarmAnimal( + sl_object.wasi_farm_refs_object, + args, + env, + { + can_thread_spawn: true, + thread_spawn_worker_url: sl_object.worker_url, + }, + override_fd_map, + thread_spawner, + ); + + const inst = await WebAssembly.instantiate(thread_spawn_wasm, { + env: { + memory: wasi.get_share_memory(), + }, + wasi: wasi.wasiThreadImport, + wasi_snapshot_preview1: wasi.wasiImport, + }); + + globalThis.postMessage({ + msg: "ready", + }); + + try { + wasi.wasi_thread_start( + inst as unknown as { + exports: { + memory: WebAssembly.Memory; + wasi_thread_start: (thread_id: number, start_arg: number) => void; + }; + }, + thread_id, + start_arg, + ); + } catch (e) { + globalThis.postMessage({ + msg: "error", + error: e, + }); + + return wasi; + } + + globalThis.postMessage({ + msg: "done", + }); + + return wasi; + } +}; diff --git a/src/wasi_farm/shared_array_buffer/util.ts b/src/wasi_farm/shared_array_buffer/util.ts index bab95f3..4ed230f 100644 --- a/src/wasi_farm/shared_array_buffer/util.ts +++ b/src/wasi_farm/shared_array_buffer/util.ts @@ -1,36 +1,68 @@ export const get_func_name_from_number = (num: number): string => { switch (num) { - case 7: return "fd_advise"; - case 8: return "fd_allocate"; - case 9: return "fd_close"; - case 10: return "fd_datasync"; - case 11: return "fd_fdstat_get"; - case 12: return "fd_fdstat_set_flags"; - case 13: return "fd_fdstat_set_rights"; - case 14: return "fd_filestat_get"; - case 15: return "fd_filestat_set_size"; - case 16: return "fd_filestat_set_times"; - case 17: return "fd_pread"; - case 18: return "fd_prestat_get"; - case 19: return "fd_prestat_dir_name"; - case 20: return "fd_pwrite"; - case 21: return "fd_read"; - case 22: return "fd_readdir"; - case 23: return "fd_renumber"; - case 24: return "fd_seek"; - case 25: return "fd_sync"; - case 26: return "fd_tell"; - case 27: return "fd_write"; - case 28: return "path_create_directory"; - case 29: return "path_filestat_get"; - case 30: return "path_filestat_set_times"; - case 31: return "path_link"; - case 32: return "path_open"; - case 33: return "path_readlink"; - case 34: return "path_remove_directory"; - case 35: return "path_rename"; - case 36: return "path_symlink"; - case 37: return "path_unlink_file"; - default: return "unknown"; + case 7: + return "fd_advise"; + case 8: + return "fd_allocate"; + case 9: + return "fd_close"; + case 10: + return "fd_datasync"; + case 11: + return "fd_fdstat_get"; + case 12: + return "fd_fdstat_set_flags"; + case 13: + return "fd_fdstat_set_rights"; + case 14: + return "fd_filestat_get"; + case 15: + return "fd_filestat_set_size"; + case 16: + return "fd_filestat_set_times"; + case 17: + return "fd_pread"; + case 18: + return "fd_prestat_get"; + case 19: + return "fd_prestat_dir_name"; + case 20: + return "fd_pwrite"; + case 21: + return "fd_read"; + case 22: + return "fd_readdir"; + case 23: + return "fd_renumber"; + case 24: + return "fd_seek"; + case 25: + return "fd_sync"; + case 26: + return "fd_tell"; + case 27: + return "fd_write"; + case 28: + return "path_create_directory"; + case 29: + return "path_filestat_get"; + case 30: + return "path_filestat_set_times"; + case 31: + return "path_link"; + case 32: + return "path_open"; + case 33: + return "path_readlink"; + case 34: + return "path_remove_directory"; + case 35: + return "path_rename"; + case 36: + return "path_symlink"; + case 37: + return "path_unlink_file"; + default: + return "unknown"; } -} +}; diff --git a/src/wasi_farm/shared_array_buffer/worker_background/index.ts b/src/wasi_farm/shared_array_buffer/worker_background/index.ts new file mode 100644 index 0000000..eb3e67c --- /dev/null +++ b/src/wasi_farm/shared_array_buffer/worker_background/index.ts @@ -0,0 +1,10 @@ +import type { WorkerBackgroundRefObject } from "./worker_export.js"; +import { WorkerBackgroundRef, WorkerRef } from "./worker_background_ref.js"; +import { url as worker_background_worker_url } from "./worker_blob.js"; + +export { + WorkerBackgroundRef, + WorkerRef, + type WorkerBackgroundRefObject, + worker_background_worker_url, +}; diff --git a/src/wasi_farm/shared_array_buffer/worker_background/minify.js b/src/wasi_farm/shared_array_buffer/worker_background/minify.js new file mode 100644 index 0000000..eecb571 --- /dev/null +++ b/src/wasi_farm/shared_array_buffer/worker_background/minify.js @@ -0,0 +1,46 @@ +import swc from "@swc/core"; + +import { readFileSync, writeFileSync } from "node:fs"; + +const old_code = readFileSync( + "./dist/workers/worker_background_worker.js", + "utf8", +); + +const { code } = await swc.minify(old_code, { + compress: { + reduce_funcs: true, + arguments: true, + booleans_as_integers: true, + hoist_funs: false, + keep_classnames: false, + unsafe: true, + }, + mangle: true, +}); + +writeFileSync( + "./dist/workers/worker_background_worker_minify.js", + code, + "utf8", +); + +// \n -> \\n + +const wrapper_code = `export const url = () => { + const code = + '${code.replace(/\\/g, "\\\\")}'; + + const blob = new Blob([code], { type: "application/javascript" }); + + const url = URL.createObjectURL(blob); + + return url; +}; +`; + +writeFileSync( + "./src/wasi_farm/shared_array_buffer/worker_background/worker_blob.ts", + wrapper_code, + "utf8", +); diff --git a/src/wasi_farm/shared_array_buffer/worker_background/spack.config.cjs b/src/wasi_farm/shared_array_buffer/worker_background/spack.config.cjs new file mode 100644 index 0000000..2b498de --- /dev/null +++ b/src/wasi_farm/shared_array_buffer/worker_background/spack.config.cjs @@ -0,0 +1,15 @@ +// https://swc.rs/docs/configuration/bundling + +const { config } = require("@swc/core/spack"); + +console.log(__dirname); + +module.exports = config({ + entry: { + web: `${__dirname}/worker.ts`, + }, + output: { + path: `${__dirname}/../../../../dist/workers/`, + name: "worker_background_worker.js", + }, +}); diff --git a/src/wasi_farm/shared_array_buffer/worker_background/worker.ts b/src/wasi_farm/shared_array_buffer/worker_background/worker.ts new file mode 100644 index 0000000..9db336e --- /dev/null +++ b/src/wasi_farm/shared_array_buffer/worker_background/worker.ts @@ -0,0 +1,290 @@ +// If you create a worker and try to increase the number of threads, +// you will have to use Atomics.wait because they need to be synchronized. +// However, this is essentially impossible because Atomics.wait blocks the threads. +// Therefore, a dedicated worker that creates a subworker (worker in worker) is prepared. +// The request is made using BroadcastChannel. + +import * as Serializer from "../../../serialize_error.js"; +import { AllocatorUseArrayBuffer } from "../allocator.js"; +import type { WorkerBackgroundRefObject } from "./worker_export.js"; + +// Note that postMessage, etc. +// cannot be used in a blocking environment such as during wasm execution. +// (at least as far as I have tried) + +class WorkerBackground { + private override_object: T; + private allocator: AllocatorUseArrayBuffer; + private lock: SharedArrayBuffer; + private signature_input: SharedArrayBuffer; + + private workers: Array = [undefined]; + + private start_worker?: Worker; + + private listen_holder: Promise; + + constructor( + override_object: T, + lock?: SharedArrayBuffer, + allocator?: AllocatorUseArrayBuffer, + signature_input?: SharedArrayBuffer, + ) { + this.override_object = override_object; + this.lock = lock ?? new SharedArrayBuffer(20); + this.allocator = + allocator ?? + new AllocatorUseArrayBuffer(new SharedArrayBuffer(10 * 1024)); + this.signature_input = signature_input ?? new SharedArrayBuffer(24); + this.listen_holder = this.listen(); + } + + static init_self( + override_object: T, + worker_background_ref_object: WorkerBackgroundRefObject, + ): WorkerBackground { + return new WorkerBackground( + override_object, + worker_background_ref_object.lock, + AllocatorUseArrayBuffer.init_self(worker_background_ref_object.allocator), + worker_background_ref_object.signature_input, + ); + } + + assign_worker_id(): number { + for (let i = 1; i < this.workers.length; i++) { + if (this.workers[i] === undefined) { + return i; + } + } + this.workers.push(undefined); + return this.workers.length - 1; + } + + ref(): WorkerBackgroundRefObject { + return { + allocator: this.allocator.get_object(), + lock: this.lock, + signature_input: this.signature_input, + }; + } + + async listen(): Promise { + const lock_view = new Int32Array(this.lock); + Atomics.store(lock_view, 0, 0); + Atomics.store(lock_view, 1, 0); + + const signature_input_view = new Int32Array(this.signature_input); + + // eslint-disable-next-line no-constant-condition + while (true) { + try { + let lock: "not-equal" | "timed-out" | "ok"; + + const { value } = Atomics.waitAsync(lock_view, 1, 0); + if (value instanceof Promise) { + lock = await value; + } else { + lock = value; + } + if (lock === "timed-out") { + throw new Error("timed-out"); + } + + const locked_value = Atomics.load(lock_view, 1); + if (locked_value !== 1) { + throw new Error("locked"); + } + + const signature_input = Atomics.load(signature_input_view, 0); + switch (signature_input) { + // create new worker + case 1: { + const url_ptr = Atomics.load(signature_input_view, 1); + const url_len = Atomics.load(signature_input_view, 2); + const url_buff = this.allocator.get_memory(url_ptr, url_len); + this.allocator.free(url_ptr, url_len); + const url = new TextDecoder().decode(url_buff); + const is_module = Atomics.load(signature_input_view, 3) === 1; + const worker = new Worker(url, { + type: is_module ? "module" : "classic", + }); + const json_ptr = Atomics.load(signature_input_view, 4); + const json_len = Atomics.load(signature_input_view, 5); + const json_buff = this.allocator.get_memory(json_ptr, json_len); + this.allocator.free(json_ptr, json_len); + const json = new TextDecoder().decode(json_buff); + const obj = JSON.parse(json); + + const worker_id = this.assign_worker_id(); + + console.log(`new worker ${worker_id}`); + + this.workers[worker_id] = worker; + + const { promise, resolve } = Promise.withResolvers(); + + worker.onmessage = async (e) => { + const { msg } = e.data; + + if (msg === "ready") { + resolve(); + } + + if (msg === "done") { + this.workers[worker_id].terminate(); + this.workers[worker_id] = undefined; + + console.log(`worker ${worker_id} done so terminate`); + } + + if (msg === "error") { + this.workers[worker_id].terminate(); + this.workers[worker_id] = undefined; + + let n = 0; + for (const worker of this.workers) { + if (worker !== undefined) { + worker.terminate(); + console.warn( + `wasi throw error but child process exists, terminate ${n}`, + ); + } + n++; + } + if (this.start_worker !== undefined) { + this.start_worker.terminate(); + console.warn( + "wasi throw error but wasi exists, terminate wasi", + ); + } + + this.workers = [undefined]; + this.start_worker = undefined; + + const error = e.data.error; + + const notify_view = new Int32Array(this.lock, 8); + + const serialized_error = Serializer.serialize(error); + + const [ptr, len] = await this.allocator.async_write( + new TextEncoder().encode(JSON.stringify(serialized_error)), + this.lock, + 3, + ); + + // notify error = code 1 + const old = Atomics.compareExchange(notify_view, 0, 0, 1); + + if (old !== 0) { + console.error("what happened?"); + + this.allocator.free(ptr, len); + + return; + } + + const num = Atomics.notify(notify_view, 0); + + if (num === 0) { + console.error(error); + + this.allocator.free(ptr, len); + + Atomics.store(notify_view, 0, 0); + } + } + }; + + worker.postMessage({ + ...this.override_object, + ...obj, + worker_id, + worker_background_ref: this.ref(), + }); + + await promise; + + Atomics.store(signature_input_view, 0, worker_id); + + break; + } + // create start + case 2: { + const url_ptr = Atomics.load(signature_input_view, 1); + const url_len = Atomics.load(signature_input_view, 2); + const url_buff = this.allocator.get_memory(url_ptr, url_len); + this.allocator.free(url_ptr, url_len); + const url = new TextDecoder().decode(url_buff); + const is_module = Atomics.load(signature_input_view, 3) === 1; + this.start_worker = new Worker(url, { + type: is_module ? "module" : "classic", + }); + const json_ptr = Atomics.load(signature_input_view, 4); + const json_len = Atomics.load(signature_input_view, 5); + const json_buff = this.allocator.get_memory(json_ptr, json_len); + this.allocator.free(json_ptr, json_len); + const json = new TextDecoder().decode(json_buff); + const obj = JSON.parse(json); + + this.start_worker.onmessage = async (e) => { + const { msg } = e.data; + + if (msg === "done") { + let n = 0; + for (const worker of this.workers) { + if (worker !== undefined) { + worker.terminate(); + console.warn(`wasi done but worker exists, terminate ${n}`); + } + n++; + } + + this.start_worker.terminate(); + this.start_worker = undefined; + + console.log("start worker done so terminate"); + } + }; + + this.start_worker.postMessage({ + ...this.override_object, + ...obj, + worker_background_ref: this.ref(), + }); + + break; + } + } + + const old_call_lock = Atomics.exchange(lock_view, 1, 0); + if (old_call_lock !== 1) { + throw new Error("Lock is already set"); + } + const num = Atomics.notify(lock_view, 1, 1); + if (num !== 1) { + if (num === 0) { + console.warn("notify failed, waiter is late"); + continue; + } + throw new Error(`notify failed: ${num}`); + } + } catch (e) { + console.error(e); + } + } + } +} + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +let worker_background: WorkerBackground; + +globalThis.onmessage = (e: MessageEvent) => { + const { override_object, worker_background_ref_object } = e.data; + worker_background = WorkerBackground.init_self( + override_object, + worker_background_ref_object, + ); + postMessage("ready"); +}; diff --git a/src/wasi_farm/shared_array_buffer/worker_background/worker_background_ref.ts b/src/wasi_farm/shared_array_buffer/worker_background/worker_background_ref.ts new file mode 100644 index 0000000..4d570df --- /dev/null +++ b/src/wasi_farm/shared_array_buffer/worker_background/worker_background_ref.ts @@ -0,0 +1,311 @@ +import * as Serializer from "../../../serialize_error.js"; +import { AllocatorUseArrayBuffer } from "../allocator.js"; +import type { WorkerBackgroundRefObject } from "./worker_export.js"; + +export class WorkerBackgroundRef { + private allocator: AllocatorUseArrayBuffer; + private lock: SharedArrayBuffer; + private signature_input: SharedArrayBuffer; + + constructor( + allocator: AllocatorUseArrayBuffer, + lock: SharedArrayBuffer, + signature_input: SharedArrayBuffer, + ) { + this.allocator = allocator; + this.lock = lock; + this.signature_input = signature_input; + } + + private block_lock_base_func(): void { + const view = new Int32Array(this.lock); + // eslint-disable-next-line no-constant-condition + while (true) { + const lock = Atomics.wait(view, 0, 1); + if (lock === "timed-out") { + throw new Error("timed-out lock"); + } + const old = Atomics.compareExchange(view, 0, 0, 1); + if (old !== 0) { + continue; + } + break; + } + } + + private async async_lock_base_func(): Promise { + const view = new Int32Array(this.lock); + // eslint-disable-next-line no-constant-condition + while (true) { + let value: "timed-out" | "not-equal" | "ok"; + const { value: _value } = Atomics.waitAsync(view, 0, 1); + if (_value instanceof Promise) { + value = await _value; + } else { + value = _value; + } + if (value === "timed-out") { + throw new Error("timed-out lock"); + } + const old = Atomics.compareExchange(view, 0, 0, 1); + if (old !== 0) { + continue; + } + break; + } + } + + private call_base_func(): void { + const view = new Int32Array(this.lock); + const old = Atomics.exchange(view, 1, 1); + if (old !== 0) { + console.error("what happened?"); + } + Atomics.notify(view, 1, 1); + } + + // wait base_func + private block_wait_base_func(): void { + const view = new Int32Array(this.lock); + const lock = Atomics.wait(view, 1, 1); + if (lock === "timed-out") { + throw new Error("timed-out lock"); + } + } + + private async async_wait_base_func(): Promise { + const view = new Int32Array(this.lock); + let value: "timed-out" | "not-equal" | "ok"; + const { value: _value } = Atomics.waitAsync(view, 1, 1); + if (_value instanceof Promise) { + value = await _value; + } else { + value = _value; + } + if (value === "timed-out") { + throw new Error("timed-out lock"); + } + } + + // release base_func + private release_base_func(): void { + const view = new Int32Array(this.lock); + Atomics.store(view, 0, 0); + Atomics.notify(view, 0, 1); + } + + new_worker( + url: string, + options?: WorkerOptions, + post_obj?: unknown, + ): WorkerRef { + this.block_lock_base_func(); + const view = new Int32Array(this.signature_input); + Atomics.store(view, 0, 1); + const url_buffer = new TextEncoder().encode(url); + this.allocator.block_write(url_buffer, this.signature_input, 1); + Atomics.store(view, 3, options.type === "module" ? 1 : 0); + const obj_json = JSON.stringify(post_obj); + const obj_buffer = new TextEncoder().encode(obj_json); + this.allocator.block_write(obj_buffer, this.signature_input, 4); + this.call_base_func(); + this.block_wait_base_func(); + + const id = Atomics.load(view, 0); + + this.release_base_func(); + + return new WorkerRef(id); + } + + async async_start_on_thread( + url: string, + options: WorkerOptions | undefined, + post_obj: unknown, + ) { + await this.async_lock_base_func(); + const view = new Int32Array(this.signature_input); + Atomics.store(view, 0, 2); + const url_buffer = new TextEncoder().encode(url); + await this.allocator.async_write(url_buffer, this.signature_input, 1); + Atomics.store(view, 3, options?.type === "module" ? 1 : 0); + const obj_json = JSON.stringify(post_obj); + const obj_buffer = new TextEncoder().encode(obj_json); + await this.allocator.async_write(obj_buffer, this.signature_input, 4); + this.call_base_func(); + await this.async_wait_base_func(); + + this.release_base_func(); + } + + block_start_on_thread( + url: string, + options: WorkerOptions | undefined, + post_obj: unknown, + ) { + this.block_lock_base_func(); + const view = new Int32Array(this.signature_input); + Atomics.store(view, 0, 2); + const url_buffer = new TextEncoder().encode(url); + this.allocator.block_write(url_buffer, this.signature_input, 1); + Atomics.store(view, 3, options?.type === "module" ? 1 : 0); + const obj_json = JSON.stringify(post_obj); + const obj_buffer = new TextEncoder().encode(obj_json); + this.allocator.block_write(obj_buffer, this.signature_input, 4); + this.call_base_func(); + this.block_wait_base_func(); + + this.release_base_func(); + } + + static init_self(sl: WorkerBackgroundRefObject): WorkerBackgroundRef { + return new WorkerBackgroundRef( + AllocatorUseArrayBuffer.init_self(sl.allocator), + sl.lock, + sl.signature_input, + ); + } + + done_notify(code: number): void { + const notify_view = new Int32Array(this.lock, 8); + + // notify done = code 2 + const old = Atomics.compareExchange(notify_view, 0, 0, 2); + + if (old !== 0) { + console.error("what happened?"); + + return; + } + + Atomics.store(notify_view, 1, code); + + const num = Atomics.notify(notify_view, 0); + + if (num === 0) { + Atomics.store(notify_view, 0, 0); + } + } + + async async_wait_done_or_error(): Promise { + const notify_view = new Int32Array(this.lock, 8); + + Atomics.store(notify_view, 0, 0); + + let value: "timed-out" | "not-equal" | "ok"; + const { value: _value } = Atomics.waitAsync(notify_view, 0, 0); + if (_value instanceof Promise) { + value = await _value; + } else { + value = _value; + } + + if (value === "timed-out") { + throw new Error("timed-out"); + } + + if (value === "not-equal") { + throw new Error("not-equal"); + } + + const code = Atomics.load(notify_view, 0); + + if (code === 2) { + const old = Atomics.compareExchange(notify_view, 0, 2, 0); + + const code = Atomics.load(notify_view, 1); + + if (old !== 2) { + console.error("what happened?"); + } + + return code; + } + + if (code !== 1) { + throw new Error("unknown code"); + } + + // get error + const ptr = Atomics.load(notify_view, 1); + const size = Atomics.load(notify_view, 2); + const error_buffer = this.allocator.get_memory(ptr, size); + const error_txt = new TextDecoder().decode(error_buffer); + const error_serialized = JSON.parse( + error_txt, + ) as Serializer.SerializedError; + const error = Serializer.deserialize(error_serialized); + + const old = Atomics.compareExchange(notify_view, 0, 1, 0); + + if (old !== 1) { + console.error("what happened?"); + } + + throw error; + } + + block_wait_done_or_error(): number { + const notify_view = new Int32Array(this.lock, 8); + + Atomics.store(notify_view, 0, 0); + + const value = Atomics.wait(notify_view, 0, 0); + + if (value === "timed-out") { + throw new Error("timed-out"); + } + + if (value === "not-equal") { + throw new Error("not-equal"); + } + + const code = Atomics.load(notify_view, 0); + + if (code === 2) { + const old = Atomics.compareExchange(notify_view, 0, 2, 0); + + const code = Atomics.load(notify_view, 1); + + if (old !== 2) { + console.error("what happened?"); + } + + return code; + } + + if (code !== 1) { + throw new Error("unknown code"); + } + + // get error + const ptr = Atomics.load(notify_view, 1); + const size = Atomics.load(notify_view, 2); + const error_buffer = this.allocator.get_memory(ptr, size); + const error_txt = new TextDecoder().decode(error_buffer); + const error_serialized = JSON.parse( + error_txt, + ) as Serializer.SerializedError; + const error = Serializer.deserialize(error_serialized); + + const old = Atomics.compareExchange(notify_view, 0, 1, 0); + + if (old !== 1) { + console.error("what happened?"); + } + + throw error; + } +} + +export class WorkerRef { + private id: number; + + constructor(id: number) { + this.id = id; + } + + get_id(): number { + return this.id; + } +} diff --git a/src/wasi_farm/shared_array_buffer/worker_background/worker_blob.ts b/src/wasi_farm/shared_array_buffer/worker_background/worker_blob.ts new file mode 100644 index 0000000..8a1adf3 --- /dev/null +++ b/src/wasi_farm/shared_array_buffer/worker_background/worker_blob.ts @@ -0,0 +1,10 @@ +export const url = () => { + const code = + 'let worker_background;function _define_property(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}let serialize=e=>({message:e.message,name:e.name,stack:e.stack,cause:e.cause});class AllocatorUseArrayBuffer{static init_self(e){return new AllocatorUseArrayBuffer(e.share_arrays_memory)}async async_write(e,r,t){let o=new Int32Array(this.share_arrays_memory);for(;;){let{value:s}=Atomics.waitAsync(o,0,1);if("timed-out"===(s instanceof Promise?await s:s))throw Error("timed-out lock");if(0!==Atomics.compareExchange(o,0,0,1))continue;let i=this.write_inner(e,r,t);return Atomics.store(o,0,0),Atomics.notify(o,0,1),i}}block_write(e,r,t){for(;;){let o=new Int32Array(this.share_arrays_memory);if("timed-out"===Atomics.wait(o,0,1))throw Error("timed-out lock");if(0!==Atomics.compareExchange(o,0,0,1))continue;let s=this.write_inner(e,r,t);return Atomics.store(o,0,0),Atomics.notify(o,0,1),s}}write_inner(e,r,t){let o,s;let i=new Int32Array(this.share_arrays_memory),a=new Uint8Array(this.share_arrays_memory);o=0===Atomics.add(i,1,1)?Atomics.store(i,2,12):Atomics.load(i,2);let n=this.share_arrays_memory.byteLength,c=e.byteLength,l=o+c;if(n{let{msg:r}=e.data;if("ready"===r&&y(),"done"===r&&(this.workers[w].terminate(),this.workers[w]=void 0,console.log(`worker ${w} done so terminate`)),"error"===r){this.workers[w].terminate(),this.workers[w]=void 0;let r=0;for(let e of this.workers)void 0!==e&&(e.terminate(),console.warn("wasi throw error but child process exists, terminate "+r)),r++;void 0!==this.start_worker&&(this.start_worker.terminate(),console.warn("wasi throw error but wasi exists, terminate wasi")),this.workers=[void 0],this.start_worker=void 0;let t=e.data.error,o=new Int32Array(this.lock,8),s=serialize(t),[i,a]=await this.allocator.async_write(new TextEncoder().encode(JSON.stringify(s)),this.lock,3),n=Atomics.compareExchange(o,0,0,1);if(0!==n){console.error("what happened?"),this.allocator.free(i,a);return}let c=Atomics.notify(o,0);0===c&&(console.error(t),this.allocator.free(i,a),Atomics.store(o,0,0))}},a.postMessage({...this.override_object,...m,worker_id:w,worker_background_ref:this.ref()}),await d,Atomics.store(r,0,w);break}case 2:{let e=Atomics.load(r,1),t=Atomics.load(r,2),o=this.allocator.get_memory(e,t);this.allocator.free(e,t);let s=new TextDecoder().decode(o),i=1===Atomics.load(r,3);this.start_worker=new Worker(s,{type:i?"module":"classic"});let a=Atomics.load(r,4),n=Atomics.load(r,5),c=this.allocator.get_memory(a,n);this.allocator.free(a,n);let l=new TextDecoder().decode(c),h=JSON.parse(l);this.start_worker.onmessage=async e=>{let{msg:r}=e.data;if("done"===r){let e=0;for(let r of this.workers)void 0!==r&&(r.terminate(),console.warn("wasi done but worker exists, terminate "+e)),e++;this.start_worker.terminate(),this.start_worker=void 0,console.log("start worker done so terminate")}},this.start_worker.postMessage({...this.override_object,...h,worker_background_ref:this.ref()})}}let i=Atomics.exchange(e,1,0);if(1!==i)throw Error("Lock is already set");let a=Atomics.notify(e,1,1);if(1!==a){if(0===a){console.warn("notify failed, waiter is late");continue}throw Error("notify failed: "+a)}}catch(e){console.error(e)}}constructor(e,r,t,o){_define_property(this,"override_object",void 0),_define_property(this,"allocator",void 0),_define_property(this,"lock",void 0),_define_property(this,"signature_input",void 0),_define_property(this,"workers",[void 0]),_define_property(this,"start_worker",void 0),_define_property(this,"listen_holder",void 0),this.override_object=e,this.lock=r??new SharedArrayBuffer(20),this.allocator=t??new AllocatorUseArrayBuffer(new SharedArrayBuffer(10240)),this.signature_input=o??new SharedArrayBuffer(24),this.listen_holder=this.listen()}};globalThis.onmessage=e=>{let{override_object:r,worker_background_ref_object:t}=e.data;worker_background=WorkerBackground.init_self(r,t),postMessage("ready")};'; + + const blob = new Blob([code], { type: "application/javascript" }); + + const url = URL.createObjectURL(blob); + + return url; +}; diff --git a/src/wasi_farm/shared_array_buffer/worker_background/worker_export.ts b/src/wasi_farm/shared_array_buffer/worker_background/worker_export.ts new file mode 100644 index 0000000..9f831a8 --- /dev/null +++ b/src/wasi_farm/shared_array_buffer/worker_background/worker_export.ts @@ -0,0 +1,18 @@ +import type { AllocatorUseArrayBufferObject } from "../allocator.js"; + +export type WorkerBackgroundRefObject = { + allocator: AllocatorUseArrayBufferObject; + lock: SharedArrayBuffer; + signature_input: SharedArrayBuffer; +}; + +export const WorkerBackgroundRefObjectConstructor = + (): WorkerBackgroundRefObject => { + return { + allocator: { + share_arrays_memory: new SharedArrayBuffer(10 * 1024), + }, + lock: new SharedArrayBuffer(20), + signature_input: new SharedArrayBuffer(24), + }; + }; diff --git a/test/run-testsuite.sh b/test/run-testsuite.sh old mode 100755 new mode 100644