knitting 0.1.52 → 0.1.54
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 +36 -25
- package/package.json +1 -1
- package/src/api.d.ts +26 -6
- package/src/api.js +147 -9
- package/src/connections/buffer-reference.d.ts +4 -2
- package/src/connections/buffer-reference.js +4 -2
- package/src/connections/process-shared-buffer.d.ts +6 -0
- package/src/connections/process-shared-buffer.js +6 -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/ipc/transport/shared-memory.d.ts +1 -3
- package/src/memory/payload-config.d.ts +9 -0
- package/src/permission/protocol.d.ts +1 -1
- package/src/permission/protocol.js +30 -20
- package/src/runtime/dispatcher.d.ts +6 -0
- package/src/runtime/pool.d.ts +11 -5
- package/src/runtime/pool.js +50 -44
- package/src/runtime/process-worker.js +2 -1
- package/src/runtime/tx-queue.js +5 -1
- package/src/types.d.ts +45 -38
- package/src/utils/http.d.ts +8 -0
- package/src/utils/http.js +7 -0
- package/src/worker/loop.js +53 -11
- package/src/worker/safety/startup.d.ts +2 -3
- package/src/worker/safety/startup.js +1 -4
- package/src/worker/timers.js +8 -3
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker-side debug handle. Lazily imported (see {@link ./gate.ts}) only when
|
|
3
|
+
* `KNITTING_DEBUG` names at least one namespace, so neither this code nor the
|
|
4
|
+
* baseline snapshot it takes exists when debug is off.
|
|
5
|
+
*
|
|
6
|
+
* Diagnostics go to stderr so they never corrupt a worker's stdout, and every
|
|
7
|
+
* line is tagged with the worker id, runtime, and a clock relative to when this
|
|
8
|
+
* worker's debug initialised. The clock is worker-local on purpose: a main-thread
|
|
9
|
+
* timestamp can't be compared against `performance.now()` here because the time
|
|
10
|
+
* origins differ across the thread/process boundary (it would read negative).
|
|
11
|
+
*/
|
|
12
|
+
import { describeGlobalKey, diffGlobals, snapshotGlobals, } from "./env-diff.js";
|
|
13
|
+
export const initDebug = ({ name, runtime, namespaces }) => {
|
|
14
|
+
const all = namespaces.has("*");
|
|
15
|
+
const enabled = (namespace) => all || namespaces.has(namespace);
|
|
16
|
+
const base = performance.now();
|
|
17
|
+
const tag = `${name}·${runtime}`;
|
|
18
|
+
const log = (namespace, message) => {
|
|
19
|
+
if (!enabled(namespace))
|
|
20
|
+
return;
|
|
21
|
+
const elapsed = (performance.now() - base).toFixed(1);
|
|
22
|
+
console.error(`[${tag}·+${elapsed}ms] ${namespace}: ${message}`);
|
|
23
|
+
};
|
|
24
|
+
// Baseline for the environment diff, taken the moment debug initialises:
|
|
25
|
+
// before worker bootstrap and before any task module is imported. Only paid
|
|
26
|
+
// when `globals` tracing is actually on.
|
|
27
|
+
let previous = enabled("globals")
|
|
28
|
+
? snapshotGlobals()
|
|
29
|
+
: undefined;
|
|
30
|
+
const envPhase = (label) => {
|
|
31
|
+
if (previous === undefined)
|
|
32
|
+
return;
|
|
33
|
+
const current = snapshotGlobals();
|
|
34
|
+
const { added, removed } = diffGlobals(previous, current);
|
|
35
|
+
previous = current;
|
|
36
|
+
if (added.length === 0 && removed.length === 0) {
|
|
37
|
+
log("globals", `${label}: no new globals`);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (added.length > 0) {
|
|
41
|
+
log("globals", `${label} +${added.length}: ${added.map(describeGlobalKey).join(" ")}`);
|
|
42
|
+
}
|
|
43
|
+
if (removed.length > 0) {
|
|
44
|
+
log("globals", `${label} -${removed.length}: ${removed.map(String).join(" ")}`);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
return { enabled, log, envPhase };
|
|
48
|
+
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export type SignalArguments = ReturnType<typeof createSharedMemoryTransport>;
|
|
2
2
|
import { type SharedBufferSource } from "../../common/shared-buffer-region.js";
|
|
3
|
-
import { type DebugOptions } from "../../types.js";
|
|
4
3
|
export declare const TRANSPORT_SIGNAL_BYTES: number;
|
|
5
4
|
export type Sab = {
|
|
6
5
|
size?: number;
|
|
@@ -10,11 +9,10 @@ type SignalForWorker = {
|
|
|
10
9
|
sabObject?: Sab;
|
|
11
10
|
isMain: boolean;
|
|
12
11
|
thread: number;
|
|
13
|
-
debug?: DebugOptions;
|
|
14
12
|
startTime?: number;
|
|
15
13
|
};
|
|
16
14
|
export declare const createSharedMemoryTransport: ({ sabObject, isMain, startTime }: SignalForWorker) => {
|
|
17
|
-
sab: import("../../
|
|
15
|
+
sab: import("../../common/shared-buffer-region.js").SharedBufferRegion;
|
|
18
16
|
op: Int32Array<import("../../common/shared-buffer-region.js").SharedBuffer>;
|
|
19
17
|
startAt: number;
|
|
20
18
|
opView: Int32Array<import("../../common/shared-buffer-region.js").SharedBuffer>;
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { type SharedBufferSource } from "../common/shared-buffer-region.js";
|
|
2
2
|
export declare const PAYLOAD_DEFAULT_MAX_BYTE_LENGTH: number;
|
|
3
3
|
export declare const PAYLOAD_DEFAULT_INITIAL_BYTES: number;
|
|
4
|
+
/** Payload backing mode. Growable uses SAB growth when the runtime supports it. */
|
|
4
5
|
export type PayloadBufferMode = "growable" | "fixed";
|
|
5
6
|
export type PayloadBufferOptions = {
|
|
7
|
+
/** Shared payload buffer mode. Defaults to growable when available. */
|
|
6
8
|
mode?: PayloadBufferMode;
|
|
9
|
+
/** Initial shared payload bytes per direction. Defaults to 4 MiB when growable. */
|
|
7
10
|
payloadInitialBytes?: number;
|
|
11
|
+
/** Shared payload growth cap. Defaults to 64 MiB. */
|
|
8
12
|
payloadMaxByteLength?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Max dynamic payload bytes for one call. Defaults to `payloadMaxByteLength >> 3`
|
|
15
|
+
* (about 8 MiB by default) and must stay `<= payloadMaxByteLength >> 3`.
|
|
16
|
+
* Over-cap payloads reject with `KNT_ERROR_3`.
|
|
17
|
+
*/
|
|
9
18
|
maxPayloadBytes?: number;
|
|
10
19
|
};
|
|
11
20
|
export type ResolvedPayloadBufferOptions = {
|
|
@@ -163,4 +163,4 @@ export declare const resolvePermissionProtocol: ({ permission, modules, }: {
|
|
|
163
163
|
modules?: string[];
|
|
164
164
|
}) => ResolvedPermissionProtocol | undefined;
|
|
165
165
|
export declare const toRuntimePermissionFlags: (protocol: ResolvedPermissionProtocol | undefined) => string[];
|
|
166
|
-
export type {
|
|
166
|
+
export type { DenoPermissionSettings, NodePermissionSettings, PermissionEnvironment, PermissionLegacyMode, PermissionMode, PermissionPath, PermissionProtocol, PermissionProtocolInput, ResolvedPermissionProtocol, SysApiName, };
|
|
@@ -107,11 +107,14 @@ const normalizeSysApiList = (values) => {
|
|
|
107
107
|
return out;
|
|
108
108
|
};
|
|
109
109
|
const hasOwn = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
110
|
-
const normalizeProtocolInput = (input) => !input
|
|
110
|
+
const normalizeProtocolInput = (input) => !input
|
|
111
|
+
? undefined
|
|
112
|
+
: (typeof input === "string" ? { mode: input } : input);
|
|
111
113
|
const isWindows = () => {
|
|
112
114
|
const nodeProcess = getNodeProcess();
|
|
113
|
-
if (typeof nodeProcess?.platform === "string")
|
|
115
|
+
if (typeof nodeProcess?.platform === "string") {
|
|
114
116
|
return nodeProcess.platform === "win32";
|
|
117
|
+
}
|
|
115
118
|
const g = globalThis;
|
|
116
119
|
return g.Deno?.build?.os === "windows";
|
|
117
120
|
};
|
|
@@ -146,7 +149,8 @@ const getHome = () => {
|
|
|
146
149
|
}
|
|
147
150
|
const g = globalThis;
|
|
148
151
|
try {
|
|
149
|
-
const home = g.Deno?.env?.get?.("HOME") ??
|
|
152
|
+
const home = g.Deno?.env?.get?.("HOME") ??
|
|
153
|
+
g.Deno?.env?.get?.("USERPROFILE");
|
|
150
154
|
if (typeof home === "string" && home.length > 0)
|
|
151
155
|
return home;
|
|
152
156
|
}
|
|
@@ -198,7 +202,11 @@ const toPathList = (values, cwd, home) => {
|
|
|
198
202
|
};
|
|
199
203
|
const toUniquePathList = (values, cwd, home) => normalizeList(toPathList(values, cwd, home));
|
|
200
204
|
const toEnvFiles = (input, cwd, home) => {
|
|
201
|
-
const values = Array.isArray(input)
|
|
205
|
+
const values = Array.isArray(input)
|
|
206
|
+
? input
|
|
207
|
+
: input
|
|
208
|
+
? [input]
|
|
209
|
+
: [DEFAULT_ENV_FILE];
|
|
202
210
|
return toUniquePathList(values, cwd, home);
|
|
203
211
|
};
|
|
204
212
|
const rawRealpathSync = realpathSyncCompat.native ?? realpathSyncCompat;
|
|
@@ -212,7 +220,8 @@ const isPathWithin = (base, candidate) => {
|
|
|
212
220
|
const canonicalBase = toCanonicalPath(base);
|
|
213
221
|
const canonicalCandidate = toCanonicalPath(candidate);
|
|
214
222
|
const relative = pathRelative(canonicalBase, canonicalCandidate);
|
|
215
|
-
return relative === "" ||
|
|
223
|
+
return relative === "" ||
|
|
224
|
+
(!relative.startsWith("..") && !pathIsAbsolute(relative));
|
|
216
225
|
};
|
|
217
226
|
const defaultSensitiveProjectAndHomePaths = (cwd, home) => {
|
|
218
227
|
const projectSensitive = DEFAULT_DENY_RELATIVE.map((entry) => pathResolve(cwd, entry));
|
|
@@ -343,6 +352,13 @@ const toDenoFlags = ({ read, readAll, write, writeAll, denyRead, denyWrite, net,
|
|
|
343
352
|
flags.push(`--deny-env=${envDeny.join(",")}`);
|
|
344
353
|
}
|
|
345
354
|
for (const file of envFiles) {
|
|
355
|
+
try {
|
|
356
|
+
if (!existsSyncCompat(file))
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
catch {
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
346
362
|
flags.push(`--env-file=${file}`);
|
|
347
363
|
}
|
|
348
364
|
if (runAll) {
|
|
@@ -476,9 +492,7 @@ export const resolvePermissionProtocol = ({ permission, modules, }) => {
|
|
|
476
492
|
const configuredRead = readAll
|
|
477
493
|
? []
|
|
478
494
|
: toPathList(Array.isArray(input.read) ? input.read : undefined, cwd, home);
|
|
479
|
-
const configuredWrite = writeAll
|
|
480
|
-
? []
|
|
481
|
-
: toPathList(Array.isArray(input.write) ? input.write : undefined, cwd, home);
|
|
495
|
+
const configuredWrite = writeAll ? [] : toPathList(Array.isArray(input.write) ? input.write : undefined, cwd, home);
|
|
482
496
|
const resolvedRead = readAll
|
|
483
497
|
? []
|
|
484
498
|
: hasExplicitRead
|
|
@@ -501,19 +515,17 @@ export const resolvePermissionProtocol = ({ permission, modules, }) => {
|
|
|
501
515
|
: normalizeStringList(Array.isArray(input.net) ? input.net : []);
|
|
502
516
|
const denyNet = normalizeStringList(input.denyNet);
|
|
503
517
|
const allowImportAll = input.allowImport === true;
|
|
504
|
-
const allowImport = allowImportAll
|
|
505
|
-
?
|
|
506
|
-
:
|
|
507
|
-
? input.allowImport
|
|
508
|
-
: [...DEFAULT_ALLOW_IMPORT_HOSTS]);
|
|
518
|
+
const allowImport = allowImportAll ? [] : normalizeStringList(Array.isArray(input.allowImport)
|
|
519
|
+
? input.allowImport
|
|
520
|
+
: [...DEFAULT_ALLOW_IMPORT_HOSTS]);
|
|
509
521
|
const envAllowAll = input.env?.allow === true;
|
|
510
|
-
const envAllow = envAllowAll
|
|
511
|
-
? []
|
|
512
|
-
: normalizeStringList(Array.isArray(input.env?.allow) ? input.env.allow : []);
|
|
522
|
+
const envAllow = envAllowAll ? [] : normalizeStringList(Array.isArray(input.env?.allow) ? input.env.allow : []);
|
|
513
523
|
const envDeny = normalizeStringList(input.env?.deny);
|
|
514
524
|
const legacyRunEnabled = input.node?.allowChildProcess === true ||
|
|
515
525
|
input.deno?.allowRun === true;
|
|
516
|
-
const runSource = hasOwn(input, "run")
|
|
526
|
+
const runSource = hasOwn(input, "run")
|
|
527
|
+
? input.run
|
|
528
|
+
: (legacyRunEnabled ? true : []);
|
|
517
529
|
const runAll = runSource === true;
|
|
518
530
|
const run = runAll
|
|
519
531
|
? []
|
|
@@ -526,9 +538,7 @@ export const resolvePermissionProtocol = ({ permission, modules, }) => {
|
|
|
526
538
|
? input.ffi
|
|
527
539
|
: (input.node?.allowAddons === true ? true : false);
|
|
528
540
|
const ffiAll = ffiSource === true;
|
|
529
|
-
const ffi = ffiAll
|
|
530
|
-
? []
|
|
531
|
-
: toUniquePathList(Array.isArray(ffiSource) ? ffiSource : undefined, cwd, home);
|
|
541
|
+
const ffi = ffiAll ? [] : toUniquePathList(Array.isArray(ffiSource) ? ffiSource : undefined, cwd, home);
|
|
532
542
|
const denyFfi = toUniquePathList(input.denyFfi, cwd, home);
|
|
533
543
|
const sysSource = input.sys;
|
|
534
544
|
const sysAll = sysSource === true;
|
|
@@ -15,6 +15,11 @@ export declare const hostDispatcherLoop: ({ signalBox: { opView, txStatus, rxSta
|
|
|
15
15
|
rerun: boolean;
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
|
+
type CheckWithState = (() => void) & {
|
|
19
|
+
isRunning: boolean;
|
|
20
|
+
rerun: boolean;
|
|
21
|
+
};
|
|
22
|
+
export type DispatcherCheck = CheckWithState;
|
|
18
23
|
export declare class ChannelHandler {
|
|
19
24
|
#private;
|
|
20
25
|
channel: RuntimeMessageChannelLike;
|
|
@@ -32,3 +37,4 @@ export declare class ChannelHandler {
|
|
|
32
37
|
*/
|
|
33
38
|
close(): void;
|
|
34
39
|
}
|
|
40
|
+
export {};
|
package/src/runtime/pool.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { type ProcessSharedMemoryBacking } from "./process-worker.js";
|
|
2
2
|
import { type Sab } from "../ipc/transport/shared-memory.js";
|
|
3
|
+
import { ChannelHandler, type DispatcherCheck } from "./dispatcher.js";
|
|
3
4
|
import { lock2 } from "../memory/lock.js";
|
|
4
5
|
import type { DebugOptions, DispatcherSettings, WorkerContext, WorkerData, WorkerSettings } from "../types.js";
|
|
5
6
|
import "../worker/loop.js";
|
|
6
7
|
import { type PayloadBufferOptions } from "../memory/payload-config.js";
|
|
7
|
-
export declare const spawnWorkerContext: ({ list, ids, names, sab, thread, debug, totalNumberOfThread, source, at, workerOptions, workerExecArgv, permission, host, payload, bufferReferenceReturn,
|
|
8
|
+
export declare const spawnWorkerContext: ({ list, ids, names, sab, thread, debug, hostDebug, totalNumberOfThread, source, at, workerOptions, workerExecArgv, permission, host, payload, bufferReferenceReturn, abortSignalCapacity, usesAbortSignal, sharedChannelHandler, }: {
|
|
8
9
|
list: string[];
|
|
9
10
|
ids: number[];
|
|
10
11
|
names: string[];
|
|
@@ -12,6 +13,7 @@ export declare const spawnWorkerContext: ({ list, ids, names, sab, thread, debug
|
|
|
12
13
|
sab?: Sab;
|
|
13
14
|
thread: number;
|
|
14
15
|
debug?: DebugOptions;
|
|
16
|
+
hostDebug?: (message: string) => void;
|
|
15
17
|
totalNumberOfThread: number;
|
|
16
18
|
source?: string;
|
|
17
19
|
workerOptions?: WorkerSettings;
|
|
@@ -20,14 +22,18 @@ export declare const spawnWorkerContext: ({ list, ids, names, sab, thread, debug
|
|
|
20
22
|
host?: DispatcherSettings;
|
|
21
23
|
payload?: PayloadBufferOptions;
|
|
22
24
|
bufferReferenceReturn?: "copy" | "borrow";
|
|
23
|
-
payloadInitialBytes?: number;
|
|
24
|
-
payloadMaxBytes?: number;
|
|
25
|
-
bufferMode?: PayloadBufferOptions["mode"];
|
|
26
|
-
maxPayloadBytes?: number;
|
|
27
25
|
abortSignalCapacity?: number;
|
|
28
26
|
usesAbortSignal?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* When set, this lane keeps its dispatcher state while the pool owns the
|
|
29
|
+
* macro channel that runs all lane checks.
|
|
30
|
+
*/
|
|
31
|
+
sharedChannelHandler?: ChannelHandler;
|
|
29
32
|
}) => WorkerContext & {
|
|
30
33
|
lock: ReturnType<typeof lock2>;
|
|
31
34
|
processSharedMemoryBackings?: readonly ProcessSharedMemoryBacking[];
|
|
35
|
+
dispatcherCheck?: DispatcherCheck;
|
|
36
|
+
laneWake?: () => void;
|
|
37
|
+
bindSend?: (fn: () => void) => void;
|
|
32
38
|
};
|
|
33
39
|
export type CreateContext = WorkerContext;
|
package/src/runtime/pool.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHostTxQueue } from "./tx-queue.js";
|
|
2
2
|
import { cleanupProcessWorkerMemoryQuietly, createProcessSharedMemoryAllocator, createProcessWorkerMemoryLayout, createProcessWorkerNativeSignalNotifier, readProcessSharedMemorySettings, readProcessWorkerCommandPrefix, readProcessWorkerRuntime, serializeWorkerBootstrapData, spawnProcessWorker, terminateWorkerQuietly, toProcessWorkerBootPayload, toWorkerCompatExecArgv, toWorkerSafeExecArgv, } from "./process-worker.js";
|
|
3
3
|
import { createSharedMemoryTransport, TRANSPORT_SIGNAL_BYTES, } from "../ipc/transport/shared-memory.js";
|
|
4
|
-
import { ChannelHandler, hostDispatcherLoop } from "./dispatcher.js";
|
|
4
|
+
import { ChannelHandler, hostDispatcherLoop, } from "./dispatcher.js";
|
|
5
5
|
import { HEADER_SLOT_STRIDE_U32, lock2, LOCK_SECTOR_BYTE_LENGTH, LockBound, } from "../memory/lock.js";
|
|
6
6
|
import "../worker/loop.js";
|
|
7
7
|
import { createSharedArrayBuffer, createWasmSharedArrayBuffer, } from "../common/runtime.js";
|
|
@@ -34,7 +34,7 @@ const withFixedPayloadConfig = (config) => ({
|
|
|
34
34
|
mode: "fixed",
|
|
35
35
|
payloadInitialBytes: config.payloadMaxByteLength,
|
|
36
36
|
});
|
|
37
|
-
export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, totalNumberOfThread, source, at, workerOptions, workerExecArgv, permission, host, payload, bufferReferenceReturn,
|
|
37
|
+
export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, hostDebug, totalNumberOfThread, source, at, workerOptions, workerExecArgv, permission, host, payload, bufferReferenceReturn, abortSignalCapacity, usesAbortSignal, sharedChannelHandler, }) => {
|
|
38
38
|
const tsFileUrl = new URL(import.meta.url);
|
|
39
39
|
const poliWorker = RUNTIME_WORKER;
|
|
40
40
|
const resolvedWorkerOptions = serializeWorkerBootstrapData(withDefaultWorkerTimers(workerOptions));
|
|
@@ -48,9 +48,6 @@ export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, total
|
|
|
48
48
|
const processSharedMemorySettings = useProcessWorkerRuntime
|
|
49
49
|
? readProcessSharedMemorySettings(resolvedWorkerOptions)
|
|
50
50
|
: undefined;
|
|
51
|
-
if (debug?.logHref === true) {
|
|
52
|
-
console.log(tsFileUrl);
|
|
53
|
-
}
|
|
54
51
|
if (!useProcessWorkerRuntime && typeof poliWorker !== "function") {
|
|
55
52
|
throw new Error("Worker is not available in this runtime");
|
|
56
53
|
}
|
|
@@ -63,15 +60,7 @@ export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, total
|
|
|
63
60
|
return bytes > 0 ? bytes : undefined;
|
|
64
61
|
};
|
|
65
62
|
const basePayloadConfig = resolvePayloadBufferOptions({
|
|
66
|
-
options:
|
|
67
|
-
...payload,
|
|
68
|
-
mode: payload?.mode ?? bufferMode,
|
|
69
|
-
maxPayloadBytes: payload?.maxPayloadBytes ?? maxPayloadBytes,
|
|
70
|
-
payloadInitialBytes: payload?.payloadInitialBytes ??
|
|
71
|
-
sanitizeBytes(payloadInitialBytes),
|
|
72
|
-
payloadMaxByteLength: payload?.payloadMaxByteLength ??
|
|
73
|
-
sanitizeBytes(payloadMaxBytes),
|
|
74
|
-
},
|
|
63
|
+
options: payload,
|
|
75
64
|
});
|
|
76
65
|
const resolvedPayloadConfig = useProcessWorkerRuntime
|
|
77
66
|
? withFixedPayloadConfig(basePayloadConfig)
|
|
@@ -183,7 +172,6 @@ export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, total
|
|
|
183
172
|
: sab,
|
|
184
173
|
isMain: true,
|
|
185
174
|
thread,
|
|
186
|
-
debug,
|
|
187
175
|
});
|
|
188
176
|
const signalBox = signals;
|
|
189
177
|
const nativeNotifySignal = createProcessWorkerNativeSignalNotifier({
|
|
@@ -201,20 +189,54 @@ export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, total
|
|
|
201
189
|
: undefined,
|
|
202
190
|
});
|
|
203
191
|
const { enqueue, rejectAll, txIdle, } = queue;
|
|
204
|
-
const
|
|
205
|
-
const
|
|
192
|
+
const thisSignal = signalBox.opView;
|
|
193
|
+
const a_add = Atomics.add;
|
|
194
|
+
const a_load = Atomics.load;
|
|
195
|
+
const a_notify = Atomics.notify;
|
|
196
|
+
const canNotifySignal = thisSignal.buffer instanceof SharedArrayBuffer;
|
|
197
|
+
const notifySignal = nativeNotifySignal ??
|
|
198
|
+
(canNotifySignal ? (() => a_notify(thisSignal, 0, 1)) : undefined);
|
|
199
|
+
// Wakes this lane's worker when it is parked (rxStatus 0). Used by send()
|
|
200
|
+
// (new work just arrived) — the dispatcher drain wakes it the same way.
|
|
201
|
+
const laneWake = () => {
|
|
202
|
+
if (a_load(signalBox.rxStatus, 0) === 0) {
|
|
203
|
+
a_add(thisSignal, 0, 1);
|
|
204
|
+
notifySignal?.();
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
let dispatchSend = () => { };
|
|
208
|
+
const send = () => dispatchSend();
|
|
209
|
+
let channelHandler;
|
|
210
|
+
const ownsChannel = sharedChannelHandler === undefined;
|
|
211
|
+
const ownChannel = sharedChannelHandler ?? new ChannelHandler();
|
|
212
|
+
const { check: dispatcherCheck } = hostDispatcherLoop({
|
|
206
213
|
signalBox,
|
|
207
214
|
queue,
|
|
208
|
-
channelHandler,
|
|
215
|
+
channelHandler: ownChannel,
|
|
209
216
|
dispatcherOptions: host,
|
|
210
217
|
notifySignal: nativeNotifySignal,
|
|
211
|
-
//thread,
|
|
212
|
-
//debugSignal: debug?.logMain ?? false,
|
|
213
|
-
//perf,
|
|
214
218
|
});
|
|
215
|
-
|
|
219
|
+
if (ownsChannel) {
|
|
220
|
+
ownChannel.open(dispatcherCheck);
|
|
221
|
+
channelHandler = ownChannel;
|
|
222
|
+
dispatchSend = () => {
|
|
223
|
+
if (dispatcherCheck.isRunning === true)
|
|
224
|
+
return;
|
|
225
|
+
dispatcherCheck.isRunning = true;
|
|
226
|
+
Promise.resolve().then(dispatcherCheck);
|
|
227
|
+
laneWake();
|
|
228
|
+
};
|
|
229
|
+
}
|
|
216
230
|
let worker;
|
|
217
231
|
const workerUrl = source ?? tsFileUrl;
|
|
232
|
+
const workerMode = useProcessWorkerRuntime
|
|
233
|
+
? "process"
|
|
234
|
+
: HAS_NODE_WORKER_THREADS
|
|
235
|
+
? "worker_threads"
|
|
236
|
+
: "worker";
|
|
237
|
+
hostDebug?.(`worker thread=${thread} mode=${workerMode}` +
|
|
238
|
+
`${processWorkerRuntime ? ` runtime=${processWorkerRuntime}` : ""}` +
|
|
239
|
+
` url=${String(workerUrl)}`);
|
|
218
240
|
const workerDataPayload = {
|
|
219
241
|
sab: signals.sab,
|
|
220
242
|
abortSignalSAB,
|
|
@@ -308,7 +330,7 @@ export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, total
|
|
|
308
330
|
return;
|
|
309
331
|
closedReason = reason;
|
|
310
332
|
rejectAll(reason);
|
|
311
|
-
channelHandler
|
|
333
|
+
channelHandler?.close();
|
|
312
334
|
};
|
|
313
335
|
const onWorkerMessage = (message) => {
|
|
314
336
|
if (!isWorkerFatalMessage(message))
|
|
@@ -350,27 +372,6 @@ export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, total
|
|
|
350
372
|
};
|
|
351
373
|
}
|
|
352
374
|
}
|
|
353
|
-
const thisSignal = signalBox.opView;
|
|
354
|
-
const a_add = Atomics.add;
|
|
355
|
-
const a_load = Atomics.load;
|
|
356
|
-
const a_notify = Atomics.notify;
|
|
357
|
-
const canNotifySignal = thisSignal.buffer instanceof SharedArrayBuffer;
|
|
358
|
-
const notifySignal = nativeNotifySignal ??
|
|
359
|
-
(canNotifySignal ? (() => a_notify(thisSignal, 0, 1)) : undefined);
|
|
360
|
-
//const scheduleFastCheck = queueMicrotask;
|
|
361
|
-
const send = () => {
|
|
362
|
-
if (check.isRunning === true)
|
|
363
|
-
return;
|
|
364
|
-
check.isRunning = true;
|
|
365
|
-
Promise.resolve().then(check);
|
|
366
|
-
// Macro lane: dispatcher check is driven by the channel callback.
|
|
367
|
-
// channelHandler.notify();
|
|
368
|
-
// Use opView as a wake counter in lock2 mode to avoid lost wakeups.
|
|
369
|
-
if (a_load(signalBox.rxStatus, 0) === 0) {
|
|
370
|
-
a_add(thisSignal, 0, 1);
|
|
371
|
-
notifySignal?.();
|
|
372
|
-
}
|
|
373
|
-
};
|
|
374
375
|
lock.setPromiseHandler((task, isRejected, value) => {
|
|
375
376
|
queue.settlePromisePayload(task, isRejected, value);
|
|
376
377
|
send();
|
|
@@ -393,6 +394,11 @@ export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, total
|
|
|
393
394
|
},
|
|
394
395
|
lock,
|
|
395
396
|
processSharedMemoryBackings: processSharedMemory?.backings,
|
|
397
|
+
dispatcherCheck,
|
|
398
|
+
laneWake: sharedChannelHandler !== undefined ? laneWake : undefined,
|
|
399
|
+
bindSend: sharedChannelHandler !== undefined
|
|
400
|
+
? ((fn) => void (dispatchSend = fn))
|
|
401
|
+
: undefined,
|
|
396
402
|
};
|
|
397
403
|
return context;
|
|
398
404
|
};
|
|
@@ -2,6 +2,7 @@ import { fileURLToPath as fileURLToPathCompat } from "node:url";
|
|
|
2
2
|
import { HEADER_SLOT_STRIDE_U32, LOCK_SECTOR_BYTE_LENGTH, LockBound, } from "../memory/lock.js";
|
|
3
3
|
import { createByteCarpet, getHeaderBlockByteLength, makeSharedBufferRegion, } from "../memory/byte-carpet.js";
|
|
4
4
|
import { RUNTIME } from "../common/runtime.js";
|
|
5
|
+
import { debugHas } from "../debug/gate.js";
|
|
5
6
|
import { RUNTIME_POOL_DEPTH, RUNTIME_POOL_DEPTH_ENV, RUNTIME_PROCESS_WORKER_BOOT_ENV, RUNTIME_PROCESS_WORKER_BOOT_VERSION, RUNTIME_PROCESS_WORKER_ENV, } from "../common/worker-runtime.js";
|
|
6
7
|
import { getNodeBuiltinModule, getNodeProcess } from "../common/node-compat.js";
|
|
7
8
|
import { toSharedBufferRegion, } from "../common/shared-buffer-region.js";
|
|
@@ -72,7 +73,7 @@ export const createProcessSharedMemoryAllocator = (debug) => {
|
|
|
72
73
|
addon = loadNodeNativeAddon(require, "knitting_shared_memory");
|
|
73
74
|
}
|
|
74
75
|
catch (error) {
|
|
75
|
-
if (debug
|
|
76
|
+
if (debugHas(debug, "lifecycle")) {
|
|
76
77
|
console.warn("Process-shared memory allocator unavailable; falling back to SharedArrayBuffer.", error);
|
|
77
78
|
}
|
|
78
79
|
return undefined;
|
package/src/runtime/tx-queue.js
CHANGED
|
@@ -50,7 +50,11 @@ export function createHostTxQueue({ max, lock, returnLock, releaseBufferReferenc
|
|
|
50
50
|
const completeFrame = releaseBufferReferenceReturn === undefined
|
|
51
51
|
? resolveReturn
|
|
52
52
|
: () => withBufferReferenceReturnReleaser(releaseBufferReferenceReturn, resolveReturn);
|
|
53
|
-
const
|
|
53
|
+
const hasActiveTasks = () => {
|
|
54
|
+
const count = (inUsed - getPendingPromiseCount()) | 0;
|
|
55
|
+
return count > 0;
|
|
56
|
+
};
|
|
57
|
+
const txIdle = () => getPendingFrameCount() === 0 && !hasActiveTasks();
|
|
54
58
|
const rejectAll = (reason) => {
|
|
55
59
|
for (let index = 0; index < queue.length; index++) {
|
|
56
60
|
const slot = queue[index];
|
package/src/types.d.ts
CHANGED
|
@@ -62,8 +62,11 @@ type Serializable = string | object | number | boolean | bigint;
|
|
|
62
62
|
type ValidInput = bigint | void | JSONValue | symbol | ArrayBuffer | Uint8Array | Int32Array | Float64Array | BigInt64Array | BigUint64Array | DataView | Error | Date | Envelope<EnvelopeHeader, EnvelopeBody>;
|
|
63
63
|
type Args = ValidInput | Serializable;
|
|
64
64
|
type MaybePromise<T> = T | Promise<T>;
|
|
65
|
+
/** Blob payloads are not supported; pass ArrayBuffer/typed arrays instead. */
|
|
65
66
|
type NoBlob<T> = T extends Blob ? never : T;
|
|
67
|
+
/** Task input may be a direct value or native Promise; thenables are plain values. */
|
|
66
68
|
type TaskInput = NoBlob<Args> | Promise<NoBlob<Args>>;
|
|
69
|
+
/** Per-call timeout. A number is milliseconds; object form can return a default. */
|
|
67
70
|
type TaskTimeout = number | {
|
|
68
71
|
time: number;
|
|
69
72
|
maybe?: true;
|
|
@@ -76,6 +79,7 @@ type BivariantCallback<Args extends unknown[], R> = {
|
|
|
76
79
|
type AbortSignalConfig = {
|
|
77
80
|
readonly hasAborted: true;
|
|
78
81
|
};
|
|
82
|
+
/** `true` or config injects an abort toolkit as the task's second parameter. */
|
|
79
83
|
type AbortSignalOption = true | AbortSignalConfig | undefined;
|
|
80
84
|
type AbortSignalMethods<AS extends AbortSignalOption> = AS extends undefined ? never : {
|
|
81
85
|
hasAborted: () => boolean;
|
|
@@ -94,7 +98,7 @@ type TaskLike<AS extends AbortSignalOption = AbortSignalOption> = {
|
|
|
94
98
|
});
|
|
95
99
|
type TaskFunctionLike = (...args: any[]) => any;
|
|
96
100
|
type Composed<A extends TaskInput = Args, B extends Args = Args, AS extends AbortSignalOption = undefined> = FixPoint<A, B, AS> & SecondPart;
|
|
97
|
-
type tasks = Record<string, Composed<any, any,
|
|
101
|
+
type tasks = Record<string, Composed<any, any, any> | TaskFunctionLike>;
|
|
98
102
|
type ComposedWithKey = Composed<any, any, AbortSignalOption> & {
|
|
99
103
|
name: string;
|
|
100
104
|
};
|
|
@@ -118,7 +122,9 @@ type FunctionMapType<T extends Record<string, TaskLike<any> | TaskFunctionLike>>
|
|
|
118
122
|
[K in keyof T]: PromiseWrapped<TaskCallable<T[K]>, AbortSignalOfTask<T[K]>>;
|
|
119
123
|
};
|
|
120
124
|
interface FixPointBase<A extends TaskInput, B extends Args, AS extends AbortSignalOption = undefined> {
|
|
125
|
+
/** Worker function. It receives one value; use a tuple/object for many inputs. */
|
|
121
126
|
readonly f: TaskFn<A, B, AS>;
|
|
127
|
+
/** Soft call timeout. Use `worker.hardTimeoutMs` for runaway CPU walls. */
|
|
122
128
|
readonly timeout?: TaskTimeout;
|
|
123
129
|
}
|
|
124
130
|
type FixPoint<A extends TaskInput, B extends Args, AS extends AbortSignalOption = undefined> = FixPointBase<A, B, AS> & (AS extends undefined ? {
|
|
@@ -127,7 +133,9 @@ type FixPoint<A extends TaskInput, B extends Args, AS extends AbortSignalOption
|
|
|
127
133
|
readonly abortSignal: AS;
|
|
128
134
|
});
|
|
129
135
|
type ImportTaskOptions<A extends TaskInput = void, B extends Args = void, AS extends AbortSignalOption = undefined> = Omit<FixPoint<A, B, AS>, "f"> & {
|
|
136
|
+
/** Module imported by the worker only. Relative paths resolve from caller. */
|
|
130
137
|
readonly href: string;
|
|
138
|
+
/** Plain function export name. Defaults to `"default"`; do not target `task()`. */
|
|
131
139
|
readonly name?: string;
|
|
132
140
|
};
|
|
133
141
|
type SecondPart = {
|
|
@@ -142,13 +150,22 @@ type SecondPart = {
|
|
|
142
150
|
readonly imported?: boolean;
|
|
143
151
|
};
|
|
144
152
|
type SingleTaskPool<A extends TaskInput = Args, B extends Args = Args, AS extends AbortSignalOption = undefined> = {
|
|
153
|
+
/** Invoke the single task. Arguments may be native Promises. */
|
|
145
154
|
call: PromiseWrapped<TaskFn<A, B, AS>, AS>;
|
|
155
|
+
/** Await worker teardown now. `using` disposes at scope exit without awaiting. */
|
|
146
156
|
shutdown: (delayMs?: number) => Promise<void>;
|
|
157
|
+
/** Starts shutdown at scope exit. Use `shutdown()` when you must await it. */
|
|
147
158
|
[Symbol.dispose]: () => void;
|
|
148
159
|
};
|
|
149
160
|
type Pool<T extends Record<string, TaskLike<any> | TaskFunctionLike>> = {
|
|
161
|
+
/** Await worker teardown now. `using` disposes at scope exit without awaiting. */
|
|
150
162
|
shutdown: (delayMs?: number) => Promise<void>;
|
|
163
|
+
/** Starts shutdown at scope exit. Use `shutdown()` when you must await it. */
|
|
151
164
|
[Symbol.dispose]: () => void;
|
|
165
|
+
/**
|
|
166
|
+
* Typed task callers. Each call accepts the task input or a native Promise.
|
|
167
|
+
* Thrown errors/rejections reject here as Error objects with cause chains.
|
|
168
|
+
*/
|
|
152
169
|
call: FunctionMapType<T>;
|
|
153
170
|
};
|
|
154
171
|
type ReturnFixed<A extends TaskInput = undefined, B extends Args = undefined, AS extends AbortSignalOption = undefined> = FixPoint<A, B, AS> & SecondPart & {
|
|
@@ -175,12 +192,13 @@ type Balancer = BalancerStrategy | {
|
|
|
175
192
|
*/
|
|
176
193
|
strategy?: BalancerStrategy;
|
|
177
194
|
};
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
logImportedUrl?: boolean;
|
|
195
|
+
/** Debug namespaces for host setup, worker state, imports, globals, and lifecycle. */
|
|
196
|
+
type DebugNamespace = "host" | "globals" | "signals" | "imports" | "lifecycle";
|
|
197
|
+
type DebugFlags = {
|
|
198
|
+
[Namespace in DebugNamespace]?: boolean;
|
|
183
199
|
};
|
|
200
|
+
/** Pass `true` for all debug, or enable namespaces by name. */
|
|
201
|
+
type DebugOptions = boolean | DebugFlags;
|
|
184
202
|
type WorkerBootstrapContext = {
|
|
185
203
|
readonly thread: number;
|
|
186
204
|
readonly totalNumberOfThread: number;
|
|
@@ -212,7 +230,7 @@ type WorkerSettings = {
|
|
|
212
230
|
/**
|
|
213
231
|
* Experimental worker runtime.
|
|
214
232
|
* "thread" uses Worker/worker_threads. "process" spawns another JavaScript
|
|
215
|
-
* runtime
|
|
233
|
+
* runtime, useful for process isolation, bwrap, and containers.
|
|
216
234
|
*/
|
|
217
235
|
runtime?: "thread" | "process";
|
|
218
236
|
/**
|
|
@@ -278,44 +296,34 @@ type DispatcherSettings = {
|
|
|
278
296
|
* Max backoff delay (milliseconds).
|
|
279
297
|
*/
|
|
280
298
|
maxBackoffMs?: number;
|
|
299
|
+
/**
|
|
300
|
+
* Host dispatcher topology.
|
|
301
|
+
* - `"per-thread"`: each worker owns its dispatcher and macro channel.
|
|
302
|
+
* - `"serial-channel"`: each worker keeps its own dispatcher check state, but
|
|
303
|
+
* one shared channel runs all lane checks from first to last.
|
|
304
|
+
*
|
|
305
|
+
* Experimental default: `"per-thread"` on Bun or with one worker, otherwise
|
|
306
|
+
* `"serial-channel"` for multi-worker Node/Deno pools. Can also be forced
|
|
307
|
+
* with the `KNITTING_DISPATCHER` env var (`serial-channel` or `per-thread`).
|
|
308
|
+
*/
|
|
309
|
+
dispatcher?: "per-thread" | "serial-channel";
|
|
281
310
|
};
|
|
282
311
|
type CreatePool = {
|
|
312
|
+
/** Number of workers. Default: 1. */
|
|
283
313
|
threads?: number;
|
|
284
|
-
/**
|
|
285
|
-
* @deprecated Too risky with processes, need to rewrite or delete.
|
|
286
|
-
*/
|
|
314
|
+
/** Add a host inline lane for regular tasks. Imported tasks still use workers. */
|
|
287
315
|
inliner?: Inliner;
|
|
288
316
|
balancer?: Balancer;
|
|
289
317
|
worker?: WorkerSettings;
|
|
290
318
|
/**
|
|
291
|
-
* Payload transport settings.
|
|
319
|
+
* Payload transport settings. Default dynamic payload cap is about 8 MiB
|
|
320
|
+
* (`payloadMaxByteLength >> 3`, with a 64 MiB growth cap).
|
|
292
321
|
*/
|
|
293
322
|
payload?: PayloadBufferOptions;
|
|
294
323
|
/**
|
|
295
324
|
* Experimental unsafe options.
|
|
296
325
|
*/
|
|
297
326
|
unsafe?: UnsafeOptions;
|
|
298
|
-
/**
|
|
299
|
-
* Initial payload SharedArrayBuffer size (bytes) per worker direction.
|
|
300
|
-
* Defaults to 4 MiB when growable SAB is available, otherwise defaults to
|
|
301
|
-
* `payloadMaxBytes`.
|
|
302
|
-
* @deprecated Use `payload.payloadInitialBytes`.
|
|
303
|
-
*/
|
|
304
|
-
payloadInitialBytes?: number;
|
|
305
|
-
/**
|
|
306
|
-
* Maximum payload SharedArrayBuffer size (bytes) per worker direction.
|
|
307
|
-
* Defaults to 64 MiB.
|
|
308
|
-
* @deprecated Use `payload.payloadMaxByteLength`.
|
|
309
|
-
*/
|
|
310
|
-
payloadMaxBytes?: number;
|
|
311
|
-
/**
|
|
312
|
-
* @deprecated Use `payload.mode`.
|
|
313
|
-
*/
|
|
314
|
-
bufferMode?: PayloadBufferMode;
|
|
315
|
-
/**
|
|
316
|
-
* @deprecated Use `payload.maxPayloadBytes`.
|
|
317
|
-
*/
|
|
318
|
-
maxPayloadBytes?: number;
|
|
319
327
|
/**
|
|
320
328
|
* Abort-aware signal pool capacity.
|
|
321
329
|
* Defaults to `258`.
|
|
@@ -332,19 +340,18 @@ type CreatePool = {
|
|
|
332
340
|
workerExecArgv?: string[];
|
|
333
341
|
/**
|
|
334
342
|
* Runtime permission protocol.
|
|
335
|
-
* Omit to use strict defaults with `allowImport: true
|
|
343
|
+
* Omit to use strict defaults with `allowImport: true`; worker console is
|
|
344
|
+
* quiet unless `permission: { console: true }`.
|
|
345
|
+
*
|
|
346
|
+
* Task code cannot terminate the host: process/Deno exit APIs are blocked.
|
|
336
347
|
* Use `"strict"` (default for object mode) or `"unsafe"`.
|
|
337
348
|
* Accepts object form for fine-grained permission controls.
|
|
338
349
|
*/
|
|
339
350
|
permission?: PermissionProtocolInput;
|
|
340
|
-
/**
|
|
341
|
-
* @deprecated Use `host` instead.
|
|
342
|
-
*/
|
|
343
|
-
dispatcher?: DispatcherSettings;
|
|
344
351
|
debug?: DebugOptions;
|
|
345
352
|
source?: string;
|
|
346
353
|
};
|
|
347
|
-
export type { AbortSignalConfig as AbortSignalConfig, AbortSignalMethods as AbortSignalMethods, AbortSignalOption as AbortSignalOption, AbortSignalToolkit as AbortSignalToolkit, Args as Args, Balancer as Balancer, BalancerStrategy as BalancerStrategy, Composed as Composed, ComposedWithKey as ComposedWithKey, CreateContext as CreateContext, CreatePool as CreatePool, 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, };
|
|
354
|
+
export type { AbortSignalConfig as AbortSignalConfig, AbortSignalMethods as AbortSignalMethods, AbortSignalOption as AbortSignalOption, AbortSignalToolkit as AbortSignalToolkit, Args as Args, Balancer as Balancer, BalancerStrategy as BalancerStrategy, 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, };
|
|
348
355
|
export type { Task as Task } from "./memory/lock.js";
|
|
349
356
|
export { LockBound as LockBound, PayloadBuffer as PayloadBuffer, PayloadSignal as PayloadSignal, TaskIndex as TaskIndex, } from "./memory/lock.js";
|
|
350
357
|
export type { RegisterMalloc as RegisterMalloc } from "./memory/regionRegistry.js";
|