@rybosome/tspice 0.0.3 → 0.0.8
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 +145 -84
- package/backend-contract/dist/.tsbuildinfo +1 -1
- package/backend-contract/dist/domains/cells-windows.d.ts +94 -0
- package/backend-contract/dist/domains/cells-windows.js +10 -0
- package/backend-contract/dist/domains/coords-vectors.d.ts +53 -3
- package/backend-contract/dist/domains/dsk.d.ts +49 -0
- package/backend-contract/dist/domains/dsk.js +2 -0
- package/backend-contract/dist/domains/ek.d.ts +186 -0
- package/backend-contract/dist/domains/ek.js +8 -0
- package/backend-contract/dist/domains/ephemeris.d.ts +141 -3
- package/backend-contract/dist/domains/error.d.ts +42 -0
- package/backend-contract/dist/domains/error.js +33 -0
- package/backend-contract/dist/domains/file-io.d.ts +114 -0
- package/backend-contract/dist/domains/file-io.js +8 -0
- package/backend-contract/dist/domains/frames.d.ts +44 -4
- package/backend-contract/dist/domains/geometry-gf.d.ts +44 -0
- package/backend-contract/dist/domains/geometry-gf.js +14 -0
- package/backend-contract/dist/domains/geometry.d.ts +21 -1
- package/backend-contract/dist/domains/ids-names-normalize.d.ts +3 -0
- package/backend-contract/dist/domains/ids-names-normalize.js +74 -0
- package/backend-contract/dist/domains/ids-names.d.ts +37 -0
- package/backend-contract/dist/domains/kernel-pool.d.ts +134 -0
- package/backend-contract/dist/domains/kernel-pool.js +2 -0
- package/backend-contract/dist/domains/kernels-utils.d.ts +44 -0
- package/backend-contract/dist/domains/kernels-utils.js +265 -0
- package/backend-contract/dist/domains/kernels.d.ts +39 -3
- package/backend-contract/dist/domains/time.d.ts +102 -0
- package/backend-contract/dist/index.d.ts +34 -15
- package/backend-contract/dist/index.js +15 -1
- package/backend-contract/dist/shared/errors.d.ts +6 -0
- package/backend-contract/dist/shared/errors.js +8 -0
- package/backend-contract/dist/shared/mat3.d.ts +52 -0
- package/backend-contract/dist/shared/mat3.js +150 -0
- package/backend-contract/dist/shared/mat6.d.ts +34 -0
- package/backend-contract/dist/shared/mat6.js +116 -0
- package/backend-contract/dist/shared/spice-handles.d.ts +20 -0
- package/backend-contract/dist/shared/spice-handles.js +82 -0
- package/backend-contract/dist/shared/spice-int.d.ts +32 -0
- package/backend-contract/dist/shared/spice-int.js +41 -0
- package/backend-contract/dist/shared/types.d.ts +136 -5
- package/backend-contract/dist/shared/types.js +1 -1
- package/backend-contract/dist/shared/vec.d.ts +54 -0
- package/backend-contract/dist/shared/vec.js +162 -0
- package/backend-fake/dist/.tsbuildinfo +1 -1
- package/backend-fake/dist/index.d.ts +21 -1
- package/backend-fake/dist/index.js +1112 -33
- package/backend-node/dist/.tsbuildinfo +1 -1
- package/backend-node/dist/codec/arrays.d.ts +9 -0
- package/backend-node/dist/codec/arrays.js +36 -0
- package/backend-node/dist/codec/errors.d.ts +6 -6
- package/backend-node/dist/codec/errors.js +6 -6
- package/backend-node/dist/domains/cells-windows.d.ts +5 -0
- package/backend-node/dist/domains/cells-windows.js +112 -0
- package/backend-node/dist/domains/coords-vectors.d.ts +1 -0
- package/backend-node/dist/domains/coords-vectors.js +66 -0
- package/backend-node/dist/domains/dsk.d.ts +6 -0
- package/backend-node/dist/domains/dsk.js +108 -0
- package/backend-node/dist/domains/ek.d.ts +10 -0
- package/backend-node/dist/domains/ek.js +100 -0
- package/backend-node/dist/domains/ephemeris.d.ts +5 -1
- package/backend-node/dist/domains/ephemeris.js +150 -1
- package/backend-node/dist/domains/error.d.ts +5 -0
- package/backend-node/dist/domains/error.js +34 -0
- package/backend-node/dist/domains/file-io.d.ts +7 -0
- package/backend-node/dist/domains/file-io.js +105 -0
- package/backend-node/dist/domains/frames.d.ts +1 -0
- package/backend-node/dist/domains/frames.js +58 -6
- package/backend-node/dist/domains/geometry-gf.d.ts +5 -0
- package/backend-node/dist/domains/geometry-gf.js +74 -0
- package/backend-node/dist/domains/geometry.d.ts +1 -0
- package/backend-node/dist/domains/geometry.js +62 -0
- package/backend-node/dist/domains/ids-names.d.ts +2 -1
- package/backend-node/dist/domains/ids-names.js +30 -0
- package/backend-node/dist/domains/kernel-pool.d.ts +5 -0
- package/backend-node/dist/domains/kernel-pool.js +74 -0
- package/backend-node/dist/domains/kernels.d.ts +1 -0
- package/backend-node/dist/domains/kernels.js +100 -13
- package/backend-node/dist/domains/time.d.ts +1 -0
- package/backend-node/dist/domains/time.js +75 -1
- package/backend-node/dist/index.d.ts +5 -1
- package/backend-node/dist/index.js +62 -1
- package/backend-node/dist/lowlevel/binding.d.ts +3 -0
- package/backend-node/dist/lowlevel/binding.js +115 -0
- package/backend-node/dist/runtime/addon.d.ts +273 -2
- package/backend-node/dist/runtime/addon.js +3 -0
- package/backend-node/dist/runtime/kernel-staging.d.ts +17 -0
- package/backend-node/dist/runtime/kernel-staging.js +80 -7
- package/backend-node/dist/runtime/spice-handles.d.ts +3 -0
- package/backend-node/dist/runtime/spice-handles.js +2 -0
- package/backend-node/dist/runtime/virtual-output-staging.d.ts +16 -0
- package/backend-node/dist/runtime/virtual-output-staging.js +148 -0
- package/backend-wasm/dist/.tsbuildinfo +1 -1
- package/backend-wasm/dist/codec/alloc.d.ts +19 -0
- package/backend-wasm/dist/codec/alloc.js +64 -0
- package/backend-wasm/dist/codec/calls.d.ts +2 -0
- package/backend-wasm/dist/codec/calls.js +13 -24
- package/backend-wasm/dist/codec/errors.d.ts +6 -0
- package/backend-wasm/dist/codec/errors.js +34 -2
- package/backend-wasm/dist/codec/found.d.ts +2 -0
- package/backend-wasm/dist/codec/found.js +20 -43
- package/backend-wasm/dist/codec/strings.d.ts +31 -1
- package/backend-wasm/dist/codec/strings.js +93 -6
- package/backend-wasm/dist/domains/cells-windows.d.ts +9 -0
- package/backend-wasm/dist/domains/cells-windows.js +392 -0
- package/backend-wasm/dist/domains/coords-vectors.d.ts +1 -0
- package/backend-wasm/dist/domains/coords-vectors.js +377 -184
- package/backend-wasm/dist/domains/dsk.d.ts +6 -0
- package/backend-wasm/dist/domains/dsk.js +179 -0
- package/backend-wasm/dist/domains/ek.d.ts +6 -0
- package/backend-wasm/dist/domains/ek.js +543 -0
- package/backend-wasm/dist/domains/ephemeris.d.ts +4 -1
- package/backend-wasm/dist/domains/ephemeris.js +405 -46
- package/backend-wasm/dist/domains/error.d.ts +5 -0
- package/backend-wasm/dist/domains/error.js +109 -0
- package/backend-wasm/dist/domains/file-io.d.ts +7 -0
- package/backend-wasm/dist/domains/file-io.js +462 -0
- package/backend-wasm/dist/domains/frames.d.ts +1 -0
- package/backend-wasm/dist/domains/frames.js +139 -6
- package/backend-wasm/dist/domains/geometry-gf.d.ts +5 -0
- package/backend-wasm/dist/domains/geometry-gf.js +178 -0
- package/backend-wasm/dist/domains/geometry.d.ts +1 -0
- package/backend-wasm/dist/domains/geometry.js +210 -0
- package/backend-wasm/dist/domains/ids-names.d.ts +2 -1
- package/backend-wasm/dist/domains/ids-names.js +89 -0
- package/backend-wasm/dist/domains/kernel-pool.d.ts +5 -0
- package/backend-wasm/dist/domains/kernel-pool.js +357 -0
- package/backend-wasm/dist/domains/kernels.d.ts +1 -0
- package/backend-wasm/dist/domains/kernels.js +108 -4
- package/backend-wasm/dist/domains/time.d.ts +2 -0
- package/backend-wasm/dist/domains/time.js +235 -133
- package/backend-wasm/dist/index.d.ts +4 -2
- package/backend-wasm/dist/lowlevel/exports.d.ts +215 -1
- package/backend-wasm/dist/lowlevel/exports.js +217 -38
- package/backend-wasm/dist/runtime/create-backend-options.d.ts +21 -0
- package/backend-wasm/dist/runtime/create-backend.node.d.ts +11 -2
- package/backend-wasm/dist/runtime/create-backend.node.js +283 -14
- package/backend-wasm/dist/runtime/create-backend.web.d.ts +5 -2
- package/backend-wasm/dist/runtime/create-backend.web.js +40 -6
- package/backend-wasm/dist/runtime/fs.d.ts +6 -0
- package/backend-wasm/dist/runtime/fs.js +29 -3
- package/backend-wasm/dist/runtime/spice-handles.d.ts +3 -0
- package/backend-wasm/dist/runtime/spice-handles.js +2 -0
- package/backend-wasm/dist/runtime/virtual-outputs.d.ts +16 -0
- package/backend-wasm/dist/runtime/virtual-outputs.js +35 -0
- package/backend-wasm/dist/tspice_backend_wasm.node.js +3 -3
- package/backend-wasm/dist/tspice_backend_wasm.wasm +0 -0
- package/backend-wasm/dist/tspice_backend_wasm.web.js +1 -1
- package/core/dist/.tsbuildinfo +1 -1
- package/core/dist/index.d.ts +21 -0
- package/core/dist/index.js +57 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/backend.d.ts +15 -6
- package/dist/backend.js +3 -6
- package/dist/clients/createSpiceAsyncFromTransport.d.ts +5 -0
- package/dist/clients/createSpiceAsyncFromTransport.js +90 -0
- package/dist/clients/createSpiceSyncFromTransport.d.ts +5 -0
- package/dist/clients/createSpiceSyncFromTransport.js +88 -0
- package/dist/clients/spiceClients.d.ts +59 -0
- package/dist/clients/spiceClients.js +292 -0
- package/dist/errors.d.ts +4 -0
- package/dist/errors.js +4 -0
- package/dist/index.d.ts +12 -7
- package/dist/index.js +5 -2
- package/dist/kernels/defaultKernelPathFromUrl.d.ts +8 -0
- package/dist/kernels/defaultKernelPathFromUrl.js +32 -0
- package/dist/kernels/kernelPack.d.ts +88 -0
- package/dist/kernels/kernelPack.js +122 -0
- package/dist/kernels/kernels.d.ts +98 -0
- package/dist/kernels/kernels.js +217 -0
- package/dist/kernels/naifKernelId.d.ts +2 -0
- package/dist/kernels/naifKernelId.js +2 -0
- package/dist/kit/index.d.ts +4 -0
- package/dist/kit/index.js +3 -0
- package/dist/kit/math/mat3.d.ts +31 -0
- package/dist/kit/math/mat3.js +82 -0
- package/dist/kit/spice/create-kit.d.ts +12 -0
- package/dist/kit/spice/create-kit.js +23 -0
- package/dist/kit/spice/frames.d.ts +8 -0
- package/dist/kit/spice/frames.js +16 -0
- package/dist/kit/spice/kernels.d.ts +14 -0
- package/dist/kit/spice/kernels.js +39 -0
- package/dist/kit/spice/state.d.ts +7 -0
- package/dist/kit/spice/state.js +36 -0
- package/dist/kit/spice/time.d.ts +9 -0
- package/dist/kit/spice/time.js +31 -0
- package/dist/kit/types/spice-types.d.ts +51 -0
- package/dist/spice.d.ts +10 -1
- package/dist/spice.js +84 -72
- package/dist/transport/caching/policy.d.ts +16 -0
- package/dist/transport/caching/policy.js +77 -0
- package/dist/transport/caching/withCaching.d.ts +125 -0
- package/dist/transport/caching/withCaching.js +335 -0
- package/dist/transport/caching/withCachingSync.d.ts +24 -0
- package/dist/transport/caching/withCachingSync.js +161 -0
- package/dist/transport/rpc/protocol.d.ts +35 -0
- package/dist/transport/rpc/protocol.js +56 -0
- package/dist/transport/rpc/taskScheduling.d.ts +20 -0
- package/dist/transport/rpc/taskScheduling.js +98 -0
- package/dist/transport/rpc/valueCodec.d.ts +5 -0
- package/dist/transport/rpc/valueCodec.js +106 -0
- package/dist/transport/types.d.ts +7 -0
- package/dist/transport/types.js +2 -0
- package/dist/types.d.ts +8 -17
- package/dist/types.js +2 -1
- package/dist/worker/browser/createSpiceWorker.d.ts +22 -0
- package/dist/worker/browser/createSpiceWorker.js +41 -0
- package/dist/worker/browser/createSpiceWorkerClient.d.ts +40 -0
- package/dist/worker/browser/createSpiceWorkerClient.js +99 -0
- package/dist/worker/browser/spiceWorkerEntry.d.ts +2 -0
- package/dist/worker/browser/spiceWorkerEntry.js +129 -0
- package/dist/worker/browser/spiceWorkerInlineSource.d.ts +2 -0
- package/dist/worker/browser/spiceWorkerInlineSource.js +4 -0
- package/dist/worker/index.d.ts +10 -0
- package/dist/worker/index.js +7 -0
- package/dist/worker/transport/createWorkerTransport.d.ts +69 -0
- package/dist/worker/transport/createWorkerTransport.js +398 -0
- package/dist/worker/transport/exposeTransportToWorker.d.ts +51 -0
- package/dist/worker/transport/exposeTransportToWorker.js +196 -0
- package/package.json +4 -4
- package/dist/spice-types.d.ts +0 -36
- /package/dist/{spice-types.js → kit/types/spice-types.js} +0 -0
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
import { deserializeError, tspiceRpcDisposeType, tspiceRpcRequestType, tspiceRpcResponseType, } from "../../transport/rpc/protocol.js";
|
|
2
|
+
import { decodeRpcValue, encodeRpcValue } from "../../transport/rpc/valueCodec.js";
|
|
3
|
+
import { canQueueMacrotask, queueMacrotask } from "../../transport/rpc/taskScheduling.js";
|
|
4
|
+
function createAbortError() {
|
|
5
|
+
// DOMException is the most accurate in browser contexts, but isn't guaranteed
|
|
6
|
+
// to exist in all runtimes (e.g. some test environments).
|
|
7
|
+
try {
|
|
8
|
+
return new DOMException("Aborted", "AbortError");
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
const err = new Error("Aborted");
|
|
12
|
+
err.name = "AbortError";
|
|
13
|
+
return err;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function createNoMacrotaskSchedulerError() {
|
|
17
|
+
return new Error("Worker transport cannot schedule macrotask settlement (MessageChannel/setTimeout missing). " +
|
|
18
|
+
"Refusing to settle responses synchronously because it would break dispose ordering guarantees.");
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Create a `SpiceTransport` backed by a `Worker`.
|
|
22
|
+
*
|
|
23
|
+
* ## Macrotask settlement ordering
|
|
24
|
+
*
|
|
25
|
+
* Worker responses are resolved/rejected on a later macrotask (via
|
|
26
|
+
* `queueMacrotask(...)`) so that calling `dispose()` in the same tick
|
|
27
|
+
* deterministically wins.
|
|
28
|
+
*
|
|
29
|
+
* Implications:
|
|
30
|
+
* - Requests never resolve/reject on the same tick a response is received.
|
|
31
|
+
* - A response received in the current tick may be ignored if `dispose()` is
|
|
32
|
+
* called before the next tick.
|
|
33
|
+
* - If no macrotask scheduler exists in the runtime (no `MessageChannel` and no `setTimeout`),
|
|
34
|
+
* the transport fails closed by rejecting requests rather than settling synchronously.
|
|
35
|
+
*/
|
|
36
|
+
export function createWorkerTransport(opts) {
|
|
37
|
+
let worker;
|
|
38
|
+
// Retain a reference for best-effort dispose signaling even after terminal
|
|
39
|
+
// teardown clears `worker`.
|
|
40
|
+
let workerForDisposeSignal;
|
|
41
|
+
let disposed = false;
|
|
42
|
+
let terminalError;
|
|
43
|
+
// If we ever discover we can't schedule a macrotask, we permanently fail
|
|
44
|
+
// closed (reject) to avoid violating settlement ordering guarantees.
|
|
45
|
+
let canScheduleMacrotask;
|
|
46
|
+
const terminateOnDispose = opts.terminateOnDispose ?? (typeof opts.worker === "function" ? true : false);
|
|
47
|
+
const signalDispose = opts.signalDispose ?? terminateOnDispose;
|
|
48
|
+
let didSignalDispose = false;
|
|
49
|
+
const signalDisposeOnce = () => {
|
|
50
|
+
if (didSignalDispose)
|
|
51
|
+
return;
|
|
52
|
+
didSignalDispose = true;
|
|
53
|
+
if (!signalDispose)
|
|
54
|
+
return;
|
|
55
|
+
const w = worker ?? workerForDisposeSignal;
|
|
56
|
+
if (!w)
|
|
57
|
+
return;
|
|
58
|
+
try {
|
|
59
|
+
const msg = { type: tspiceRpcDisposeType };
|
|
60
|
+
w.postMessage(msg);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// ignore
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const pendingById = new Map();
|
|
67
|
+
// Requests with a received response that are awaiting next-macrotask
|
|
68
|
+
// settlement. Keeping these separate from `pendingById` lets us remove a
|
|
69
|
+
// request from the timeout/abort race immediately upon response receipt,
|
|
70
|
+
// while still allowing `dispose()` (and worker errors) to deterministically
|
|
71
|
+
// win before settlement.
|
|
72
|
+
const queuedSettlementById = new Map();
|
|
73
|
+
// Whether a single macrotask has been queued to settle all currently-queued responses.
|
|
74
|
+
let settlementQueued = false;
|
|
75
|
+
let nextId = 1;
|
|
76
|
+
const formatRequestContext = (op, id) => id === undefined ? `(op=${op})` : `(op=${op}, id=${id})`;
|
|
77
|
+
const ensureCanScheduleMacrotask = () => {
|
|
78
|
+
if (canScheduleMacrotask === undefined) {
|
|
79
|
+
// Fail fast before posting any messages if the runtime lacks a macrotask
|
|
80
|
+
// scheduler.
|
|
81
|
+
canScheduleMacrotask = canQueueMacrotask();
|
|
82
|
+
}
|
|
83
|
+
if (canScheduleMacrotask === false) {
|
|
84
|
+
throw createNoMacrotaskSchedulerError();
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const rejectAllPending = (getReason) => {
|
|
88
|
+
for (const [id, pending] of pendingById) {
|
|
89
|
+
pendingById.delete(id);
|
|
90
|
+
pending.rejectAndCleanup(getReason(pending, id));
|
|
91
|
+
}
|
|
92
|
+
// Queued settlements already ran `cleanup()` when their response was received.
|
|
93
|
+
for (const [id, settlement] of Array.from(queuedSettlementById)) {
|
|
94
|
+
queuedSettlementById.delete(id);
|
|
95
|
+
const pending = settlement.pending;
|
|
96
|
+
pending.reject(getReason(pending, id));
|
|
97
|
+
// Explicitly drop response payload references to help GC.
|
|
98
|
+
settlement.value = undefined;
|
|
99
|
+
settlement.error = undefined;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
const terminalTeardown = (err, opts) => {
|
|
103
|
+
if (terminalError)
|
|
104
|
+
return;
|
|
105
|
+
terminalError = err;
|
|
106
|
+
// Terminal teardown transitions the transport into a disposed state even if
|
|
107
|
+
// the caller never explicitly invoked `dispose()`.
|
|
108
|
+
disposed = true;
|
|
109
|
+
// Prevent any future settlement work from being queued.
|
|
110
|
+
settlementQueued = false;
|
|
111
|
+
rejectAllPending(opts?.getReason ?? (() => err));
|
|
112
|
+
// Prefer the latest live worker for any best-effort dispose signaling.
|
|
113
|
+
if (worker)
|
|
114
|
+
workerForDisposeSignal = worker;
|
|
115
|
+
const w = worker;
|
|
116
|
+
worker = undefined;
|
|
117
|
+
if (!w)
|
|
118
|
+
return;
|
|
119
|
+
w.removeEventListener("message", onMessage);
|
|
120
|
+
w.removeEventListener("error", onError);
|
|
121
|
+
w.removeEventListener("messageerror", onMessageError);
|
|
122
|
+
if (!terminateOnDispose)
|
|
123
|
+
return;
|
|
124
|
+
if (opts?.deferTerminate) {
|
|
125
|
+
const ok = queueMacrotask(() => {
|
|
126
|
+
try {
|
|
127
|
+
w.terminate();
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// ignore
|
|
131
|
+
}
|
|
132
|
+
}, { allowSyncFallback: false });
|
|
133
|
+
// No scheduler: explicitly fall back to a synchronous terminate so we
|
|
134
|
+
// don't leave an owned worker running.
|
|
135
|
+
if (!ok) {
|
|
136
|
+
try {
|
|
137
|
+
w.terminate();
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
// ignore
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
w.terminate();
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
// ignore
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
const hardFailNoMacrotaskScheduler = (err) => {
|
|
153
|
+
// Permanently fail closed.
|
|
154
|
+
canScheduleMacrotask = false;
|
|
155
|
+
if (terminalError)
|
|
156
|
+
return;
|
|
157
|
+
// Best-effort: if configured, attempt to notify the worker to dispose any
|
|
158
|
+
// server-side resources *before* we remove listeners/terminate.
|
|
159
|
+
signalDisposeOnce();
|
|
160
|
+
terminalTeardown(err);
|
|
161
|
+
};
|
|
162
|
+
const flushQueuedSettlements = () => {
|
|
163
|
+
settlementQueued = false;
|
|
164
|
+
for (const [id, settlement] of Array.from(queuedSettlementById)) {
|
|
165
|
+
queuedSettlementById.delete(id);
|
|
166
|
+
const pending = settlement.pending;
|
|
167
|
+
const op = pending.op;
|
|
168
|
+
const kind = settlement.kind;
|
|
169
|
+
// Drop references to response payloads as soon as possible.
|
|
170
|
+
let value = settlement.value;
|
|
171
|
+
let error = settlement.error;
|
|
172
|
+
settlement.value = undefined;
|
|
173
|
+
settlement.error = undefined;
|
|
174
|
+
if (disposed) {
|
|
175
|
+
pending.reject(new Error(`Worker transport disposed ${formatRequestContext(op, id)}`));
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (kind === "resolve") {
|
|
179
|
+
pending.resolve(value);
|
|
180
|
+
value = undefined;
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
pending.reject(error);
|
|
184
|
+
error = undefined;
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const scheduleSettlementMacrotask = () => {
|
|
188
|
+
if (settlementQueued)
|
|
189
|
+
return;
|
|
190
|
+
settlementQueued = true;
|
|
191
|
+
const ok = queueMacrotask(flushQueuedSettlements, { allowSyncFallback: false });
|
|
192
|
+
if (ok) {
|
|
193
|
+
canScheduleMacrotask = true;
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
// No macrotask scheduler available. Hard-fail and tear down rather than
|
|
197
|
+
// settling synchronously and violating ordering guarantees.
|
|
198
|
+
hardFailNoMacrotaskScheduler(createNoMacrotaskSchedulerError());
|
|
199
|
+
};
|
|
200
|
+
const onMessage = (ev) => {
|
|
201
|
+
const msg = ev?.data;
|
|
202
|
+
if (!msg || msg.type !== tspiceRpcResponseType || typeof msg.id !== "number")
|
|
203
|
+
return;
|
|
204
|
+
const id = msg.id;
|
|
205
|
+
const pending = pendingById.get(id);
|
|
206
|
+
if (!pending)
|
|
207
|
+
return;
|
|
208
|
+
// Remove immediately so a queued timeout handler can't win after we've
|
|
209
|
+
// already received a legitimate response.
|
|
210
|
+
pendingById.delete(id);
|
|
211
|
+
// Clean up request-specific resources immediately (abort listeners, timers),
|
|
212
|
+
// but defer settling to a macrotask so `dispose()` can deterministically win.
|
|
213
|
+
pending.cleanup();
|
|
214
|
+
// If we already know we can't schedule macrotasks, reject immediately.
|
|
215
|
+
if (canScheduleMacrotask === false) {
|
|
216
|
+
pending.reject(createNoMacrotaskSchedulerError());
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
const op = pending.op;
|
|
220
|
+
// Extract response fields up-front so the deferred macrotask doesn't close
|
|
221
|
+
// over the full `msg` payload.
|
|
222
|
+
let kind;
|
|
223
|
+
let value = undefined;
|
|
224
|
+
let error = undefined;
|
|
225
|
+
if (msg.ok === true) {
|
|
226
|
+
if (!("value" in msg)) {
|
|
227
|
+
kind = "reject";
|
|
228
|
+
error = new Error(`Malformed worker response: ok=true but missing value ${formatRequestContext(op, id)}`);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
kind = "resolve";
|
|
232
|
+
value = decodeRpcValue(msg.value);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
else if (msg.ok === false) {
|
|
236
|
+
if (!("error" in msg)) {
|
|
237
|
+
kind = "reject";
|
|
238
|
+
error = new Error(`Malformed worker response: ok=false but missing error ${formatRequestContext(op, id)}`);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
kind = "reject";
|
|
242
|
+
error = deserializeError(msg.error);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
kind = "reject";
|
|
247
|
+
error = new Error(`Malformed worker response: missing ok flag ${formatRequestContext(op, id)}`);
|
|
248
|
+
}
|
|
249
|
+
queuedSettlementById.set(id, { pending, kind, value, error });
|
|
250
|
+
scheduleSettlementMacrotask();
|
|
251
|
+
};
|
|
252
|
+
const onError = (ev) => {
|
|
253
|
+
let message;
|
|
254
|
+
try {
|
|
255
|
+
message = ev?.message;
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
// ignore
|
|
259
|
+
}
|
|
260
|
+
const safeMessage = typeof message === "string" && message.length > 0 ? message : "Worker error";
|
|
261
|
+
terminalTeardown(new Error(safeMessage), {
|
|
262
|
+
getReason: (pending, id) => new Error(`${safeMessage} ${formatRequestContext(pending.op, id)}`),
|
|
263
|
+
});
|
|
264
|
+
};
|
|
265
|
+
const onMessageError = (_ev) => {
|
|
266
|
+
const err = new Error("Worker message deserialization failed");
|
|
267
|
+
terminalTeardown(err, {
|
|
268
|
+
getReason: (pending, id) => new Error(`Worker message deserialization failed ${formatRequestContext(pending.op, id)}`),
|
|
269
|
+
});
|
|
270
|
+
};
|
|
271
|
+
const ensureWorker = () => {
|
|
272
|
+
ensureCanScheduleMacrotask();
|
|
273
|
+
if (!worker) {
|
|
274
|
+
// Lazily construct/attach so transports can be created in environments
|
|
275
|
+
// that don't immediately support `Worker`.
|
|
276
|
+
try {
|
|
277
|
+
worker = typeof opts.worker === "function" ? opts.worker() : opts.worker;
|
|
278
|
+
}
|
|
279
|
+
catch (err) {
|
|
280
|
+
const out = new Error("Failed to create Worker");
|
|
281
|
+
out.cause = err;
|
|
282
|
+
throw out;
|
|
283
|
+
}
|
|
284
|
+
workerForDisposeSignal = worker;
|
|
285
|
+
worker.addEventListener("message", onMessage);
|
|
286
|
+
worker.addEventListener("error", onError);
|
|
287
|
+
worker.addEventListener("messageerror", onMessageError);
|
|
288
|
+
}
|
|
289
|
+
return worker;
|
|
290
|
+
};
|
|
291
|
+
const dispose = () => {
|
|
292
|
+
// Idempotent. Even if we're already in a terminal state, callers should be
|
|
293
|
+
// able to invoke `dispose()` and still get a best-effort dispose signal.
|
|
294
|
+
if (disposed) {
|
|
295
|
+
signalDisposeOnce();
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
disposed = true;
|
|
299
|
+
// Best-effort: tell the worker it should dispose any server-side resources.
|
|
300
|
+
//
|
|
301
|
+
// This is intentionally opt-in for shared workers; `tspice:dispose` is a
|
|
302
|
+
// global cleanup signal and may affect other clients.
|
|
303
|
+
signalDisposeOnce();
|
|
304
|
+
if (terminalError)
|
|
305
|
+
return;
|
|
306
|
+
terminalTeardown(new Error("Worker transport disposed"), {
|
|
307
|
+
getReason: (pending, id) => new Error(`Worker transport disposed ${formatRequestContext(pending.op, id)}`),
|
|
308
|
+
deferTerminate: true,
|
|
309
|
+
});
|
|
310
|
+
};
|
|
311
|
+
const request = async (op, args, requestOpts) => {
|
|
312
|
+
if (terminalError)
|
|
313
|
+
throw terminalError;
|
|
314
|
+
if (disposed)
|
|
315
|
+
throw new Error(`Worker transport disposed ${formatRequestContext(op)}`);
|
|
316
|
+
if (canScheduleMacrotask === false)
|
|
317
|
+
throw createNoMacrotaskSchedulerError();
|
|
318
|
+
const id = nextId++;
|
|
319
|
+
const w = ensureWorker();
|
|
320
|
+
const timeoutMs = requestOpts?.timeoutMs ?? opts.timeoutMs;
|
|
321
|
+
const signal = requestOpts?.signal;
|
|
322
|
+
if (timeoutMs !== undefined && timeoutMs > 0) {
|
|
323
|
+
const hasTimers = typeof setTimeout === "function" && typeof clearTimeout === "function";
|
|
324
|
+
if (!hasTimers) {
|
|
325
|
+
throw new Error(`Worker request timeoutMs=${timeoutMs} requires timers (setTimeout/clearTimeout) ${formatRequestContext(op, id)}`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return await new Promise((resolve, reject) => {
|
|
329
|
+
let requestTimeout;
|
|
330
|
+
// Cleanup is intentionally idempotent. It may be called from multiple
|
|
331
|
+
// paths (timeout, abort, response receipt, or dispose()) depending on
|
|
332
|
+
// ordering.
|
|
333
|
+
let didCleanup = false;
|
|
334
|
+
let onAbort;
|
|
335
|
+
const cleanup = () => {
|
|
336
|
+
if (didCleanup)
|
|
337
|
+
return;
|
|
338
|
+
didCleanup = true;
|
|
339
|
+
if (requestTimeout !== undefined) {
|
|
340
|
+
clearTimeout(requestTimeout);
|
|
341
|
+
requestTimeout = undefined;
|
|
342
|
+
}
|
|
343
|
+
if (signal && onAbort)
|
|
344
|
+
signal.removeEventListener("abort", onAbort);
|
|
345
|
+
};
|
|
346
|
+
const rejectAndCleanup = (reason) => {
|
|
347
|
+
cleanup();
|
|
348
|
+
reject(reason);
|
|
349
|
+
};
|
|
350
|
+
const pending = {
|
|
351
|
+
op,
|
|
352
|
+
resolve,
|
|
353
|
+
reject,
|
|
354
|
+
cleanup,
|
|
355
|
+
rejectAndCleanup,
|
|
356
|
+
};
|
|
357
|
+
pendingById.set(id, pending);
|
|
358
|
+
onAbort = () => {
|
|
359
|
+
if (pendingById.get(id) !== pending)
|
|
360
|
+
return;
|
|
361
|
+
pendingById.delete(id);
|
|
362
|
+
pending.rejectAndCleanup(createAbortError());
|
|
363
|
+
};
|
|
364
|
+
if (signal) {
|
|
365
|
+
if (signal.aborted) {
|
|
366
|
+
pendingById.delete(id);
|
|
367
|
+
pending.rejectAndCleanup(createAbortError());
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
signal.addEventListener("abort", onAbort);
|
|
371
|
+
}
|
|
372
|
+
if (timeoutMs !== undefined && timeoutMs > 0) {
|
|
373
|
+
requestTimeout = setTimeout(() => {
|
|
374
|
+
if (pendingById.get(id) !== pending)
|
|
375
|
+
return;
|
|
376
|
+
pendingById.delete(id);
|
|
377
|
+
pending.rejectAndCleanup(new Error(`Worker request timed out after ${timeoutMs}ms ${formatRequestContext(op, id)}`));
|
|
378
|
+
}, timeoutMs);
|
|
379
|
+
}
|
|
380
|
+
const msg = { type: tspiceRpcRequestType, id, op, args };
|
|
381
|
+
try {
|
|
382
|
+
w.postMessage({ ...msg, args: args.map(encodeRpcValue) });
|
|
383
|
+
}
|
|
384
|
+
catch (err) {
|
|
385
|
+
if (pendingById.get(id) === pending)
|
|
386
|
+
pendingById.delete(id);
|
|
387
|
+
const out = new Error(`Worker postMessage failed ${formatRequestContext(op, id)}`);
|
|
388
|
+
out.cause = err;
|
|
389
|
+
pending.rejectAndCleanup(out);
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
};
|
|
393
|
+
return {
|
|
394
|
+
request,
|
|
395
|
+
dispose,
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
//# sourceMappingURL=createWorkerTransport.js.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { SpiceTransport } from "../../transport/types.js";
|
|
2
|
+
type WorkerGlobalScopeLike = {
|
|
3
|
+
addEventListener(type: "message", listener: (ev: {
|
|
4
|
+
data: unknown;
|
|
5
|
+
}) => void): void;
|
|
6
|
+
removeEventListener(type: "message", listener: (ev: {
|
|
7
|
+
data: unknown;
|
|
8
|
+
}) => void): void;
|
|
9
|
+
postMessage(msg: unknown): void;
|
|
10
|
+
close?: () => void;
|
|
11
|
+
};
|
|
12
|
+
/** Expose a {@link SpiceTransport} inside a Worker, handling RPC request/response messaging. */
|
|
13
|
+
export declare function exposeTransportToWorker(opts: {
|
|
14
|
+
transport: SpiceTransport;
|
|
15
|
+
/**
|
|
16
|
+
* Override the Worker global scope for testing.
|
|
17
|
+
*
|
|
18
|
+
* Defaults to `globalThis`.
|
|
19
|
+
*/
|
|
20
|
+
self?: WorkerGlobalScopeLike;
|
|
21
|
+
/** Optional cleanup hook called when a dispose message is received. */
|
|
22
|
+
onDispose?: () => void | Promise<void>;
|
|
23
|
+
/** Whether to call `self.close()` after disposing. Defaults to `true`. */
|
|
24
|
+
closeOnDispose?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Maximum number of in-flight `transport.request()` calls allowed at once.
|
|
27
|
+
* Additional requests are queued (FIFO) until prior requests settle.
|
|
28
|
+
*
|
|
29
|
+
* Defaults to `Infinity`.
|
|
30
|
+
*/
|
|
31
|
+
maxConcurrentRequests?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Maximum number of queued requests allowed when `maxConcurrentRequests` is
|
|
34
|
+
* finite.
|
|
35
|
+
*
|
|
36
|
+
* When `maxConcurrentRequests` is finite, additional requests are queued
|
|
37
|
+
* (FIFO) until prior requests settle.
|
|
38
|
+
*
|
|
39
|
+
* When the queue is full, new incoming requests are immediately rejected
|
|
40
|
+
* with an RPC error response.
|
|
41
|
+
*
|
|
42
|
+
* Defaults:
|
|
43
|
+
* - `Infinity` when `maxConcurrentRequests` is `Infinity` (preserves existing behavior)
|
|
44
|
+
* - `1000` when `maxConcurrentRequests` is finite
|
|
45
|
+
*/
|
|
46
|
+
maxQueuedRequests?: number;
|
|
47
|
+
}): {
|
|
48
|
+
dispose: () => void;
|
|
49
|
+
};
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=exposeTransportToWorker.d.ts.map
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { serializeError, tspiceRpcDisposeType, tspiceRpcRequestType, tspiceRpcResponseType, } from "../../transport/rpc/protocol.js";
|
|
2
|
+
import { decodeRpcValue, encodeRpcValue } from "../../transport/rpc/valueCodec.js";
|
|
3
|
+
import { queueMacrotask } from "../../transport/rpc/taskScheduling.js";
|
|
4
|
+
/** Expose a {@link SpiceTransport} inside a Worker, handling RPC request/response messaging. */
|
|
5
|
+
export function exposeTransportToWorker(opts) {
|
|
6
|
+
const self = opts.self ?? globalThis;
|
|
7
|
+
let disposed = false;
|
|
8
|
+
const maxConcurrentRequests = opts.maxConcurrentRequests ?? Infinity;
|
|
9
|
+
if (maxConcurrentRequests !== Infinity) {
|
|
10
|
+
// Guard against deadlocking the queue when `maxConcurrentRequests` is 0/NaN/etc.
|
|
11
|
+
if (!Number.isFinite(maxConcurrentRequests) || maxConcurrentRequests < 1) {
|
|
12
|
+
throw new Error("exposeTransportToWorker(): maxConcurrentRequests must be >= 1");
|
|
13
|
+
}
|
|
14
|
+
// Prefer integers for deterministic queue semantics.
|
|
15
|
+
if (!Number.isInteger(maxConcurrentRequests)) {
|
|
16
|
+
throw new Error("exposeTransportToWorker(): maxConcurrentRequests must be an integer");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
let inFlight = 0;
|
|
20
|
+
const defaultMaxQueuedRequests = maxConcurrentRequests === Infinity ? Infinity : 1000;
|
|
21
|
+
const maxQueuedRequests = opts.maxQueuedRequests ?? defaultMaxQueuedRequests;
|
|
22
|
+
if (maxQueuedRequests !== Infinity) {
|
|
23
|
+
if (!Number.isFinite(maxQueuedRequests) || maxQueuedRequests < 0) {
|
|
24
|
+
throw new Error("exposeTransportToWorker(): maxQueuedRequests must be >= 0");
|
|
25
|
+
}
|
|
26
|
+
if (!Number.isInteger(maxQueuedRequests)) {
|
|
27
|
+
throw new Error("exposeTransportToWorker(): maxQueuedRequests must be an integer");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// FIFO queue with a moving head index to avoid O(n) `shift()`.
|
|
31
|
+
const queued = [];
|
|
32
|
+
let queuedHead = 0;
|
|
33
|
+
const queuedSize = () => queued.length - queuedHead;
|
|
34
|
+
const FAIL_QUEUED_REQUESTS_CHUNK_SIZE = 100;
|
|
35
|
+
const failQueuedRequests = async (reqs, err) => {
|
|
36
|
+
// Best-effort (avoid throwing during disposal).
|
|
37
|
+
try {
|
|
38
|
+
for (let i = 0; i < reqs.length; i += FAIL_QUEUED_REQUESTS_CHUNK_SIZE) {
|
|
39
|
+
const end = Math.min(i + FAIL_QUEUED_REQUESTS_CHUNK_SIZE, reqs.length);
|
|
40
|
+
for (let j = i; j < end; j++) {
|
|
41
|
+
const q = reqs[j];
|
|
42
|
+
const res = {
|
|
43
|
+
type: tspiceRpcResponseType,
|
|
44
|
+
id: q.id,
|
|
45
|
+
ok: false,
|
|
46
|
+
// Serialize per response so each postMessage gets a fresh object.
|
|
47
|
+
error: serializeError(err),
|
|
48
|
+
};
|
|
49
|
+
self.postMessage(res);
|
|
50
|
+
}
|
|
51
|
+
// Yield between chunks so disposing a huge queue doesn't block the
|
|
52
|
+
// worker for an unbounded amount of time.
|
|
53
|
+
if (end < reqs.length) {
|
|
54
|
+
await new Promise((resolve) => {
|
|
55
|
+
queueMacrotask(resolve, { allowSyncFallback: true });
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// ignore
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const clearQueue = () => {
|
|
65
|
+
queued.length = 0;
|
|
66
|
+
queuedHead = 0;
|
|
67
|
+
};
|
|
68
|
+
const maybeCompactQueue = () => {
|
|
69
|
+
// Periodically compact to avoid unbounded memory growth from a large queue.
|
|
70
|
+
if (queuedHead === 0)
|
|
71
|
+
return;
|
|
72
|
+
if (queuedHead < 100)
|
|
73
|
+
return;
|
|
74
|
+
queued.splice(0, queuedHead);
|
|
75
|
+
queuedHead = 0;
|
|
76
|
+
};
|
|
77
|
+
const drain = () => {
|
|
78
|
+
if (disposed)
|
|
79
|
+
return;
|
|
80
|
+
while (inFlight < maxConcurrentRequests && queuedHead < queued.length) {
|
|
81
|
+
const req = queued[queuedHead];
|
|
82
|
+
queuedHead += 1;
|
|
83
|
+
runRequest(req);
|
|
84
|
+
}
|
|
85
|
+
maybeCompactQueue();
|
|
86
|
+
};
|
|
87
|
+
const runRequest = (req) => {
|
|
88
|
+
inFlight += 1;
|
|
89
|
+
void (async () => {
|
|
90
|
+
try {
|
|
91
|
+
const value = await opts.transport.request(req.op, req.args.map(decodeRpcValue));
|
|
92
|
+
if (disposed)
|
|
93
|
+
return;
|
|
94
|
+
const res = {
|
|
95
|
+
type: tspiceRpcResponseType,
|
|
96
|
+
id: req.id,
|
|
97
|
+
ok: true,
|
|
98
|
+
value: encodeRpcValue(value),
|
|
99
|
+
};
|
|
100
|
+
self.postMessage(res);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
if (disposed)
|
|
104
|
+
return;
|
|
105
|
+
const res = {
|
|
106
|
+
type: tspiceRpcResponseType,
|
|
107
|
+
id: req.id,
|
|
108
|
+
ok: false,
|
|
109
|
+
error: serializeError(err),
|
|
110
|
+
};
|
|
111
|
+
self.postMessage(res);
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
inFlight -= 1;
|
|
115
|
+
drain();
|
|
116
|
+
}
|
|
117
|
+
})();
|
|
118
|
+
};
|
|
119
|
+
const onMessage = (ev) => {
|
|
120
|
+
const msg = ev.data;
|
|
121
|
+
if (!msg || typeof msg.type !== "string")
|
|
122
|
+
return;
|
|
123
|
+
if (msg.type === tspiceRpcDisposeType) {
|
|
124
|
+
// Dispose is a one-way signal; ignore any further traffic.
|
|
125
|
+
if (disposed)
|
|
126
|
+
return;
|
|
127
|
+
disposed = true;
|
|
128
|
+
const queuedToFail = queued.slice(queuedHead);
|
|
129
|
+
clearQueue();
|
|
130
|
+
void (async () => {
|
|
131
|
+
try {
|
|
132
|
+
await failQueuedRequests(queuedToFail, new Error("Worker disposed"));
|
|
133
|
+
await opts.onDispose?.();
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
self.removeEventListener("message", onMessage);
|
|
137
|
+
const closeOnDispose = opts.closeOnDispose ?? true;
|
|
138
|
+
if (closeOnDispose) {
|
|
139
|
+
try {
|
|
140
|
+
self.close?.();
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
// ignore
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
})();
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
// Ignore any further traffic after disposal (including in-flight requests
|
|
151
|
+
// that may finish later).
|
|
152
|
+
if (disposed)
|
|
153
|
+
return;
|
|
154
|
+
if (msg.type === tspiceRpcRequestType) {
|
|
155
|
+
const req = msg;
|
|
156
|
+
const id = req.id;
|
|
157
|
+
const op = req.op;
|
|
158
|
+
const args = req.args;
|
|
159
|
+
if (typeof id !== "number" || typeof op !== "string" || !Array.isArray(args)) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const queuedReq = { id, op, args };
|
|
163
|
+
if (inFlight < maxConcurrentRequests) {
|
|
164
|
+
runRequest(queuedReq);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
if (queuedSize() >= maxQueuedRequests) {
|
|
168
|
+
const res = {
|
|
169
|
+
type: tspiceRpcResponseType,
|
|
170
|
+
id,
|
|
171
|
+
ok: false,
|
|
172
|
+
error: serializeError(new Error(`Worker backpressure queue overflow (maxQueuedRequests=${maxQueuedRequests})`)),
|
|
173
|
+
};
|
|
174
|
+
self.postMessage(res);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
queued.push(queuedReq);
|
|
178
|
+
}
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
self.addEventListener("message", onMessage);
|
|
183
|
+
const dispose = () => {
|
|
184
|
+
if (disposed)
|
|
185
|
+
return;
|
|
186
|
+
disposed = true;
|
|
187
|
+
const queuedToFail = queued.slice(queuedHead);
|
|
188
|
+
clearQueue();
|
|
189
|
+
void failQueuedRequests(queuedToFail, new Error("Worker disposed"));
|
|
190
|
+
// Note: this does not cancel any in-flight `transport.request()` calls; it
|
|
191
|
+
// just prevents any further responses from being posted.
|
|
192
|
+
self.removeEventListener("message", onMessage);
|
|
193
|
+
};
|
|
194
|
+
return { dispose };
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=exposeTransportToWorker.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rybosome/tspice",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"imports": {
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"optionalDependencies": {
|
|
26
|
-
"@rybosome/tspice-native-darwin-arm64": "0.0.
|
|
27
|
-
"@rybosome/tspice-native-darwin-x64": "0.0.
|
|
28
|
-
"@rybosome/tspice-native-linux-x64-gnu": "0.0.
|
|
26
|
+
"@rybosome/tspice-native-darwin-arm64": "0.0.8",
|
|
27
|
+
"@rybosome/tspice-native-darwin-x64": "0.0.8",
|
|
28
|
+
"@rybosome/tspice-native-linux-x64-gnu": "0.0.8"
|
|
29
29
|
},
|
|
30
30
|
"files": [
|
|
31
31
|
"dist",
|