knitting 0.1.55 → 0.1.60
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 +254 -40
- package/knitting.d.ts +7 -797
- package/knitting.js +6 -9780
- package/map.md +31 -15
- package/package.json +20 -6
- package/process-shared-buffer.d.ts +1 -0
- package/process-shared-buffer.js +1 -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/shared-memory.d.ts +1 -155
- package/shared-memory.js +1 -1342
- package/src/api.d.ts +92 -0
- package/src/api.js +798 -0
- package/src/common/envelope.d.ts +17 -0
- package/src/common/envelope.js +22 -0
- package/src/common/module-url.d.ts +2 -0
- package/src/common/module-url.js +52 -0
- package/src/common/node-compat.d.ts +22 -0
- package/src/common/node-compat.js +24 -0
- package/src/common/path-canonical.d.ts +6 -0
- package/src/common/path-canonical.js +55 -0
- package/src/common/runtime.d.ts +16 -0
- package/src/common/runtime.js +105 -0
- package/src/common/shared-buffer-region.d.ts +11 -0
- package/src/common/shared-buffer-region.js +21 -0
- package/src/common/shared-buffer-text.d.ts +16 -0
- package/src/common/shared-buffer-text.js +65 -0
- package/src/common/task-source.d.ts +5 -0
- package/src/common/task-source.js +100 -0
- package/src/common/task-symbol.d.ts +1 -0
- package/src/common/task-symbol.js +1 -0
- package/src/common/with-resolvers.d.ts +9 -0
- package/src/common/with-resolvers.js +23 -0
- package/src/common/worker-runtime.d.ts +42 -0
- package/src/common/worker-runtime.js +70 -0
- package/src/connections/buffer-reference-native.d.ts +56 -0
- package/src/connections/buffer-reference-native.js +241 -0
- package/src/connections/buffer-reference.d.ts +99 -0
- package/src/connections/buffer-reference.js +575 -0
- package/src/connections/bun.d.ts +22 -0
- package/src/connections/bun.js +225 -0
- package/src/connections/deno.d.ts +24 -0
- package/src/connections/deno.js +226 -0
- package/src/connections/external-array-buffer.d.ts +2 -0
- package/src/connections/external-array-buffer.js +33 -0
- package/src/connections/file-descriptor.d.ts +39 -0
- package/src/connections/file-descriptor.js +161 -0
- package/src/connections/index.d.ts +4 -0
- package/src/connections/index.js +4 -0
- package/src/connections/node-addons.d.ts +16 -0
- package/src/connections/node-addons.js +92 -0
- package/src/connections/node-buffer-pointer.d.ts +20 -0
- package/src/connections/node-buffer-pointer.js +16 -0
- 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 +30 -0
- package/src/connections/node.js +62 -0
- package/src/connections/numeric-array.d.ts +5 -0
- package/src/connections/numeric-array.js +17 -0
- package/src/connections/package-assets.d.ts +2 -0
- package/src/connections/package-assets.js +55 -0
- package/src/connections/posix.d.ts +74 -0
- package/src/connections/posix.js +178 -0
- package/src/connections/process-shared-buffer.d.ts +76 -0
- package/src/connections/process-shared-buffer.js +245 -0
- package/src/connections/shared-array-buffer-payload.d.ts +36 -0
- package/src/connections/shared-array-buffer-payload.js +235 -0
- package/src/connections/types.d.ts +54 -0
- package/src/connections/types.js +37 -0
- package/src/connections/windows.d.ts +37 -0
- package/src/connections/windows.js +245 -0
- package/src/debug/env-diff.d.ts +26 -0
- package/src/debug/env-diff.js +49 -0
- package/src/debug/gate.d.ts +18 -0
- package/src/debug/gate.js +69 -0
- package/src/debug/handle.d.ts +23 -0
- package/src/debug/handle.js +48 -0
- package/src/error.d.ts +14 -0
- package/src/error.js +50 -0
- package/src/ipc/tools/ring-queue.d.ts +33 -0
- package/src/ipc/tools/ring-queue.js +159 -0
- package/src/ipc/transport/shared-memory.d.ts +23 -0
- package/src/ipc/transport/shared-memory.js +35 -0
- package/src/memory/byte-carpet.d.ts +73 -0
- package/src/memory/byte-carpet.js +157 -0
- package/src/memory/lock.d.ts +213 -0
- package/src/memory/lock.js +760 -0
- package/src/memory/payload-config.d.ts +31 -0
- package/src/memory/payload-config.js +67 -0
- package/src/memory/payloadCodec.d.ts +55 -0
- package/src/memory/payloadCodec.js +1473 -0
- package/src/memory/regionRegistry.d.ts +17 -0
- package/src/memory/regionRegistry.js +285 -0
- package/src/memory/shared-buffer-io.d.ts +55 -0
- package/src/memory/shared-buffer-io.js +403 -0
- package/src/permission/compatibility.d.ts +28 -0
- package/src/permission/compatibility.js +239 -0
- package/src/permission/index.d.ts +4 -0
- package/src/permission/index.js +3 -0
- package/src/permission/protocol.d.ts +167 -0
- package/src/permission/protocol.js +690 -0
- package/src/runtime/balancer.d.ts +19 -0
- package/src/runtime/balancer.js +149 -0
- 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.d.ts +40 -0
- package/src/runtime/dispatcher.js +142 -0
- package/src/runtime/inline-executor.d.ts +10 -0
- package/src/runtime/inline-executor.js +294 -0
- package/src/runtime/pool.d.ts +44 -0
- package/src/runtime/pool.js +472 -0
- package/src/runtime/process-worker.d.ts +92 -0
- package/src/runtime/process-worker.js +713 -0
- package/src/runtime/tx-queue.d.ts +28 -0
- package/src/runtime/tx-queue.js +158 -0
- package/src/shared/abortSignal.d.ts +23 -0
- package/src/shared/abortSignal.js +134 -0
- package/src/types.d.ts +399 -0
- package/src/types.js +2 -0
- package/src/utils/http.d.ts +29 -0
- package/src/utils/http.js +100 -0
- package/src/worker/bootstrap.d.ts +5 -0
- package/src/worker/bootstrap.js +78 -0
- package/src/worker/composable-runners.d.ts +12 -0
- package/src/worker/composable-runners.js +98 -0
- package/src/worker/loop.d.ts +3 -0
- package/src/worker/loop.js +395 -0
- package/src/worker/process-worker-bootstrap.d.ts +8 -0
- package/src/worker/process-worker-bootstrap.js +160 -0
- package/src/worker/rx-queue.d.ts +25 -0
- package/src/worker/rx-queue.js +173 -0
- package/src/worker/safety/index.d.ts +4 -0
- package/src/worker/safety/index.js +4 -0
- package/src/worker/safety/performance.d.ts +1 -0
- package/src/worker/safety/performance.js +17 -0
- package/src/worker/safety/process.d.ts +2 -0
- package/src/worker/safety/process.js +79 -0
- package/src/worker/safety/startup.d.ts +16 -0
- package/src/worker/safety/startup.js +30 -0
- package/src/worker/safety/worker-data.d.ts +2 -0
- package/src/worker/safety/worker-data.js +36 -0
- package/src/worker/task-loader.d.ts +28 -0
- package/src/worker/task-loader.js +76 -0
- package/src/worker/timers.d.ts +18 -0
- package/src/worker/timers.js +118 -0
- package/unsafe.d.ts +1 -71
- package/unsafe.js +1 -878
- package/utils.d.ts +1 -31
- package/utils.js +1 -116
package/src/types.d.ts
ADDED
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
import { endpointSymbol } from "./common/task-symbol.js";
|
|
2
|
+
import type { Envelope, EnvelopeBody, EnvelopeHeader } from "./common/envelope.js";
|
|
3
|
+
import type { LockBufferTextCompat, SharedBufferTextCompat } from "./common/shared-buffer-text.js";
|
|
4
|
+
import type { SharedBufferRegion, SharedBufferSource } from "./common/shared-buffer-region.js";
|
|
5
|
+
import type { PayloadBufferMode, PayloadBufferOptions } from "./memory/payload-config.js";
|
|
6
|
+
import type { PermissionProtocol, PermissionProtocolInput, ResolvedPermissionProtocol } from "./permission/protocol.js";
|
|
7
|
+
type WorkerCall = {
|
|
8
|
+
fnNumber: number;
|
|
9
|
+
timeout?: TaskTimeout;
|
|
10
|
+
abortSignal?: AbortSignalOption;
|
|
11
|
+
};
|
|
12
|
+
type WorkerInvoke = (args: Uint8Array) => Promise<unknown>;
|
|
13
|
+
interface WorkerContext {
|
|
14
|
+
txIdle(): boolean;
|
|
15
|
+
call(descriptor: WorkerCall): WorkerInvoke;
|
|
16
|
+
kills(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
type CreateContext = WorkerContext;
|
|
19
|
+
type WorkerData = {
|
|
20
|
+
sab: SharedBufferSource;
|
|
21
|
+
abortSignalSAB?: SharedBufferSource;
|
|
22
|
+
abortSignalMax?: number;
|
|
23
|
+
list: string[];
|
|
24
|
+
ids: number[];
|
|
25
|
+
names: string[];
|
|
26
|
+
thread: number;
|
|
27
|
+
totalNumberOfThread: number;
|
|
28
|
+
debug?: DebugOptions;
|
|
29
|
+
startAt: number;
|
|
30
|
+
workerOptions?: WorkerSettings;
|
|
31
|
+
at: number[];
|
|
32
|
+
lock: LockBuffers;
|
|
33
|
+
returnLock: LockBuffers;
|
|
34
|
+
payloadConfig?: PayloadBufferOptions;
|
|
35
|
+
bufferReferenceReturn?: "copy" | "borrow";
|
|
36
|
+
permission?: ResolvedPermissionProtocol;
|
|
37
|
+
};
|
|
38
|
+
type UnsafeOptions = {
|
|
39
|
+
/**
|
|
40
|
+
* Experimental `BufferReference` return lifetime.
|
|
41
|
+
*
|
|
42
|
+
* `"copy"` is safe after worker release. `"borrow"` skips the Deno/Bun copy,
|
|
43
|
+
* but must be released before producer shutdown and must not outlive its ref.
|
|
44
|
+
*/
|
|
45
|
+
BufferReferenceReturn?: "copy" | "borrow";
|
|
46
|
+
};
|
|
47
|
+
type LockBuffers = {
|
|
48
|
+
headers: SharedBufferSource;
|
|
49
|
+
headerSlotStrideU32?: number;
|
|
50
|
+
lockSector: SharedBufferSource;
|
|
51
|
+
payload: SharedBufferSource;
|
|
52
|
+
payloadSector: SharedBufferSource;
|
|
53
|
+
textCompat?: LockBufferTextCompat;
|
|
54
|
+
};
|
|
55
|
+
type JSONValue = string | number | boolean | null | JSONArray | JSONObject;
|
|
56
|
+
interface JSONObject {
|
|
57
|
+
[key: string]: JSONValue;
|
|
58
|
+
}
|
|
59
|
+
interface JSONArray extends Array<JSONValue> {
|
|
60
|
+
}
|
|
61
|
+
type Serializable = string | object | number | boolean | bigint;
|
|
62
|
+
type ValidInput = bigint | void | JSONValue | symbol | ArrayBuffer | Uint8Array | Int32Array | Float64Array | BigInt64Array | BigUint64Array | DataView | Error | Date | Envelope<EnvelopeHeader, EnvelopeBody>;
|
|
63
|
+
type Args = ValidInput | Serializable;
|
|
64
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
65
|
+
/** Blob payloads are not supported; pass ArrayBuffer/typed arrays instead. */
|
|
66
|
+
type NoBlob<T> = T extends Blob ? never : T;
|
|
67
|
+
/** Task input may be a direct value or native Promise; thenables are plain values. */
|
|
68
|
+
type TaskInput = NoBlob<Args> | Promise<NoBlob<Args>>;
|
|
69
|
+
/** Per-call timeout. A number is milliseconds; object form can return a default. */
|
|
70
|
+
type TaskTimeout = number | {
|
|
71
|
+
time: number;
|
|
72
|
+
maybe?: true;
|
|
73
|
+
default?: unknown;
|
|
74
|
+
error?: unknown;
|
|
75
|
+
};
|
|
76
|
+
type BivariantCallback<Args extends unknown[], R> = {
|
|
77
|
+
bivarianceHack(...args: Args): R;
|
|
78
|
+
}["bivarianceHack"];
|
|
79
|
+
type AbortSignalConfig = {
|
|
80
|
+
readonly hasAborted: true;
|
|
81
|
+
};
|
|
82
|
+
/** `true` or config injects an abort toolkit as the task's second parameter. */
|
|
83
|
+
type AbortSignalOption = true | AbortSignalConfig | undefined;
|
|
84
|
+
type AbortSignalMethods<AS extends AbortSignalOption> = AS extends undefined ? never : {
|
|
85
|
+
hasAborted: () => boolean;
|
|
86
|
+
now: () => number;
|
|
87
|
+
};
|
|
88
|
+
type AbortSignalToolkit<AS extends AbortSignalOption> = AbortSignalMethods<AS>;
|
|
89
|
+
type TaskFn<A extends TaskInput, B extends Args, AS extends AbortSignalOption = undefined> = BivariantCallback<AS extends undefined ? [NoBlob<Awaited<A>>] : [NoBlob<Awaited<A>>, AbortSignalToolkit<AS>], MaybePromise<NoBlob<B>>>;
|
|
90
|
+
type PromiseWithMaybeReject<T> = Promise<T> & {
|
|
91
|
+
reject: (reason?: unknown) => void;
|
|
92
|
+
};
|
|
93
|
+
type TaskLike<AS extends AbortSignalOption = AbortSignalOption> = {
|
|
94
|
+
readonly f: (...args: any[]) => any;
|
|
95
|
+
} & (AS extends undefined ? {
|
|
96
|
+
readonly abortSignal?: undefined;
|
|
97
|
+
} : {
|
|
98
|
+
readonly abortSignal: AS;
|
|
99
|
+
});
|
|
100
|
+
type TaskFunctionLike = (...args: any[]) => any;
|
|
101
|
+
type Composed<A extends TaskInput = Args, B extends Args = Args, AS extends AbortSignalOption = undefined> = FixPoint<A, B, AS> & SecondPart;
|
|
102
|
+
type tasks = Record<string, Composed<any, any, any> | TaskFunctionLike>;
|
|
103
|
+
type ComposedWithKey = Composed<any, any, AbortSignalOption> & {
|
|
104
|
+
name: string;
|
|
105
|
+
};
|
|
106
|
+
type PromiseWrapped<F extends (...args: any[]) => any, AS extends AbortSignalOption = undefined> = (...args: PromisifyCallArgs<F, AS>) => AS extends undefined ? Promise<Awaited<ReturnType<F>>> : PromiseWithMaybeReject<Awaited<ReturnType<F>>>;
|
|
107
|
+
type PromiseInput<T> = T | Promise<T>;
|
|
108
|
+
type PromisifyArgs<T extends unknown[]> = {
|
|
109
|
+
[K in keyof T]: PromiseInput<T[K]>;
|
|
110
|
+
};
|
|
111
|
+
type NormalizeUndefinedSingleArg<T extends unknown[]> = T extends [undefined] ? [] | [undefined] : T;
|
|
112
|
+
type AbortAwareCallArgs<T extends unknown[]> = T extends [
|
|
113
|
+
...infer Head,
|
|
114
|
+
AbortSignalToolkit<any>
|
|
115
|
+
] ? NormalizeUndefinedSingleArg<Head> : NormalizeUndefinedSingleArg<T>;
|
|
116
|
+
type HostCallArgs<F extends (...args: any[]) => any, AS extends AbortSignalOption> = AS extends undefined ? Parameters<F> : AbortAwareCallArgs<Parameters<F>>;
|
|
117
|
+
type PromisifyCallArgs<F extends (...args: any[]) => any, AS extends AbortSignalOption> = HostCallArgs<F, AS> extends infer T ? T extends unknown[] ? PromisifyArgs<T> : never : never;
|
|
118
|
+
type TaskCallable<T> = T extends TaskLike<any> ? T["f"] : T extends TaskFunctionLike ? T : never;
|
|
119
|
+
type AbortSignalOfTask<T> = T extends {
|
|
120
|
+
readonly abortSignal: infer AS;
|
|
121
|
+
} ? Extract<AS, AbortSignalOption> : undefined;
|
|
122
|
+
type FunctionMapType<T extends Record<string, TaskLike<any> | TaskFunctionLike>> = {
|
|
123
|
+
[K in keyof T]: PromiseWrapped<TaskCallable<T[K]>, AbortSignalOfTask<T[K]>>;
|
|
124
|
+
};
|
|
125
|
+
interface FixPointBase<A extends TaskInput, B extends Args, AS extends AbortSignalOption = undefined> {
|
|
126
|
+
/** Worker function. It receives one value; use a tuple/object for many inputs. */
|
|
127
|
+
readonly f: TaskFn<A, B, AS>;
|
|
128
|
+
/** Soft call timeout. Use `worker.hardTimeoutMs` for runaway CPU walls. */
|
|
129
|
+
readonly timeout?: TaskTimeout;
|
|
130
|
+
}
|
|
131
|
+
type FixPoint<A extends TaskInput, B extends Args, AS extends AbortSignalOption = undefined> = FixPointBase<A, B, AS> & (AS extends undefined ? {
|
|
132
|
+
readonly abortSignal?: undefined;
|
|
133
|
+
} : {
|
|
134
|
+
readonly abortSignal: AS;
|
|
135
|
+
});
|
|
136
|
+
type ImportTaskOptions<A extends TaskInput = void, B extends Args = void, AS extends AbortSignalOption = undefined> = Omit<FixPoint<A, B, AS>, "f"> & {
|
|
137
|
+
/** Module imported by the worker only. Relative paths resolve from caller. */
|
|
138
|
+
readonly href: string;
|
|
139
|
+
/** Plain function export name. Defaults to `"default"`; do not target `task()`. */
|
|
140
|
+
readonly name?: string;
|
|
141
|
+
};
|
|
142
|
+
type SecondPart = {
|
|
143
|
+
readonly [endpointSymbol]: true;
|
|
144
|
+
readonly id: number;
|
|
145
|
+
/** Logical export order used to match worker tasks before names are known. */
|
|
146
|
+
readonly at: number;
|
|
147
|
+
readonly importedFrom: string;
|
|
148
|
+
/**
|
|
149
|
+
* Imported tasks stay on worker lanes so imports run under worker permissions.
|
|
150
|
+
*/
|
|
151
|
+
readonly imported?: boolean;
|
|
152
|
+
};
|
|
153
|
+
type SingleTaskPool<A extends TaskInput = Args, B extends Args = Args, AS extends AbortSignalOption = undefined> = {
|
|
154
|
+
/** Invoke the single task. Arguments may be native Promises. */
|
|
155
|
+
call: PromiseWrapped<TaskFn<A, B, AS>, AS>;
|
|
156
|
+
/** Await worker teardown now. `using` disposes at scope exit without awaiting. */
|
|
157
|
+
shutdown: (delayMs?: number) => Promise<void>;
|
|
158
|
+
/** Starts shutdown at scope exit. Use `shutdown()` when you must await it. */
|
|
159
|
+
[Symbol.dispose]: () => void;
|
|
160
|
+
};
|
|
161
|
+
type Pool<T extends Record<string, TaskLike<any> | TaskFunctionLike>> = {
|
|
162
|
+
/** Await worker teardown now. `using` disposes at scope exit without awaiting. */
|
|
163
|
+
shutdown: (delayMs?: number) => Promise<void>;
|
|
164
|
+
/** Starts shutdown at scope exit. Use `shutdown()` when you must await it. */
|
|
165
|
+
[Symbol.dispose]: () => void;
|
|
166
|
+
/**
|
|
167
|
+
* Typed task callers. Each call accepts the task input or a native Promise.
|
|
168
|
+
* Thrown errors/rejections reject here as Error objects with cause chains.
|
|
169
|
+
*/
|
|
170
|
+
call: FunctionMapType<T>;
|
|
171
|
+
};
|
|
172
|
+
type ReturnFixed<A extends TaskInput = undefined, B extends Args = undefined, AS extends AbortSignalOption = undefined> = FixPoint<A, B, AS> & SecondPart & {
|
|
173
|
+
createPool: (options?: CreatePool) => SingleTaskPool<A, B, AS>;
|
|
174
|
+
};
|
|
175
|
+
type External = unknown;
|
|
176
|
+
type Inliner = {
|
|
177
|
+
position?: "first" | "last";
|
|
178
|
+
/**
|
|
179
|
+
* Inline tasks per event loop tick.
|
|
180
|
+
* Defaults to 1 when inliner is enabled.
|
|
181
|
+
*/
|
|
182
|
+
batchSize?: number;
|
|
183
|
+
/**
|
|
184
|
+
* Minimum in-flight calls before routing can use the inline host lane.
|
|
185
|
+
* Defaults to 1 (inline lane available immediately).
|
|
186
|
+
*/
|
|
187
|
+
dispatchThreshold?: number;
|
|
188
|
+
};
|
|
189
|
+
type BalancerStrategy = "roundRobin" | "robinRound" | "firstIdle" | "randomLane" | "firstIdleOrRandom";
|
|
190
|
+
type Balancer = BalancerStrategy | {
|
|
191
|
+
/**
|
|
192
|
+
* Optional. Defaults to "roundRobin".
|
|
193
|
+
*/
|
|
194
|
+
strategy?: BalancerStrategy;
|
|
195
|
+
};
|
|
196
|
+
/** Debug namespaces for host setup, worker state, imports, globals, and lifecycle. */
|
|
197
|
+
type DebugNamespace = "host" | "globals" | "signals" | "imports" | "lifecycle";
|
|
198
|
+
type DebugFlags = {
|
|
199
|
+
[Namespace in DebugNamespace]?: boolean;
|
|
200
|
+
};
|
|
201
|
+
/** Pass `true` for all debug, or enable namespaces by name. */
|
|
202
|
+
type DebugOptions = boolean | DebugFlags;
|
|
203
|
+
type WorkerBootstrapContext = {
|
|
204
|
+
readonly thread: number;
|
|
205
|
+
readonly totalNumberOfThread: number;
|
|
206
|
+
readonly runtime: "node" | "deno" | "bun" | "unknown";
|
|
207
|
+
};
|
|
208
|
+
type WorkerBootstrapFunction<Data = unknown> = (data: Data, context: WorkerBootstrapContext) => MaybePromise<void>;
|
|
209
|
+
type WorkerBootstrapOptions<Data = unknown> = {
|
|
210
|
+
/**
|
|
211
|
+
* Module imported inside the worker before task modules are imported.
|
|
212
|
+
* Relative paths are resolved from the `createPool(...)` caller.
|
|
213
|
+
*/
|
|
214
|
+
href: string;
|
|
215
|
+
/**
|
|
216
|
+
* Exported bootstrap function name. Defaults to `"default"`.
|
|
217
|
+
*/
|
|
218
|
+
name?: string;
|
|
219
|
+
/**
|
|
220
|
+
* Structured data passed to the bootstrap function.
|
|
221
|
+
*/
|
|
222
|
+
data?: Data;
|
|
223
|
+
};
|
|
224
|
+
/** Native worker artifact and on-demand compiler settings. */
|
|
225
|
+
type CompiledWorkerOptions = {
|
|
226
|
+
/**
|
|
227
|
+
* Native executable path. Relative paths resolve from the createPool caller.
|
|
228
|
+
* Defaults to the task module path with its extension replaced by `.knt`.
|
|
229
|
+
*/
|
|
230
|
+
artifact?: string;
|
|
231
|
+
/**
|
|
232
|
+
* Versioned metadata sidecar. Defaults to `<artifact>.json`.
|
|
233
|
+
*/
|
|
234
|
+
manifest?: string;
|
|
235
|
+
/**
|
|
236
|
+
* Build a missing/incompatible artifact, or use `"always"` to rebuild once
|
|
237
|
+
* whenever a pool is created. Defaults to true.
|
|
238
|
+
*/
|
|
239
|
+
build?: boolean | "always";
|
|
240
|
+
/**
|
|
241
|
+
* Porffor main executable or checkout. Defaults to PORFFOR_MAIN/PORF, then
|
|
242
|
+
* `porf` on PATH; a pinned compiler is cached locally when none is present.
|
|
243
|
+
*/
|
|
244
|
+
compiler?: string;
|
|
245
|
+
};
|
|
246
|
+
type CompiledWorkerSource = string | URL | {
|
|
247
|
+
readonly importedFrom: string;
|
|
248
|
+
};
|
|
249
|
+
type CompiledWorkerCheck = {
|
|
250
|
+
/** True only when the executable and compatible manifest both validate. */
|
|
251
|
+
compiled: boolean;
|
|
252
|
+
artifact: string;
|
|
253
|
+
manifest: string;
|
|
254
|
+
reason?: string;
|
|
255
|
+
compiler?: string;
|
|
256
|
+
protocol?: string;
|
|
257
|
+
tasks?: readonly string[];
|
|
258
|
+
};
|
|
259
|
+
type WorkerSettings = {
|
|
260
|
+
resolveAfterFinishingAll?: true;
|
|
261
|
+
/**
|
|
262
|
+
* Privileged async worker hook that runs once before task modules import.
|
|
263
|
+
* Use it to shape the worker environment before user task code loads.
|
|
264
|
+
*/
|
|
265
|
+
bootstrap?: WorkerBootstrapOptions;
|
|
266
|
+
/**
|
|
267
|
+
* Experimental worker runtime.
|
|
268
|
+
* "thread" uses Worker/worker_threads. "process" spawns another JavaScript
|
|
269
|
+
* runtime, useful for process isolation, bwrap, and containers. "compiled"
|
|
270
|
+
* validates and runs a `.knt` native worker, building it on first use.
|
|
271
|
+
*/
|
|
272
|
+
runtime?: "thread" | "process" | "compiled";
|
|
273
|
+
/** Artifact settings used when runtime is "compiled". */
|
|
274
|
+
compiled?: CompiledWorkerOptions;
|
|
275
|
+
/**
|
|
276
|
+
* Runtime executable for process workers. Standalone `"porffor"` selects the
|
|
277
|
+
* compiled backend and rebuilds once per pool; with `runtime: "compiled"` it
|
|
278
|
+
* reuses the validated artifact.
|
|
279
|
+
*/
|
|
280
|
+
processRuntime?: "bun" | "deno" | "node" | "porffor";
|
|
281
|
+
/**
|
|
282
|
+
* Command argv to prepend before the process worker runtime command.
|
|
283
|
+
* Useful for wrappers such as systemd-run, cgexec, nice, taskset, or
|
|
284
|
+
* docker. Knitting appends the runtime command after this prefix.
|
|
285
|
+
*
|
|
286
|
+
* Example:
|
|
287
|
+
* ["systemd-run", "--scope", "-p", "MemoryMax=500M", "-p", "CPUQuota=25%"]
|
|
288
|
+
*
|
|
289
|
+
* With containers, use processSharedMemory: "named", share the IPC
|
|
290
|
+
* namespace, mount the worker files at the same path, and forward
|
|
291
|
+
* KNITTING_PROCESS_WORKER plus KNITTING_PROCESS_WORKER_BOOT.
|
|
292
|
+
*/
|
|
293
|
+
processCommandPrefix?: string[];
|
|
294
|
+
/**
|
|
295
|
+
* How process workers discover their shared-memory control channel.
|
|
296
|
+
*
|
|
297
|
+
* "inherit" keeps the POSIX fd-inheritance path and is the default outside
|
|
298
|
+
* Windows. "named" creates an OS-named shared-memory object that wrappers
|
|
299
|
+
* such as containers can reopen by name when they share the same IPC
|
|
300
|
+
* namespace.
|
|
301
|
+
*/
|
|
302
|
+
processSharedMemory?: ProcessSharedMemoryMode | ProcessSharedMemorySettings;
|
|
303
|
+
timers?: WorkerTimers;
|
|
304
|
+
/**
|
|
305
|
+
* Hard task execution timeout in milliseconds.
|
|
306
|
+
* When exceeded, the pool is force-shutdown to stop runaway CPU tasks.
|
|
307
|
+
*/
|
|
308
|
+
hardTimeoutMs?: number;
|
|
309
|
+
};
|
|
310
|
+
type ProcessSharedMemoryMode = "inherit" | "named";
|
|
311
|
+
type ProcessSharedMemorySettings = {
|
|
312
|
+
mode?: ProcessSharedMemoryMode;
|
|
313
|
+
namePrefix?: string;
|
|
314
|
+
unlinkOnShutdown?: boolean;
|
|
315
|
+
};
|
|
316
|
+
type WorkerTimers = {
|
|
317
|
+
/**
|
|
318
|
+
* Busy-spin budget before parking (microseconds).
|
|
319
|
+
*/
|
|
320
|
+
spinMicroseconds?: number;
|
|
321
|
+
/**
|
|
322
|
+
* Atomics.wait timeout when parked (milliseconds).
|
|
323
|
+
*/
|
|
324
|
+
parkMs?: number;
|
|
325
|
+
/**
|
|
326
|
+
* Atomics.pause duration during spin (nanoseconds).
|
|
327
|
+
* Set to 0 (or less) to disable pause calls.
|
|
328
|
+
*/
|
|
329
|
+
pauseNanoseconds?: number;
|
|
330
|
+
};
|
|
331
|
+
type DispatcherSettings = {
|
|
332
|
+
/**
|
|
333
|
+
* How many immediate notify loops before backoff kicks in.
|
|
334
|
+
*/
|
|
335
|
+
stallFreeLoops?: number;
|
|
336
|
+
/**
|
|
337
|
+
* Max backoff delay (milliseconds).
|
|
338
|
+
*/
|
|
339
|
+
maxBackoffMs?: number;
|
|
340
|
+
/**
|
|
341
|
+
* Host dispatcher topology.
|
|
342
|
+
* - `"per-thread"`: each worker owns its dispatcher and macro channel.
|
|
343
|
+
* - `"serial-channel"`: each worker keeps its own dispatcher check state, but
|
|
344
|
+
* one shared channel runs all lane checks from first to last.
|
|
345
|
+
*
|
|
346
|
+
* Experimental default: `"per-thread"` on Bun or with one worker, otherwise
|
|
347
|
+
* `"serial-channel"` for multi-worker Node/Deno pools. Can also be forced
|
|
348
|
+
* with the `KNITTING_DISPATCHER` env var (`serial-channel` or `per-thread`).
|
|
349
|
+
*/
|
|
350
|
+
dispatcher?: "per-thread" | "serial-channel";
|
|
351
|
+
};
|
|
352
|
+
type CreatePool = {
|
|
353
|
+
/** Number of workers. Default: 1. */
|
|
354
|
+
threads?: number;
|
|
355
|
+
/** Add a host inline lane for regular tasks. Imported tasks still use workers. */
|
|
356
|
+
inliner?: Inliner;
|
|
357
|
+
balancer?: Balancer;
|
|
358
|
+
worker?: WorkerSettings;
|
|
359
|
+
/**
|
|
360
|
+
* Payload transport settings. Default dynamic payload cap is about 8 MiB
|
|
361
|
+
* (`payloadMaxByteLength >> 3`, with a 64 MiB growth cap).
|
|
362
|
+
*/
|
|
363
|
+
payload?: PayloadBufferOptions;
|
|
364
|
+
/**
|
|
365
|
+
* Experimental unsafe options.
|
|
366
|
+
*/
|
|
367
|
+
unsafe?: UnsafeOptions;
|
|
368
|
+
/**
|
|
369
|
+
* Abort-aware signal pool capacity.
|
|
370
|
+
* Defaults to `258`.
|
|
371
|
+
*/
|
|
372
|
+
abortSignalCapacity?: number;
|
|
373
|
+
/**
|
|
374
|
+
* Host dispatcher backoff and scheduling options.
|
|
375
|
+
*/
|
|
376
|
+
host?: DispatcherSettings;
|
|
377
|
+
/**
|
|
378
|
+
* Extra Node.js execArgv flags for worker threads (e.g. ["--expose-gc"]).
|
|
379
|
+
* Defaults to process.execArgv plus "--expose-gc" when allowed.
|
|
380
|
+
*/
|
|
381
|
+
workerExecArgv?: string[];
|
|
382
|
+
/**
|
|
383
|
+
* Runtime permission protocol.
|
|
384
|
+
* Omit to use strict defaults with `allowImport: true`; worker console is
|
|
385
|
+
* quiet unless `permission: { console: true }`.
|
|
386
|
+
*
|
|
387
|
+
* Task code cannot terminate the host: process/Deno exit APIs are blocked.
|
|
388
|
+
* Use `"strict"` (default for object mode) or `"unsafe"`.
|
|
389
|
+
* Accepts object form for fine-grained permission controls.
|
|
390
|
+
*/
|
|
391
|
+
permission?: PermissionProtocolInput;
|
|
392
|
+
debug?: DebugOptions;
|
|
393
|
+
source?: string;
|
|
394
|
+
};
|
|
395
|
+
export type { AbortSignalConfig as AbortSignalConfig, AbortSignalMethods as AbortSignalMethods, AbortSignalOption as AbortSignalOption, AbortSignalToolkit as AbortSignalToolkit, Args as Args, Balancer as Balancer, BalancerStrategy as BalancerStrategy, CompiledWorkerCheck as CompiledWorkerCheck, CompiledWorkerOptions as CompiledWorkerOptions, CompiledWorkerSource as CompiledWorkerSource, Composed as Composed, ComposedWithKey as ComposedWithKey, CreateContext as CreateContext, CreatePool as CreatePool, DebugNamespace as DebugNamespace, DebugOptions as DebugOptions, DispatcherSettings as DispatcherSettings, Envelope as Envelope, EnvelopeBody as EnvelopeBody, EnvelopeHeader as EnvelopeHeader, External as External, FixPoint as FixPoint, FunctionMapType as FunctionMapType, ImportTaskOptions as ImportTaskOptions, Inliner as Inliner, LockBuffers as LockBuffers, LockBufferTextCompat as LockBufferTextCompat, MaybePromise as MaybePromise, PayloadBufferMode as PayloadBufferMode, PayloadBufferOptions as PayloadBufferOptions, PermissionProtocol as PermissionProtocol, PermissionProtocolInput as PermissionProtocolInput, Pool as Pool, ProcessSharedMemoryMode as ProcessSharedMemoryMode, ProcessSharedMemorySettings as ProcessSharedMemorySettings, ResolvedPermissionProtocol as ResolvedPermissionProtocol, ReturnFixed as ReturnFixed, SecondPart as SecondPart, SharedBufferRegion as SharedBufferRegion, SharedBufferSource as SharedBufferSource, SharedBufferTextCompat as SharedBufferTextCompat, SingleTaskPool as SingleTaskPool, TaskFn as TaskFn, TaskInput as TaskInput, tasks as tasks, TaskTimeout as TaskTimeout, ValidInput as ValidInput, WorkerBootstrapContext as WorkerBootstrapContext, WorkerBootstrapFunction as WorkerBootstrapFunction, WorkerBootstrapOptions as WorkerBootstrapOptions, WorkerCall as WorkerCall, WorkerContext as WorkerContext, WorkerData as WorkerData, WorkerInvoke as WorkerInvoke, WorkerSettings as WorkerSettings, WorkerTimers as WorkerTimers, };
|
|
396
|
+
import type { Task as TaskType } from "./memory/lock.js";
|
|
397
|
+
export { LockBound as LockBound, PayloadBuffer as PayloadBuffer, PayloadSignal as PayloadSignal, TaskIndex as TaskIndex, } from "./memory/lock.js";
|
|
398
|
+
export type Task = TaskType;
|
|
399
|
+
export type { RegisterMalloc as RegisterMalloc } from "./memory/regionRegistry.js";
|
package/src/types.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type BufferLike = ArrayBuffer | SharedArrayBuffer | ArrayBufferView;
|
|
2
|
+
export type NumberFormat = "f64" | "f32" | "i32";
|
|
3
|
+
export type NumberBufferOptions = {
|
|
4
|
+
format?: NumberFormat;
|
|
5
|
+
};
|
|
6
|
+
/** View ArrayBuffer/SharedArrayBuffer/typed-array bytes as Uint8Array. */
|
|
7
|
+
export declare const bufferToBytes: (source: BufferLike) => Uint8Array;
|
|
8
|
+
/** Copy bytes into a SharedArrayBuffer for zero-copy worker inputs. */
|
|
9
|
+
export declare const bytesToBuffer: (source: BufferLike) => SharedArrayBuffer;
|
|
10
|
+
/** Decode UTF-8 bytes from ArrayBuffer/SharedArrayBuffer/typed-array input. */
|
|
11
|
+
export declare const bufferToString: (source: BufferLike) => string;
|
|
12
|
+
/** Encode UTF-8 text into a SharedArrayBuffer. */
|
|
13
|
+
export declare const stringToBuffer: (text: string) => SharedArrayBuffer;
|
|
14
|
+
/** Decode JSON from UTF-8 bytes. */
|
|
15
|
+
export declare const bufferToJson: <T = unknown>(source: BufferLike) => T;
|
|
16
|
+
/** Encode JSON into a SharedArrayBuffer. */
|
|
17
|
+
export declare const jsonToBuffer: (value: unknown) => SharedArrayBuffer;
|
|
18
|
+
/** Encode numbers into a SharedArrayBuffer (`f64` by default). */
|
|
19
|
+
export declare const numbersToBuffer: (numbers: ArrayLike<number>, options?: NumberBufferOptions) => SharedArrayBuffer;
|
|
20
|
+
/** Decode numeric typed-array views from worker-friendly byte buffers. */
|
|
21
|
+
export declare function bufferToNumbers(source: BufferLike, options?: {
|
|
22
|
+
format?: "f64";
|
|
23
|
+
}): Float64Array;
|
|
24
|
+
export declare function bufferToNumbers(source: BufferLike, options: {
|
|
25
|
+
format: "f32";
|
|
26
|
+
}): Float32Array;
|
|
27
|
+
export declare function bufferToNumbers(source: BufferLike, options: {
|
|
28
|
+
format: "i32";
|
|
29
|
+
}): Int32Array;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
const nodeBuffer = globalThis.Buffer;
|
|
2
|
+
const hasNodeBuffer = typeof nodeBuffer?.from === "function" &&
|
|
3
|
+
typeof nodeBuffer?.byteLength === "function";
|
|
4
|
+
const textEncoder = new TextEncoder();
|
|
5
|
+
const textDecoder = new TextDecoder();
|
|
6
|
+
const hasSharedArrayBuffer = typeof SharedArrayBuffer === "function";
|
|
7
|
+
const isSharedArrayBuffer = (value) => hasSharedArrayBuffer && value instanceof SharedArrayBuffer;
|
|
8
|
+
const BYTES_PER_ELEMENT = {
|
|
9
|
+
f64: 8,
|
|
10
|
+
f32: 4,
|
|
11
|
+
i32: 4,
|
|
12
|
+
};
|
|
13
|
+
const toBytes = (source) => {
|
|
14
|
+
if (source instanceof Uint8Array)
|
|
15
|
+
return source;
|
|
16
|
+
if (ArrayBuffer.isView(source)) {
|
|
17
|
+
return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
|
|
18
|
+
}
|
|
19
|
+
if (source instanceof ArrayBuffer || isSharedArrayBuffer(source)) {
|
|
20
|
+
return new Uint8Array(source);
|
|
21
|
+
}
|
|
22
|
+
throw new TypeError("Expected an ArrayBuffer, SharedArrayBuffer, or typed-array view.");
|
|
23
|
+
};
|
|
24
|
+
/** View ArrayBuffer/SharedArrayBuffer/typed-array bytes as Uint8Array. */
|
|
25
|
+
export const bufferToBytes = (source) => toBytes(source);
|
|
26
|
+
/** Copy bytes into a SharedArrayBuffer for zero-copy worker inputs. */
|
|
27
|
+
export const bytesToBuffer = (source) => {
|
|
28
|
+
const bytes = toBytes(source);
|
|
29
|
+
const sab = new SharedArrayBuffer(bytes.byteLength);
|
|
30
|
+
new Uint8Array(sab).set(bytes);
|
|
31
|
+
return sab;
|
|
32
|
+
};
|
|
33
|
+
const makeNumberView = (format, buffer, byteOffset, length) => {
|
|
34
|
+
switch (format) {
|
|
35
|
+
case "f64":
|
|
36
|
+
return new Float64Array(buffer, byteOffset, length);
|
|
37
|
+
case "f32":
|
|
38
|
+
return new Float32Array(buffer, byteOffset, length);
|
|
39
|
+
case "i32":
|
|
40
|
+
return new Int32Array(buffer, byteOffset, length);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
/** Decode UTF-8 bytes from ArrayBuffer/SharedArrayBuffer/typed-array input. */
|
|
44
|
+
export const bufferToString = (source) => {
|
|
45
|
+
const bytes = toBytes(source);
|
|
46
|
+
if (hasNodeBuffer) {
|
|
47
|
+
return nodeBuffer
|
|
48
|
+
.from(bytes.buffer, bytes.byteOffset, bytes.byteLength)
|
|
49
|
+
.toString("utf8");
|
|
50
|
+
}
|
|
51
|
+
return textDecoder.decode(bytes);
|
|
52
|
+
};
|
|
53
|
+
/** Encode UTF-8 text into a SharedArrayBuffer. */
|
|
54
|
+
export const stringToBuffer = (text) => {
|
|
55
|
+
if (typeof text !== "string") {
|
|
56
|
+
throw new TypeError("stringToBuffer expects a string.");
|
|
57
|
+
}
|
|
58
|
+
if (hasNodeBuffer) {
|
|
59
|
+
const byteLength = nodeBuffer.byteLength(text, "utf8");
|
|
60
|
+
const sab = new SharedArrayBuffer(byteLength);
|
|
61
|
+
nodeBuffer.from(sab).write(text, "utf8");
|
|
62
|
+
return sab;
|
|
63
|
+
}
|
|
64
|
+
const encoded = textEncoder.encode(text);
|
|
65
|
+
const sab = new SharedArrayBuffer(encoded.byteLength);
|
|
66
|
+
new Uint8Array(sab).set(encoded);
|
|
67
|
+
return sab;
|
|
68
|
+
};
|
|
69
|
+
/** Decode JSON from UTF-8 bytes. */
|
|
70
|
+
export const bufferToJson = (source) => JSON.parse(bufferToString(source));
|
|
71
|
+
/** Encode JSON into a SharedArrayBuffer. */
|
|
72
|
+
export const jsonToBuffer = (value) => {
|
|
73
|
+
const text = JSON.stringify(value);
|
|
74
|
+
if (typeof text !== "string") {
|
|
75
|
+
throw new TypeError("jsonToBuffer: value is not JSON-serializable (stringify returned undefined).");
|
|
76
|
+
}
|
|
77
|
+
return stringToBuffer(text);
|
|
78
|
+
};
|
|
79
|
+
/** Encode numbers into a SharedArrayBuffer (`f64` by default). */
|
|
80
|
+
export const numbersToBuffer = (numbers, options) => {
|
|
81
|
+
const format = options?.format ?? "f64";
|
|
82
|
+
const sab = new SharedArrayBuffer(numbers.length * BYTES_PER_ELEMENT[format]);
|
|
83
|
+
makeNumberView(format, sab, 0, numbers.length).set(numbers);
|
|
84
|
+
return sab;
|
|
85
|
+
};
|
|
86
|
+
export function bufferToNumbers(source, options) {
|
|
87
|
+
const format = options?.format ?? "f64";
|
|
88
|
+
const bytesPer = BYTES_PER_ELEMENT[format];
|
|
89
|
+
const bytes = toBytes(source);
|
|
90
|
+
if (bytes.byteLength % bytesPer !== 0) {
|
|
91
|
+
throw new RangeError(`bufferToNumbers: byte length ${bytes.byteLength} is not a multiple of ` +
|
|
92
|
+
`${bytesPer} for format "${format}".`);
|
|
93
|
+
}
|
|
94
|
+
const length = bytes.byteLength / bytesPer;
|
|
95
|
+
if (bytes.byteOffset % bytesPer === 0) {
|
|
96
|
+
return makeNumberView(format, bytes.buffer, bytes.byteOffset, length);
|
|
97
|
+
}
|
|
98
|
+
const copy = bytes.slice();
|
|
99
|
+
return makeNumberView(format, copy.buffer, 0, length);
|
|
100
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
import { RUNTIME } from "../common/runtime.js";
|
|
10
|
+
import { toModuleUrl } from "../common/module-url.js";
|
|
11
|
+
import { ProcessSharedBuffer } from "../connections/process-shared-buffer.js";
|
|
12
|
+
const DEFAULT_BOOTSTRAP_EXPORT_NAME = "default";
|
|
13
|
+
const isWorkerBootstrapOptions = (value) => {
|
|
14
|
+
if (!value || typeof value !== "object")
|
|
15
|
+
return false;
|
|
16
|
+
const candidate = value;
|
|
17
|
+
return typeof candidate.href === "string" &&
|
|
18
|
+
candidate.href.length > 0 &&
|
|
19
|
+
(candidate.name === undefined ||
|
|
20
|
+
(typeof candidate.name === "string" && candidate.name.length > 0));
|
|
21
|
+
};
|
|
22
|
+
const isProcessSharedBufferMetadata = (value) => {
|
|
23
|
+
try {
|
|
24
|
+
ProcessSharedBuffer.fromMetadata(value);
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const reviveWorkerBootstrapValue = (value, seen = new WeakMap()) => {
|
|
32
|
+
if (isProcessSharedBufferMetadata(value)) {
|
|
33
|
+
return ProcessSharedBuffer.fromMetadata(value);
|
|
34
|
+
}
|
|
35
|
+
if (value === null || typeof value !== "object")
|
|
36
|
+
return value;
|
|
37
|
+
const existing = seen.get(value);
|
|
38
|
+
if (existing !== undefined)
|
|
39
|
+
return existing;
|
|
40
|
+
if (Array.isArray(value)) {
|
|
41
|
+
const out = [];
|
|
42
|
+
seen.set(value, out);
|
|
43
|
+
for (const item of value) {
|
|
44
|
+
out.push(reviveWorkerBootstrapValue(item, seen));
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
const prototype = Object.getPrototypeOf(value);
|
|
49
|
+
if (prototype !== Object.prototype && prototype !== null)
|
|
50
|
+
return value;
|
|
51
|
+
const out = {};
|
|
52
|
+
seen.set(value, out);
|
|
53
|
+
for (const [key, item] of Object.entries(value)) {
|
|
54
|
+
out[key] = reviveWorkerBootstrapValue(item, seen);
|
|
55
|
+
}
|
|
56
|
+
return out;
|
|
57
|
+
};
|
|
58
|
+
export const runWorkerBootstrap = async ({ bootstrap, thread, totalNumberOfThread, }) => {
|
|
59
|
+
if (bootstrap === undefined)
|
|
60
|
+
return;
|
|
61
|
+
if (!isWorkerBootstrapOptions(bootstrap)) {
|
|
62
|
+
throw new TypeError("worker.bootstrap must include a non-empty href");
|
|
63
|
+
}
|
|
64
|
+
const module = await import(__rewriteRelativeImportExtension(toModuleUrl(bootstrap.href)));
|
|
65
|
+
const name = bootstrap.name ?? DEFAULT_BOOTSTRAP_EXPORT_NAME;
|
|
66
|
+
const selected = module[name];
|
|
67
|
+
if (typeof selected !== "function") {
|
|
68
|
+
const available = Object.keys(module).join(", ");
|
|
69
|
+
throw new TypeError(`worker.bootstrap expected export "${name}" from "${bootstrap.href}" to be a function.` +
|
|
70
|
+
` Available exports: ${available || "(none)"}`);
|
|
71
|
+
}
|
|
72
|
+
const context = Object.freeze({
|
|
73
|
+
thread,
|
|
74
|
+
totalNumberOfThread,
|
|
75
|
+
runtime: RUNTIME,
|
|
76
|
+
});
|
|
77
|
+
await selected(reviveWorkerBootstrapValue(bootstrap.data), context);
|
|
78
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Task } from "../memory/lock.js";
|
|
2
|
+
import type { TimeoutSpec } from "./task-loader.js";
|
|
3
|
+
type WorkerJob = (args: unknown, abortToolkit?: unknown) => unknown;
|
|
4
|
+
type SlotRunner = (slot: Task) => unknown;
|
|
5
|
+
type HasAborted = (signal: number) => boolean;
|
|
6
|
+
export declare const composeWorkerRunner: ({ job, timeout, hasAborted, now, }: {
|
|
7
|
+
job: WorkerJob;
|
|
8
|
+
timeout?: TimeoutSpec;
|
|
9
|
+
hasAborted?: HasAborted;
|
|
10
|
+
now?: () => number;
|
|
11
|
+
}) => SlotRunner;
|
|
12
|
+
export {};
|