knitting 0.1.56 → 0.1.61
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/BROWSER.md +134 -0
- package/README.md +347 -46
- package/knitting.browser.d.ts +6 -0
- package/knitting.browser.js +1 -0
- package/knitting.d.ts +3 -2
- package/knitting.js +3 -3
- package/map.md +21 -9
- package/package.json +17 -2
- package/prebuilds/darwin-arm64-node-127/knitting_buffer_pointer.node +0 -0
- package/prebuilds/darwin-arm64-node-127/knitting_shared_memory.node +0 -0
- package/prebuilds/darwin-arm64-node-127/knitting_shm.node +0 -0
- package/prebuilds/darwin-arm64-node-137/knitting_buffer_pointer.node +0 -0
- package/prebuilds/darwin-arm64-node-137/knitting_shared_memory.node +0 -0
- package/prebuilds/darwin-arm64-node-137/knitting_shm.node +0 -0
- package/prebuilds/win32-x64/knitting_windows_shared_memory.dll +0 -0
- package/prebuilds/win32-x64-node-127/knitting_buffer_pointer.node +0 -0
- package/prebuilds/win32-x64-node-127/knitting_shared_memory.node +0 -0
- package/prebuilds/win32-x64-node-127/knitting_shm.node +0 -0
- package/prebuilds/win32-x64-node-137/knitting_buffer_pointer.node +0 -0
- package/prebuilds/win32-x64-node-137/knitting_shared_memory.node +0 -0
- package/prebuilds/win32-x64-node-137/knitting_shm.node +0 -0
- package/scripts/build-compiled-worker.ts +276 -0
- package/scripts/compiled-worker/porffor.d.ts +5 -0
- package/scripts/compiled-worker/runtime.ts +529 -0
- package/scripts/compiled-worker/task-shim.ts +32 -0
- package/src/api.d.ts +24 -1
- package/src/api.js +311 -27
- package/src/common/module-url.d.ts +1 -0
- package/src/common/module-url.js +30 -2
- package/src/common/node-compat.d.ts +2 -0
- package/src/common/path-canonical.js +20 -6
- package/src/common/runtime.d.ts +3 -1
- package/src/common/runtime.js +25 -4
- package/src/common/task-source.d.ts +2 -0
- package/src/common/task-source.js +17 -1
- package/src/common/worker-runtime.js +16 -7
- package/src/connections/buffer-reference-native.js +25 -1
- package/src/connections/buffer-reference.d.ts +23 -2
- package/src/connections/buffer-reference.js +143 -29
- package/src/connections/bun.d.ts +1 -1
- package/src/connections/bun.js +25 -14
- package/src/connections/deno.d.ts +3 -1
- package/src/connections/deno.js +35 -14
- package/src/connections/external-array-buffer.d.ts +2 -0
- package/src/connections/external-array-buffer.js +33 -0
- package/src/connections/node-addons.d.ts +11 -0
- package/src/connections/node-addons.js +49 -1
- package/src/connections/node-ffi-api.d.ts +19 -0
- package/src/connections/node-ffi-api.js +28 -0
- package/src/connections/node-ffi.d.ts +27 -0
- package/src/connections/node-ffi.js +262 -0
- package/src/connections/node.d.ts +1 -1
- package/src/connections/node.js +20 -20
- package/src/connections/package-assets.js +25 -15
- package/src/connections/posix.d.ts +42 -0
- package/src/connections/posix.js +101 -0
- package/src/connections/process-shared-buffer.d.ts +1 -0
- package/src/connections/process-shared-buffer.js +11 -45
- package/src/connections/types.d.ts +4 -0
- package/src/connections/windows.d.ts +19 -10
- package/src/connections/windows.js +87 -66
- package/src/error.d.ts +7 -6
- package/src/error.js +8 -7
- package/src/memory/lock.d.ts +112 -77
- package/src/memory/lock.js +314 -87
- package/src/memory/payloadCodec.d.ts +11 -2
- package/src/memory/payloadCodec.js +129 -37
- package/src/memory/regionRegistry.d.ts +1 -3
- package/src/memory/regionRegistry.js +16 -14
- package/src/permission/compatibility.d.ts +28 -0
- package/src/permission/compatibility.js +239 -0
- package/src/permission/index.d.ts +2 -0
- package/src/permission/index.js +1 -0
- package/src/permission/protocol.d.ts +1 -0
- package/src/permission/protocol.js +59 -15
- package/src/runtime/compiled-artifact.d.ts +21 -0
- package/src/runtime/compiled-artifact.js +260 -0
- package/src/runtime/compiled-builder.d.ts +8 -0
- package/src/runtime/compiled-builder.js +42 -0
- package/src/runtime/compiled-worker.d.ts +27 -0
- package/src/runtime/compiled-worker.js +562 -0
- package/src/runtime/dispatcher.js +9 -0
- package/src/runtime/inline-executor.js +27 -15
- package/src/runtime/pool.d.ts +121 -5
- package/src/runtime/pool.js +263 -49
- package/src/runtime/process-worker.d.ts +3 -13
- package/src/runtime/process-worker.js +97 -101
- package/src/runtime/tx-queue.d.ts +18 -2
- package/src/runtime/tx-queue.js +56 -16
- package/src/runtime/worker-common.d.ts +13 -0
- package/src/runtime/worker-common.js +102 -0
- package/src/types.d.ts +89 -9
- package/src/worker/composable-runners.js +3 -2
- package/src/worker/loop.d.ts +1 -0
- package/src/worker/loop.js +52 -17
- package/src/worker/rx-queue.d.ts +11 -1
- package/src/worker/rx-queue.js +4 -1
- package/src/worker/task-loader.d.ts +5 -4
- package/src/worker/task-loader.js +13 -7
- package/src/worker/timers.d.ts +8 -1
- package/src/worker/timers.js +28 -23
|
@@ -1,27 +1,37 @@
|
|
|
1
1
|
import { withResolvers } from "../common/with-resolvers.js";
|
|
2
2
|
import RingQueue from "../ipc/tools/ring-queue.js";
|
|
3
3
|
import { createRuntimeMessageChannel } from "../common/worker-runtime.js";
|
|
4
|
+
// const objects, not `enum`s: Andromeda's Nova engine can't parse `enum`. Same
|
|
5
|
+
// values and emit on Node/Deno/Bun.
|
|
6
|
+
const SlotStateMacro = {
|
|
7
|
+
Free: -1,
|
|
8
|
+
Pending: 0,
|
|
9
|
+
};
|
|
10
|
+
const TimeoutKind = {
|
|
11
|
+
Reject: 0,
|
|
12
|
+
Resolve: 1,
|
|
13
|
+
};
|
|
4
14
|
const normalizeTimeout = (timeout) => {
|
|
5
15
|
if (timeout == null)
|
|
6
16
|
return undefined;
|
|
7
17
|
if (typeof timeout === "number") {
|
|
8
18
|
return timeout >= 0
|
|
9
|
-
? { ms: timeout, kind:
|
|
19
|
+
? { ms: timeout, kind: TimeoutKind.Reject, value: new Error("Task timeout") }
|
|
10
20
|
: undefined;
|
|
11
21
|
}
|
|
12
22
|
const ms = timeout.time;
|
|
13
23
|
if (!(ms >= 0))
|
|
14
24
|
return undefined;
|
|
15
25
|
if ("default" in timeout) {
|
|
16
|
-
return { ms, kind:
|
|
26
|
+
return { ms, kind: TimeoutKind.Resolve, value: timeout.default };
|
|
17
27
|
}
|
|
18
28
|
if (timeout.maybe === true) {
|
|
19
|
-
return { ms, kind:
|
|
29
|
+
return { ms, kind: TimeoutKind.Resolve, value: undefined };
|
|
20
30
|
}
|
|
21
31
|
if ("error" in timeout) {
|
|
22
|
-
return { ms, kind:
|
|
32
|
+
return { ms, kind: TimeoutKind.Reject, value: timeout.error };
|
|
23
33
|
}
|
|
24
|
-
return { ms, kind:
|
|
34
|
+
return { ms, kind: TimeoutKind.Reject, value: new Error("Task timeout") };
|
|
25
35
|
};
|
|
26
36
|
const raceTimeout = (promise, spec) => new Promise((resolve, reject) => {
|
|
27
37
|
let done = false;
|
|
@@ -29,7 +39,7 @@ const raceTimeout = (promise, spec) => new Promise((resolve, reject) => {
|
|
|
29
39
|
if (done)
|
|
30
40
|
return;
|
|
31
41
|
done = true;
|
|
32
|
-
if (spec.kind ===
|
|
42
|
+
if (spec.kind === TimeoutKind.Resolve) {
|
|
33
43
|
resolve(spec.value);
|
|
34
44
|
}
|
|
35
45
|
else {
|
|
@@ -52,8 +62,10 @@ const raceTimeout = (promise, spec) => new Promise((resolve, reject) => {
|
|
|
52
62
|
});
|
|
53
63
|
const INLINE_ABORT_TOOLKIT = (() => {
|
|
54
64
|
const hasAborted = () => false;
|
|
65
|
+
const now = () => performance.now();
|
|
55
66
|
return {
|
|
56
67
|
hasAborted,
|
|
68
|
+
now,
|
|
57
69
|
};
|
|
58
70
|
})();
|
|
59
71
|
const composeInlineCallable = (fn, timeout, useAbortToolkit = false) => {
|
|
@@ -86,7 +98,7 @@ export const createInlineExecutor = ({ tasks, genTaskID, batchSize, }) => {
|
|
|
86
98
|
});
|
|
87
99
|
const initCap = 16;
|
|
88
100
|
let fnByIndex = new Int32Array(initCap);
|
|
89
|
-
let stateByIndex = new Int8Array(initCap).fill(
|
|
101
|
+
let stateByIndex = new Int8Array(initCap).fill(SlotStateMacro.Free);
|
|
90
102
|
let argsByIndex = new Array(initCap);
|
|
91
103
|
let taskIdByIndex = new Array(initCap).fill(-1);
|
|
92
104
|
let deferredByIndex = new Array(initCap);
|
|
@@ -126,13 +138,13 @@ export const createInlineExecutor = ({ tasks, genTaskID, batchSize, }) => {
|
|
|
126
138
|
send();
|
|
127
139
|
};
|
|
128
140
|
const enqueueIfCurrent = (index, taskID) => {
|
|
129
|
-
if (stateByIndex[index] !==
|
|
141
|
+
if (stateByIndex[index] !== SlotStateMacro.Pending ||
|
|
130
142
|
taskIdByIndex[index] !== taskID)
|
|
131
143
|
return;
|
|
132
144
|
enqueue(index);
|
|
133
145
|
};
|
|
134
146
|
const settleIfCurrent = (index, taskID, isError, value) => {
|
|
135
|
-
if (stateByIndex[index] !==
|
|
147
|
+
if (stateByIndex[index] !== SlotStateMacro.Pending ||
|
|
136
148
|
taskIdByIndex[index] !== taskID)
|
|
137
149
|
return;
|
|
138
150
|
const deferred = deferredByIndex[index];
|
|
@@ -153,7 +165,7 @@ export const createInlineExecutor = ({ tasks, genTaskID, batchSize, }) => {
|
|
|
153
165
|
nextFnByIndex.set(fnByIndex);
|
|
154
166
|
fnByIndex = nextFnByIndex;
|
|
155
167
|
const nextStateByIndex = new Int8Array(newCap);
|
|
156
|
-
nextStateByIndex.fill(
|
|
168
|
+
nextStateByIndex.fill(SlotStateMacro.Free);
|
|
157
169
|
nextStateByIndex.set(stateByIndex);
|
|
158
170
|
stateByIndex = nextStateByIndex;
|
|
159
171
|
argsByIndex.length = newCap;
|
|
@@ -172,7 +184,7 @@ export const createInlineExecutor = ({ tasks, genTaskID, batchSize, }) => {
|
|
|
172
184
|
if (maybeIndex === undefined)
|
|
173
185
|
break;
|
|
174
186
|
const index = maybeIndex | 0;
|
|
175
|
-
if (stateByIndex[index] !==
|
|
187
|
+
if (stateByIndex[index] !== SlotStateMacro.Pending)
|
|
176
188
|
continue;
|
|
177
189
|
const taskID = taskIdByIndex[index];
|
|
178
190
|
try {
|
|
@@ -213,7 +225,7 @@ export const createInlineExecutor = ({ tasks, genTaskID, batchSize, }) => {
|
|
|
213
225
|
}
|
|
214
226
|
function cleanup(index) {
|
|
215
227
|
working--;
|
|
216
|
-
stateByIndex[index] =
|
|
228
|
+
stateByIndex[index] = SlotStateMacro.Free;
|
|
217
229
|
fnByIndex[index] = 0;
|
|
218
230
|
taskIdByIndex[index] = -1;
|
|
219
231
|
argsByIndex[index] = undefined;
|
|
@@ -230,7 +242,7 @@ export const createInlineExecutor = ({ tasks, genTaskID, batchSize, }) => {
|
|
|
230
242
|
argsByIndex[index] = args;
|
|
231
243
|
fnByIndex[index] = fnNumber | 0;
|
|
232
244
|
deferredByIndex[index] = deferred;
|
|
233
|
-
stateByIndex[index] =
|
|
245
|
+
stateByIndex[index] = SlotStateMacro.Pending;
|
|
234
246
|
working++;
|
|
235
247
|
if (args instanceof Promise) {
|
|
236
248
|
args.then((value) => {
|
|
@@ -250,7 +262,7 @@ export const createInlineExecutor = ({ tasks, genTaskID, batchSize, }) => {
|
|
|
250
262
|
return {
|
|
251
263
|
kills: async () => {
|
|
252
264
|
for (let index = 0; index < stateByIndex.length; index++) {
|
|
253
|
-
if (stateByIndex[index] !==
|
|
265
|
+
if (stateByIndex[index] !== SlotStateMacro.Pending)
|
|
254
266
|
continue;
|
|
255
267
|
try {
|
|
256
268
|
deferredByIndex[index]?.reject("Thread closed");
|
|
@@ -271,7 +283,7 @@ export const createInlineExecutor = ({ tasks, genTaskID, batchSize, }) => {
|
|
|
271
283
|
taskIdByIndex.fill(-1);
|
|
272
284
|
deferredByIndex.fill(undefined);
|
|
273
285
|
fnByIndex.fill(0);
|
|
274
|
-
stateByIndex.fill(
|
|
286
|
+
stateByIndex.fill(SlotStateMacro.Free);
|
|
275
287
|
working = 0;
|
|
276
288
|
isInMacro = false;
|
|
277
289
|
isInMicro = false;
|
package/src/runtime/pool.d.ts
CHANGED
|
@@ -1,11 +1,104 @@
|
|
|
1
|
+
import { createHostTxQueue } from "./tx-queue.js";
|
|
1
2
|
import { type ProcessSharedMemoryBacking } from "./process-worker.js";
|
|
2
3
|
import { type Sab } from "../ipc/transport/shared-memory.js";
|
|
3
4
|
import { ChannelHandler, type DispatcherCheck } from "./dispatcher.js";
|
|
4
|
-
import { lock2 } from "../memory/lock.js";
|
|
5
|
-
import
|
|
5
|
+
import { lock2, type Task } from "../memory/lock.js";
|
|
6
|
+
import "../memory/payloadCodec.js";
|
|
7
|
+
import type { DebugOptions, DispatcherSettings, LockBuffers, WorkerContext, WorkerData, WorkerSettings } from "../types.js";
|
|
6
8
|
import "../worker/loop.js";
|
|
7
9
|
import { type PayloadBufferOptions } from "../memory/payload-config.js";
|
|
8
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Build the buffers, host-side locks and pending registry that a stealing pool
|
|
12
|
+
* shares. One submit region for every worker to claim from, one private return
|
|
13
|
+
* region per worker, and a single pool-global queue so a response arriving on
|
|
14
|
+
* any lane settles the right promise.
|
|
15
|
+
*
|
|
16
|
+
* Region width follows paper §6.1: the largest power-of-two `g` leaving a spare
|
|
17
|
+
* region for a delayed claimant (`slots / g >= consumers + 1`). At 32 slots that
|
|
18
|
+
* caps how wide a region can be well before it caps the worker count.
|
|
19
|
+
*/
|
|
20
|
+
export declare const resolveStealRegionLanes: (consumers: number) => number;
|
|
21
|
+
/** Maximum claimants that leave the protocol's required spare region. */
|
|
22
|
+
export declare const MAX_STEAL_CONSUMERS: number;
|
|
23
|
+
export declare const createStealPoolBuffers: ({ threads, payload, regionLanes, abortSignalCapacity, usesAbortSignal, }: {
|
|
24
|
+
threads: number;
|
|
25
|
+
payload?: PayloadBufferOptions;
|
|
26
|
+
regionLanes?: number;
|
|
27
|
+
abortSignalCapacity?: number;
|
|
28
|
+
usesAbortSignal?: boolean;
|
|
29
|
+
}) => {
|
|
30
|
+
submitBuffers: LockBuffers;
|
|
31
|
+
returnBuffers: LockBuffers[];
|
|
32
|
+
hostSubmitLock: {
|
|
33
|
+
enlist: (task: Task) => true;
|
|
34
|
+
encode: (task: Task, state?: number) => boolean;
|
|
35
|
+
encodeManyFrom: (list: import("../ipc/tools/ring-queue.js").default<Task>) => number;
|
|
36
|
+
encodeAll: () => boolean;
|
|
37
|
+
publish: (task: Task) => boolean;
|
|
38
|
+
flushPending: () => boolean;
|
|
39
|
+
decode: () => boolean;
|
|
40
|
+
hasSpace: () => boolean;
|
|
41
|
+
resolved: import("../ipc/tools/ring-queue.js").default<Task>;
|
|
42
|
+
hostBits: Int32Array<import("../common/shared-buffer-region.js").SharedBuffer>;
|
|
43
|
+
workerBits: Int32Array<import("../common/shared-buffer-region.js").SharedBuffer>;
|
|
44
|
+
recyclecList: import("../ipc/tools/ring-queue.js").default<Task>;
|
|
45
|
+
resolveHost: ({ queue, onResolved, shouldSettle, activeRejectPlaceholder, }: {
|
|
46
|
+
queue: Task[];
|
|
47
|
+
onResolved?: (task: Task) => void;
|
|
48
|
+
shouldSettle?: (task: Task) => boolean;
|
|
49
|
+
activeRejectPlaceholder?: Task["reject"];
|
|
50
|
+
}) => () => number;
|
|
51
|
+
hasPendingFrames: () => boolean;
|
|
52
|
+
getPendingFrameCount: () => number;
|
|
53
|
+
getPendingPromiseCount: () => number;
|
|
54
|
+
resetPendingState: () => void;
|
|
55
|
+
deactivateStealConsumer: (id: number) => boolean;
|
|
56
|
+
takeDeferredCount: () => number;
|
|
57
|
+
setPromiseHandler: (handler?: import("../memory/lock.js").PromisePayloadHandler) => void;
|
|
58
|
+
};
|
|
59
|
+
hostReturnLocks: {
|
|
60
|
+
enlist: (task: Task) => true;
|
|
61
|
+
encode: (task: Task, state?: number) => boolean;
|
|
62
|
+
encodeManyFrom: (list: import("../ipc/tools/ring-queue.js").default<Task>) => number;
|
|
63
|
+
encodeAll: () => boolean;
|
|
64
|
+
publish: (task: Task) => boolean;
|
|
65
|
+
flushPending: () => boolean;
|
|
66
|
+
decode: () => boolean;
|
|
67
|
+
hasSpace: () => boolean;
|
|
68
|
+
resolved: import("../ipc/tools/ring-queue.js").default<Task>;
|
|
69
|
+
hostBits: Int32Array<import("../common/shared-buffer-region.js").SharedBuffer>;
|
|
70
|
+
workerBits: Int32Array<import("../common/shared-buffer-region.js").SharedBuffer>;
|
|
71
|
+
recyclecList: import("../ipc/tools/ring-queue.js").default<Task>;
|
|
72
|
+
resolveHost: ({ queue, onResolved, shouldSettle, activeRejectPlaceholder, }: {
|
|
73
|
+
queue: Task[];
|
|
74
|
+
onResolved?: (task: Task) => void;
|
|
75
|
+
shouldSettle?: (task: Task) => boolean;
|
|
76
|
+
activeRejectPlaceholder?: Task["reject"];
|
|
77
|
+
}) => () => number;
|
|
78
|
+
hasPendingFrames: () => boolean;
|
|
79
|
+
getPendingFrameCount: () => number;
|
|
80
|
+
getPendingPromiseCount: () => number;
|
|
81
|
+
resetPendingState: () => void;
|
|
82
|
+
deactivateStealConsumer: (id: number) => boolean;
|
|
83
|
+
takeDeferredCount: () => number;
|
|
84
|
+
setPromiseHandler: (handler?: import("../memory/lock.js").PromisePayloadHandler) => void;
|
|
85
|
+
}[];
|
|
86
|
+
sharedQueue: {
|
|
87
|
+
rejectAll: (reason: string) => void;
|
|
88
|
+
hasPendingFrames: () => boolean;
|
|
89
|
+
txIdle: () => boolean;
|
|
90
|
+
completeFrame: () => number;
|
|
91
|
+
setReturnHooks: (lane: number, hooks: (import("../connections/buffer-reference.js").BufferReferenceReturnHooks | ((token: bigint) => void)) | undefined) => void;
|
|
92
|
+
enqueue: (functionID: number, timeout?: import("../types.js").TaskTimeout, abortSignal?: import("../types.js").AbortSignalOption) => (rawArgs: unknown) => Promise<never> | import("../common/with-resolvers.js").PromiseWithMaybeReject<unknown>;
|
|
93
|
+
flushToWorker: () => boolean;
|
|
94
|
+
enqueueKnown: (task: Task) => boolean;
|
|
95
|
+
settlePromisePayload: (task: Task, isRejected: boolean, value: unknown) => boolean;
|
|
96
|
+
};
|
|
97
|
+
regionLanes: number;
|
|
98
|
+
abortSignalSAB: SharedArrayBuffer;
|
|
99
|
+
abortSignalMax: number;
|
|
100
|
+
};
|
|
101
|
+
export declare const spawnWorkerContext: ({ list, ids, names, sab, thread, debug, hostDebug, totalNumberOfThread, source, at, workerOptions, workerExecArgv, permission, host, payload, bufferReferenceReturn, abortSignalCapacity, usesAbortSignal, sharedChannelHandler, stealPool, }: {
|
|
9
102
|
list: string[];
|
|
10
103
|
ids: number[];
|
|
11
104
|
names: string[];
|
|
@@ -29,11 +122,34 @@ export declare const spawnWorkerContext: ({ list, ids, names, sab, thread, debug
|
|
|
29
122
|
* macro channel that runs all lane checks.
|
|
30
123
|
*/
|
|
31
124
|
sharedChannelHandler?: ChannelHandler;
|
|
32
|
-
|
|
125
|
+
/**
|
|
126
|
+
* Work-stealing wiring. When present the submit region, both host-side locks
|
|
127
|
+
* and the pending registry are owned by `createPool` and shared: every worker
|
|
128
|
+
* claims from one request region, and the host demultiplexes responses by
|
|
129
|
+
* task id. This lane only contributes its private return region and its
|
|
130
|
+
* worker. The dispatcher is owned by the pool too, so none is built here.
|
|
131
|
+
*/
|
|
132
|
+
stealPool?: {
|
|
133
|
+
submitBuffers: LockBuffers;
|
|
134
|
+
returnBuffers: LockBuffers;
|
|
135
|
+
hostSubmitLock: ReturnType<typeof lock2>;
|
|
136
|
+
hostReturnLock: ReturnType<typeof lock2>;
|
|
137
|
+
sharedQueue: ReturnType<typeof createHostTxQueue>;
|
|
138
|
+
consumers: number;
|
|
139
|
+
consumerId: number;
|
|
140
|
+
regionLanes: number;
|
|
141
|
+
abortSignalSAB?: LockBuffers["headers"];
|
|
142
|
+
abortSignalMax?: number;
|
|
143
|
+
};
|
|
144
|
+
}) => (WorkerContext & {
|
|
145
|
+
dispatcherCheck?: never;
|
|
146
|
+
laneWake?: never;
|
|
147
|
+
bindSend?: never;
|
|
148
|
+
}) | (WorkerContext & {
|
|
33
149
|
lock: ReturnType<typeof lock2>;
|
|
34
150
|
processSharedMemoryBackings?: readonly ProcessSharedMemoryBacking[];
|
|
35
151
|
dispatcherCheck?: DispatcherCheck;
|
|
36
152
|
laneWake?: () => void;
|
|
37
153
|
bindSend?: (fn: () => void) => void;
|
|
38
|
-
};
|
|
154
|
+
});
|
|
39
155
|
export type CreateContext = WorkerContext;
|