@volter/tabnode 0.2.14-volter.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +78 -0
- package/THIRD-PARTY-NOTICES.md +12 -0
- package/dist/__sw__.js +526 -0
- package/dist/assets/runtime-worker-4MKaHFVb.js +75221 -0
- package/dist/assets/runtime-worker-4MKaHFVb.js.map +1 -0
- package/dist/code-transforms.d.ts +21 -0
- package/dist/code-transforms.d.ts.map +1 -0
- package/dist/config/cdn.d.ts +12 -0
- package/dist/config/cdn.d.ts.map +1 -0
- package/dist/create-runtime.d.ts +22 -0
- package/dist/create-runtime.d.ts.map +1 -0
- package/dist/host-globals.d.ts +62 -0
- package/dist/host-globals.d.ts.map +1 -0
- package/dist/index.cjs +36021 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +127 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +36020 -0
- package/dist/index.mjs.map +1 -0
- package/dist/node-internals.d.ts +68 -0
- package/dist/node-internals.d.ts.map +1 -0
- package/dist/node-lib/binding/blob.d.ts +12 -0
- package/dist/node-lib/binding/blob.d.ts.map +1 -0
- package/dist/node-lib/binding/buffer.d.ts +144 -0
- package/dist/node-lib/binding/buffer.d.ts.map +1 -0
- package/dist/node-lib/binding/cares_wrap.d.ts +14 -0
- package/dist/node-lib/binding/cares_wrap.d.ts.map +1 -0
- package/dist/node-lib/binding/fds.d.ts +30 -0
- package/dist/node-lib/binding/fds.d.ts.map +1 -0
- package/dist/node-lib/binding/fs.d.ts +157 -0
- package/dist/node-lib/binding/fs.d.ts.map +1 -0
- package/dist/node-lib/binding/handles.d.ts +81 -0
- package/dist/node-lib/binding/handles.d.ts.map +1 -0
- package/dist/node-lib/binding/http_parser.d.ts +122 -0
- package/dist/node-lib/binding/http_parser.d.ts.map +1 -0
- package/dist/node-lib/binding/index.d.ts +3 -0
- package/dist/node-lib/binding/index.d.ts.map +1 -0
- package/dist/node-lib/binding/llhttp-wasm.d.ts +22 -0
- package/dist/node-lib/binding/llhttp-wasm.d.ts.map +1 -0
- package/dist/node-lib/binding/misc.d.ts +123 -0
- package/dist/node-lib/binding/misc.d.ts.map +1 -0
- package/dist/node-lib/binding/pipe_wrap.d.ts +84 -0
- package/dist/node-lib/binding/pipe_wrap.d.ts.map +1 -0
- package/dist/node-lib/binding/process_wrap.d.ts +173 -0
- package/dist/node-lib/binding/process_wrap.d.ts.map +1 -0
- package/dist/node-lib/binding/spawn_sync.d.ts +30 -0
- package/dist/node-lib/binding/spawn_sync.d.ts.map +1 -0
- package/dist/node-lib/binding/stream_wrap.d.ts +191 -0
- package/dist/node-lib/binding/stream_wrap.d.ts.map +1 -0
- package/dist/node-lib/binding/stubs.d.ts +23 -0
- package/dist/node-lib/binding/stubs.d.ts.map +1 -0
- package/dist/node-lib/binding/tcp_wrap.d.ts +98 -0
- package/dist/node-lib/binding/tcp_wrap.d.ts.map +1 -0
- package/dist/node-lib/binding/tty_wrap.d.ts +36 -0
- package/dist/node-lib/binding/tty_wrap.d.ts.map +1 -0
- package/dist/node-lib/binding/util.d.ts +126 -0
- package/dist/node-lib/binding/util.d.ts.map +1 -0
- package/dist/node-lib/binding/uv.d.ts +32 -0
- package/dist/node-lib/binding/uv.d.ts.map +1 -0
- package/dist/node-lib/binding/zlib-pako.d.ts +22 -0
- package/dist/node-lib/binding/zlib-pako.d.ts.map +1 -0
- package/dist/node-lib/binding/zlib.d.ts +38 -0
- package/dist/node-lib/binding/zlib.d.ts.map +1 -0
- package/dist/node-lib/buffer-module.d.ts +51 -0
- package/dist/node-lib/buffer-module.d.ts.map +1 -0
- package/dist/node-lib/child-process-module.d.ts +26 -0
- package/dist/node-lib/child-process-module.d.ts.map +1 -0
- package/dist/node-lib/events-module.d.ts +58 -0
- package/dist/node-lib/events-module.d.ts.map +1 -0
- package/dist/node-lib/fs-module.d.ts +5 -0
- package/dist/node-lib/fs-module.d.ts.map +1 -0
- package/dist/node-lib/http-bridge.d.ts +43 -0
- package/dist/node-lib/http-bridge.d.ts.map +1 -0
- package/dist/node-lib/http-module.d.ts +35 -0
- package/dist/node-lib/http-module.d.ts.map +1 -0
- package/dist/node-lib/internals/addresses.d.ts +40 -0
- package/dist/node-lib/internals/addresses.d.ts.map +1 -0
- package/dist/node-lib/internals/buffer-and-streams.d.ts +96 -0
- package/dist/node-lib/internals/buffer-and-streams.d.ts.map +1 -0
- package/dist/node-lib/internals/child-process.d.ts +27 -0
- package/dist/node-lib/internals/child-process.d.ts.map +1 -0
- package/dist/node-lib/internals/events-util.d.ts +83 -0
- package/dist/node-lib/internals/events-util.d.ts.map +1 -0
- package/dist/node-lib/internals/index.d.ts +2 -0
- package/dist/node-lib/internals/index.d.ts.map +1 -0
- package/dist/node-lib/internals/modules.d.ts +67 -0
- package/dist/node-lib/internals/modules.d.ts.map +1 -0
- package/dist/node-lib/internals/readline-access.d.ts +2 -0
- package/dist/node-lib/internals/readline-access.d.ts.map +1 -0
- package/dist/node-lib/internals/runtime.d.ts +150 -0
- package/dist/node-lib/internals/runtime.d.ts.map +1 -0
- package/dist/node-lib/internals/util.d.ts +33 -0
- package/dist/node-lib/internals/util.d.ts.map +1 -0
- package/dist/node-lib/lazy.d.ts +31 -0
- package/dist/node-lib/lazy.d.ts.map +1 -0
- package/dist/node-lib/load.d.ts +27 -0
- package/dist/node-lib/load.d.ts.map +1 -0
- package/dist/node-lib/module-hooks.d.ts +89 -0
- package/dist/node-lib/module-hooks.d.ts.map +1 -0
- package/dist/node-lib/net-module.d.ts +181 -0
- package/dist/node-lib/net-module.d.ts.map +1 -0
- package/dist/node-lib/node-versions.d.ts +27 -0
- package/dist/node-lib/node-versions.d.ts.map +1 -0
- package/dist/node-lib/public-modules.d.ts +2 -0
- package/dist/node-lib/public-modules.d.ts.map +1 -0
- package/dist/node-lib/require-hook.d.ts +15 -0
- package/dist/node-lib/require-hook.d.ts.map +1 -0
- package/dist/node-lib/small-modules.d.ts +16 -0
- package/dist/node-lib/small-modules.d.ts.map +1 -0
- package/dist/node-lib/sources.d.ts +4 -0
- package/dist/node-lib/sources.d.ts.map +1 -0
- package/dist/node-lib/stream-module.d.ts +77 -0
- package/dist/node-lib/stream-module.d.ts.map +1 -0
- package/dist/node-lib/timers.d.ts +19 -0
- package/dist/node-lib/timers.d.ts.map +1 -0
- package/dist/node-lib/util-module.d.ts +76 -0
- package/dist/node-lib/util-module.d.ts.map +1 -0
- package/dist/node-resolution.d.ts +50 -0
- package/dist/node-resolution.d.ts.map +1 -0
- package/dist/node-resolver.d.ts +7 -0
- package/dist/node-resolver.d.ts.map +1 -0
- package/dist/npm/index.d.ts +73 -0
- package/dist/npm/index.d.ts.map +1 -0
- package/dist/npm/registry.d.ts +111 -0
- package/dist/npm/registry.d.ts.map +1 -0
- package/dist/npm/resolver.d.ts +79 -0
- package/dist/npm/resolver.d.ts.map +1 -0
- package/dist/npm/tarball.d.ts +28 -0
- package/dist/npm/tarball.d.ts.map +1 -0
- package/dist/process-tokens.d.ts +77 -0
- package/dist/process-tokens.d.ts.map +1 -0
- package/dist/punycode-source.d.ts +3 -0
- package/dist/punycode-source.d.ts.map +1 -0
- package/dist/runtime-interface.d.ts +74 -0
- package/dist/runtime-interface.d.ts.map +1 -0
- package/dist/runtime.d.ts +144 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/server-bridge.d.ts +147 -0
- package/dist/server-bridge.d.ts.map +1 -0
- package/dist/shims/async_hooks.d.ts +50 -0
- package/dist/shims/async_hooks.d.ts.map +1 -0
- package/dist/shims/child_process.d.ts +104 -0
- package/dist/shims/child_process.d.ts.map +1 -0
- package/dist/shims/cluster.d.ts +52 -0
- package/dist/shims/cluster.d.ts.map +1 -0
- package/dist/shims/command-line.d.ts +43 -0
- package/dist/shims/command-line.d.ts.map +1 -0
- package/dist/shims/constants.d.ts +222 -0
- package/dist/shims/constants.d.ts.map +1 -0
- package/dist/shims/crypto-constants.d.ts +12 -0
- package/dist/shims/crypto-constants.d.ts.map +1 -0
- package/dist/shims/crypto.d.ts +144 -0
- package/dist/shims/crypto.d.ts.map +1 -0
- package/dist/shims/dgram.d.ts +34 -0
- package/dist/shims/dgram.d.ts.map +1 -0
- package/dist/shims/dns.d.ts +91 -0
- package/dist/shims/dns.d.ts.map +1 -0
- package/dist/shims/domain.d.ts +25 -0
- package/dist/shims/domain.d.ts.map +1 -0
- package/dist/shims/esbuild.d.ts +205 -0
- package/dist/shims/esbuild.d.ts.map +1 -0
- package/dist/shims/fs.d.ts +25 -0
- package/dist/shims/fs.d.ts.map +1 -0
- package/dist/shims/http2.d.ts +81 -0
- package/dist/shims/http2.d.ts.map +1 -0
- package/dist/shims/inspector.d.ts +25 -0
- package/dist/shims/inspector.d.ts.map +1 -0
- package/dist/shims/module.d.ts +22 -0
- package/dist/shims/module.d.ts.map +1 -0
- package/dist/shims/os.d.ts +159 -0
- package/dist/shims/os.d.ts.map +1 -0
- package/dist/shims/path.d.ts +52 -0
- package/dist/shims/path.d.ts.map +1 -0
- package/dist/shims/perf_hooks.d.ts +50 -0
- package/dist/shims/perf_hooks.d.ts.map +1 -0
- package/dist/shims/process.d.ts +226 -0
- package/dist/shims/process.d.ts.map +1 -0
- package/dist/shims/rollup.d.ts +71 -0
- package/dist/shims/rollup.d.ts.map +1 -0
- package/dist/shims/string_decoder.d.ts +41 -0
- package/dist/shims/string_decoder.d.ts.map +1 -0
- package/dist/shims/sync-child.d.ts +64 -0
- package/dist/shims/sync-child.d.ts.map +1 -0
- package/dist/shims/tls.d.ts +53 -0
- package/dist/shims/tls.d.ts.map +1 -0
- package/dist/shims/url.d.ts +84 -0
- package/dist/shims/url.d.ts.map +1 -0
- package/dist/shims/v8.d.ts +73 -0
- package/dist/shims/v8.d.ts.map +1 -0
- package/dist/shims/vfs-adapter.d.ts +126 -0
- package/dist/shims/vfs-adapter.d.ts.map +1 -0
- package/dist/shims/vm.d.ts +52 -0
- package/dist/shims/vm.d.ts.map +1 -0
- package/dist/shims/wasi.d.ts +78 -0
- package/dist/shims/wasi.d.ts.map +1 -0
- package/dist/shims/worker_threads.d.ts +66 -0
- package/dist/shims/worker_threads.d.ts.map +1 -0
- package/dist/shims/zlib-constants.d.ts +66 -0
- package/dist/shims/zlib-constants.d.ts.map +1 -0
- package/dist/shims/zlib.d.ts +102 -0
- package/dist/shims/zlib.d.ts.map +1 -0
- package/dist/transform.d.ts +24 -0
- package/dist/transform.d.ts.map +1 -0
- package/dist/types/package-json.d.ts +18 -0
- package/dist/types/package-json.d.ts.map +1 -0
- package/dist/utils/binary-encoding.d.ts +13 -0
- package/dist/utils/binary-encoding.d.ts.map +1 -0
- package/dist/utils/glob.d.ts +19 -0
- package/dist/utils/glob.d.ts.map +1 -0
- package/dist/utils/hash.d.ts +6 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/virtual-fs.d.ts +259 -0
- package/dist/virtual-fs.d.ts.map +1 -0
- package/dist/vite-plugin.cjs +50 -0
- package/dist/vite-plugin.cjs.map +1 -0
- package/dist/vite-plugin.d.ts +36 -0
- package/dist/vite-plugin.d.ts.map +1 -0
- package/dist/vite-plugin.mjs +31 -0
- package/dist/vite-plugin.mjs.map +1 -0
- package/dist/worker/runtime-worker.d.ts +8 -0
- package/dist/worker/runtime-worker.d.ts.map +1 -0
- package/dist/worker-runtime.d.ts +50 -0
- package/dist/worker-runtime.d.ts.map +1 -0
- package/package.json +88 -0
- package/src/code-transforms.ts +560 -0
- package/src/config/cdn.ts +13 -0
- package/src/create-runtime.ts +89 -0
- package/src/host-globals.ts +121 -0
- package/src/index.ts +235 -0
- package/src/node-internals.ts +283 -0
- package/src/node-lib/LICENSE +47 -0
- package/src/node-lib/_http_agent.js +547 -0
- package/src/node-lib/_http_client.js +996 -0
- package/src/node-lib/_http_common.js +269 -0
- package/src/node-lib/_http_incoming.js +453 -0
- package/src/node-lib/_http_outgoing.js +1262 -0
- package/src/node-lib/_http_server.js +1230 -0
- package/src/node-lib/assert/strict.js +3 -0
- package/src/node-lib/assert.js +844 -0
- package/src/node-lib/binding/blob.ts +35 -0
- package/src/node-lib/binding/buffer.ts +465 -0
- package/src/node-lib/binding/cares_wrap.ts +57 -0
- package/src/node-lib/binding/fds.ts +80 -0
- package/src/node-lib/binding/fs.ts +857 -0
- package/src/node-lib/binding/handles.ts +187 -0
- package/src/node-lib/binding/http_parser.ts +536 -0
- package/src/node-lib/binding/index.ts +77 -0
- package/src/node-lib/binding/llhttp-wasm.ts +670 -0
- package/src/node-lib/binding/misc.ts +252 -0
- package/src/node-lib/binding/pipe_wrap.ts +166 -0
- package/src/node-lib/binding/process_wrap.ts +371 -0
- package/src/node-lib/binding/spawn_sync.ts +141 -0
- package/src/node-lib/binding/stream_wrap.ts +413 -0
- package/src/node-lib/binding/stubs.ts +19 -0
- package/src/node-lib/binding/tcp_wrap.ts +254 -0
- package/src/node-lib/binding/tty_wrap.ts +56 -0
- package/src/node-lib/binding/util.ts +274 -0
- package/src/node-lib/binding/uv.ts +102 -0
- package/src/node-lib/binding/zlib-pako.ts +50 -0
- package/src/node-lib/binding/zlib.ts +259 -0
- package/src/node-lib/buffer-module.ts +70 -0
- package/src/node-lib/buffer.js +1373 -0
- package/src/node-lib/child-process-module.ts +58 -0
- package/src/node-lib/child_process.js +1046 -0
- package/src/node-lib/constants.js +41 -0
- package/src/node-lib/diagnostics_channel.js +438 -0
- package/src/node-lib/events-module.ts +80 -0
- package/src/node-lib/events.js +1223 -0
- package/src/node-lib/fs-module.ts +43 -0
- package/src/node-lib/fs.js +3377 -0
- package/src/node-lib/http-bridge.ts +299 -0
- package/src/node-lib/http-module.ts +53 -0
- package/src/node-lib/http.js +198 -0
- package/src/node-lib/https.js +429 -0
- package/src/node-lib/internal/assert/assertion_error.js +417 -0
- package/src/node-lib/internal/assert/calltracker.js +153 -0
- package/src/node-lib/internal/assert/myers_diff.js +177 -0
- package/src/node-lib/internal/assert/utils.js +278 -0
- package/src/node-lib/internal/buffer.js +1120 -0
- package/src/node-lib/internal/child_process/serialization.js +169 -0
- package/src/node-lib/internal/child_process.js +1135 -0
- package/src/node-lib/internal/constants.js +56 -0
- package/src/node-lib/internal/deps/minimatch/index.js +1628 -0
- package/src/node-lib/internal/errors.js +1912 -0
- package/src/node-lib/internal/events/abort_listener.js +54 -0
- package/src/node-lib/internal/events/symbols.js +11 -0
- package/src/node-lib/internal/fixed_queue.js +119 -0
- package/src/node-lib/internal/freelist.js +30 -0
- package/src/node-lib/internal/fs/cp/cp-sync.js +242 -0
- package/src/node-lib/internal/fs/cp/cp.js +382 -0
- package/src/node-lib/internal/fs/dir.js +369 -0
- package/src/node-lib/internal/fs/glob.js +763 -0
- package/src/node-lib/internal/fs/promises.js +1312 -0
- package/src/node-lib/internal/fs/read/context.js +129 -0
- package/src/node-lib/internal/fs/recursive_watch.js +275 -0
- package/src/node-lib/internal/fs/rimraf.js +311 -0
- package/src/node-lib/internal/fs/streams.js +571 -0
- package/src/node-lib/internal/fs/sync_write_stream.js +49 -0
- package/src/node-lib/internal/fs/utils.js +987 -0
- package/src/node-lib/internal/fs/watchers.js +418 -0
- package/src/node-lib/internal/http.js +62 -0
- package/src/node-lib/internal/mime.js +389 -0
- package/src/node-lib/internal/modules/customization_hooks.js +406 -0
- package/src/node-lib/internal/net.js +95 -0
- package/src/node-lib/internal/querystring.js +119 -0
- package/src/node-lib/internal/readline/callbacks.js +132 -0
- package/src/node-lib/internal/readline/emitKeypressEvents.js +99 -0
- package/src/node-lib/internal/readline/interface.js +1418 -0
- package/src/node-lib/internal/readline/promises.js +144 -0
- package/src/node-lib/internal/readline/utils.js +405 -0
- package/src/node-lib/internal/socket_list.js +108 -0
- package/src/node-lib/internal/stream_base_commons.js +280 -0
- package/src/node-lib/internal/streams/add-abort-signal.js +60 -0
- package/src/node-lib/internal/streams/compose.js +257 -0
- package/src/node-lib/internal/streams/destroy.js +361 -0
- package/src/node-lib/internal/streams/duplex.js +203 -0
- package/src/node-lib/internal/streams/duplexify.js +379 -0
- package/src/node-lib/internal/streams/duplexpair.js +62 -0
- package/src/node-lib/internal/streams/end-of-stream.js +331 -0
- package/src/node-lib/internal/streams/from.js +208 -0
- package/src/node-lib/internal/streams/lazy_transform.js +57 -0
- package/src/node-lib/internal/streams/legacy.js +125 -0
- package/src/node-lib/internal/streams/operators.js +436 -0
- package/src/node-lib/internal/streams/passthrough.js +47 -0
- package/src/node-lib/internal/streams/pipeline.js +465 -0
- package/src/node-lib/internal/streams/readable.js +1762 -0
- package/src/node-lib/internal/streams/state.js +51 -0
- package/src/node-lib/internal/streams/transform.js +204 -0
- package/src/node-lib/internal/streams/utils.js +363 -0
- package/src/node-lib/internal/streams/writable.js +1163 -0
- package/src/node-lib/internal/tty.js +260 -0
- package/src/node-lib/internal/util/colors.js +40 -0
- package/src/node-lib/internal/util/comparisons.js +1028 -0
- package/src/node-lib/internal/util/debuglog.js +524 -0
- package/src/node-lib/internal/util/inspect.js +2535 -0
- package/src/node-lib/internal/util/parse_args/parse_args.js +412 -0
- package/src/node-lib/internal/util/parse_args/utils.js +197 -0
- package/src/node-lib/internal/util.js +1003 -0
- package/src/node-lib/internal/validators.js +654 -0
- package/src/node-lib/internals/addresses.ts +159 -0
- package/src/node-lib/internals/buffer-and-streams.ts +224 -0
- package/src/node-lib/internals/child-process.ts +64 -0
- package/src/node-lib/internals/events-util.ts +105 -0
- package/src/node-lib/internals/index.ts +66 -0
- package/src/node-lib/internals/modules.ts +117 -0
- package/src/node-lib/internals/readline-access.ts +16 -0
- package/src/node-lib/internals/runtime.ts +277 -0
- package/src/node-lib/internals/util.ts +98 -0
- package/src/node-lib/lazy.ts +158 -0
- package/src/node-lib/load.ts +390 -0
- package/src/node-lib/module-hooks.ts +281 -0
- package/src/node-lib/net-module.ts +248 -0
- package/src/node-lib/net.js +2540 -0
- package/src/node-lib/node-versions.ts +34 -0
- package/src/node-lib/os.js +356 -0
- package/src/node-lib/path.js +1694 -0
- package/src/node-lib/primordials.js +743 -0
- package/src/node-lib/public-modules.ts +109 -0
- package/src/node-lib/punycode.js +455 -0
- package/src/node-lib/querystring.js +484 -0
- package/src/node-lib/readline/promises.js +73 -0
- package/src/node-lib/readline.js +523 -0
- package/src/node-lib/require-hook.ts +27 -0
- package/src/node-lib/small-modules.ts +35 -0
- package/src/node-lib/sources.ts +200 -0
- package/src/node-lib/stream/promises.js +44 -0
- package/src/node-lib/stream-module.ts +101 -0
- package/src/node-lib/stream.js +152 -0
- package/src/node-lib/timers.ts +33 -0
- package/src/node-lib/tty.js +168 -0
- package/src/node-lib/util-module.ts +104 -0
- package/src/node-lib/util.js +689 -0
- package/src/node-lib/wasi.js +179 -0
- package/src/node-lib/zlib.js +1036 -0
- package/src/node-resolution.ts +241 -0
- package/src/node-resolver.ts +33 -0
- package/src/npm/index.ts +425 -0
- package/src/npm/registry.ts +235 -0
- package/src/npm/resolver.ts +589 -0
- package/src/npm/tarball.ts +246 -0
- package/src/process-tokens.ts +156 -0
- package/src/punycode-source.ts +6 -0
- package/src/runtime-interface.ts +85 -0
- package/src/runtime.ts +3073 -0
- package/src/server-bridge.ts +971 -0
- package/src/shims/async_hooks.ts +181 -0
- package/src/shims/child_process.ts +1591 -0
- package/src/shims/cluster.ts +79 -0
- package/src/shims/command-line.ts +79 -0
- package/src/shims/constants.ts +68 -0
- package/src/shims/crypto-constants.ts +11 -0
- package/src/shims/crypto.ts +1061 -0
- package/src/shims/dgram.ts +47 -0
- package/src/shims/dns.ts +185 -0
- package/src/shims/domain.ts +58 -0
- package/src/shims/esbuild.ts +1638 -0
- package/src/shims/fs.ts +82 -0
- package/src/shims/http2.ts +96 -0
- package/src/shims/inspector.ts +30 -0
- package/src/shims/module.ts +86 -0
- package/src/shims/os.ts +195 -0
- package/src/shims/path.ts +246 -0
- package/src/shims/perf_hooks.ts +92 -0
- package/src/shims/process.ts +804 -0
- package/src/shims/rollup.ts +149 -0
- package/src/shims/string_decoder.ts +396 -0
- package/src/shims/sync-child.ts +469 -0
- package/src/shims/tls.ts +94 -0
- package/src/shims/url.ts +217 -0
- package/src/shims/v8.ts +113 -0
- package/src/shims/vfs-adapter.ts +408 -0
- package/src/shims/vm.ts +132 -0
- package/src/shims/wasi.ts +1440 -0
- package/src/shims/worker_threads.ts +114 -0
- package/src/shims/zlib-constants.ts +65 -0
- package/src/shims/zlib.ts +228 -0
- package/src/transform.ts +324 -0
- package/src/types/external.d.ts +55 -0
- package/src/types/package-json.ts +17 -0
- package/src/types/pako-zlib.d.ts +30 -0
- package/src/types/sha.js.d.ts +14 -0
- package/src/utils/binary-encoding.ts +43 -0
- package/src/utils/glob.ts +54 -0
- package/src/utils/hash.ts +12 -0
- package/src/virtual-fs.ts +1048 -0
- package/src/vite-plugin.ts +76 -0
- package/src/worker/runtime-worker.ts +128 -0
- package/src/worker-runtime.ts +145 -0
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A child process run to completion before the call returns, as
|
|
3
|
+
* `child_process.spawnSync` and `execSync` do in Node.
|
|
4
|
+
*
|
|
5
|
+
* Which program died: Node's own `test/wasi` suite drives every one of its
|
|
6
|
+
* fixtures through `spawnSyncAndAssert`, and generators shell out the same way
|
|
7
|
+
* (`ni`, `pagefind`). What Node does: it runs the child to its end and answers
|
|
8
|
+
* its status, its output and its pid. What the engine did: it answered ENOSYS,
|
|
9
|
+
* because a realm has no primitive that blocks while its own loop runs the
|
|
10
|
+
* child.
|
|
11
|
+
*
|
|
12
|
+
* What it does now: the child runs on a thread of its own, in an engine of its
|
|
13
|
+
* own, and the caller blocks on shared memory until that thread reports the
|
|
14
|
+
* child's end — the shape `esbuild.transformSync` already has here. The thread
|
|
15
|
+
* has no filesystem of its own: every call its engine makes on the tree
|
|
16
|
+
* crosses back to the caller through the same shared window and the caller,
|
|
17
|
+
* still inside the synchronous call, answers it from the filesystem the parent
|
|
18
|
+
* is running on. So the child reads what the parent wrote a statement ago and
|
|
19
|
+
* writes what the parent reads a statement later, as two processes over one
|
|
20
|
+
* filesystem do.
|
|
21
|
+
*
|
|
22
|
+
* What it does not cover, each answered rather than guessed at: a realm that
|
|
23
|
+
* cannot block (a page's main thread, where `Atomics.wait` is refused) and a
|
|
24
|
+
* realm without shared memory answer ENOSYS with the reason on the result's
|
|
25
|
+
* `error`, as Node answers a child it could not start. A program the engine's
|
|
26
|
+
* shell has no command for is ENOENT, as it is on a machine that does not
|
|
27
|
+
* carry that binary. A child is never killed by a signal here, so `signal` is
|
|
28
|
+
* always null and `options.timeout` and `options.killSignal` are not honoured;
|
|
29
|
+
* a child that watches the tree sees no change, because the parent turns no
|
|
30
|
+
* loop while it waits.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import type { VirtualFS } from '../virtual-fs';
|
|
34
|
+
|
|
35
|
+
/** The tree a synchronous child runs on: the parent's own. */
|
|
36
|
+
let hostVfs: VirtualFS | null = null;
|
|
37
|
+
export function setSyncChildVfs(vfs: VirtualFS): void { hostVfs = vfs; }
|
|
38
|
+
|
|
39
|
+
/** The host's `process`, taken before a guest's takes the global name. */
|
|
40
|
+
const hostProcess = typeof process !== 'undefined' && process !== null ? (process as unknown as { getBuiltinModule?: (name: string) => unknown }) : null;
|
|
41
|
+
|
|
42
|
+
/** What a synchronous child answers when it has ended. */
|
|
43
|
+
export interface SyncChildResult {
|
|
44
|
+
status: number | null;
|
|
45
|
+
signal: string | null;
|
|
46
|
+
stdout: string;
|
|
47
|
+
stderr: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** What a caller asks for. */
|
|
51
|
+
export interface SyncChildRequest {
|
|
52
|
+
command: string;
|
|
53
|
+
cwd?: string;
|
|
54
|
+
env?: Record<string, string>;
|
|
55
|
+
input?: string;
|
|
56
|
+
onStdout?: (text: string) => void;
|
|
57
|
+
onStderr?: (text: string) => void;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const CONTROL_BYTES = 32;
|
|
61
|
+
/** The shared window a message crosses through; a longer message crosses in chunks. */
|
|
62
|
+
const DATA_BYTES = 1 << 22;
|
|
63
|
+
/** Where the caller reads what the thread wrote. */
|
|
64
|
+
const TO_PARENT = 0, TO_PARENT_LEN = 1;
|
|
65
|
+
/** Where the thread reads what the caller wrote. */
|
|
66
|
+
const TO_WORKER = 2, TO_WORKER_LEN = 3;
|
|
67
|
+
/** 1 once the thread runs. */
|
|
68
|
+
const STARTED = 4;
|
|
69
|
+
/**
|
|
70
|
+
* How long a call waits for the thread to be running at all. A worker a realm
|
|
71
|
+
* starts is started by that realm's own loop: in a browser one created and
|
|
72
|
+
* then waited on inside the same synchronous call never starts, which is why
|
|
73
|
+
* the thread is warmed when the shim is initialized there. A Node host starts
|
|
74
|
+
* its threads itself and needs no warming.
|
|
75
|
+
*/
|
|
76
|
+
const START_WAIT_MS = 5_000;
|
|
77
|
+
/** How long a caller waits on one child. */
|
|
78
|
+
const RUN_WAIT_MS = 10 * 60_000;
|
|
79
|
+
/**
|
|
80
|
+
* How long a caller waits for the thread to say it has the run at all. A
|
|
81
|
+
* `spawnSync` for a program the tab has no binary for must answer, not wait:
|
|
82
|
+
* the thread writes `begin` the moment it takes the message, before it loads
|
|
83
|
+
* anything, so a thread that died, never got the message, or never reached
|
|
84
|
+
* its own code releases the caller here with a reason instead of leaving it on
|
|
85
|
+
* `Atomics.wait` for the whole run bound. Generous enough for a loaded
|
|
86
|
+
* machine, short enough that a wedged thread is a reported error and not a
|
|
87
|
+
* program that hangs with an empty console.
|
|
88
|
+
*/
|
|
89
|
+
const BEGIN_WAIT_MS = 15_000;
|
|
90
|
+
/**
|
|
91
|
+
* How long the thread waits to load a second engine before it reports that it
|
|
92
|
+
* could not. A dynamic import cannot be cancelled, but it can be raced: an
|
|
93
|
+
* import that never settles (a module URL the thread's realm cannot fetch)
|
|
94
|
+
* used to leave the caller blocked with nothing written at either end.
|
|
95
|
+
*/
|
|
96
|
+
const ENGINE_LOAD_WAIT_MS = 60_000;
|
|
97
|
+
|
|
98
|
+
interface SyncService {
|
|
99
|
+
control: Int32Array;
|
|
100
|
+
toParent: Uint8Array;
|
|
101
|
+
toWorker: Uint8Array;
|
|
102
|
+
worker: { postMessage(message: unknown): void; terminate(): unknown; unref?: () => void; on?: (event: string, listener: (value: unknown) => void) => unknown; onerror?: unknown };
|
|
103
|
+
/** What the thread reported through its error event, where the realm's loop ran to deliver it. */
|
|
104
|
+
failure?: string;
|
|
105
|
+
}
|
|
106
|
+
let service: SyncService | null = null;
|
|
107
|
+
|
|
108
|
+
/** The engine's own module, so the thread can load a second one of it. */
|
|
109
|
+
function engineModuleURL(): string | null {
|
|
110
|
+
try {
|
|
111
|
+
const url = (import.meta as unknown as { url?: string }).url;
|
|
112
|
+
return typeof url === 'string' && url.length > 0 ? url : null;
|
|
113
|
+
} catch { return null; }
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* The thread a synchronous child runs on: a module worker that loads a second
|
|
118
|
+
* engine, answers every filesystem call of its guest back across the window,
|
|
119
|
+
* and reports the child's end. `control[TO_PARENT]` is 1 for a whole message
|
|
120
|
+
* and 2 for a chunk with more to come; the receiver stores 0 to acknowledge.
|
|
121
|
+
*/
|
|
122
|
+
function workerSource(): string {
|
|
123
|
+
return [
|
|
124
|
+
"globalThis.__substrateSyncChildThread = true;",
|
|
125
|
+
"const inNode = typeof self === 'undefined' || typeof self.postMessage !== 'function';",
|
|
126
|
+
"const port = inNode ? (await import('node:worker_threads')).parentPort : self;",
|
|
127
|
+
"const encoder = new TextEncoder(), decoder = new TextDecoder();",
|
|
128
|
+
"let control, toParent, toWorker, engine, holdsLinks = false;",
|
|
129
|
+
// A message to the caller, chunked; each chunk waits for the caller to take it.
|
|
130
|
+
"function send(text) {",
|
|
131
|
+
" const bytes = encoder.encode(text); let offset = 0;",
|
|
132
|
+
" do {",
|
|
133
|
+
" const length = Math.min(bytes.length - offset, toParent.length);",
|
|
134
|
+
" toParent.set(bytes.subarray(offset, offset + length)); offset += length;",
|
|
135
|
+
" control[1] = length; const more = offset < bytes.length;",
|
|
136
|
+
" Atomics.store(control, 0, more ? 2 : 1); Atomics.notify(control, 0);",
|
|
137
|
+
// A caller that has gone away is not waited on forever: the thread gives
|
|
138
|
+
// up on this child rather than spinning on a window nobody reads.
|
|
139
|
+
" const until = Date.now() + " + String(RUN_WAIT_MS) + ";",
|
|
140
|
+
" while (Atomics.load(control, 0) !== 0) {",
|
|
141
|
+
" Atomics.wait(control, 0, more ? 2 : 1, 1000);",
|
|
142
|
+
" if (Atomics.load(control, 0) !== 0 && Date.now() > until) throw new Error('the caller of a synchronous child stopped reading');",
|
|
143
|
+
" }",
|
|
144
|
+
" } while (offset < bytes.length);",
|
|
145
|
+
"}",
|
|
146
|
+
"function receive() {",
|
|
147
|
+
" const chunks = [];",
|
|
148
|
+
" for (;;) {",
|
|
149
|
+
" const until = Date.now() + " + String(RUN_WAIT_MS) + ";",
|
|
150
|
+
" while (Atomics.load(control, 2) === 0) {",
|
|
151
|
+
" Atomics.wait(control, 2, 0, 1000);",
|
|
152
|
+
" if (Atomics.load(control, 2) === 0 && Date.now() > until) throw new Error('the caller of a synchronous child stopped answering');",
|
|
153
|
+
" }",
|
|
154
|
+
" const state = Atomics.load(control, 2);",
|
|
155
|
+
" chunks.push(toWorker.slice(0, control[3]));",
|
|
156
|
+
" Atomics.store(control, 2, 0); Atomics.notify(control, 2);",
|
|
157
|
+
" if (state !== 2) break;",
|
|
158
|
+
" }",
|
|
159
|
+
" let total = 0; for (const chunk of chunks) total += chunk.length;",
|
|
160
|
+
" const joined = new Uint8Array(total); let at = 0;",
|
|
161
|
+
" for (const chunk of chunks) { joined.set(chunk, at); at += chunk.length; }",
|
|
162
|
+
" return decoder.decode(joined);",
|
|
163
|
+
"}",
|
|
164
|
+
"function call(method, args) {",
|
|
165
|
+
" send(JSON.stringify({ t: 'fs', m: method, a: args }));",
|
|
166
|
+
" const answer = JSON.parse(receive());",
|
|
167
|
+
" if (!answer.ok) throw Object.assign(new Error(answer.e.message), answer.e);",
|
|
168
|
+
" return answer.v;",
|
|
169
|
+
"}",
|
|
170
|
+
"const toBytes = (b64) => { const raw = atob(b64); const out = new Uint8Array(raw.length); for (let i = 0; i < raw.length; i++) out[i] = raw.charCodeAt(i); return out; };",
|
|
171
|
+
"const fromBytes = (bytes) => { let raw = ''; for (let i = 0; i < bytes.length; i += 0x8000) raw += String.fromCharCode.apply(null, bytes.subarray(i, i + 0x8000)); return btoa(raw); };",
|
|
172
|
+
"function reviveStat(s) {",
|
|
173
|
+
" return { size: s.size, mode: s.mode, uid: 0, gid: 0, dev: 0, ino: s.ino, nlink: 1, rdev: 0, blksize: 4096, blocks: Math.ceil(s.size / 512),",
|
|
174
|
+
" mtime: new Date(s.mtimeMs), atime: new Date(s.atimeMs), ctime: new Date(s.ctimeMs), birthtime: new Date(s.birthtimeMs),",
|
|
175
|
+
" mtimeMs: s.mtimeMs, atimeMs: s.atimeMs, ctimeMs: s.ctimeMs, birthtimeMs: s.birthtimeMs,",
|
|
176
|
+
" isFile: () => s.file, isDirectory: () => s.dir, isSymbolicLink: () => s.link,",
|
|
177
|
+
" isBlockDevice: () => false, isCharacterDevice: () => false, isFIFO: () => false, isSocket: () => false };",
|
|
178
|
+
"}",
|
|
179
|
+
"function proxyOf(VirtualFS) {",
|
|
180
|
+
" const stubs = new Map();",
|
|
181
|
+
" return class ProxyVFS extends VirtualFS {",
|
|
182
|
+
" get holdsLinks() { return holdsLinks; }",
|
|
183
|
+
" existsSync(p) { return call('existsSync', [p]); }",
|
|
184
|
+
" statSync(p) { return reviveStat(call('statSync', [p])); }",
|
|
185
|
+
" lstatSync(p) { return reviveStat(call('lstatSync', [p])); }",
|
|
186
|
+
" readFileSync(p, e) { const v = call('readFileSync', [p, typeof e === 'string' ? e : (e && e.encoding) || null]); return typeof v === 'string' ? v : toBytes(v.b64); }",
|
|
187
|
+
" writeFileSync(p, d) { return call('writeFileSync', [p, typeof d === 'string' ? d : { b64: fromBytes(d instanceof Uint8Array ? d : new Uint8Array(d)) }]); }",
|
|
188
|
+
" readdirSync(p, o) { return call('readdirSync', [p, o || null]); }",
|
|
189
|
+
" realpathSync(p) { return call('realpathSync', [p]); }",
|
|
190
|
+
" readlinkSync(p) { return call('readlinkSync', [p]); }",
|
|
191
|
+
" symlinkSync(t, p) { return call('symlinkSync', [t, p]); }",
|
|
192
|
+
" mkdirSync(p, o) { return call('mkdirSync', [p, o || null]); }",
|
|
193
|
+
" unlinkSync(p) { return call('unlinkSync', [p]); }",
|
|
194
|
+
" rmdirSync(p, o) { return call('rmdirSync', [p, o || null]); }",
|
|
195
|
+
" renameSync(a, b) { return call('renameSync', [a, b]); }",
|
|
196
|
+
" copyFileSync(a, b) { return call('copyFileSync', [a, b]); }",
|
|
197
|
+
" accessSync(p, m) { return call('accessSync', [p, typeof m === 'number' ? m : null]); }",
|
|
198
|
+
// The tree's own node, which the engine reads for a file's identity and its
|
|
199
|
+
// times: a stub per path, stable for the child's life.
|
|
200
|
+
" getNode(p) { if (!this.existsSync(p)) return undefined; let stub = stubs.get(p); if (!stub) { const s = this.statSync(p); stub = { type: s.isDirectory() ? 'directory' : 'file', mtime: s.mtimeMs, atime: s.atimeMs }; stubs.set(p, stub); } return stub; }",
|
|
201
|
+
" readFile(p, o, cb) { const done = typeof o === 'function' ? o : cb; const enc = typeof o === 'string' ? o : (o && o.encoding); queueMicrotask(() => { try { done(null, this.readFileSync(p, enc)); } catch (e) { done(e); } }); }",
|
|
202
|
+
" stat(p, cb) { queueMicrotask(() => { try { cb(null, this.statSync(p)); } catch (e) { cb(e); } }); }",
|
|
203
|
+
" lstat(p, cb) { queueMicrotask(() => { try { cb(null, this.lstatSync(p)); } catch (e) { cb(e); } }); }",
|
|
204
|
+
" readdir(p, o, cb) { const done = typeof o === 'function' ? o : cb; queueMicrotask(() => { try { done(null, this.readdirSync(p, typeof o === 'function' ? null : o)); } catch (e) { done(e); } }); }",
|
|
205
|
+
" realpath(p, cb) { queueMicrotask(() => { try { cb(null, this.realpathSync(p)); } catch (e) { cb(e); } }); }",
|
|
206
|
+
" access(p, m, cb) { const done = typeof m === 'function' ? m : cb; queueMicrotask(() => { try { this.accessSync(p, typeof m === 'number' ? m : undefined); done(null); } catch (e) { done(e); } }); }",
|
|
207
|
+
// A child watching the tree sees nothing: the parent is inside one call and
|
|
208
|
+
// turns no loop, so no change can be delivered while the child runs.
|
|
209
|
+
" watch() { const w = { close() {}, on() { return w; }, ref() { return w; }, unref() { return w; } }; return w; }",
|
|
210
|
+
" on() { return this; }",
|
|
211
|
+
" off() { return this; }",
|
|
212
|
+
" };",
|
|
213
|
+
"}",
|
|
214
|
+
"async function run(message) {",
|
|
215
|
+
" try {",
|
|
216
|
+
// The sentinel the caller's first bound waits on: written before anything
|
|
217
|
+
// that can block, so the caller learns the thread has the run.
|
|
218
|
+
" send(JSON.stringify({ t: 'begin' }));",
|
|
219
|
+
" holdsLinks = message.holdsLinks === true;",
|
|
220
|
+
" if (!engine) engine = await Promise.race([",
|
|
221
|
+
" import(message.engineURL),",
|
|
222
|
+
" new Promise((resolve, reject) => setTimeout(() => reject(new Error('the thread could not load the engine within ' + (message.loadWaitMs / 1000) + ' s from ' + message.engineURL)), message.loadWaitMs)),",
|
|
223
|
+
" ]);",
|
|
224
|
+
" const vfs = new (proxyOf(engine.VirtualFS))();",
|
|
225
|
+
" const container = engine.createContainer({ vfs, cwd: message.cwd, env: message.env });",
|
|
226
|
+
" const result = await container.run(message.command, {",
|
|
227
|
+
" cwd: message.cwd, env: message.env,",
|
|
228
|
+
" ...(typeof message.input === 'string' ? { stdin: message.input } : {}),",
|
|
229
|
+
" onStdout: (text) => send(JSON.stringify({ t: 'out', s: 1, d: String(text) })),",
|
|
230
|
+
" onStderr: (text) => send(JSON.stringify({ t: 'out', s: 2, d: String(text) })),",
|
|
231
|
+
" });",
|
|
232
|
+
" send(JSON.stringify({ t: 'done', stdout: result.stdout, stderr: result.stderr, status: result.exitCode }));",
|
|
233
|
+
" } catch (error) {",
|
|
234
|
+
" send(JSON.stringify({ t: 'failed', message: String((error && error.stack) || error) }));",
|
|
235
|
+
" }",
|
|
236
|
+
"}",
|
|
237
|
+
"function receiveMessage(message) {",
|
|
238
|
+
" if (message.type === 'attach') {",
|
|
239
|
+
" control = new Int32Array(message.control); toParent = new Uint8Array(message.toParent); toWorker = new Uint8Array(message.toWorker);",
|
|
240
|
+
" Atomics.store(control, 4, 1); Atomics.notify(control, 4);",
|
|
241
|
+
" } else if (message.type === 'run') { run(message); }",
|
|
242
|
+
"}",
|
|
243
|
+
"if (!inNode) self.onmessage = (event) => receiveMessage(event.data);",
|
|
244
|
+
"else port.on('message', receiveMessage);",
|
|
245
|
+
].join('\n');
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/** The Worker class this realm has: a browser's own, or a Node host's thread. */
|
|
249
|
+
function workerClass(): (new (url: unknown, options?: unknown) => SyncService['worker']) | null {
|
|
250
|
+
const own = (globalThis as unknown as { Worker?: new (url: unknown, options?: unknown) => SyncService['worker'] }).Worker;
|
|
251
|
+
if (typeof own === 'function') return own;
|
|
252
|
+
const builtin = hostProcess && typeof hostProcess.getBuiltinModule === 'function' ? hostProcess.getBuiltinModule('worker_threads') as { Worker?: new (url: unknown, options?: unknown) => SyncService['worker'] } | undefined : undefined;
|
|
253
|
+
return builtin && typeof builtin.Worker === 'function' ? builtin.Worker : null;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/** Whether this realm may block on shared memory at all; the reason when it may not. */
|
|
257
|
+
export function syncChildRefusal(): string | null {
|
|
258
|
+
if (typeof SharedArrayBuffer !== 'function' || typeof Atomics === 'undefined') {
|
|
259
|
+
return 'this realm has no shared memory to wait on a child with (SharedArrayBuffer is absent)';
|
|
260
|
+
}
|
|
261
|
+
try {
|
|
262
|
+
// A wait whose value does not match returns at once; a realm that refuses
|
|
263
|
+
// to block at all (a page's main thread) throws here instead.
|
|
264
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 1, 0);
|
|
265
|
+
} catch {
|
|
266
|
+
return 'this realm cannot block on shared memory, so it cannot wait for a child (a page\'s main thread refuses Atomics.wait; a worker does not)';
|
|
267
|
+
}
|
|
268
|
+
if (workerClass() === null) return 'this realm cannot start a thread to run a child on (Worker is absent)';
|
|
269
|
+
if (engineModuleURL() === null) return 'the engine cannot name its own module, so a thread cannot load one';
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Starts the thread without waiting on it. Called when the shim is
|
|
275
|
+
* initialized in a realm whose worker cannot start inside a synchronous call,
|
|
276
|
+
* and by a call that finds none.
|
|
277
|
+
*/
|
|
278
|
+
export function warmSyncChild(): void {
|
|
279
|
+
// A thread that is itself running a synchronous child is not given one of
|
|
280
|
+
// its own before it needs it: a realm warms one thread, not one per child.
|
|
281
|
+
if ((globalThis as Record<string, unknown>).__substrateSyncChildThread === true) return;
|
|
282
|
+
if (service || syncChildRefusal() !== null) return;
|
|
283
|
+
const WorkerClass = workerClass()!;
|
|
284
|
+
const control = new Int32Array(new SharedArrayBuffer(CONTROL_BYTES));
|
|
285
|
+
const toParent = new Uint8Array(new SharedArrayBuffer(DATA_BYTES));
|
|
286
|
+
const toWorker = new Uint8Array(new SharedArrayBuffer(DATA_BYTES));
|
|
287
|
+
const source = workerSource();
|
|
288
|
+
const inBrowser = typeof (globalThis as Record<string, unknown>).WorkerGlobalScope !== 'undefined' || typeof (globalThis as Record<string, unknown>).document !== 'undefined';
|
|
289
|
+
const url = inBrowser && typeof Blob === 'function' && typeof URL.createObjectURL === 'function'
|
|
290
|
+
? URL.createObjectURL(new Blob([source], { type: 'text/javascript' }))
|
|
291
|
+
: new URL(`data:text/javascript,${encodeURIComponent(source)}`);
|
|
292
|
+
const worker = new WorkerClass(url, { type: 'module' });
|
|
293
|
+
const started: SyncService = { control, toParent, toWorker, worker };
|
|
294
|
+
const failed = (event: unknown) => { started.failure = String((event as { message?: unknown } | null)?.message ?? event); };
|
|
295
|
+
if (typeof worker.on === 'function') worker.on('error', failed);
|
|
296
|
+
else worker.onerror = failed;
|
|
297
|
+
// A Node host is not held open by the thread.
|
|
298
|
+
if (typeof worker.unref === 'function') worker.unref();
|
|
299
|
+
worker.postMessage({ type: 'attach', control: control.buffer, toParent: toParent.buffer, toWorker: toWorker.buffer });
|
|
300
|
+
service = started;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function dropService(): void {
|
|
304
|
+
if (!service) return;
|
|
305
|
+
try { service.worker.terminate(); } catch { /* already gone */ }
|
|
306
|
+
service = null;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const encoder = new TextEncoder();
|
|
310
|
+
const decoder = new TextDecoder();
|
|
311
|
+
|
|
312
|
+
/** A message to the thread, chunked; each chunk waits for the thread to take it. */
|
|
313
|
+
function sendToWorker(active: SyncService, text: string): void {
|
|
314
|
+
const bytes = encoder.encode(text);
|
|
315
|
+
let offset = 0;
|
|
316
|
+
do {
|
|
317
|
+
const length = Math.min(bytes.length - offset, active.toWorker.length);
|
|
318
|
+
active.toWorker.set(bytes.subarray(offset, offset + length));
|
|
319
|
+
offset += length;
|
|
320
|
+
active.control[TO_WORKER_LEN] = length;
|
|
321
|
+
const more = offset < bytes.length;
|
|
322
|
+
Atomics.store(active.control, TO_WORKER, more ? 2 : 1);
|
|
323
|
+
Atomics.notify(active.control, TO_WORKER);
|
|
324
|
+
while (Atomics.load(active.control, TO_WORKER) !== 0) Atomics.wait(active.control, TO_WORKER, more ? 2 : 1, RUN_WAIT_MS);
|
|
325
|
+
} while (offset < bytes.length);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/** Blocks until the thread has written a whole message, and returns it. */
|
|
329
|
+
function receiveFromWorker(active: SyncService, waitMs: number): string {
|
|
330
|
+
const chunks: Uint8Array[] = [];
|
|
331
|
+
for (;;) {
|
|
332
|
+
Atomics.wait(active.control, TO_PARENT, 0, waitMs);
|
|
333
|
+
const state = Atomics.load(active.control, TO_PARENT);
|
|
334
|
+
if (state === 0) {
|
|
335
|
+
const failure = active.failure;
|
|
336
|
+
dropService();
|
|
337
|
+
throw new Error(`the thread a synchronous child runs on answered nothing within ${waitMs / 1000} s${failure ? ` (${failure})` : ''}`);
|
|
338
|
+
}
|
|
339
|
+
chunks.push(active.toParent.slice(0, active.control[TO_PARENT_LEN]));
|
|
340
|
+
Atomics.store(active.control, TO_PARENT, 0);
|
|
341
|
+
Atomics.notify(active.control, TO_PARENT);
|
|
342
|
+
if (state !== 2) break;
|
|
343
|
+
}
|
|
344
|
+
let total = 0;
|
|
345
|
+
for (const chunk of chunks) total += chunk.length;
|
|
346
|
+
const joined = new Uint8Array(total);
|
|
347
|
+
let at = 0;
|
|
348
|
+
for (const chunk of chunks) { joined.set(chunk, at); at += chunk.length; }
|
|
349
|
+
return decoder.decode(joined);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/** The tree's answer to one call the child made, in the shape JSON carries. */
|
|
353
|
+
function answerFilesystem(method: string, args: unknown[]): unknown {
|
|
354
|
+
const vfs = hostVfs as unknown as Record<string, (...rest: unknown[]) => unknown>;
|
|
355
|
+
const plain = args.map((value) => (value === null ? undefined : value));
|
|
356
|
+
if (method === 'statSync' || method === 'lstatSync') {
|
|
357
|
+
const stats = vfs[method]!(plain[0]) as { size: number; mode: number; mtime: Date | number; atime: Date | number; ctime: Date | number; birthtime: Date | number; isFile(): boolean; isDirectory(): boolean; isSymbolicLink(): boolean };
|
|
358
|
+
const ms = (value: Date | number) => (value instanceof Date ? value.getTime() : Number(value) || 0);
|
|
359
|
+
return {
|
|
360
|
+
file: stats.isFile(), dir: stats.isDirectory(), link: stats.isSymbolicLink(),
|
|
361
|
+
size: stats.size, mode: stats.mode, ino: inodeOf(String(plain[0])),
|
|
362
|
+
mtimeMs: ms(stats.mtime), atimeMs: ms(stats.atime), ctimeMs: ms(stats.ctime), birthtimeMs: ms(stats.birthtime),
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
if (method === 'readFileSync') {
|
|
366
|
+
const value = vfs.readFileSync!(plain[0], plain[1]);
|
|
367
|
+
return typeof value === 'string' ? value : { b64: base64(value as Uint8Array) };
|
|
368
|
+
}
|
|
369
|
+
if (method === 'writeFileSync') {
|
|
370
|
+
const data = plain[1] as string | { b64: string };
|
|
371
|
+
return vfs.writeFileSync!(plain[0], typeof data === 'string' ? data : bytes(data.b64)) ?? null;
|
|
372
|
+
}
|
|
373
|
+
const answer = vfs[method];
|
|
374
|
+
if (typeof answer !== 'function') throw Object.assign(new Error(`ENOSYS: the tree answers no ${method}`), { code: 'ENOSYS' });
|
|
375
|
+
return answer.apply(hostVfs, plain) ?? null;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/** A file's identity, stable for as long as the parent's tree holds it. */
|
|
379
|
+
const inodes = new Map<string, number>();
|
|
380
|
+
let nextInode = 1;
|
|
381
|
+
function inodeOf(path: string): number {
|
|
382
|
+
let inode = inodes.get(path);
|
|
383
|
+
if (inode === undefined) { inode = nextInode++; inodes.set(path, inode); }
|
|
384
|
+
return inode;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function base64(value: Uint8Array): string {
|
|
388
|
+
let raw = '';
|
|
389
|
+
for (let i = 0; i < value.length; i += 0x8000) raw += String.fromCharCode.apply(null, Array.from(value.subarray(i, i + 0x8000)));
|
|
390
|
+
return btoa(raw);
|
|
391
|
+
}
|
|
392
|
+
function bytes(b64: string): Uint8Array {
|
|
393
|
+
const raw = atob(b64);
|
|
394
|
+
const out = new Uint8Array(raw.length);
|
|
395
|
+
for (let i = 0; i < raw.length; i++) out[i] = raw.charCodeAt(i);
|
|
396
|
+
return out;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Runs one child to its end and answers what it did. Throws only when this
|
|
401
|
+
* realm cannot run a synchronous child at all; the caller turns that into the
|
|
402
|
+
* result Node gives for a child it could not start.
|
|
403
|
+
*/
|
|
404
|
+
export function runSyncChild(request: SyncChildRequest): SyncChildResult {
|
|
405
|
+
const refusal = syncChildRefusal();
|
|
406
|
+
if (refusal !== null) throw new Error(refusal);
|
|
407
|
+
if (hostVfs === null) throw new Error('the engine has no filesystem for a child to run on');
|
|
408
|
+
if (!service) warmSyncChild();
|
|
409
|
+
const active = service!;
|
|
410
|
+
if (Atomics.load(active.control, STARTED) !== 1) {
|
|
411
|
+
Atomics.wait(active.control, STARTED, 0, START_WAIT_MS);
|
|
412
|
+
if (Atomics.load(active.control, STARTED) !== 1) {
|
|
413
|
+
const failure = active.failure;
|
|
414
|
+
dropService();
|
|
415
|
+
throw new Error(`the thread a synchronous child runs on did not start within ${START_WAIT_MS / 1000} s${failure ? ` (${failure})` : ''}`);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
Atomics.store(active.control, TO_PARENT, 0);
|
|
419
|
+
active.worker.postMessage({
|
|
420
|
+
type: 'run',
|
|
421
|
+
command: request.command,
|
|
422
|
+
cwd: request.cwd,
|
|
423
|
+
env: request.env,
|
|
424
|
+
input: request.input,
|
|
425
|
+
engineURL: engineModuleURL(),
|
|
426
|
+
loadWaitMs: ENGINE_LOAD_WAIT_MS,
|
|
427
|
+
holdsLinks: (hostVfs as unknown as { holdsLinks?: boolean }).holdsLinks === true,
|
|
428
|
+
});
|
|
429
|
+
let stdout = '';
|
|
430
|
+
let stderr = '';
|
|
431
|
+
// The first message of a run is the thread's `begin`, and it is waited for
|
|
432
|
+
// on the short bound; everything after it is the child's own work on the
|
|
433
|
+
// long one.
|
|
434
|
+
let waitMs = BEGIN_WAIT_MS;
|
|
435
|
+
for (;;) {
|
|
436
|
+
const message = JSON.parse(receiveFromWorker(active, waitMs)) as
|
|
437
|
+
| { t: 'begin' }
|
|
438
|
+
| { t: 'fs'; m: string; a: unknown[] }
|
|
439
|
+
| { t: 'out'; s: 1 | 2; d: string }
|
|
440
|
+
| { t: 'done'; stdout: string; stderr: string; status: number }
|
|
441
|
+
| { t: 'failed'; message: string };
|
|
442
|
+
waitMs = RUN_WAIT_MS;
|
|
443
|
+
if (message.t === 'begin') continue;
|
|
444
|
+
if (message.t === 'fs') {
|
|
445
|
+
let answer: string;
|
|
446
|
+
try { answer = JSON.stringify({ ok: true, v: answerFilesystem(message.m, message.a) }); }
|
|
447
|
+
catch (error) {
|
|
448
|
+
const failure = error as { message?: string; code?: string; errno?: number; syscall?: string; path?: string };
|
|
449
|
+
answer = JSON.stringify({ ok: false, e: { message: String(failure?.message ?? error), code: failure?.code, errno: failure?.errno, syscall: failure?.syscall, path: failure?.path } });
|
|
450
|
+
}
|
|
451
|
+
sendToWorker(active, answer);
|
|
452
|
+
continue;
|
|
453
|
+
}
|
|
454
|
+
if (message.t === 'out') {
|
|
455
|
+
if (message.s === 1) { stdout += message.d; request.onStdout?.(message.d); }
|
|
456
|
+
else { stderr += message.d; request.onStderr?.(message.d); }
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
if (message.t === 'failed') throw new Error(message.message);
|
|
460
|
+
// The run's own totals win over what was streamed, as they are what the
|
|
461
|
+
// command reports; a stream that already carried them is not doubled.
|
|
462
|
+
return {
|
|
463
|
+
status: message.status,
|
|
464
|
+
signal: null,
|
|
465
|
+
stdout: message.stdout.length >= stdout.length ? message.stdout : stdout,
|
|
466
|
+
stderr: message.stderr.length >= stderr.length ? message.stderr : stderr,
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
}
|
package/src/shims/tls.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tls shim - TLS/SSL is not available in browser
|
|
3
|
+
* Provides stubs that allow code to load without crashing
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { EventEmitter } from '../node-lib/events-module';
|
|
7
|
+
|
|
8
|
+
export class TLSSocket extends EventEmitter {
|
|
9
|
+
authorized = false;
|
|
10
|
+
encrypted = true;
|
|
11
|
+
|
|
12
|
+
constructor(_socket?: unknown, _options?: unknown) {
|
|
13
|
+
super();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
getPeerCertificate(_detailed?: boolean): object {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getCipher(): { name: string; version: string } | null {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getProtocol(): string | null {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
setServername(_name: string): void {}
|
|
29
|
+
|
|
30
|
+
renegotiate(_options: unknown, _callback: (err: Error | null) => void): boolean {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class Server extends EventEmitter {
|
|
36
|
+
constructor(_options?: unknown, _connectionListener?: (socket: TLSSocket) => void) {
|
|
37
|
+
super();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
listen(..._args: unknown[]): this {
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
close(_callback?: (err?: Error) => void): this {
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
address(): { port: number; family: string; address: string } | string | null {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
getTicketKeys(): Buffer {
|
|
53
|
+
return Buffer.from('');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
setTicketKeys(_keys: Buffer): void {}
|
|
57
|
+
|
|
58
|
+
setSecureContext(_options: unknown): void {}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function createServer(_options?: unknown, _connectionListener?: (socket: TLSSocket) => void): Server {
|
|
62
|
+
return new Server(_options, _connectionListener);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function connect(_options: unknown, _callback?: () => void): TLSSocket {
|
|
66
|
+
const socket = new TLSSocket();
|
|
67
|
+
if (_callback) {
|
|
68
|
+
setTimeout(_callback, 0);
|
|
69
|
+
}
|
|
70
|
+
return socket;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const createSecureContext = (_options?: unknown) => ({});
|
|
74
|
+
|
|
75
|
+
export const getCiphers = () => ['TLS_AES_256_GCM_SHA384', 'TLS_AES_128_GCM_SHA256'];
|
|
76
|
+
|
|
77
|
+
export const DEFAULT_ECDH_CURVE = 'auto';
|
|
78
|
+
export const DEFAULT_MAX_VERSION = 'TLSv1.3';
|
|
79
|
+
export const DEFAULT_MIN_VERSION = 'TLSv1.2';
|
|
80
|
+
|
|
81
|
+
export const rootCertificates: string[] = [];
|
|
82
|
+
|
|
83
|
+
export default {
|
|
84
|
+
TLSSocket,
|
|
85
|
+
Server,
|
|
86
|
+
createServer,
|
|
87
|
+
connect,
|
|
88
|
+
createSecureContext,
|
|
89
|
+
getCiphers,
|
|
90
|
+
DEFAULT_ECDH_CURVE,
|
|
91
|
+
DEFAULT_MAX_VERSION,
|
|
92
|
+
DEFAULT_MIN_VERSION,
|
|
93
|
+
rootCertificates,
|
|
94
|
+
};
|