@ricsam/isolate 0.0.1 → 0.1.0
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/dist/cjs/bridge/diagnostics.cjs +58 -0
- package/dist/cjs/bridge/diagnostics.cjs.map +10 -0
- package/dist/cjs/bridge/legacy-adapters.cjs +242 -0
- package/dist/cjs/bridge/legacy-adapters.cjs.map +10 -0
- package/dist/cjs/bridge/request-context.cjs +59 -0
- package/dist/cjs/bridge/request-context.cjs.map +10 -0
- package/dist/cjs/bridge/runtime-bindings.cjs +367 -0
- package/dist/cjs/bridge/runtime-bindings.cjs.map +10 -0
- package/dist/cjs/browser/browser-runtime.cjs +157 -0
- package/dist/cjs/browser/browser-runtime.cjs.map +10 -0
- package/dist/cjs/daemon.cjs +91 -0
- package/dist/cjs/daemon.cjs.map +10 -0
- package/dist/cjs/files/index.cjs +140 -0
- package/dist/cjs/files/index.cjs.map +10 -0
- package/dist/cjs/host/create-isolate-host.cjs +235 -0
- package/dist/cjs/host/create-isolate-host.cjs.map +10 -0
- package/dist/cjs/host/index.cjs +47 -0
- package/dist/cjs/host/index.cjs.map +10 -0
- package/dist/cjs/index.cjs +55 -0
- package/dist/cjs/index.cjs.map +10 -0
- package/dist/cjs/internal/client/connection.cjs +1919 -0
- package/dist/cjs/internal/client/connection.cjs.map +10 -0
- package/dist/cjs/internal/client/index.cjs +48 -0
- package/dist/cjs/internal/client/index.cjs.map +10 -0
- package/dist/cjs/internal/client/types.cjs +30 -0
- package/dist/cjs/internal/client/types.cjs.map +9 -0
- package/dist/cjs/internal/console/index.cjs +506 -0
- package/dist/cjs/internal/console/index.cjs.map +10 -0
- package/dist/cjs/internal/console/utils.cjs +70 -0
- package/dist/cjs/internal/console/utils.cjs.map +10 -0
- package/dist/cjs/internal/core/index.cjs +2745 -0
- package/dist/cjs/internal/core/index.cjs.map +10 -0
- package/dist/cjs/internal/crypto/index.cjs +470 -0
- package/dist/cjs/internal/crypto/index.cjs.map +10 -0
- package/dist/cjs/internal/daemon/callback-fs-handler.cjs +355 -0
- package/dist/cjs/internal/daemon/callback-fs-handler.cjs.map +10 -0
- package/dist/cjs/internal/daemon/connection.cjs +1952 -0
- package/dist/cjs/internal/daemon/connection.cjs.map +10 -0
- package/dist/cjs/internal/daemon/daemon.cjs +98 -0
- package/dist/cjs/internal/daemon/daemon.cjs.map +10 -0
- package/dist/cjs/internal/daemon/index.cjs +145 -0
- package/dist/cjs/internal/daemon/index.cjs.map +10 -0
- package/dist/cjs/internal/daemon/runtime-pool.cjs +106 -0
- package/dist/cjs/internal/daemon/runtime-pool.cjs.map +10 -0
- package/dist/cjs/internal/daemon/types.cjs +30 -0
- package/dist/cjs/internal/daemon/types.cjs.map +9 -0
- package/dist/cjs/internal/encoding/index.cjs +419 -0
- package/dist/cjs/internal/encoding/index.cjs.map +10 -0
- package/dist/cjs/internal/fetch/consistency/origins.cjs +598 -0
- package/dist/cjs/internal/fetch/consistency/origins.cjs.map +10 -0
- package/dist/cjs/internal/fetch/index.cjs +2640 -0
- package/dist/cjs/internal/fetch/index.cjs.map +10 -0
- package/dist/cjs/internal/fetch/stream-state.cjs +256 -0
- package/dist/cjs/internal/fetch/stream-state.cjs.map +10 -0
- package/dist/cjs/internal/fs/index.cjs +847 -0
- package/dist/cjs/internal/fs/index.cjs.map +10 -0
- package/dist/cjs/internal/fs/node-adapter.cjs +254 -0
- package/dist/cjs/internal/fs/node-adapter.cjs.map +10 -0
- package/dist/cjs/internal/module-loader/bundle.cjs +482 -0
- package/dist/cjs/internal/module-loader/bundle.cjs.map +10 -0
- package/dist/cjs/internal/module-loader/index.cjs +240 -0
- package/dist/cjs/internal/module-loader/index.cjs.map +10 -0
- package/dist/cjs/internal/module-loader/mappings.cjs +120 -0
- package/dist/cjs/internal/module-loader/mappings.cjs.map +10 -0
- package/dist/cjs/internal/module-loader/resolve.cjs +177 -0
- package/dist/cjs/internal/module-loader/resolve.cjs.map +10 -0
- package/dist/cjs/internal/module-loader/strip-types.cjs +236 -0
- package/dist/cjs/internal/module-loader/strip-types.cjs.map +10 -0
- package/dist/cjs/internal/path/index.cjs +503 -0
- package/dist/cjs/internal/path/index.cjs.map +10 -0
- package/dist/cjs/internal/playwright/client.cjs +49 -0
- package/dist/cjs/internal/playwright/client.cjs.map +10 -0
- package/dist/cjs/internal/playwright/handler.cjs +1416 -0
- package/dist/cjs/internal/playwright/handler.cjs.map +10 -0
- package/dist/cjs/internal/playwright/index.cjs +1289 -0
- package/dist/cjs/internal/playwright/index.cjs.map +10 -0
- package/dist/cjs/internal/playwright/types.cjs +47 -0
- package/dist/cjs/internal/playwright/types.cjs.map +10 -0
- package/dist/cjs/internal/protocol/codec.cjs +510 -0
- package/dist/cjs/internal/protocol/codec.cjs.map +10 -0
- package/dist/cjs/internal/protocol/framing.cjs +141 -0
- package/dist/cjs/internal/protocol/framing.cjs.map +10 -0
- package/dist/cjs/internal/protocol/index.cjs +110 -0
- package/dist/cjs/internal/protocol/index.cjs.map +10 -0
- package/dist/cjs/internal/protocol/marshalValue.cjs +518 -0
- package/dist/cjs/internal/protocol/marshalValue.cjs.map +10 -0
- package/dist/cjs/internal/protocol/serialization.cjs +109 -0
- package/dist/cjs/internal/protocol/serialization.cjs.map +10 -0
- package/dist/cjs/internal/protocol/types.cjs +181 -0
- package/dist/cjs/internal/protocol/types.cjs.map +10 -0
- package/dist/cjs/internal/runtime/index.cjs +1235 -0
- package/dist/cjs/internal/runtime/index.cjs.map +10 -0
- package/dist/cjs/internal/server/index.cjs +223 -0
- package/dist/cjs/internal/server/index.cjs.map +10 -0
- package/dist/cjs/internal/test-environment/index.cjs +1415 -0
- package/dist/cjs/internal/test-environment/index.cjs.map +10 -0
- package/dist/cjs/internal/timers/index.cjs +200 -0
- package/dist/cjs/internal/timers/index.cjs.map +10 -0
- package/dist/cjs/internal/transform/index.cjs +361 -0
- package/dist/cjs/internal/transform/index.cjs.map +10 -0
- package/dist/cjs/internal/typecheck/index.cjs +60 -0
- package/dist/cjs/internal/typecheck/index.cjs.map +10 -0
- package/dist/cjs/internal/typecheck/isolate-types.cjs +2614 -0
- package/dist/cjs/internal/typecheck/isolate-types.cjs.map +10 -0
- package/dist/cjs/internal/typecheck/typecheck.cjs +131 -0
- package/dist/cjs/internal/typecheck/typecheck.cjs.map +10 -0
- package/dist/cjs/modules/index.cjs +160 -0
- package/dist/cjs/modules/index.cjs.map +10 -0
- package/dist/cjs/package.json +5 -0
- package/dist/cjs/runtime/script-runtime.cjs +97 -0
- package/dist/cjs/runtime/script-runtime.cjs.map +10 -0
- package/dist/cjs/server/app-server.cjs +158 -0
- package/dist/cjs/server/app-server.cjs.map +10 -0
- package/dist/cjs/testing/integration-helpers.cjs +127 -0
- package/dist/cjs/testing/integration-helpers.cjs.map +10 -0
- package/dist/cjs/typecheck/index.cjs +96 -0
- package/dist/cjs/typecheck/index.cjs.map +10 -0
- package/dist/cjs/types.cjs +30 -0
- package/dist/cjs/types.cjs.map +9 -0
- package/dist/mjs/bridge/diagnostics.mjs +18 -0
- package/dist/mjs/bridge/diagnostics.mjs.map +10 -0
- package/dist/mjs/bridge/legacy-adapters.mjs +178 -0
- package/dist/mjs/bridge/legacy-adapters.mjs.map +10 -0
- package/dist/mjs/bridge/request-context.mjs +19 -0
- package/dist/mjs/bridge/request-context.mjs.map +10 -0
- package/dist/mjs/bridge/runtime-bindings.mjs +303 -0
- package/dist/mjs/bridge/runtime-bindings.mjs.map +10 -0
- package/dist/mjs/browser/browser-runtime.mjs +93 -0
- package/dist/mjs/browser/browser-runtime.mjs.map +10 -0
- package/dist/mjs/daemon.mjs +91 -0
- package/dist/mjs/daemon.mjs.map +10 -0
- package/dist/mjs/files/index.mjs +76 -0
- package/dist/mjs/files/index.mjs.map +10 -0
- package/dist/mjs/host/create-isolate-host.mjs +171 -0
- package/dist/mjs/host/create-isolate-host.mjs.map +10 -0
- package/dist/mjs/host/index.mjs +7 -0
- package/dist/mjs/host/index.mjs.map +10 -0
- package/dist/mjs/index.mjs +15 -0
- package/dist/mjs/index.mjs.map +10 -0
- package/dist/mjs/internal/client/connection.mjs +1872 -0
- package/dist/mjs/internal/client/connection.mjs.map +10 -0
- package/dist/mjs/internal/client/index.mjs +8 -0
- package/dist/mjs/internal/client/index.mjs.map +10 -0
- package/dist/mjs/internal/client/types.mjs +2 -0
- package/dist/mjs/internal/client/types.mjs.map +9 -0
- package/dist/mjs/internal/console/index.mjs +442 -0
- package/dist/mjs/internal/console/index.mjs.map +10 -0
- package/dist/mjs/internal/console/utils.mjs +30 -0
- package/dist/mjs/internal/console/utils.mjs.map +10 -0
- package/dist/mjs/internal/core/index.mjs +2681 -0
- package/dist/mjs/internal/core/index.mjs.map +10 -0
- package/dist/mjs/internal/crypto/index.mjs +406 -0
- package/dist/mjs/internal/crypto/index.mjs.map +10 -0
- package/dist/mjs/internal/daemon/callback-fs-handler.mjs +315 -0
- package/dist/mjs/internal/daemon/callback-fs-handler.mjs.map +10 -0
- package/dist/mjs/internal/daemon/connection.mjs +1931 -0
- package/dist/mjs/internal/daemon/connection.mjs.map +10 -0
- package/dist/mjs/internal/daemon/daemon.mjs +98 -0
- package/dist/mjs/internal/daemon/daemon.mjs.map +10 -0
- package/dist/mjs/internal/daemon/index.mjs +105 -0
- package/dist/mjs/internal/daemon/index.mjs.map +10 -0
- package/dist/mjs/internal/daemon/runtime-pool.mjs +66 -0
- package/dist/mjs/internal/daemon/runtime-pool.mjs.map +10 -0
- package/dist/mjs/internal/daemon/types.mjs +2 -0
- package/dist/mjs/internal/daemon/types.mjs.map +9 -0
- package/dist/mjs/internal/encoding/index.mjs +379 -0
- package/dist/mjs/internal/encoding/index.mjs.map +10 -0
- package/dist/mjs/internal/fetch/consistency/origins.mjs +558 -0
- package/dist/mjs/internal/fetch/consistency/origins.mjs.map +10 -0
- package/dist/mjs/internal/fetch/index.mjs +2580 -0
- package/dist/mjs/internal/fetch/index.mjs.map +10 -0
- package/dist/mjs/internal/fetch/stream-state.mjs +216 -0
- package/dist/mjs/internal/fetch/stream-state.mjs.map +10 -0
- package/dist/mjs/internal/fs/index.mjs +783 -0
- package/dist/mjs/internal/fs/index.mjs.map +10 -0
- package/dist/mjs/internal/fs/node-adapter.mjs +190 -0
- package/dist/mjs/internal/fs/node-adapter.mjs.map +10 -0
- package/dist/mjs/internal/module-loader/bundle.mjs +418 -0
- package/dist/mjs/internal/module-loader/bundle.mjs.map +10 -0
- package/dist/mjs/internal/module-loader/index.mjs +185 -0
- package/dist/mjs/internal/module-loader/index.mjs.map +10 -0
- package/dist/mjs/internal/module-loader/mappings.mjs +80 -0
- package/dist/mjs/internal/module-loader/mappings.mjs.map +10 -0
- package/dist/mjs/internal/module-loader/resolve.mjs +113 -0
- package/dist/mjs/internal/module-loader/resolve.mjs.map +10 -0
- package/dist/mjs/internal/module-loader/strip-types.mjs +172 -0
- package/dist/mjs/internal/module-loader/strip-types.mjs.map +10 -0
- package/dist/mjs/internal/path/index.mjs +463 -0
- package/dist/mjs/internal/path/index.mjs.map +10 -0
- package/dist/mjs/internal/playwright/client.mjs +13 -0
- package/dist/mjs/internal/playwright/client.mjs.map +10 -0
- package/dist/mjs/internal/playwright/handler.mjs +1378 -0
- package/dist/mjs/internal/playwright/handler.mjs.map +10 -0
- package/dist/mjs/internal/playwright/index.mjs +1234 -0
- package/dist/mjs/internal/playwright/index.mjs.map +10 -0
- package/dist/mjs/internal/playwright/types.mjs +7 -0
- package/dist/mjs/internal/playwright/types.mjs.map +10 -0
- package/dist/mjs/internal/protocol/codec.mjs +470 -0
- package/dist/mjs/internal/protocol/codec.mjs.map +10 -0
- package/dist/mjs/internal/protocol/framing.mjs +101 -0
- package/dist/mjs/internal/protocol/framing.mjs.map +10 -0
- package/dist/mjs/internal/protocol/index.mjs +98 -0
- package/dist/mjs/internal/protocol/index.mjs.map +10 -0
- package/dist/mjs/internal/protocol/marshalValue.mjs +494 -0
- package/dist/mjs/internal/protocol/marshalValue.mjs.map +10 -0
- package/dist/mjs/internal/protocol/serialization.mjs +69 -0
- package/dist/mjs/internal/protocol/serialization.mjs.map +10 -0
- package/dist/mjs/internal/protocol/types.mjs +141 -0
- package/dist/mjs/internal/protocol/types.mjs.map +10 -0
- package/dist/mjs/internal/runtime/index.mjs +1198 -0
- package/dist/mjs/internal/runtime/index.mjs.map +10 -0
- package/dist/mjs/internal/server/index.mjs +183 -0
- package/dist/mjs/internal/server/index.mjs.map +10 -0
- package/dist/mjs/internal/test-environment/index.mjs +1351 -0
- package/dist/mjs/internal/test-environment/index.mjs.map +10 -0
- package/dist/mjs/internal/timers/index.mjs +136 -0
- package/dist/mjs/internal/timers/index.mjs.map +10 -0
- package/dist/mjs/internal/transform/index.mjs +321 -0
- package/dist/mjs/internal/transform/index.mjs.map +10 -0
- package/dist/mjs/internal/typecheck/index.mjs +35 -0
- package/dist/mjs/internal/typecheck/index.mjs.map +10 -0
- package/dist/mjs/internal/typecheck/isolate-types.mjs +2574 -0
- package/dist/mjs/internal/typecheck/isolate-types.mjs.map +10 -0
- package/dist/mjs/internal/typecheck/typecheck.mjs +91 -0
- package/dist/mjs/internal/typecheck/typecheck.mjs.map +10 -0
- package/dist/mjs/modules/index.mjs +96 -0
- package/dist/mjs/modules/index.mjs.map +10 -0
- package/dist/mjs/package.json +5 -0
- package/dist/mjs/runtime/script-runtime.mjs +57 -0
- package/dist/mjs/runtime/script-runtime.mjs.map +10 -0
- package/dist/mjs/server/app-server.mjs +118 -0
- package/dist/mjs/server/app-server.mjs.map +10 -0
- package/dist/mjs/testing/integration-helpers.mjs +63 -0
- package/dist/mjs/testing/integration-helpers.mjs.map +10 -0
- package/dist/mjs/typecheck/index.mjs +56 -0
- package/dist/mjs/typecheck/index.mjs.map +10 -0
- package/dist/mjs/types.mjs +2 -0
- package/dist/mjs/types.mjs.map +9 -0
- package/dist/types/bridge/diagnostics.d.ts +12 -0
- package/dist/types/bridge/legacy-adapters.d.ts +14 -0
- package/dist/types/bridge/request-context.d.ts +10 -0
- package/dist/types/bridge/runtime-bindings.d.ts +14 -0
- package/dist/types/browser/browser-runtime.d.ts +3 -0
- package/dist/types/daemon.d.ts +2 -0
- package/dist/types/files/index.d.ts +5 -0
- package/dist/types/host/create-isolate-host.d.ts +2 -0
- package/dist/types/host/index.d.ts +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/internal/client/connection.d.ts +9 -0
- package/dist/types/internal/client/index.d.ts +8 -0
- package/dist/types/internal/client/types.d.ts +198 -0
- package/dist/types/internal/console/index.d.ts +108 -0
- package/dist/types/internal/console/utils.d.ts +27 -0
- package/dist/types/internal/core/index.d.ts +119 -0
- package/dist/types/internal/crypto/index.d.ts +18 -0
- package/dist/types/internal/daemon/callback-fs-handler.d.ts +28 -0
- package/dist/types/internal/daemon/connection.d.ts +9 -0
- package/dist/types/internal/daemon/daemon.d.ts +2 -0
- package/dist/types/internal/daemon/index.d.ts +14 -0
- package/dist/types/internal/daemon/runtime-pool.d.ts +16 -0
- package/dist/types/internal/daemon/types.d.ts +211 -0
- package/dist/types/internal/encoding/index.d.ts +21 -0
- package/dist/types/internal/fetch/consistency/origins.d.ts +179 -0
- package/dist/types/internal/fetch/index.d.ts +93 -0
- package/dist/types/internal/fetch/stream-state.d.ts +65 -0
- package/dist/types/internal/fs/index.d.ts +70 -0
- package/dist/types/internal/fs/node-adapter.d.ts +24 -0
- package/dist/types/internal/module-loader/bundle.d.ts +33 -0
- package/dist/types/internal/module-loader/index.d.ts +30 -0
- package/dist/types/internal/module-loader/mappings.d.ts +47 -0
- package/dist/types/internal/module-loader/resolve.d.ts +26 -0
- package/dist/types/internal/module-loader/strip-types.d.ts +19 -0
- package/dist/types/internal/path/index.d.ts +23 -0
- package/dist/types/internal/playwright/client.d.ts +7 -0
- package/dist/types/internal/playwright/handler.d.ts +44 -0
- package/dist/types/internal/playwright/index.d.ts +14 -0
- package/dist/types/internal/playwright/types.d.ts +145 -0
- package/dist/types/internal/protocol/codec.d.ts +242 -0
- package/dist/types/internal/protocol/framing.d.ts +89 -0
- package/dist/types/internal/protocol/index.d.ts +10 -0
- package/dist/types/internal/protocol/marshalValue.d.ts +79 -0
- package/dist/types/internal/protocol/serialization.d.ts +23 -0
- package/dist/types/internal/protocol/types.d.ts +996 -0
- package/dist/types/internal/runtime/index.d.ts +200 -0
- package/dist/types/internal/server/index.d.ts +42 -0
- package/dist/types/internal/test-environment/index.d.ts +112 -0
- package/dist/types/internal/timers/index.d.ts +22 -0
- package/dist/types/internal/transform/index.d.ts +36 -0
- package/dist/types/internal/typecheck/index.d.ts +7 -0
- package/dist/types/internal/typecheck/isolate-types.d.ts +94 -0
- package/dist/types/internal/typecheck/typecheck.d.ts +148 -0
- package/dist/types/modules/index.d.ts +2 -0
- package/dist/types/runtime/script-runtime.d.ts +6 -0
- package/dist/types/server/app-server.d.ts +3 -0
- package/dist/types/testing/integration-helpers.d.ts +9 -0
- package/dist/types/typecheck/index.d.ts +8 -0
- package/dist/types/types.d.ts +233 -0
- package/package.json +74 -6
- package/README.md +0 -45
|
@@ -0,0 +1,1198 @@
|
|
|
1
|
+
// packages/isolate/src/internal/runtime/index.ts
|
|
2
|
+
import ivm from "isolated-vm";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { setupCore } from "../core/index.mjs";
|
|
5
|
+
import { normalizeEntryFilename } from "../protocol/index.mjs";
|
|
6
|
+
import {
|
|
7
|
+
transformEntryCode,
|
|
8
|
+
transformModuleCode,
|
|
9
|
+
contentHash,
|
|
10
|
+
mapErrorStack
|
|
11
|
+
} from "../transform/index.mjs";
|
|
12
|
+
import { normalizeEntryFilename as normalizeEntryFilename2 } from "../protocol/index.mjs";
|
|
13
|
+
import { setupConsole } from "../console/index.mjs";
|
|
14
|
+
import { setupEncoding } from "../encoding/index.mjs";
|
|
15
|
+
import { setupTimers } from "../timers/index.mjs";
|
|
16
|
+
import { setupPath } from "../path/index.mjs";
|
|
17
|
+
import { setupCrypto } from "../crypto/index.mjs";
|
|
18
|
+
import { setupFetch } from "../fetch/index.mjs";
|
|
19
|
+
import { setupFs } from "../fs/index.mjs";
|
|
20
|
+
import {
|
|
21
|
+
setupTestEnvironment,
|
|
22
|
+
runTests as runTestsInContext,
|
|
23
|
+
hasTests as hasTestsInContext,
|
|
24
|
+
getTestCount as getTestCountInContext
|
|
25
|
+
} from "../test-environment/index.mjs";
|
|
26
|
+
import {
|
|
27
|
+
setupPlaywright
|
|
28
|
+
} from "../playwright/index.mjs";
|
|
29
|
+
import {
|
|
30
|
+
marshalValue,
|
|
31
|
+
unmarshalValue
|
|
32
|
+
} from "../protocol/index.mjs";
|
|
33
|
+
import { setupCore as setupCore2 } from "../core/index.mjs";
|
|
34
|
+
import { setupConsole as setupConsole2 } from "../console/index.mjs";
|
|
35
|
+
import {
|
|
36
|
+
simpleConsoleHandler
|
|
37
|
+
} from "../console/utils.mjs";
|
|
38
|
+
import { setupCrypto as setupCrypto2 } from "../crypto/index.mjs";
|
|
39
|
+
import { setupEncoding as setupEncoding2 } from "../encoding/index.mjs";
|
|
40
|
+
import { setupFetch as setupFetch2 } from "../fetch/index.mjs";
|
|
41
|
+
import { setupFs as setupFs2, createNodeFileSystemHandler } from "../fs/index.mjs";
|
|
42
|
+
import { setupPath as setupPath2 } from "../path/index.mjs";
|
|
43
|
+
import { setupTimers as setupTimers2 } from "../timers/index.mjs";
|
|
44
|
+
import {
|
|
45
|
+
setupTestEnvironment as setupTestEnvironment2,
|
|
46
|
+
runTests,
|
|
47
|
+
hasTests,
|
|
48
|
+
getTestCount
|
|
49
|
+
} from "../test-environment/index.mjs";
|
|
50
|
+
import {
|
|
51
|
+
setupPlaywright as setupPlaywright2,
|
|
52
|
+
createPlaywrightHandler,
|
|
53
|
+
defaultPlaywrightHandler,
|
|
54
|
+
getDefaultPlaywrightHandlerMetadata
|
|
55
|
+
} from "../playwright/index.mjs";
|
|
56
|
+
function getConfiguredExecutionTimeout(timeoutMs) {
|
|
57
|
+
if (typeof timeoutMs !== "number" || !Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
return timeoutMs;
|
|
61
|
+
}
|
|
62
|
+
function createTimeoutError(label, timeoutMs) {
|
|
63
|
+
const error = new Error(`${label} timed out after ${timeoutMs}ms`);
|
|
64
|
+
error.name = "TimeoutError";
|
|
65
|
+
return error;
|
|
66
|
+
}
|
|
67
|
+
function createDisposedRuntimeError() {
|
|
68
|
+
return new Error("Runtime has been disposed");
|
|
69
|
+
}
|
|
70
|
+
function createTimedOutRuntimeError(timeoutMs) {
|
|
71
|
+
const error = new Error(`Runtime execution timed out after ${timeoutMs}ms; create a new runtime.`);
|
|
72
|
+
error.name = "TimeoutError";
|
|
73
|
+
return error;
|
|
74
|
+
}
|
|
75
|
+
function assertRuntimeUsable(state) {
|
|
76
|
+
if (state.timedOutExecutionMs !== undefined) {
|
|
77
|
+
throw createTimedOutRuntimeError(state.timedOutExecutionMs);
|
|
78
|
+
}
|
|
79
|
+
if (state.isDisposed) {
|
|
80
|
+
throw createDisposedRuntimeError();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function logRuntimeDisposal(state, options) {
|
|
84
|
+
const message = `[isolate-runtime] Disposing runtime ${state.id}: ${options.reason}`;
|
|
85
|
+
if (options.error) {
|
|
86
|
+
console.error(message, options.error);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
console.warn(message);
|
|
90
|
+
}
|
|
91
|
+
async function disposeRuntimeState(state, options = { reason: "RuntimeHandle.dispose() called", log: false }) {
|
|
92
|
+
if (state.disposePromise) {
|
|
93
|
+
return state.disposePromise;
|
|
94
|
+
}
|
|
95
|
+
state.disposeReason = options.reason;
|
|
96
|
+
state.isDisposed = true;
|
|
97
|
+
if (options.log !== false) {
|
|
98
|
+
logRuntimeDisposal(state, options);
|
|
99
|
+
}
|
|
100
|
+
state.disposePromise = (async () => {
|
|
101
|
+
if (state.customFnInvokeRef) {
|
|
102
|
+
try {
|
|
103
|
+
state.customFnInvokeRef.release();
|
|
104
|
+
} catch {} finally {
|
|
105
|
+
state.customFnInvokeRef = undefined;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const disposeHandle = (dispose) => {
|
|
109
|
+
if (!dispose)
|
|
110
|
+
return;
|
|
111
|
+
try {
|
|
112
|
+
dispose();
|
|
113
|
+
} catch {}
|
|
114
|
+
};
|
|
115
|
+
disposeHandle(state.handles.playwright?.dispose.bind(state.handles.playwright));
|
|
116
|
+
disposeHandle(state.handles.testEnvironment?.dispose.bind(state.handles.testEnvironment));
|
|
117
|
+
disposeHandle(state.handles.fs?.dispose.bind(state.handles.fs));
|
|
118
|
+
disposeHandle(state.handles.fetch?.dispose.bind(state.handles.fetch));
|
|
119
|
+
disposeHandle(state.handles.crypto?.dispose.bind(state.handles.crypto));
|
|
120
|
+
disposeHandle(state.handles.path?.dispose.bind(state.handles.path));
|
|
121
|
+
disposeHandle(state.handles.timers?.dispose.bind(state.handles.timers));
|
|
122
|
+
disposeHandle(state.handles.encoding?.dispose.bind(state.handles.encoding));
|
|
123
|
+
disposeHandle(state.handles.console?.dispose.bind(state.handles.console));
|
|
124
|
+
disposeHandle(state.handles.core?.dispose.bind(state.handles.core));
|
|
125
|
+
state.pendingCallbacks.length = 0;
|
|
126
|
+
state.moduleCache.clear();
|
|
127
|
+
state.moduleLoadsInFlight.clear();
|
|
128
|
+
state.moduleToFilename.clear();
|
|
129
|
+
state.moduleImportChain.clear();
|
|
130
|
+
state.specifierToImporter.clear();
|
|
131
|
+
state.sourceMaps.clear();
|
|
132
|
+
try {
|
|
133
|
+
state.context.release();
|
|
134
|
+
} catch {}
|
|
135
|
+
try {
|
|
136
|
+
state.isolate.dispose();
|
|
137
|
+
} catch {}
|
|
138
|
+
})();
|
|
139
|
+
return state.disposePromise;
|
|
140
|
+
}
|
|
141
|
+
async function runWithExecutionTimeout(state, timeoutMs, label, operation) {
|
|
142
|
+
const effectiveTimeoutMs = getConfiguredExecutionTimeout(timeoutMs);
|
|
143
|
+
if (effectiveTimeoutMs === undefined) {
|
|
144
|
+
return operation();
|
|
145
|
+
}
|
|
146
|
+
let timeoutId;
|
|
147
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
148
|
+
timeoutId = setTimeout(() => {
|
|
149
|
+
const timeoutError = createTimeoutError(label, effectiveTimeoutMs);
|
|
150
|
+
state.timedOutExecutionMs ??= effectiveTimeoutMs;
|
|
151
|
+
disposeRuntimeState(state, {
|
|
152
|
+
reason: timeoutError.message,
|
|
153
|
+
error: timeoutError
|
|
154
|
+
});
|
|
155
|
+
reject(timeoutError);
|
|
156
|
+
}, effectiveTimeoutMs);
|
|
157
|
+
});
|
|
158
|
+
try {
|
|
159
|
+
return await Promise.race([operation(), timeoutPromise]);
|
|
160
|
+
} finally {
|
|
161
|
+
if (timeoutId) {
|
|
162
|
+
clearTimeout(timeoutId);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
var iteratorSessions = new Map;
|
|
167
|
+
var ISOLATE_MARSHAL_CODE = `
|
|
168
|
+
(function() {
|
|
169
|
+
// Marshal a value (JavaScript → Ref)
|
|
170
|
+
function marshalForHost(value, depth = 0) {
|
|
171
|
+
if (depth > 100) throw new Error('Maximum marshalling depth exceeded');
|
|
172
|
+
|
|
173
|
+
if (value === null) return null;
|
|
174
|
+
if (value === undefined) return { __type: 'UndefinedRef' };
|
|
175
|
+
|
|
176
|
+
const type = typeof value;
|
|
177
|
+
if (type === 'string' || type === 'number' || type === 'boolean') return value;
|
|
178
|
+
if (type === 'bigint') return { __type: 'BigIntRef', value: value.toString() };
|
|
179
|
+
if (type === 'function') throw new Error('Cannot marshal functions from isolate');
|
|
180
|
+
if (type === 'symbol') throw new Error('Cannot marshal Symbol values');
|
|
181
|
+
|
|
182
|
+
if (type === 'object') {
|
|
183
|
+
if (value instanceof Date) {
|
|
184
|
+
return { __type: 'DateRef', timestamp: value.getTime() };
|
|
185
|
+
}
|
|
186
|
+
if (value instanceof RegExp) {
|
|
187
|
+
return { __type: 'RegExpRef', source: value.source, flags: value.flags };
|
|
188
|
+
}
|
|
189
|
+
if (value instanceof URL) {
|
|
190
|
+
return { __type: 'URLRef', href: value.href };
|
|
191
|
+
}
|
|
192
|
+
if (typeof Headers !== 'undefined' && value instanceof Headers) {
|
|
193
|
+
const pairs = [];
|
|
194
|
+
value.forEach((v, k) => pairs.push([k, v]));
|
|
195
|
+
return { __type: 'HeadersRef', pairs };
|
|
196
|
+
}
|
|
197
|
+
if (value instanceof Uint8Array) {
|
|
198
|
+
return { __type: 'Uint8ArrayRef', data: Array.from(value) };
|
|
199
|
+
}
|
|
200
|
+
if (value instanceof ArrayBuffer) {
|
|
201
|
+
return { __type: 'Uint8ArrayRef', data: Array.from(new Uint8Array(value)) };
|
|
202
|
+
}
|
|
203
|
+
if (typeof Request !== 'undefined' && value instanceof Request) {
|
|
204
|
+
throw new Error('Cannot marshal Request from isolate. Use fetch callback instead.');
|
|
205
|
+
}
|
|
206
|
+
if (typeof Response !== 'undefined' && value instanceof Response) {
|
|
207
|
+
throw new Error('Cannot marshal Response from isolate. Return plain objects instead.');
|
|
208
|
+
}
|
|
209
|
+
if (typeof File !== 'undefined' && value instanceof File) {
|
|
210
|
+
throw new Error('Cannot marshal File from isolate.');
|
|
211
|
+
}
|
|
212
|
+
if (typeof Blob !== 'undefined' && value instanceof Blob) {
|
|
213
|
+
throw new Error('Cannot marshal Blob from isolate.');
|
|
214
|
+
}
|
|
215
|
+
if (typeof FormData !== 'undefined' && value instanceof FormData) {
|
|
216
|
+
throw new Error('Cannot marshal FormData from isolate.');
|
|
217
|
+
}
|
|
218
|
+
if (Array.isArray(value)) {
|
|
219
|
+
return value.map(v => marshalForHost(v, depth + 1));
|
|
220
|
+
}
|
|
221
|
+
// Plain object
|
|
222
|
+
const result = {};
|
|
223
|
+
for (const key of Object.keys(value)) {
|
|
224
|
+
result[key] = marshalForHost(value[key], depth + 1);
|
|
225
|
+
}
|
|
226
|
+
return result;
|
|
227
|
+
}
|
|
228
|
+
return value;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Unmarshal a value (Ref → JavaScript)
|
|
232
|
+
function unmarshalFromHost(value, depth = 0) {
|
|
233
|
+
if (depth > 100) throw new Error('Maximum unmarshalling depth exceeded');
|
|
234
|
+
|
|
235
|
+
if (value === null) return null;
|
|
236
|
+
if (typeof value !== 'object') return value;
|
|
237
|
+
|
|
238
|
+
if (value.__type) {
|
|
239
|
+
switch (value.__type) {
|
|
240
|
+
case 'UndefinedRef': return undefined;
|
|
241
|
+
case 'DateRef': return new Date(value.timestamp);
|
|
242
|
+
case 'RegExpRef': return new RegExp(value.source, value.flags);
|
|
243
|
+
case 'BigIntRef': return BigInt(value.value);
|
|
244
|
+
case 'URLRef': return new URL(value.href);
|
|
245
|
+
case 'HeadersRef': return new Headers(value.pairs);
|
|
246
|
+
case 'Uint8ArrayRef': return new Uint8Array(value.data);
|
|
247
|
+
case 'RequestRef': {
|
|
248
|
+
const init = {
|
|
249
|
+
method: value.method,
|
|
250
|
+
headers: value.headers,
|
|
251
|
+
body: value.body ? new Uint8Array(value.body) : null,
|
|
252
|
+
};
|
|
253
|
+
if (value.mode) init.mode = value.mode;
|
|
254
|
+
if (value.credentials) init.credentials = value.credentials;
|
|
255
|
+
if (value.cache) init.cache = value.cache;
|
|
256
|
+
if (value.redirect) init.redirect = value.redirect;
|
|
257
|
+
if (value.referrer) init.referrer = value.referrer;
|
|
258
|
+
if (value.referrerPolicy) init.referrerPolicy = value.referrerPolicy;
|
|
259
|
+
if (value.integrity) init.integrity = value.integrity;
|
|
260
|
+
return new Request(value.url, init);
|
|
261
|
+
}
|
|
262
|
+
case 'ResponseRef': {
|
|
263
|
+
return new Response(value.body ? new Uint8Array(value.body) : null, {
|
|
264
|
+
status: value.status,
|
|
265
|
+
statusText: value.statusText,
|
|
266
|
+
headers: value.headers,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
case 'FileRef': {
|
|
270
|
+
if (!value.name) {
|
|
271
|
+
return new Blob([new Uint8Array(value.data)], { type: value.type });
|
|
272
|
+
}
|
|
273
|
+
return new File([new Uint8Array(value.data)], value.name, {
|
|
274
|
+
type: value.type,
|
|
275
|
+
lastModified: value.lastModified,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
case 'FormDataRef': {
|
|
279
|
+
const fd = new FormData();
|
|
280
|
+
for (const [key, entry] of value.entries) {
|
|
281
|
+
if (typeof entry === 'string') {
|
|
282
|
+
fd.append(key, entry);
|
|
283
|
+
} else {
|
|
284
|
+
const file = unmarshalFromHost(entry, depth + 1);
|
|
285
|
+
fd.append(key, file);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return fd;
|
|
289
|
+
}
|
|
290
|
+
case 'CallbackRef': {
|
|
291
|
+
const callbackId = value.callbackId;
|
|
292
|
+
return async function(...args) {
|
|
293
|
+
const argsJson = JSON.stringify(marshalForHost(args));
|
|
294
|
+
const resultJson = await __customFn_invoke.apply(
|
|
295
|
+
undefined,
|
|
296
|
+
[callbackId, argsJson],
|
|
297
|
+
{ result: { promise: true, copy: true } }
|
|
298
|
+
);
|
|
299
|
+
const result = JSON.parse(resultJson);
|
|
300
|
+
if (result.ok) {
|
|
301
|
+
return unmarshalFromHost(result.value);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const error = new Error(result.error.message);
|
|
305
|
+
error.name = result.error.name;
|
|
306
|
+
throw error;
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
case 'PromiseRef': {
|
|
310
|
+
const promiseId = value.promiseId;
|
|
311
|
+
return (async () => {
|
|
312
|
+
const argsJson = JSON.stringify([promiseId]);
|
|
313
|
+
const resultJson = await __customFn_invoke.apply(
|
|
314
|
+
undefined,
|
|
315
|
+
[value.__resolveCallbackId, argsJson],
|
|
316
|
+
{ result: { promise: true, copy: true } }
|
|
317
|
+
);
|
|
318
|
+
const result = JSON.parse(resultJson);
|
|
319
|
+
if (result.ok) {
|
|
320
|
+
return unmarshalFromHost(result.value);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const error = new Error(result.error.message);
|
|
324
|
+
error.name = result.error.name;
|
|
325
|
+
throw error;
|
|
326
|
+
})();
|
|
327
|
+
}
|
|
328
|
+
case 'AsyncIteratorRef': {
|
|
329
|
+
const iteratorId = value.iteratorId;
|
|
330
|
+
const nextCallbackId = value.__nextCallbackId;
|
|
331
|
+
const returnCallbackId = value.__returnCallbackId;
|
|
332
|
+
const throwCallbackId = value.__throwCallbackId;
|
|
333
|
+
return {
|
|
334
|
+
[Symbol.asyncIterator]() { return this; },
|
|
335
|
+
async next() {
|
|
336
|
+
const argsJson = JSON.stringify([iteratorId]);
|
|
337
|
+
const resultJson = await __customFn_invoke.apply(
|
|
338
|
+
undefined,
|
|
339
|
+
[nextCallbackId, argsJson],
|
|
340
|
+
{ result: { promise: true, copy: true } }
|
|
341
|
+
);
|
|
342
|
+
const result = JSON.parse(resultJson);
|
|
343
|
+
if (!result.ok) {
|
|
344
|
+
const error = new Error(result.error.message);
|
|
345
|
+
error.name = result.error.name;
|
|
346
|
+
throw error;
|
|
347
|
+
}
|
|
348
|
+
return {
|
|
349
|
+
done: result.value.done,
|
|
350
|
+
value: unmarshalFromHost(result.value.value)
|
|
351
|
+
};
|
|
352
|
+
},
|
|
353
|
+
async return(v) {
|
|
354
|
+
const argsJson = JSON.stringify([iteratorId, marshalForHost(v)]);
|
|
355
|
+
const resultJson = await __customFn_invoke.apply(
|
|
356
|
+
undefined,
|
|
357
|
+
[returnCallbackId, argsJson],
|
|
358
|
+
{ result: { promise: true, copy: true } }
|
|
359
|
+
);
|
|
360
|
+
const result = JSON.parse(resultJson);
|
|
361
|
+
if (!result.ok) {
|
|
362
|
+
const error = new Error(result.error.message);
|
|
363
|
+
error.name = result.error.name;
|
|
364
|
+
throw error;
|
|
365
|
+
}
|
|
366
|
+
return {
|
|
367
|
+
done: result.value.done ?? true,
|
|
368
|
+
value: unmarshalFromHost(result.value.value ?? result.value),
|
|
369
|
+
};
|
|
370
|
+
},
|
|
371
|
+
async throw(e) {
|
|
372
|
+
if (throwCallbackId == null) {
|
|
373
|
+
throw e;
|
|
374
|
+
}
|
|
375
|
+
const errorValue = e && typeof e === 'object'
|
|
376
|
+
? { message: e.message, name: e.name, stack: e.stack }
|
|
377
|
+
: { message: String(e), name: 'Error' };
|
|
378
|
+
const argsJson = JSON.stringify([iteratorId, errorValue]);
|
|
379
|
+
const resultJson = await __customFn_invoke.apply(
|
|
380
|
+
undefined,
|
|
381
|
+
[throwCallbackId, argsJson],
|
|
382
|
+
{ result: { promise: true, copy: true } }
|
|
383
|
+
);
|
|
384
|
+
const result = JSON.parse(resultJson);
|
|
385
|
+
if (!result.ok) {
|
|
386
|
+
const error = new Error(result.error.message);
|
|
387
|
+
error.name = result.error.name;
|
|
388
|
+
throw error;
|
|
389
|
+
}
|
|
390
|
+
return {
|
|
391
|
+
done: result.value.done,
|
|
392
|
+
value: unmarshalFromHost(result.value.value),
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
default:
|
|
398
|
+
// Unknown ref type, return as-is
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (Array.isArray(value)) {
|
|
404
|
+
return value.map(v => unmarshalFromHost(v, depth + 1));
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Plain object - recursively unmarshal
|
|
408
|
+
const result = {};
|
|
409
|
+
for (const key of Object.keys(value)) {
|
|
410
|
+
result[key] = unmarshalFromHost(value[key], depth + 1);
|
|
411
|
+
}
|
|
412
|
+
return result;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// Expose as globals
|
|
416
|
+
globalThis.__marshalForHost = marshalForHost;
|
|
417
|
+
globalThis.__unmarshalFromHost = unmarshalFromHost;
|
|
418
|
+
})();
|
|
419
|
+
`;
|
|
420
|
+
async function setupCustomFunctions(context, customFunctions, marshalOptions) {
|
|
421
|
+
const global = context.global;
|
|
422
|
+
const invokeCallbackRef = new ivm.Reference(async (nameOrId, argsJson) => {
|
|
423
|
+
if (typeof nameOrId === "number" && marshalOptions) {
|
|
424
|
+
const rawArgs2 = JSON.parse(argsJson);
|
|
425
|
+
const args2 = unmarshalValue(rawArgs2);
|
|
426
|
+
try {
|
|
427
|
+
const result = await marshalOptions.invokeCallback(nameOrId, args2);
|
|
428
|
+
const ctx = marshalOptions.createMarshalContext();
|
|
429
|
+
const marshalledResult = await marshalValue(result, ctx);
|
|
430
|
+
const processedResult = marshalOptions.addCallbackIdsToRefs(marshalledResult);
|
|
431
|
+
return JSON.stringify({ ok: true, value: processedResult });
|
|
432
|
+
} catch (error) {
|
|
433
|
+
const err = error;
|
|
434
|
+
return JSON.stringify({
|
|
435
|
+
ok: false,
|
|
436
|
+
error: { message: err.message, name: err.name }
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
const name = String(nameOrId);
|
|
441
|
+
const def = customFunctions[name];
|
|
442
|
+
if (!def) {
|
|
443
|
+
return JSON.stringify({
|
|
444
|
+
ok: false,
|
|
445
|
+
error: {
|
|
446
|
+
message: `Custom function '${name}' not found`,
|
|
447
|
+
name: "Error"
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
const rawArgs = JSON.parse(argsJson);
|
|
452
|
+
const args = unmarshalValue(rawArgs);
|
|
453
|
+
try {
|
|
454
|
+
const result = await def.fn(...args);
|
|
455
|
+
if (marshalOptions) {
|
|
456
|
+
const ctx = marshalOptions.createMarshalContext();
|
|
457
|
+
const marshalledResult2 = await marshalValue(result, ctx);
|
|
458
|
+
const processedResult = marshalOptions.addCallbackIdsToRefs(marshalledResult2);
|
|
459
|
+
return JSON.stringify({ ok: true, value: processedResult });
|
|
460
|
+
}
|
|
461
|
+
const marshalledResult = await marshalValue(result);
|
|
462
|
+
return JSON.stringify({ ok: true, value: marshalledResult });
|
|
463
|
+
} catch (error) {
|
|
464
|
+
const err = error;
|
|
465
|
+
return JSON.stringify({
|
|
466
|
+
ok: false,
|
|
467
|
+
error: { message: err.message, name: err.name }
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
global.setSync("__customFn_invoke", invokeCallbackRef);
|
|
472
|
+
context.evalSync(ISOLATE_MARSHAL_CODE);
|
|
473
|
+
for (const name of Object.keys(customFunctions)) {
|
|
474
|
+
const def = customFunctions[name];
|
|
475
|
+
if (def.type === "async") {
|
|
476
|
+
context.evalSync(`
|
|
477
|
+
globalThis.${name} = async function(...args) {
|
|
478
|
+
const marshalledArgs = __marshalForHost(args);
|
|
479
|
+
const resultJson = await __customFn_invoke.apply(
|
|
480
|
+
undefined,
|
|
481
|
+
["${name}", JSON.stringify(marshalledArgs)],
|
|
482
|
+
{ result: { promise: true, copy: true } }
|
|
483
|
+
);
|
|
484
|
+
const result = JSON.parse(resultJson);
|
|
485
|
+
if (result.ok) {
|
|
486
|
+
return __unmarshalFromHost(result.value);
|
|
487
|
+
}
|
|
488
|
+
const error = new Error(result.error.message);
|
|
489
|
+
error.name = result.error.name;
|
|
490
|
+
throw error;
|
|
491
|
+
};
|
|
492
|
+
`);
|
|
493
|
+
} else if (def.type === "sync") {
|
|
494
|
+
context.evalSync(`
|
|
495
|
+
globalThis.${name} = function(...args) {
|
|
496
|
+
const marshalledArgs = __marshalForHost(args);
|
|
497
|
+
const resultJson = __customFn_invoke.applySync(
|
|
498
|
+
undefined,
|
|
499
|
+
["${name}", JSON.stringify(marshalledArgs)],
|
|
500
|
+
{ result: { copy: true } }
|
|
501
|
+
);
|
|
502
|
+
const result = JSON.parse(resultJson);
|
|
503
|
+
if (result.ok) {
|
|
504
|
+
return __unmarshalFromHost(result.value);
|
|
505
|
+
}
|
|
506
|
+
const error = new Error(result.error.message);
|
|
507
|
+
error.name = result.error.name;
|
|
508
|
+
throw error;
|
|
509
|
+
};
|
|
510
|
+
`);
|
|
511
|
+
} else if (def.type === "asyncIterator") {
|
|
512
|
+
context.evalSync(`
|
|
513
|
+
globalThis.${name} = function(...args) {
|
|
514
|
+
const marshalledArgs = __marshalForHost(args);
|
|
515
|
+
const iteratorPromise = (async () => {
|
|
516
|
+
const resultJson = await __customFn_invoke.apply(
|
|
517
|
+
undefined,
|
|
518
|
+
["${name}", JSON.stringify(marshalledArgs)],
|
|
519
|
+
{ result: { promise: true, copy: true } }
|
|
520
|
+
);
|
|
521
|
+
const result = JSON.parse(resultJson);
|
|
522
|
+
if (result.ok) {
|
|
523
|
+
return __unmarshalFromHost(result.value);
|
|
524
|
+
}
|
|
525
|
+
throw Object.assign(new Error(result.error.message), {
|
|
526
|
+
name: result.error.name,
|
|
527
|
+
});
|
|
528
|
+
})();
|
|
529
|
+
return {
|
|
530
|
+
[Symbol.asyncIterator]() { return this; },
|
|
531
|
+
async next() {
|
|
532
|
+
const iterator = await iteratorPromise;
|
|
533
|
+
return iterator.next();
|
|
534
|
+
},
|
|
535
|
+
async return(v) {
|
|
536
|
+
const iterator = await iteratorPromise;
|
|
537
|
+
return iterator.return ? iterator.return(v) : { done: true, value: v };
|
|
538
|
+
},
|
|
539
|
+
async throw(e) {
|
|
540
|
+
const iterator = await iteratorPromise;
|
|
541
|
+
if (!iterator.throw) {
|
|
542
|
+
throw e;
|
|
543
|
+
}
|
|
544
|
+
return iterator.throw(e);
|
|
545
|
+
}
|
|
546
|
+
};
|
|
547
|
+
};
|
|
548
|
+
`);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
return invokeCallbackRef;
|
|
552
|
+
}
|
|
553
|
+
function createLocalCustomFunctionsMarshalOptions() {
|
|
554
|
+
const returnedCallbacks = new Map;
|
|
555
|
+
const returnedPromises = new Map;
|
|
556
|
+
const returnedIterators = new Map;
|
|
557
|
+
let nextLocalCallbackId = 1e6;
|
|
558
|
+
const createMarshalContext = () => ({
|
|
559
|
+
registerCallback: (fn) => {
|
|
560
|
+
const callbackId = nextLocalCallbackId++;
|
|
561
|
+
returnedCallbacks.set(callbackId, fn);
|
|
562
|
+
return callbackId;
|
|
563
|
+
},
|
|
564
|
+
registerPromise: (promise) => {
|
|
565
|
+
const promiseId = nextLocalCallbackId++;
|
|
566
|
+
returnedPromises.set(promiseId, promise);
|
|
567
|
+
return promiseId;
|
|
568
|
+
},
|
|
569
|
+
registerIterator: (iterator) => {
|
|
570
|
+
const iteratorId = nextLocalCallbackId++;
|
|
571
|
+
returnedIterators.set(iteratorId, iterator);
|
|
572
|
+
return iteratorId;
|
|
573
|
+
}
|
|
574
|
+
});
|
|
575
|
+
const isPromiseRef = (value) => typeof value === "object" && value !== null && value.__type === "PromiseRef";
|
|
576
|
+
const isAsyncIteratorRef = (value) => typeof value === "object" && value !== null && value.__type === "AsyncIteratorRef";
|
|
577
|
+
const addCallbackIdsToRefs = (value) => {
|
|
578
|
+
if (value === null || typeof value !== "object")
|
|
579
|
+
return value;
|
|
580
|
+
if (isPromiseRef(value)) {
|
|
581
|
+
if ("__resolveCallbackId" in value)
|
|
582
|
+
return value;
|
|
583
|
+
const resolveCallbackId = nextLocalCallbackId++;
|
|
584
|
+
returnedCallbacks.set(resolveCallbackId, async (promiseId) => {
|
|
585
|
+
const promise = returnedPromises.get(promiseId);
|
|
586
|
+
if (!promise) {
|
|
587
|
+
throw new Error(`Promise ${promiseId} not found`);
|
|
588
|
+
}
|
|
589
|
+
const result2 = await promise;
|
|
590
|
+
returnedPromises.delete(promiseId);
|
|
591
|
+
const ctx = createMarshalContext();
|
|
592
|
+
const marshalled = await marshalValue(result2, ctx);
|
|
593
|
+
return addCallbackIdsToRefs(marshalled);
|
|
594
|
+
});
|
|
595
|
+
return { ...value, __resolveCallbackId: resolveCallbackId };
|
|
596
|
+
}
|
|
597
|
+
if (isAsyncIteratorRef(value)) {
|
|
598
|
+
if ("__nextCallbackId" in value)
|
|
599
|
+
return value;
|
|
600
|
+
const nextCallbackId = nextLocalCallbackId++;
|
|
601
|
+
returnedCallbacks.set(nextCallbackId, async (iteratorId) => {
|
|
602
|
+
const iterator = returnedIterators.get(iteratorId);
|
|
603
|
+
if (!iterator) {
|
|
604
|
+
throw new Error(`Iterator ${iteratorId} not found`);
|
|
605
|
+
}
|
|
606
|
+
const result2 = await iterator.next();
|
|
607
|
+
if (result2.done) {
|
|
608
|
+
returnedIterators.delete(iteratorId);
|
|
609
|
+
}
|
|
610
|
+
const ctx = createMarshalContext();
|
|
611
|
+
const marshalledValue = await marshalValue(result2.value, ctx);
|
|
612
|
+
return {
|
|
613
|
+
done: result2.done,
|
|
614
|
+
value: addCallbackIdsToRefs(marshalledValue)
|
|
615
|
+
};
|
|
616
|
+
});
|
|
617
|
+
const returnCallbackId = nextLocalCallbackId++;
|
|
618
|
+
returnedCallbacks.set(returnCallbackId, async (iteratorId, returnValue) => {
|
|
619
|
+
const iterator = returnedIterators.get(iteratorId);
|
|
620
|
+
returnedIterators.delete(iteratorId);
|
|
621
|
+
if (!iterator || !iterator.return) {
|
|
622
|
+
return { done: true, value: undefined };
|
|
623
|
+
}
|
|
624
|
+
const result2 = await iterator.return(returnValue);
|
|
625
|
+
const ctx = createMarshalContext();
|
|
626
|
+
const marshalledValue = await marshalValue(result2.value, ctx);
|
|
627
|
+
return {
|
|
628
|
+
done: true,
|
|
629
|
+
value: addCallbackIdsToRefs(marshalledValue)
|
|
630
|
+
};
|
|
631
|
+
});
|
|
632
|
+
const throwCallbackId = nextLocalCallbackId++;
|
|
633
|
+
returnedCallbacks.set(throwCallbackId, async (iteratorId, errorValue) => {
|
|
634
|
+
const iterator = returnedIterators.get(iteratorId);
|
|
635
|
+
if (!iterator) {
|
|
636
|
+
throw new Error(`Iterator ${iteratorId} not found`);
|
|
637
|
+
}
|
|
638
|
+
try {
|
|
639
|
+
if (!iterator.throw) {
|
|
640
|
+
throw Object.assign(new Error(errorValue?.message ?? "Iterator does not support throw()"), { name: errorValue?.name ?? "Error", stack: errorValue?.stack });
|
|
641
|
+
}
|
|
642
|
+
const thrownError = Object.assign(new Error(errorValue?.message ?? "Iterator throw()"), { name: errorValue?.name ?? "Error", stack: errorValue?.stack });
|
|
643
|
+
const result2 = await iterator.throw(thrownError);
|
|
644
|
+
if (result2.done) {
|
|
645
|
+
returnedIterators.delete(iteratorId);
|
|
646
|
+
}
|
|
647
|
+
const ctx = createMarshalContext();
|
|
648
|
+
const marshalledValue = await marshalValue(result2.value, ctx);
|
|
649
|
+
return {
|
|
650
|
+
done: result2.done,
|
|
651
|
+
value: addCallbackIdsToRefs(marshalledValue)
|
|
652
|
+
};
|
|
653
|
+
} catch (error) {
|
|
654
|
+
returnedIterators.delete(iteratorId);
|
|
655
|
+
throw error;
|
|
656
|
+
}
|
|
657
|
+
});
|
|
658
|
+
return {
|
|
659
|
+
...value,
|
|
660
|
+
__nextCallbackId: nextCallbackId,
|
|
661
|
+
__returnCallbackId: returnCallbackId,
|
|
662
|
+
__throwCallbackId: throwCallbackId
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
if (Array.isArray(value)) {
|
|
666
|
+
return value.map((item) => addCallbackIdsToRefs(item));
|
|
667
|
+
}
|
|
668
|
+
const result = {};
|
|
669
|
+
for (const key of Object.keys(value)) {
|
|
670
|
+
result[key] = addCallbackIdsToRefs(value[key]);
|
|
671
|
+
}
|
|
672
|
+
return result;
|
|
673
|
+
};
|
|
674
|
+
const invokeCallback = async (callbackId, args) => {
|
|
675
|
+
const callback = returnedCallbacks.get(callbackId);
|
|
676
|
+
if (!callback) {
|
|
677
|
+
throw new Error(`Local callback ${callbackId} not found`);
|
|
678
|
+
}
|
|
679
|
+
return await callback(...args);
|
|
680
|
+
};
|
|
681
|
+
return { createMarshalContext, addCallbackIdsToRefs, invokeCallback };
|
|
682
|
+
}
|
|
683
|
+
function createModuleResolver(state) {
|
|
684
|
+
return async (specifier, referrer) => {
|
|
685
|
+
const importerPath = state.moduleToFilename.get(referrer) ?? "<unknown>";
|
|
686
|
+
const importerResolveDir = path.posix.dirname(importerPath);
|
|
687
|
+
const importerStack = state.moduleImportChain.get(importerPath) ?? [];
|
|
688
|
+
const resolvedSpecifier = specifier.startsWith(".") ? path.posix.normalize(path.posix.join(importerResolveDir, specifier)) : specifier;
|
|
689
|
+
state.specifierToImporter.set(resolvedSpecifier, importerPath);
|
|
690
|
+
const staticCached = state.staticModuleCache.get(resolvedSpecifier);
|
|
691
|
+
if (staticCached)
|
|
692
|
+
return staticCached;
|
|
693
|
+
const cached = state.moduleCache.get(resolvedSpecifier);
|
|
694
|
+
if (cached)
|
|
695
|
+
return cached;
|
|
696
|
+
if (!state.moduleLoader) {
|
|
697
|
+
throw new Error(`No module loader registered. Cannot import: ${specifier}`);
|
|
698
|
+
}
|
|
699
|
+
const result = await state.moduleLoader(specifier, {
|
|
700
|
+
path: importerPath,
|
|
701
|
+
resolveDir: importerResolveDir
|
|
702
|
+
});
|
|
703
|
+
const { code, resolveDir } = result;
|
|
704
|
+
if (result.filename.includes("/")) {
|
|
705
|
+
throw new Error(`moduleLoader returned a filename with slashes: "${result.filename}". ` + `filename must be a basename (e.g. "utils.js"), not a path.`);
|
|
706
|
+
}
|
|
707
|
+
const resolvedFilename = path.posix.join(resolveDir, result.filename);
|
|
708
|
+
const hash = contentHash(code);
|
|
709
|
+
const cacheKey = `${resolvedSpecifier}:${hash}`;
|
|
710
|
+
const inFlightKey = `${result.static ? "static" : "dynamic"}:${cacheKey}`;
|
|
711
|
+
const staticCachedAfterLoad = state.staticModuleCache.get(resolvedSpecifier);
|
|
712
|
+
if (staticCachedAfterLoad)
|
|
713
|
+
return staticCachedAfterLoad;
|
|
714
|
+
const cachedAfterLoad = state.moduleCache.get(resolvedSpecifier);
|
|
715
|
+
if (cachedAfterLoad)
|
|
716
|
+
return cachedAfterLoad;
|
|
717
|
+
const hashCached = state.moduleCache.get(cacheKey);
|
|
718
|
+
if (hashCached)
|
|
719
|
+
return hashCached;
|
|
720
|
+
const inFlight = state.moduleLoadsInFlight.get(inFlightKey);
|
|
721
|
+
if (inFlight)
|
|
722
|
+
return inFlight;
|
|
723
|
+
const loadPromise = (async () => {
|
|
724
|
+
let mod;
|
|
725
|
+
try {
|
|
726
|
+
let transformed = state.transformCache.get(hash);
|
|
727
|
+
if (!transformed) {
|
|
728
|
+
transformed = await transformModuleCode(code, resolvedSpecifier);
|
|
729
|
+
state.transformCache.set(hash, transformed);
|
|
730
|
+
}
|
|
731
|
+
if (transformed.sourceMap) {
|
|
732
|
+
state.sourceMaps.set(resolvedSpecifier, transformed.sourceMap);
|
|
733
|
+
}
|
|
734
|
+
mod = await state.isolate.compileModule(transformed.code, {
|
|
735
|
+
filename: resolvedSpecifier
|
|
736
|
+
});
|
|
737
|
+
state.moduleToFilename.set(mod, resolvedFilename);
|
|
738
|
+
state.moduleImportChain.set(resolvedFilename, [...importerStack, importerPath]);
|
|
739
|
+
if (result.static) {
|
|
740
|
+
state.staticModuleCache.set(resolvedSpecifier, mod);
|
|
741
|
+
} else {
|
|
742
|
+
state.moduleCache.set(resolvedSpecifier, mod);
|
|
743
|
+
state.moduleCache.set(cacheKey, mod);
|
|
744
|
+
}
|
|
745
|
+
return mod;
|
|
746
|
+
} catch (err) {
|
|
747
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
748
|
+
error.message = `Failed to compile module "${resolvedSpecifier}" (imported by "${importerPath}"):
|
|
749
|
+
${error.message}`;
|
|
750
|
+
if (importerStack.length > 0) {
|
|
751
|
+
error.message += `
|
|
752
|
+
|
|
753
|
+
Import chain:
|
|
754
|
+
${[...importerStack, importerPath].join(`
|
|
755
|
+
-> `)}`;
|
|
756
|
+
}
|
|
757
|
+
if (mod) {
|
|
758
|
+
state.moduleToFilename.delete(mod);
|
|
759
|
+
if (result.static) {
|
|
760
|
+
if (state.staticModuleCache.get(resolvedSpecifier) === mod) {
|
|
761
|
+
state.staticModuleCache.delete(resolvedSpecifier);
|
|
762
|
+
}
|
|
763
|
+
} else {
|
|
764
|
+
if (state.moduleCache.get(resolvedSpecifier) === mod) {
|
|
765
|
+
state.moduleCache.delete(resolvedSpecifier);
|
|
766
|
+
}
|
|
767
|
+
if (state.moduleCache.get(cacheKey) === mod) {
|
|
768
|
+
state.moduleCache.delete(cacheKey);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
throw error;
|
|
773
|
+
}
|
|
774
|
+
})();
|
|
775
|
+
state.moduleLoadsInFlight.set(inFlightKey, loadPromise);
|
|
776
|
+
try {
|
|
777
|
+
return await loadPromise;
|
|
778
|
+
} finally {
|
|
779
|
+
state.moduleLoadsInFlight.delete(inFlightKey);
|
|
780
|
+
}
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
function convertFetchCallback(callback) {
|
|
784
|
+
if (!callback) {
|
|
785
|
+
return {};
|
|
786
|
+
}
|
|
787
|
+
return {
|
|
788
|
+
onFetch: async (url, init) => {
|
|
789
|
+
return Promise.resolve(callback(url, init));
|
|
790
|
+
}
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
async function createRuntime(options) {
|
|
794
|
+
const opts = options ?? {};
|
|
795
|
+
const id = crypto.randomUUID();
|
|
796
|
+
const isolate = new ivm.Isolate({
|
|
797
|
+
memoryLimit: opts.memoryLimitMB
|
|
798
|
+
});
|
|
799
|
+
const context = await isolate.createContext();
|
|
800
|
+
const state = {
|
|
801
|
+
id,
|
|
802
|
+
isolate,
|
|
803
|
+
context,
|
|
804
|
+
handles: {},
|
|
805
|
+
moduleCache: new Map,
|
|
806
|
+
staticModuleCache: new Map,
|
|
807
|
+
moduleLoadsInFlight: new Map,
|
|
808
|
+
transformCache: new Map,
|
|
809
|
+
moduleToFilename: new Map,
|
|
810
|
+
sourceMaps: new Map,
|
|
811
|
+
moduleImportChain: new Map,
|
|
812
|
+
specifierToImporter: new Map,
|
|
813
|
+
pendingCallbacks: [],
|
|
814
|
+
evalChain: Promise.resolve(),
|
|
815
|
+
executionTimeout: getConfiguredExecutionTimeout(opts.executionTimeout),
|
|
816
|
+
isDisposed: false,
|
|
817
|
+
moduleLoader: opts.moduleLoader,
|
|
818
|
+
customFunctions: opts.customFunctions
|
|
819
|
+
};
|
|
820
|
+
state.handles.core = await setupCore(context);
|
|
821
|
+
state.handles.console = await setupConsole(context, opts.console);
|
|
822
|
+
state.handles.encoding = await setupEncoding(context);
|
|
823
|
+
state.handles.timers = await setupTimers(context);
|
|
824
|
+
state.handles.path = await setupPath(context, { cwd: opts.cwd });
|
|
825
|
+
state.handles.crypto = await setupCrypto(context);
|
|
826
|
+
state.handles.fetch = await setupFetch(context, convertFetchCallback(opts.fetch));
|
|
827
|
+
if (opts.fs) {
|
|
828
|
+
state.handles.fs = await setupFs(context, opts.fs);
|
|
829
|
+
}
|
|
830
|
+
if (opts.customFunctions) {
|
|
831
|
+
const customMarshalOptions = opts.customFunctionsMarshalOptions ?? createLocalCustomFunctionsMarshalOptions();
|
|
832
|
+
state.customFnInvokeRef = await setupCustomFunctions(context, opts.customFunctions, customMarshalOptions);
|
|
833
|
+
}
|
|
834
|
+
if (opts.testEnvironment) {
|
|
835
|
+
const testEnvOptions = typeof opts.testEnvironment === "object" ? opts.testEnvironment : undefined;
|
|
836
|
+
state.handles.testEnvironment = await setupTestEnvironment(context, testEnvOptions);
|
|
837
|
+
}
|
|
838
|
+
if (opts.playwright) {
|
|
839
|
+
if (!opts.playwright.handler) {
|
|
840
|
+
throw new Error("Playwright configured without handler. Provide playwright.handler in createRuntime options.");
|
|
841
|
+
}
|
|
842
|
+
let eventCallback = opts.playwright.onEvent;
|
|
843
|
+
if (opts.playwright.console && opts.console?.onEntry) {
|
|
844
|
+
const originalCallback = eventCallback;
|
|
845
|
+
const consoleHandler = opts.console.onEntry;
|
|
846
|
+
eventCallback = (event) => {
|
|
847
|
+
if (originalCallback) {
|
|
848
|
+
originalCallback(event);
|
|
849
|
+
}
|
|
850
|
+
if (event.type === "browserConsoleLog") {
|
|
851
|
+
consoleHandler({
|
|
852
|
+
type: "browserOutput",
|
|
853
|
+
level: event.level,
|
|
854
|
+
stdout: event.stdout,
|
|
855
|
+
location: event.location,
|
|
856
|
+
timestamp: event.timestamp
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
const playwrightSetupOptions = {
|
|
862
|
+
handler: opts.playwright.handler,
|
|
863
|
+
timeout: opts.playwright.timeout,
|
|
864
|
+
console: opts.playwright.console && !opts.console?.onEntry,
|
|
865
|
+
onEvent: eventCallback
|
|
866
|
+
};
|
|
867
|
+
state.handles.playwright = await setupPlaywright(context, playwrightSetupOptions);
|
|
868
|
+
}
|
|
869
|
+
const ensureRuntimeUsable = () => {
|
|
870
|
+
assertRuntimeUsable(state);
|
|
871
|
+
};
|
|
872
|
+
const fetchHandle = {
|
|
873
|
+
async dispatchRequest(request, options2) {
|
|
874
|
+
ensureRuntimeUsable();
|
|
875
|
+
if (!state.handles.fetch) {
|
|
876
|
+
throw new Error("Fetch handle not available");
|
|
877
|
+
}
|
|
878
|
+
return state.handles.fetch.dispatchRequest(request, options2);
|
|
879
|
+
},
|
|
880
|
+
getUpgradeRequest() {
|
|
881
|
+
ensureRuntimeUsable();
|
|
882
|
+
if (!state.handles.fetch) {
|
|
883
|
+
throw new Error("Fetch handle not available");
|
|
884
|
+
}
|
|
885
|
+
return state.handles.fetch.getUpgradeRequest();
|
|
886
|
+
},
|
|
887
|
+
dispatchWebSocketOpen(connectionId) {
|
|
888
|
+
ensureRuntimeUsable();
|
|
889
|
+
if (!state.handles.fetch) {
|
|
890
|
+
throw new Error("Fetch handle not available");
|
|
891
|
+
}
|
|
892
|
+
state.handles.fetch.dispatchWebSocketOpen(connectionId);
|
|
893
|
+
},
|
|
894
|
+
dispatchWebSocketMessage(connectionId, message) {
|
|
895
|
+
ensureRuntimeUsable();
|
|
896
|
+
if (!state.handles.fetch) {
|
|
897
|
+
throw new Error("Fetch handle not available");
|
|
898
|
+
}
|
|
899
|
+
state.handles.fetch.dispatchWebSocketMessage(connectionId, message);
|
|
900
|
+
},
|
|
901
|
+
dispatchWebSocketClose(connectionId, code, reason) {
|
|
902
|
+
ensureRuntimeUsable();
|
|
903
|
+
if (!state.handles.fetch) {
|
|
904
|
+
throw new Error("Fetch handle not available");
|
|
905
|
+
}
|
|
906
|
+
state.handles.fetch.dispatchWebSocketClose(connectionId, code, reason);
|
|
907
|
+
},
|
|
908
|
+
dispatchWebSocketError(connectionId, error) {
|
|
909
|
+
ensureRuntimeUsable();
|
|
910
|
+
if (!state.handles.fetch) {
|
|
911
|
+
throw new Error("Fetch handle not available");
|
|
912
|
+
}
|
|
913
|
+
state.handles.fetch.dispatchWebSocketError(connectionId, error);
|
|
914
|
+
},
|
|
915
|
+
onWebSocketCommand(callback) {
|
|
916
|
+
ensureRuntimeUsable();
|
|
917
|
+
if (!state.handles.fetch) {
|
|
918
|
+
throw new Error("Fetch handle not available");
|
|
919
|
+
}
|
|
920
|
+
return state.handles.fetch.onWebSocketCommand(callback);
|
|
921
|
+
},
|
|
922
|
+
hasServeHandler() {
|
|
923
|
+
ensureRuntimeUsable();
|
|
924
|
+
if (!state.handles.fetch) {
|
|
925
|
+
throw new Error("Fetch handle not available");
|
|
926
|
+
}
|
|
927
|
+
return state.handles.fetch.hasServeHandler();
|
|
928
|
+
},
|
|
929
|
+
hasActiveConnections() {
|
|
930
|
+
ensureRuntimeUsable();
|
|
931
|
+
if (!state.handles.fetch) {
|
|
932
|
+
throw new Error("Fetch handle not available");
|
|
933
|
+
}
|
|
934
|
+
return state.handles.fetch.hasActiveConnections();
|
|
935
|
+
},
|
|
936
|
+
dispatchClientWebSocketOpen(socketId, protocol, extensions) {
|
|
937
|
+
ensureRuntimeUsable();
|
|
938
|
+
if (!state.handles.fetch) {
|
|
939
|
+
throw new Error("Fetch handle not available");
|
|
940
|
+
}
|
|
941
|
+
state.handles.fetch.dispatchClientWebSocketOpen(socketId, protocol, extensions);
|
|
942
|
+
},
|
|
943
|
+
dispatchClientWebSocketMessage(socketId, data) {
|
|
944
|
+
ensureRuntimeUsable();
|
|
945
|
+
if (!state.handles.fetch) {
|
|
946
|
+
throw new Error("Fetch handle not available");
|
|
947
|
+
}
|
|
948
|
+
state.handles.fetch.dispatchClientWebSocketMessage(socketId, data);
|
|
949
|
+
},
|
|
950
|
+
dispatchClientWebSocketClose(socketId, code, reason, wasClean) {
|
|
951
|
+
ensureRuntimeUsable();
|
|
952
|
+
if (!state.handles.fetch) {
|
|
953
|
+
throw new Error("Fetch handle not available");
|
|
954
|
+
}
|
|
955
|
+
state.handles.fetch.dispatchClientWebSocketClose(socketId, code, reason, wasClean);
|
|
956
|
+
},
|
|
957
|
+
dispatchClientWebSocketError(socketId) {
|
|
958
|
+
ensureRuntimeUsable();
|
|
959
|
+
if (!state.handles.fetch) {
|
|
960
|
+
throw new Error("Fetch handle not available");
|
|
961
|
+
}
|
|
962
|
+
state.handles.fetch.dispatchClientWebSocketError(socketId);
|
|
963
|
+
},
|
|
964
|
+
onClientWebSocketCommand(callback) {
|
|
965
|
+
ensureRuntimeUsable();
|
|
966
|
+
if (!state.handles.fetch) {
|
|
967
|
+
throw new Error("Fetch handle not available");
|
|
968
|
+
}
|
|
969
|
+
return state.handles.fetch.onClientWebSocketCommand(callback);
|
|
970
|
+
},
|
|
971
|
+
onEvent(callback) {
|
|
972
|
+
ensureRuntimeUsable();
|
|
973
|
+
if (!state.handles.fetch) {
|
|
974
|
+
throw new Error("Fetch handle not available");
|
|
975
|
+
}
|
|
976
|
+
return state.handles.fetch.onEvent(callback);
|
|
977
|
+
},
|
|
978
|
+
dispatchEvent(event, payload) {
|
|
979
|
+
ensureRuntimeUsable();
|
|
980
|
+
if (!state.handles.fetch) {
|
|
981
|
+
throw new Error("Fetch handle not available");
|
|
982
|
+
}
|
|
983
|
+
state.handles.fetch.dispatchEvent(event, payload);
|
|
984
|
+
}
|
|
985
|
+
};
|
|
986
|
+
const timersHandle = {
|
|
987
|
+
clearAll() {
|
|
988
|
+
ensureRuntimeUsable();
|
|
989
|
+
state.handles.timers?.clearAll();
|
|
990
|
+
}
|
|
991
|
+
};
|
|
992
|
+
const consoleHandle = {
|
|
993
|
+
reset() {
|
|
994
|
+
ensureRuntimeUsable();
|
|
995
|
+
state.handles.console?.reset();
|
|
996
|
+
},
|
|
997
|
+
getTimers() {
|
|
998
|
+
ensureRuntimeUsable();
|
|
999
|
+
return state.handles.console?.getTimers() ?? new Map;
|
|
1000
|
+
},
|
|
1001
|
+
getCounters() {
|
|
1002
|
+
ensureRuntimeUsable();
|
|
1003
|
+
return state.handles.console?.getCounters() ?? new Map;
|
|
1004
|
+
},
|
|
1005
|
+
getGroupDepth() {
|
|
1006
|
+
ensureRuntimeUsable();
|
|
1007
|
+
return state.handles.console?.getGroupDepth() ?? 0;
|
|
1008
|
+
}
|
|
1009
|
+
};
|
|
1010
|
+
const testEnvironmentHandle = {
|
|
1011
|
+
async runTests(timeout) {
|
|
1012
|
+
ensureRuntimeUsable();
|
|
1013
|
+
if (!state.handles.testEnvironment) {
|
|
1014
|
+
throw new Error("Test environment not enabled. Set testEnvironment: true in createRuntime options.");
|
|
1015
|
+
}
|
|
1016
|
+
const executionTimeout = timeout ?? state.executionTimeout;
|
|
1017
|
+
return runWithExecutionTimeout(state, executionTimeout, "Test", async () => {
|
|
1018
|
+
return runTestsInContext(state.context);
|
|
1019
|
+
});
|
|
1020
|
+
},
|
|
1021
|
+
hasTests() {
|
|
1022
|
+
ensureRuntimeUsable();
|
|
1023
|
+
if (!state.handles.testEnvironment) {
|
|
1024
|
+
throw new Error("Test environment not enabled. Set testEnvironment: true in createRuntime options.");
|
|
1025
|
+
}
|
|
1026
|
+
return hasTestsInContext(state.context);
|
|
1027
|
+
},
|
|
1028
|
+
getTestCount() {
|
|
1029
|
+
ensureRuntimeUsable();
|
|
1030
|
+
if (!state.handles.testEnvironment) {
|
|
1031
|
+
throw new Error("Test environment not enabled. Set testEnvironment: true in createRuntime options.");
|
|
1032
|
+
}
|
|
1033
|
+
return getTestCountInContext(state.context);
|
|
1034
|
+
},
|
|
1035
|
+
reset() {
|
|
1036
|
+
ensureRuntimeUsable();
|
|
1037
|
+
state.handles.testEnvironment?.dispose();
|
|
1038
|
+
}
|
|
1039
|
+
};
|
|
1040
|
+
const playwrightHandle = {
|
|
1041
|
+
getCollectedData() {
|
|
1042
|
+
ensureRuntimeUsable();
|
|
1043
|
+
if (!state.handles.playwright) {
|
|
1044
|
+
throw new Error("Playwright not configured. Provide playwright.handler in createRuntime options.");
|
|
1045
|
+
}
|
|
1046
|
+
return {
|
|
1047
|
+
browserConsoleLogs: state.handles.playwright.getBrowserConsoleLogs(),
|
|
1048
|
+
pageErrors: state.handles.playwright.getPageErrors(),
|
|
1049
|
+
networkRequests: state.handles.playwright.getNetworkRequests(),
|
|
1050
|
+
networkResponses: state.handles.playwright.getNetworkResponses(),
|
|
1051
|
+
requestFailures: state.handles.playwright.getRequestFailures()
|
|
1052
|
+
};
|
|
1053
|
+
},
|
|
1054
|
+
clearCollectedData() {
|
|
1055
|
+
ensureRuntimeUsable();
|
|
1056
|
+
state.handles.playwright?.clearCollected();
|
|
1057
|
+
}
|
|
1058
|
+
};
|
|
1059
|
+
return {
|
|
1060
|
+
id,
|
|
1061
|
+
pendingCallbacks: state.pendingCallbacks,
|
|
1062
|
+
fetch: fetchHandle,
|
|
1063
|
+
timers: timersHandle,
|
|
1064
|
+
console: consoleHandle,
|
|
1065
|
+
testEnvironment: testEnvironmentHandle,
|
|
1066
|
+
playwright: playwrightHandle,
|
|
1067
|
+
async eval(code, filenameOrOptions) {
|
|
1068
|
+
const options2 = typeof filenameOrOptions === "string" ? { filename: filenameOrOptions } : filenameOrOptions;
|
|
1069
|
+
const executionTimeout = options2?.executionTimeout ?? state.executionTimeout;
|
|
1070
|
+
const runEval = async () => {
|
|
1071
|
+
assertRuntimeUsable(state);
|
|
1072
|
+
const filename = normalizeEntryFilename(options2?.filename);
|
|
1073
|
+
try {
|
|
1074
|
+
await runWithExecutionTimeout(state, executionTimeout, "Execution", async () => {
|
|
1075
|
+
const transformed = await transformEntryCode(code, filename);
|
|
1076
|
+
if (transformed.sourceMap) {
|
|
1077
|
+
state.sourceMaps.set(filename, transformed.sourceMap);
|
|
1078
|
+
}
|
|
1079
|
+
const mod = await state.isolate.compileModule(transformed.code, {
|
|
1080
|
+
filename
|
|
1081
|
+
});
|
|
1082
|
+
state.moduleToFilename.set(mod, filename);
|
|
1083
|
+
state.moduleImportChain.set(filename, []);
|
|
1084
|
+
const resolver = createModuleResolver(state);
|
|
1085
|
+
try {
|
|
1086
|
+
await mod.instantiate(state.context, resolver);
|
|
1087
|
+
} catch (err) {
|
|
1088
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1089
|
+
const specifierMatch = error.message.match(/The requested module '([^']+)'/);
|
|
1090
|
+
const exportMatch = error.message.match(/export named '([^']+)'/);
|
|
1091
|
+
const failingSpecifier = specifierMatch?.[1];
|
|
1092
|
+
const failingExport = exportMatch?.[1];
|
|
1093
|
+
const importerFile = failingSpecifier ? state.specifierToImporter.get(failingSpecifier) : undefined;
|
|
1094
|
+
const details = [];
|
|
1095
|
+
if (importerFile) {
|
|
1096
|
+
const chain = state.moduleImportChain.get(importerFile) ?? [];
|
|
1097
|
+
const fullChain = [...chain, importerFile];
|
|
1098
|
+
if (failingSpecifier)
|
|
1099
|
+
fullChain.push(failingSpecifier);
|
|
1100
|
+
const trimmed = fullChain.length > 12 ? fullChain.slice(-12) : fullChain;
|
|
1101
|
+
const prefix = fullChain.length > 12 ? ` ...
|
|
1102
|
+
` : "";
|
|
1103
|
+
details.push(`Import chain:
|
|
1104
|
+
${prefix}${trimmed.map((p) => ` ${p}`).join(`
|
|
1105
|
+
-> `)}`);
|
|
1106
|
+
} else if (failingSpecifier) {
|
|
1107
|
+
for (const [modPath, chain] of state.moduleImportChain) {
|
|
1108
|
+
if (modPath.includes(failingSpecifier) || modPath.endsWith(failingSpecifier)) {
|
|
1109
|
+
const fullChain = [...chain, modPath];
|
|
1110
|
+
const trimmed = fullChain.length > 12 ? fullChain.slice(-12) : fullChain;
|
|
1111
|
+
details.push(`Import chain:
|
|
1112
|
+
${trimmed.map((p) => ` ${p}`).join(`
|
|
1113
|
+
-> `)}`);
|
|
1114
|
+
break;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
if (failingExport && failingSpecifier) {
|
|
1119
|
+
details.push(`Hint: If '${failingExport}' is a TypeScript type/interface, use \`import type\` to prevent it from being resolved at runtime:
|
|
1120
|
+
` + ` import type { ${failingExport} } from '${failingSpecifier}';`);
|
|
1121
|
+
}
|
|
1122
|
+
const suffix = details.length > 0 ? `
|
|
1123
|
+
|
|
1124
|
+
` + details.join(`
|
|
1125
|
+
|
|
1126
|
+
`) : "";
|
|
1127
|
+
error.message = `Module instantiation failed: ${error.message}${suffix}`;
|
|
1128
|
+
throw error;
|
|
1129
|
+
}
|
|
1130
|
+
await mod.evaluate();
|
|
1131
|
+
const ns = mod.namespace;
|
|
1132
|
+
const runRef = await ns.get("default", { reference: true });
|
|
1133
|
+
try {
|
|
1134
|
+
await runRef.apply(undefined, [], {
|
|
1135
|
+
result: { promise: true }
|
|
1136
|
+
});
|
|
1137
|
+
} finally {
|
|
1138
|
+
runRef.release();
|
|
1139
|
+
}
|
|
1140
|
+
if (state.pendingCallbacks.length > 0) {
|
|
1141
|
+
await Promise.all(state.pendingCallbacks);
|
|
1142
|
+
state.pendingCallbacks.length = 0;
|
|
1143
|
+
}
|
|
1144
|
+
});
|
|
1145
|
+
} catch (err) {
|
|
1146
|
+
const error = err;
|
|
1147
|
+
if (error.stack && state.sourceMaps.size > 0) {
|
|
1148
|
+
error.stack = mapErrorStack(error.stack, state.sourceMaps);
|
|
1149
|
+
}
|
|
1150
|
+
throw error;
|
|
1151
|
+
}
|
|
1152
|
+
};
|
|
1153
|
+
const queuedEval = state.evalChain.then(runEval, runEval);
|
|
1154
|
+
state.evalChain = queuedEval.then(() => {
|
|
1155
|
+
return;
|
|
1156
|
+
}, () => {
|
|
1157
|
+
return;
|
|
1158
|
+
});
|
|
1159
|
+
return queuedEval;
|
|
1160
|
+
},
|
|
1161
|
+
clearModuleCache() {
|
|
1162
|
+
ensureRuntimeUsable();
|
|
1163
|
+
state.moduleCache.clear();
|
|
1164
|
+
state.moduleLoadsInFlight.clear();
|
|
1165
|
+
state.moduleToFilename.clear();
|
|
1166
|
+
state.moduleImportChain.clear();
|
|
1167
|
+
state.specifierToImporter.clear();
|
|
1168
|
+
state.sourceMaps.clear();
|
|
1169
|
+
},
|
|
1170
|
+
async dispose() {
|
|
1171
|
+
await disposeRuntimeState(state);
|
|
1172
|
+
}
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
export {
|
|
1176
|
+
simpleConsoleHandler,
|
|
1177
|
+
setupTimers2 as setupTimers,
|
|
1178
|
+
setupTestEnvironment2 as setupTestEnvironment,
|
|
1179
|
+
setupPlaywright2 as setupPlaywright,
|
|
1180
|
+
setupPath2 as setupPath,
|
|
1181
|
+
setupFs2 as setupFs,
|
|
1182
|
+
setupFetch2 as setupFetch,
|
|
1183
|
+
setupEncoding2 as setupEncoding,
|
|
1184
|
+
setupCrypto2 as setupCrypto,
|
|
1185
|
+
setupCore2 as setupCore,
|
|
1186
|
+
setupConsole2 as setupConsole,
|
|
1187
|
+
runTests,
|
|
1188
|
+
normalizeEntryFilename2 as normalizeEntryFilename,
|
|
1189
|
+
hasTests,
|
|
1190
|
+
getTestCount,
|
|
1191
|
+
getDefaultPlaywrightHandlerMetadata,
|
|
1192
|
+
defaultPlaywrightHandler,
|
|
1193
|
+
createRuntime,
|
|
1194
|
+
createPlaywrightHandler,
|
|
1195
|
+
createNodeFileSystemHandler
|
|
1196
|
+
};
|
|
1197
|
+
|
|
1198
|
+
//# debugId=246B42CD1F0441B264756E2164756E21
|