@ttsc/wasm 0.30.3 → 0.31.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/README.md +3 -3
- package/build/build-wasm.cjs +5 -4
- package/build/go-build-cache.cjs +347 -0
- package/build/pack-prepare.cjs +3 -2
- package/cmd/ttsc-wasm/main.go +22 -10
- package/cmd/ttsc-wasm/main_wasm.go +2 -2
- package/dist/.ttsc-wasm-build.json +138 -58
- package/dist/go.mod +7 -5
- package/dist/ttsc.wasm +2 -2
- package/go.mod +7 -5
- package/go.sum +10 -10
- package/host/api.go +34 -41
- package/host/doc.go +7 -6
- package/host/expose.go +42 -0
- package/host/fountain.go +192 -22
- package/host/host.go +10 -25
- package/host/host_native.go +3 -5
- package/host/invoke.go +133 -0
- package/host/plugin.go +37 -72
- package/host/result.go +108 -0
- package/lib/src/BootTtscWorkerTerminationError.d.ts +20 -0
- package/lib/src/BootTtscWorkerTerminationError.js +20 -0
- package/lib/src/BootTtscWorkerTerminationError.js.map +1 -1
- package/lib/src/MemFSError.d.ts +21 -2
- package/lib/src/MemFSError.js +25 -2
- package/lib/src/MemFSError.js.map +1 -1
- package/lib/src/bootTtsc.d.ts +49 -2
- package/lib/src/bootTtsc.js +89 -23
- package/lib/src/bootTtsc.js.map +1 -1
- package/lib/src/createMemFS.d.ts +45 -0
- package/lib/src/createMemFS.js +269 -66
- package/lib/src/createMemFS.js.map +1 -1
- package/lib/src/parseResult.d.ts +19 -0
- package/lib/src/parseResult.js +19 -0
- package/lib/src/parseResult.js.map +1 -1
- package/lib/src/structures/IBootResult.d.ts +20 -2
- package/lib/src/structures/IBootTtscOptions.d.ts +28 -6
- package/lib/src/structures/IFileStats.d.ts +51 -0
- package/lib/src/structures/IMemFSHost.d.ts +89 -0
- package/lib/src/structures/ITtscApi.d.ts +154 -9
- package/lib/src/structures/ITtscBuildOpts.d.ts +18 -1
- package/lib/src/structures/ITtscCompileResult.d.ts +20 -2
- package/lib/src/structures/ITtscDiagnostic.d.ts +25 -1
- package/lib/src/structures/ITtscFileQuery.d.ts +19 -1
- package/lib/src/structures/ITtscFountainDiagnosticsResult.d.ts +20 -1
- package/lib/src/structures/ITtscNodeAtPositionResult.d.ts +18 -1
- package/lib/src/structures/ITtscNodeInfo.d.ts +23 -2
- package/lib/src/structures/ITtscPluginOpts.d.ts +24 -3
- package/lib/src/structures/ITtscPositionQuery.d.ts +21 -4
- package/lib/src/structures/ITtscReleaseSnapshotResult.d.ts +22 -2
- package/lib/src/structures/ITtscResult.d.ts +31 -5
- package/lib/src/structures/ITtscSnapshotHandle.d.ts +19 -1
- package/lib/src/structures/ITtscSnapshotResult.d.ts +22 -1
- package/lib/src/structures/ITtscSnapshotsResult.d.ts +19 -1
- package/lib/src/structures/ITtscSourceFileTextResult.d.ts +19 -1
- package/lib/src/structures/ITtscSourceFilesResult.d.ts +23 -2
- package/lib/src/structures/ITtscSymbolAtPositionResult.d.ts +18 -1
- package/lib/src/structures/ITtscSymbolDeclaration.d.ts +25 -2
- package/lib/src/structures/ITtscSymbolInfo.d.ts +19 -1
- package/lib/src/structures/ITtscTransformResult.d.ts +21 -3
- package/lib/src/structures/ITtscTypeAtPositionResult.d.ts +18 -1
- package/lib/src/structures/ITtscTypeInfo.d.ts +19 -1
- package/lib/src/structures/ITtscVersion.d.ts +28 -1
- package/lib/src/structures/IWasmExecFS.d.ts +310 -0
- package/package.json +4 -2
- package/shim-vendor/shim/ast/enums_gen.go +4 -2
- package/shim-vendor/shim/ast/go.mod +5 -5
- package/shim-vendor/shim/ast/go.sum +10 -10
- package/shim-vendor/shim/ast/lint.go +1088 -20
- package/shim-vendor/shim/ast/parent.go +38 -22
- package/shim-vendor/shim/ast/safe_text.go +48 -26
- package/shim-vendor/shim/ast/shim.go +1307 -20
- package/shim-vendor/shim/ast/test/next_jsdoc_comment_location_reaches_variable_statement_test.go +51 -0
- package/shim-vendor/shim/ast/test/node_text_joins_multi_hop_qualified_name_test.go +24 -9
- package/shim-vendor/shim/ast/test/node_text_joins_one_hop_qualified_name_test.go +9 -5
- package/shim-vendor/shim/ast/test/node_text_returns_empty_for_nil_test.go +13 -5
- package/shim-vendor/shim/ast/test/node_text_returns_identifier_text_test.go +12 -5
- package/shim-vendor/shim/ast/test/node_text_skips_empty_qualified_left_test.go +35 -5
- package/shim-vendor/shim/astnav/go.mod +5 -5
- package/shim-vendor/shim/astnav/go.sum +12 -10
- package/shim-vendor/shim/astnav/shim.go +9 -0
- package/shim-vendor/shim/bundled/go.mod +7 -1
- package/shim-vendor/shim/bundled/go.sum +12 -0
- package/shim-vendor/shim/checker/enums_gen.go +4 -2
- package/shim-vendor/shim/checker/extra-shim.json +6 -0
- package/shim-vendor/shim/checker/go.mod +5 -5
- package/shim-vendor/shim/checker/go.sum +10 -10
- package/shim-vendor/shim/checker/node_builder_fields_gen.go +19 -0
- package/shim-vendor/shim/checker/shim.go +827 -114
- package/shim-vendor/shim/compiler/emit_sourcemap.go +68 -29
- package/shim-vendor/shim/compiler/emitassemble.go +36 -2
- package/shim-vendor/shim/compiler/emithook.go +13 -3
- package/shim-vendor/shim/compiler/go.mod +5 -5
- package/shim-vendor/shim/compiler/go.sum +10 -10
- package/shim-vendor/shim/compiler/incremental.go +56 -20
- package/shim-vendor/shim/compiler/resolution.go +92 -9
- package/shim-vendor/shim/core/enums_gen.go +2 -2
- package/shim-vendor/shim/core/go.mod +6 -1
- package/shim-vendor/shim/core/go.sum +10 -0
- package/shim-vendor/shim/core/modulekind.go +9 -0
- package/shim-vendor/shim/core/shim.go +157 -6
- package/shim-vendor/shim/diagnosticwriter/go.mod +10 -1
- package/shim-vendor/shim/diagnosticwriter/go.sum +20 -0
- package/shim-vendor/shim/diagnosticwriter/lint.go +188 -10
- package/shim-vendor/shim/diagnosticwriter/shim.go +14 -0
- package/shim-vendor/shim/lsp/go.mod +5 -5
- package/shim-vendor/shim/lsp/go.sum +10 -10
- package/shim-vendor/shim/lsp/shim.go +78 -2
- package/shim-vendor/shim/parser/go.mod +10 -1
- package/shim-vendor/shim/parser/go.sum +22 -0
- package/shim-vendor/shim/printer/emithost.go +46 -1
- package/shim-vendor/shim/printer/go.mod +5 -5
- package/shim-vendor/shim/printer/go.sum +10 -10
- package/shim-vendor/shim/printer/shim.go +114 -7
- package/shim-vendor/shim/printer/sourcemap.go +55 -0
- package/shim-vendor/shim/scanner/go.mod +10 -1
- package/shim-vendor/shim/scanner/go.sum +20 -0
- package/shim-vendor/shim/scanner/regexp.go +19 -4
- package/shim-vendor/shim/scanner/shim.go +3 -0
- package/shim-vendor/shim/stringutil/extra-shim.json +1 -0
- package/shim-vendor/shim/stringutil/go.mod +5 -0
- package/shim-vendor/shim/stringutil/go.sum +2 -0
- package/shim-vendor/shim/stringutil/shim.go +119 -0
- package/shim-vendor/shim/transformers/go.mod +5 -5
- package/shim-vendor/shim/transformers/go.sum +12 -10
- package/shim-vendor/shim/transformers/shim.go +12 -3
- package/shim-vendor/shim/tsoptions/command_line_raw.go +44 -0
- package/shim-vendor/shim/tsoptions/go.mod +10 -1
- package/shim-vendor/shim/tsoptions/go.sum +22 -0
- package/shim-vendor/shim/tsoptions/shim.go +1 -1
- package/shim-vendor/shim/tspath/go.mod +1 -1
- package/shim-vendor/shim/tspath/go.sum +6 -0
- package/shim-vendor/shim/vfs/cachedvfs/go.mod +3 -1
- package/shim-vendor/shim/vfs/cachedvfs/go.sum +12 -0
- package/shim-vendor/shim/vfs/decode.go +26 -0
- package/shim-vendor/shim/vfs/decode_test.go +42 -0
- package/shim-vendor/shim/vfs/go.mod +7 -1
- package/shim-vendor/shim/vfs/go.sum +12 -0
- package/shim-vendor/shim/vfs/osvfs/go.mod +7 -1
- package/shim-vendor/shim/vfs/osvfs/go.sum +12 -0
- package/src/BootTtscWorkerTerminationError.ts +22 -0
- package/src/MemFSError.ts +29 -2
- package/src/bootTtsc.ts +104 -28
- package/src/createMemFS.ts +291 -64
- package/src/parseResult.ts +19 -0
- package/src/structures/IBootResult.ts +21 -2
- package/src/structures/IBootTtscOptions.ts +32 -6
- package/src/structures/IFileStats.ts +65 -0
- package/src/structures/IMemFSHost.ts +97 -0
- package/src/structures/ITtscApi.ts +154 -9
- package/src/structures/ITtscBuildOpts.ts +19 -1
- package/src/structures/ITtscCompileResult.ts +21 -2
- package/src/structures/ITtscDiagnostic.ts +32 -1
- package/src/structures/ITtscFileQuery.ts +19 -1
- package/src/structures/ITtscFountainDiagnosticsResult.ts +20 -1
- package/src/structures/ITtscNodeAtPositionResult.ts +18 -1
- package/src/structures/ITtscNodeInfo.ts +27 -2
- package/src/structures/ITtscPluginOpts.ts +28 -3
- package/src/structures/ITtscPositionQuery.ts +21 -4
- package/src/structures/ITtscReleaseSnapshotResult.ts +22 -2
- package/src/structures/ITtscResult.ts +34 -5
- package/src/structures/ITtscSnapshotHandle.ts +19 -1
- package/src/structures/ITtscSnapshotResult.ts +22 -1
- package/src/structures/ITtscSnapshotsResult.ts +19 -1
- package/src/structures/ITtscSourceFileTextResult.ts +19 -1
- package/src/structures/ITtscSourceFilesResult.ts +23 -2
- package/src/structures/ITtscSymbolAtPositionResult.ts +18 -1
- package/src/structures/ITtscSymbolDeclaration.ts +27 -2
- package/src/structures/ITtscSymbolInfo.ts +23 -1
- package/src/structures/ITtscTransformResult.ts +22 -3
- package/src/structures/ITtscTypeAtPositionResult.ts +18 -1
- package/src/structures/ITtscTypeInfo.ts +20 -1
- package/src/structures/ITtscVersion.ts +33 -1
- package/src/structures/IWasmExecFS.ts +336 -0
package/src/MemFSError.ts
CHANGED
|
@@ -3,14 +3,37 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Matches the shape of `NodeJS.ErrnoException` so Go's `os` package interprets
|
|
5
5
|
* it as a proper `os.PathError` with a numeric error code. Thrown by the MemFS
|
|
6
|
-
* implementation
|
|
7
|
-
*
|
|
6
|
+
* implementation for rejected virtual filesystem operations.
|
|
7
|
+
*
|
|
8
|
+
* @evidence contracts/common.md#principled-implementation
|
|
9
|
+
* Error fields follow NodeJS.ErrnoException and Go's js/wasm filesystem bridge;
|
|
10
|
+
* numeric errno values describe that virtual ABI, not the browser host OS.
|
|
11
|
+
* @evidence contracts/common.md#clear-and-simple-design
|
|
12
|
+
* The Error subclass groups the bridge's machine fields with its message;
|
|
13
|
+
* one private mapping owns errno translation for every virtual operation.
|
|
14
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts
|
|
15
|
+
* POSIX error identifiers are protocol constants; failed operations remain
|
|
16
|
+
* errors instead of returning a fake successful callback value.
|
|
17
|
+
* @evidence contracts/common.md#meaningful-documentation
|
|
18
|
+
* Native JSDoc explains the bridge and members' machine-readable roles,
|
|
19
|
+
* following the documentation skill's concrete context guidance.
|
|
20
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources MemFSError retains only its own fields and is released with the thrown error.
|
|
21
|
+
* @evidenceExclude contracts/performance.md#efficient-algorithms MemFSError maps a code with one constant switch and chooses no processing strategy.
|
|
22
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work MemFSError is an error value and coordinates no shared or repeated computation.
|
|
8
23
|
*/
|
|
9
24
|
export class MemFSError extends Error {
|
|
25
|
+
/** POSIX symbolic error, consumed by the Go bridge. */
|
|
10
26
|
public code: string;
|
|
27
|
+
|
|
28
|
+
/** Negative Linux-style errno for the virtual filesystem ABI. */
|
|
11
29
|
public errno: number;
|
|
30
|
+
|
|
31
|
+
/** Normalized virtual path, when the failing operation identifies one. */
|
|
12
32
|
public path?: string;
|
|
33
|
+
|
|
34
|
+
/** Filesystem operation that produced the error. */
|
|
13
35
|
public syscall?: string;
|
|
36
|
+
|
|
14
37
|
constructor(code: string, syscall: string, path?: string) {
|
|
15
38
|
super(`${code}: ${syscall} ${path ?? ""}`.trim());
|
|
16
39
|
this.code = code;
|
|
@@ -37,8 +60,12 @@ function errnoForCode(code: string): number {
|
|
|
37
60
|
return -21;
|
|
38
61
|
case "EINVAL":
|
|
39
62
|
return -22;
|
|
63
|
+
case "EFBIG":
|
|
64
|
+
return -27;
|
|
40
65
|
case "ESPIPE":
|
|
41
66
|
return -29;
|
|
67
|
+
case "EPIPE":
|
|
68
|
+
return -32;
|
|
42
69
|
case "ENOTEMPTY":
|
|
43
70
|
return -39;
|
|
44
71
|
default:
|
package/src/bootTtsc.ts
CHANGED
|
@@ -16,16 +16,16 @@ import type { ITtscApi } from "./structures/ITtscApi";
|
|
|
16
16
|
declare const importScripts: (...urls: string[]) => void;
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* composite key lets HMR / cache-busting query strings get a fresh boot while
|
|
24
|
-
* still single-flighting genuine concurrent duplicate calls.
|
|
19
|
+
* One boot attempt shared by every caller that names the same API and binary.
|
|
20
|
+
* `controller` cancels the shared attempt, `host` is the filesystem its runtime
|
|
21
|
+
* binds, and `wasmExecUrl` is the runtime script it loaded; a joining caller
|
|
22
|
+
* must not name a different host or script.
|
|
25
23
|
*/
|
|
26
24
|
interface BootInFlight {
|
|
27
25
|
controller: AbortController;
|
|
28
26
|
promise: Promise<IBootResult>;
|
|
27
|
+
host: IBootResult["host"];
|
|
28
|
+
wasmExecUrl: string;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
interface BootCancellationReason {
|
|
@@ -33,6 +33,14 @@ interface BootCancellationReason {
|
|
|
33
33
|
reason?: unknown;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Per-(apiName, wasmUrl) single-flight cache for boots. Keying on apiName alone
|
|
38
|
+
* would let a second call with the same apiName but a different wasmUrl
|
|
39
|
+
* silently return the cached IBootResult of the first wasm. The caller would
|
|
40
|
+
* think they booted a fresh binary while the cached one stayed in place. The
|
|
41
|
+
* composite key lets HMR / cache-busting query strings get a fresh boot while
|
|
42
|
+
* still single-flighting genuine concurrent duplicate calls.
|
|
43
|
+
*/
|
|
36
44
|
const bootsInFlight = new Map<string, BootInFlight>();
|
|
37
45
|
|
|
38
46
|
/**
|
|
@@ -46,25 +54,23 @@ const terminalBootFailuresByApiName = new Map<
|
|
|
46
54
|
>();
|
|
47
55
|
|
|
48
56
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* - "Ready"]`resolver — they would race and the second would overwrite the first,
|
|
53
|
-
* stranding the first boot's await. The chain serializes them so one boot's
|
|
54
|
-
* Go-side`Ready.Invoke()` always lands on the resolver that boot installed.
|
|
57
|
+
* Serialize boots sharing an API name because each installs the same
|
|
58
|
+
* `globalThis[apiName + "Ready"]` resolver. Serialization prevents a later
|
|
59
|
+
* attempt from overwriting the resolver before the earlier attempt settles.
|
|
55
60
|
*/
|
|
56
61
|
const bootChainByApiName = new Map<string, Promise<unknown>>();
|
|
57
62
|
|
|
58
63
|
function bootKey(apiName: string, wasmUrl: string): string {
|
|
59
|
-
return
|
|
64
|
+
return JSON.stringify([apiName, resolveWasmUrl(wasmUrl)]);
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
/**
|
|
63
|
-
* Resolve `wasmUrl` against the current
|
|
68
|
+
* Resolve `wasmUrl` against the current location before keying so that
|
|
64
69
|
* `./playground.wasm`, `/compiler/playground.wasm`, and the fully qualified
|
|
65
70
|
* absolute href all collapse to the same cache entry instead of spawning
|
|
66
|
-
* duplicate boots.
|
|
67
|
-
*
|
|
71
|
+
* duplicate boots. In environments without a location, such as Node-side tests,
|
|
72
|
+
* relative URLs use the synthetic `http://local/` base. If parsing fails, the
|
|
73
|
+
* input retains its original spelling.
|
|
68
74
|
*/
|
|
69
75
|
function resolveWasmUrl(wasmUrl: string): string {
|
|
70
76
|
try {
|
|
@@ -88,25 +94,94 @@ function resolveWasmUrl(wasmUrl: string): string {
|
|
|
88
94
|
* stop the old runtime; replace the Worker before retrying.
|
|
89
95
|
*
|
|
90
96
|
* **Single-Worker caveat.** Even with the chain, a second boot loaded into the
|
|
91
|
-
*
|
|
92
|
-
* of the first
|
|
97
|
+
* same Worker after a first boot completes will overlay its Go runtime on top
|
|
98
|
+
* of the first. `importScripts(wasmExecUrl)` rebinds `globalThis.Go`, and the
|
|
93
99
|
* first wasm's keepalive goroutine keeps running through the new runtime's
|
|
94
100
|
* js-bridge tables. The serialization is sufficient for the typical use case
|
|
95
101
|
* (one boot per Worker over the page's lifetime) but DOES NOT make a Worker
|
|
96
102
|
* safe to host two wasm instances at once. Create a fresh Worker per concurrent
|
|
97
103
|
* wasm.
|
|
104
|
+
*
|
|
105
|
+
* @evidence contracts/common.md#principled-implementation
|
|
106
|
+
* The documented Go wasm_exec bridge is installed before streaming
|
|
107
|
+
* instantiation, and Promise sharing coordinates calls that use its global
|
|
108
|
+
* readiness slot. This follows the host.Expose integration rather than
|
|
109
|
+
* inventing a second runtime protocol.
|
|
110
|
+
*
|
|
111
|
+
* @evidence contracts/common.md#clear-and-simple-design
|
|
112
|
+
* The entry owns one attempt's host and cancellation, the per-API chain owns
|
|
113
|
+
* readiness-slot serialization, and bootTtscOnce owns setup and cleanup.
|
|
114
|
+
* These separate identities are needed because duplicate calls may join,
|
|
115
|
+
* distinct binary URLs may queue, and a started runtime cannot be retried.
|
|
116
|
+
*
|
|
117
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts
|
|
118
|
+
* The ttsc default API name and Ready/Failed slots are the host protocol,
|
|
119
|
+
* not consumer or fixture matches. The attempt installs missing Go host
|
|
120
|
+
* shims and removes only its own failed installation; it does not replace an
|
|
121
|
+
* existing foreign filesystem. The documented one-runtime-per-Worker
|
|
122
|
+
* limitation is retained rather than hidden beneath retries after go.run.
|
|
123
|
+
*
|
|
124
|
+
* @evidence contracts/common.md#meaningful-documentation
|
|
125
|
+
* JSDoc explains why same-URL calls share a boot, why API-slot serialization
|
|
126
|
+
* is needed and why post-start failure requires Worker replacement. Separate
|
|
127
|
+
* paragraphs state purpose and the shared-runtime caveat under the
|
|
128
|
+
* documentation skill; option and result interfaces document cancellation
|
|
129
|
+
* and host ownership.
|
|
130
|
+
*
|
|
131
|
+
* @evidence contracts/performance.md#efficient-algorithms
|
|
132
|
+
* Cache lookup uses normalized URL length U and expected constant-time Map
|
|
133
|
+
* access; fetch/streaming compilation process the B binary bytes without a
|
|
134
|
+
* second JavaScript binary buffer. C joined callers add O(C) abort listeners,
|
|
135
|
+
* and cancellation uses events rather than a polling scan.
|
|
136
|
+
*
|
|
137
|
+
* @evidence contracts/performance.md#reuse-equivalent-work
|
|
138
|
+
* One API/normalized-URL pair shares fetch and instantiation only with the same
|
|
139
|
+
* runtime-script URL and an identical supplied host. Omitted hosts reuse the
|
|
140
|
+
* entry's actual host. Per-API Promise
|
|
141
|
+
* chains serialize access to the global readiness slot; distinct URLs are
|
|
142
|
+
* distinct boot identities. The URL must identify immutable binary content
|
|
143
|
+
* for successful-result reuse to remain valid within the Worker lifetime.
|
|
144
|
+
*
|
|
145
|
+
* @evidence contracts/performance.md#bound-retention-and-release-resources
|
|
146
|
+
* Each entry owns its controller, host and result; settlement removes joined
|
|
147
|
+
* caller listeners and internal cancellation listeners. Successful boot keys,
|
|
148
|
+
* API chain heads and terminal failures remain until Worker termination, with
|
|
149
|
+
* no fixed key or retained-byte bound. Failed pre-start entries are removed;
|
|
150
|
+
* started runtimes cannot be stopped here and require Worker replacement.
|
|
98
151
|
*/
|
|
99
152
|
export function bootTtsc(options: IBootTtscOptions): Promise<IBootResult> {
|
|
100
153
|
const apiName = options.apiName ?? "ttsc";
|
|
101
|
-
|
|
154
|
+
let wasmUrl: string;
|
|
155
|
+
let wasmExecUrl: string;
|
|
156
|
+
try {
|
|
157
|
+
wasmUrl = resolveWasmUrl(options.wasmUrl);
|
|
158
|
+
wasmExecUrl = resolveWasmUrl(
|
|
159
|
+
options.wasmExecUrl ?? defaultWasmExecUrl(wasmUrl),
|
|
160
|
+
);
|
|
161
|
+
} catch (error) {
|
|
162
|
+
return Promise.reject(error);
|
|
163
|
+
}
|
|
164
|
+
const key = bootKey(apiName, wasmUrl);
|
|
102
165
|
const terminalFailure = terminalBootFailuresByApiName.get(apiName);
|
|
103
166
|
if (terminalFailure) return Promise.reject(terminalFailure);
|
|
104
167
|
const inflight = bootsInFlight.get(key);
|
|
105
168
|
if (inflight) {
|
|
169
|
+
if (
|
|
170
|
+
(options.host !== undefined && options.host !== inflight.host) ||
|
|
171
|
+
wasmExecUrl !== inflight.wasmExecUrl
|
|
172
|
+
) {
|
|
173
|
+
return Promise.reject(
|
|
174
|
+
new Error(
|
|
175
|
+
`bootTtsc: ${apiName} is already bound to a different host or wasm_exec.js URL; use the original boot options or replace the Worker.`,
|
|
176
|
+
),
|
|
177
|
+
);
|
|
178
|
+
}
|
|
106
179
|
attachBootCancellation(inflight, options.signal);
|
|
107
180
|
return inflight.promise;
|
|
108
181
|
}
|
|
109
182
|
const controller = new AbortController();
|
|
183
|
+
const host = options.host ?? createMemFS();
|
|
184
|
+
const bootOptions = { ...options, host, wasmUrl, wasmExecUrl };
|
|
110
185
|
const prior = bootChainByApiName.get(apiName) ?? Promise.resolve();
|
|
111
186
|
const queuedCancellation = createBootCancellationPromise(
|
|
112
187
|
controller.signal,
|
|
@@ -125,7 +200,7 @@ export function bootTtsc(options: IBootTtscOptions): Promise<IBootResult> {
|
|
|
125
200
|
"waiting for an earlier boot",
|
|
126
201
|
);
|
|
127
202
|
queuedCancellation.dispose();
|
|
128
|
-
return bootTtscOnce(
|
|
203
|
+
return bootTtscOnce(bootOptions, apiName, controller.signal);
|
|
129
204
|
});
|
|
130
205
|
let entry!: BootInFlight;
|
|
131
206
|
const promise = Promise.race([queued, queuedCancellation.promise])
|
|
@@ -134,7 +209,7 @@ export function bootTtsc(options: IBootTtscOptions): Promise<IBootResult> {
|
|
|
134
209
|
throw err;
|
|
135
210
|
})
|
|
136
211
|
.finally(queuedCancellation.dispose);
|
|
137
|
-
entry = { controller, promise };
|
|
212
|
+
entry = { controller, promise, host, wasmExecUrl };
|
|
138
213
|
bootsInFlight.set(key, entry);
|
|
139
214
|
attachBootCancellation(entry, options.signal);
|
|
140
215
|
// Track the chain head for this apiName so the next boot waits on it.
|
|
@@ -195,6 +270,11 @@ async function bootTtscOnce(
|
|
|
195
270
|
};
|
|
196
271
|
|
|
197
272
|
try {
|
|
273
|
+
if (globalAny.fs !== host.fs) {
|
|
274
|
+
throw new Error(
|
|
275
|
+
"bootTtsc: globalThis.fs belongs to a different host; supply its original MemFS host or boot in a fresh Worker.",
|
|
276
|
+
);
|
|
277
|
+
}
|
|
198
278
|
throwIfBootCanceled(signal, apiName, phase);
|
|
199
279
|
// wasm_exec.js installs `globalThis.Go`. It also reads globalThis.fs at
|
|
200
280
|
// module-eval time, so this import must follow the assignment above.
|
|
@@ -416,15 +496,11 @@ function bootCancellationError(
|
|
|
416
496
|
}
|
|
417
497
|
|
|
418
498
|
/**
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
* If `wasmUrl` has no directory component, returns `"wasm_exec.js"` (same
|
|
422
|
-
* directory as the caller's base URL).
|
|
499
|
+
* Resolve the sibling runtime script using URL path semantics, dropping the
|
|
500
|
+
* binary's query and fragment so slashes in either cannot become directories.
|
|
423
501
|
*/
|
|
424
502
|
function defaultWasmExecUrl(wasmUrl: string): string {
|
|
425
|
-
|
|
426
|
-
if (slash < 0) return "wasm_exec.js";
|
|
427
|
-
return wasmUrl.slice(0, slash + 1) + "wasm_exec.js";
|
|
503
|
+
return new URL("wasm_exec.js", resolveWasmUrl(wasmUrl)).href;
|
|
428
504
|
}
|
|
429
505
|
|
|
430
506
|
/**
|