knitting 0.1.54 → 0.1.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/knitting.d.ts +797 -5
- package/knitting.js +9780 -5
- package/map.md +9 -12
- package/package.json +14 -13
- package/shared-memory.d.ts +155 -0
- package/shared-memory.js +1342 -0
- package/unsafe.d.ts +71 -1
- package/unsafe.js +878 -1
- package/utils.d.ts +31 -1
- package/utils.js +116 -1
- package/process-shared-buffer.d.ts +0 -1
- package/process-shared-buffer.js +0 -1
- package/src/api.d.ts +0 -69
- package/src/api.js +0 -627
- package/src/common/envelope.d.ts +0 -17
- package/src/common/envelope.js +0 -22
- package/src/common/module-url.d.ts +0 -1
- package/src/common/module-url.js +0 -24
- package/src/common/node-compat.d.ts +0 -20
- package/src/common/node-compat.js +0 -24
- package/src/common/path-canonical.d.ts +0 -6
- package/src/common/path-canonical.js +0 -41
- package/src/common/runtime.d.ts +0 -15
- package/src/common/runtime.js +0 -91
- package/src/common/shared-buffer-region.d.ts +0 -11
- package/src/common/shared-buffer-region.js +0 -21
- package/src/common/shared-buffer-text.d.ts +0 -16
- package/src/common/shared-buffer-text.js +0 -65
- package/src/common/task-source.d.ts +0 -3
- package/src/common/task-source.js +0 -84
- package/src/common/task-symbol.d.ts +0 -1
- package/src/common/task-symbol.js +0 -1
- package/src/common/with-resolvers.d.ts +0 -9
- package/src/common/with-resolvers.js +0 -23
- package/src/common/worker-runtime.d.ts +0 -42
- package/src/common/worker-runtime.js +0 -61
- package/src/connections/buffer-reference-native.d.ts +0 -56
- package/src/connections/buffer-reference-native.js +0 -217
- package/src/connections/buffer-reference.d.ts +0 -78
- package/src/connections/buffer-reference.js +0 -461
- package/src/connections/bun.d.ts +0 -22
- package/src/connections/bun.js +0 -214
- package/src/connections/deno.d.ts +0 -22
- package/src/connections/deno.js +0 -205
- package/src/connections/file-descriptor.d.ts +0 -39
- package/src/connections/file-descriptor.js +0 -161
- package/src/connections/index.d.ts +0 -4
- package/src/connections/index.js +0 -4
- package/src/connections/node-addons.d.ts +0 -5
- package/src/connections/node-addons.js +0 -43
- package/src/connections/node-buffer-pointer.d.ts +0 -20
- package/src/connections/node-buffer-pointer.js +0 -16
- package/src/connections/node.d.ts +0 -30
- package/src/connections/node.js +0 -62
- package/src/connections/posix.d.ts +0 -32
- package/src/connections/posix.js +0 -77
- package/src/connections/process-shared-buffer.d.ts +0 -75
- package/src/connections/process-shared-buffer.js +0 -279
- package/src/connections/shared-array-buffer-payload.d.ts +0 -36
- package/src/connections/shared-array-buffer-payload.js +0 -235
- package/src/connections/types.d.ts +0 -50
- package/src/connections/types.js +0 -37
- package/src/connections/windows.d.ts +0 -28
- package/src/connections/windows.js +0 -224
- package/src/debug/env-diff.d.ts +0 -26
- package/src/debug/env-diff.js +0 -49
- package/src/debug/gate.d.ts +0 -18
- package/src/debug/gate.js +0 -69
- package/src/debug/handle.d.ts +0 -23
- package/src/debug/handle.js +0 -48
- package/src/error.d.ts +0 -13
- package/src/error.js +0 -49
- package/src/ipc/tools/ring-queue.d.ts +0 -33
- package/src/ipc/tools/ring-queue.js +0 -159
- package/src/ipc/transport/shared-memory.d.ts +0 -23
- package/src/ipc/transport/shared-memory.js +0 -35
- package/src/memory/byte-carpet.d.ts +0 -73
- package/src/memory/byte-carpet.js +0 -157
- package/src/memory/lock.d.ts +0 -201
- package/src/memory/lock.js +0 -739
- package/src/memory/payload-config.d.ts +0 -31
- package/src/memory/payload-config.js +0 -67
- package/src/memory/payloadCodec.d.ts +0 -46
- package/src/memory/payloadCodec.js +0 -1334
- package/src/memory/regionRegistry.d.ts +0 -17
- package/src/memory/regionRegistry.js +0 -285
- package/src/memory/shared-buffer-io.d.ts +0 -55
- package/src/memory/shared-buffer-io.js +0 -403
- package/src/permission/index.d.ts +0 -2
- package/src/permission/index.js +0 -2
- package/src/permission/protocol.d.ts +0 -166
- package/src/permission/protocol.js +0 -650
- package/src/runtime/balancer.d.ts +0 -19
- package/src/runtime/balancer.js +0 -149
- package/src/runtime/dispatcher.d.ts +0 -40
- package/src/runtime/dispatcher.js +0 -142
- package/src/runtime/inline-executor.d.ts +0 -10
- package/src/runtime/inline-executor.js +0 -282
- package/src/runtime/pool.d.ts +0 -39
- package/src/runtime/pool.js +0 -404
- package/src/runtime/process-worker.d.ts +0 -92
- package/src/runtime/process-worker.js +0 -673
- package/src/runtime/tx-queue.d.ts +0 -26
- package/src/runtime/tx-queue.js +0 -155
- package/src/shared/abortSignal.d.ts +0 -23
- package/src/shared/abortSignal.js +0 -134
- package/src/types.d.ts +0 -357
- package/src/types.js +0 -2
- package/src/utils/http.d.ts +0 -29
- package/src/utils/http.js +0 -100
- package/src/worker/bootstrap.d.ts +0 -5
- package/src/worker/bootstrap.js +0 -78
- package/src/worker/composable-runners.d.ts +0 -12
- package/src/worker/composable-runners.js +0 -97
- package/src/worker/loop.d.ts +0 -2
- package/src/worker/loop.js +0 -382
- package/src/worker/process-worker-bootstrap.d.ts +0 -8
- package/src/worker/process-worker-bootstrap.js +0 -160
- package/src/worker/rx-queue.d.ts +0 -25
- package/src/worker/rx-queue.js +0 -173
- package/src/worker/safety/index.d.ts +0 -4
- package/src/worker/safety/index.js +0 -4
- package/src/worker/safety/performance.d.ts +0 -1
- package/src/worker/safety/performance.js +0 -17
- package/src/worker/safety/process.d.ts +0 -2
- package/src/worker/safety/process.js +0 -79
- package/src/worker/safety/startup.d.ts +0 -16
- package/src/worker/safety/startup.js +0 -30
- package/src/worker/safety/worker-data.d.ts +0 -2
- package/src/worker/safety/worker-data.js +0 -36
- package/src/worker/task-loader.d.ts +0 -27
- package/src/worker/task-loader.js +0 -78
- package/src/worker/timers.d.ts +0 -18
- package/src/worker/timers.js +0 -116
package/src/worker/rx-queue.js
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import RingQueue from "../ipc/tools/ring-queue.js";
|
|
2
|
-
import { attachPayloadTransportFinalizer, runTaskFinalizers, TaskFlag, TaskIndex, } from "../memory/lock.js";
|
|
3
|
-
import { composeWorkerRunner } from "./composable-runners.js";
|
|
4
|
-
import { BUFFER_REFERENCE_RETURN_RELEASE_TOKEN } from "../connections/buffer-reference.js";
|
|
5
|
-
export const createWorkerRxQueue = ({ listOfFunctions, workerOptions, lock, returnLock, borrowReturnedBufferReferences, hasAborted, now, }) => {
|
|
6
|
-
const PLACE_HOLDER = (_) => {
|
|
7
|
-
throw ("UNREACHABLE FROM PLACE HOLDER (thread)");
|
|
8
|
-
};
|
|
9
|
-
let hasAnythingFinished = 0;
|
|
10
|
-
let awaiting = 0;
|
|
11
|
-
const jobs = listOfFunctions.reduce((acc, fixed) => (acc.push(fixed.run), acc), []);
|
|
12
|
-
const toWork = new RingQueue();
|
|
13
|
-
const pendingFrames = new RingQueue();
|
|
14
|
-
const toWorkPush = (slot) => toWork.push(slot);
|
|
15
|
-
const toWorkShift = () => toWork.shiftNoClear();
|
|
16
|
-
const pendingShift = () => pendingFrames.shiftNoClear();
|
|
17
|
-
const pendingUnshift = (slot) => pendingFrames.unshift(slot);
|
|
18
|
-
const pendingPush = (slot) => pendingFrames.push(slot);
|
|
19
|
-
const recyclePush = (slot) => lock.recyclecList.push(slot);
|
|
20
|
-
const FUNCTION_ID_MASK = 0xFFFF;
|
|
21
|
-
const IDX_FLAGS = TaskIndex.FlagsToHost;
|
|
22
|
-
const FLAG_REJECT = TaskFlag.Reject;
|
|
23
|
-
// Return-payload finalizers wait until the host consumes the return.
|
|
24
|
-
// Quiescence (hostBits XOR workerBits == 0) lets us release them in batch.
|
|
25
|
-
const a_load = Atomics.load;
|
|
26
|
-
const returnHostBits = returnLock.hostBits;
|
|
27
|
-
const returnWorkerBits = returnLock.workerBits;
|
|
28
|
-
const deferredReleases = [];
|
|
29
|
-
const explicitReturnReleases = new Map();
|
|
30
|
-
const drainReturnReleases = () => {
|
|
31
|
-
if (deferredReleases.length === 0)
|
|
32
|
-
return;
|
|
33
|
-
if ((a_load(returnHostBits, 0) ^ a_load(returnWorkerBits, 0)) !== 0)
|
|
34
|
-
return;
|
|
35
|
-
for (let i = 0; i < deferredReleases.length; i++) {
|
|
36
|
-
try {
|
|
37
|
-
deferredReleases[i]();
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
// best effort
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
deferredReleases.length = 0;
|
|
44
|
-
};
|
|
45
|
-
const releaseReturnedBufferReference = (token) => {
|
|
46
|
-
const key = token.toString();
|
|
47
|
-
const release = explicitReturnReleases.get(key);
|
|
48
|
-
if (release === undefined)
|
|
49
|
-
return;
|
|
50
|
-
explicitReturnReleases.delete(key);
|
|
51
|
-
try {
|
|
52
|
-
release();
|
|
53
|
-
}
|
|
54
|
-
catch {
|
|
55
|
-
// best effort
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
const runByIndex = listOfFunctions.reduce((acc, fixed, idx) => {
|
|
59
|
-
const job = jobs[idx];
|
|
60
|
-
acc.push(composeWorkerRunner({
|
|
61
|
-
job,
|
|
62
|
-
timeout: fixed.timeout,
|
|
63
|
-
hasAborted,
|
|
64
|
-
now,
|
|
65
|
-
}));
|
|
66
|
-
return acc;
|
|
67
|
-
}, []);
|
|
68
|
-
const hasCompleted = workerOptions?.resolveAfterFinishingAll === true
|
|
69
|
-
? () => hasAnythingFinished !== 0 && toWork.size === 0
|
|
70
|
-
: () => hasAnythingFinished !== 0;
|
|
71
|
-
const { decode, resolved } = lock;
|
|
72
|
-
const resolvedShift = () => resolved.shiftNoClear();
|
|
73
|
-
const enqueueLock = () => {
|
|
74
|
-
if (!decode())
|
|
75
|
-
return false;
|
|
76
|
-
let task = resolvedShift();
|
|
77
|
-
while (task) {
|
|
78
|
-
task.resolve = PLACE_HOLDER;
|
|
79
|
-
task.reject = PLACE_HOLDER;
|
|
80
|
-
attachPayloadTransportFinalizer(task, task.value);
|
|
81
|
-
toWorkPush(task);
|
|
82
|
-
task = resolvedShift();
|
|
83
|
-
}
|
|
84
|
-
return true;
|
|
85
|
-
};
|
|
86
|
-
const encodeReturnSafe = (slot) => {
|
|
87
|
-
if (!returnLock.encode(slot))
|
|
88
|
-
return false;
|
|
89
|
-
return true;
|
|
90
|
-
};
|
|
91
|
-
const sendReturn = (slot, shouldReject) => {
|
|
92
|
-
slot[IDX_FLAGS] = shouldReject ? FLAG_REJECT : 0;
|
|
93
|
-
if (!encodeReturnSafe(slot))
|
|
94
|
-
return false;
|
|
95
|
-
// Preserve return finalizers past slot recycle; release after drain.
|
|
96
|
-
if (slot.finalize !== undefined) {
|
|
97
|
-
const token = slot.finalize[BUFFER_REFERENCE_RETURN_RELEASE_TOKEN];
|
|
98
|
-
if (token === undefined || borrowReturnedBufferReferences !== true) {
|
|
99
|
-
deferredReleases.push(slot.finalize);
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
explicitReturnReleases.set(token.toString(), slot.finalize);
|
|
103
|
-
}
|
|
104
|
-
slot.finalize = undefined;
|
|
105
|
-
}
|
|
106
|
-
hasAnythingFinished--;
|
|
107
|
-
recyclePush(slot);
|
|
108
|
-
return true;
|
|
109
|
-
};
|
|
110
|
-
const settleNow = (slot, isError, value, wasAwaited) => {
|
|
111
|
-
runTaskFinalizers(slot);
|
|
112
|
-
slot.value = value;
|
|
113
|
-
hasAnythingFinished++;
|
|
114
|
-
if (wasAwaited && awaiting > 0)
|
|
115
|
-
awaiting--;
|
|
116
|
-
const shouldReject = isError ||
|
|
117
|
-
slot[IDX_FLAGS] === FLAG_REJECT;
|
|
118
|
-
if (!sendReturn(slot, shouldReject))
|
|
119
|
-
pendingPush(slot);
|
|
120
|
-
};
|
|
121
|
-
const writeOne = () => {
|
|
122
|
-
const slot = pendingShift();
|
|
123
|
-
if (!slot)
|
|
124
|
-
return false;
|
|
125
|
-
if (!sendReturn(slot, slot[IDX_FLAGS] === FLAG_REJECT)) {
|
|
126
|
-
pendingUnshift(slot);
|
|
127
|
-
return false;
|
|
128
|
-
}
|
|
129
|
-
return true;
|
|
130
|
-
};
|
|
131
|
-
return {
|
|
132
|
-
hasCompleted,
|
|
133
|
-
hasPending: () => toWork.size !== 0,
|
|
134
|
-
writeBatch: (max) => {
|
|
135
|
-
let wrote = 0;
|
|
136
|
-
while (wrote < max) {
|
|
137
|
-
if (!writeOne())
|
|
138
|
-
break;
|
|
139
|
-
wrote++;
|
|
140
|
-
}
|
|
141
|
-
return wrote;
|
|
142
|
-
},
|
|
143
|
-
serviceBatchImmediate: () => {
|
|
144
|
-
let processed = 0;
|
|
145
|
-
while (processed < 5 && toWork.size !== 0) {
|
|
146
|
-
const slot = toWorkShift();
|
|
147
|
-
try {
|
|
148
|
-
const fnIndex = slot[TaskIndex.FunctionID] & FUNCTION_ID_MASK;
|
|
149
|
-
const result = runByIndex[fnIndex](slot);
|
|
150
|
-
slot[IDX_FLAGS] = 0;
|
|
151
|
-
slot.value = null;
|
|
152
|
-
if (result instanceof Promise) {
|
|
153
|
-
awaiting++;
|
|
154
|
-
result.then((value) => settleNow(slot, false, value, true), (err) => settleNow(slot, true, err, true));
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
settleNow(slot, false, result, false);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
catch (err) {
|
|
161
|
-
settleNow(slot, true, err, false);
|
|
162
|
-
}
|
|
163
|
-
++processed;
|
|
164
|
-
}
|
|
165
|
-
return processed;
|
|
166
|
-
},
|
|
167
|
-
enqueueLock,
|
|
168
|
-
drainReturnReleases,
|
|
169
|
-
releaseReturnedBufferReference,
|
|
170
|
-
hasAwaiting: () => awaiting > 0,
|
|
171
|
-
getAwaiting: () => awaiting,
|
|
172
|
-
};
|
|
173
|
-
};
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export { installTerminationGuard, installUnhandledRejectionSilencer, } from "./process.js";
|
|
2
|
-
export { installPerformanceNowGuard } from "./performance.js";
|
|
3
|
-
export { scrubWorkerDataSensitiveBuffers } from "./worker-data.js";
|
|
4
|
-
export { assertWorkerSharedMemoryBootData, assertWorkerImportsResolved, } from "./startup.js";
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export { installTerminationGuard, installUnhandledRejectionSilencer, } from "./process.js";
|
|
2
|
-
export { installPerformanceNowGuard } from "./performance.js";
|
|
3
|
-
export { scrubWorkerDataSensitiveBuffers } from "./worker-data.js";
|
|
4
|
-
export { assertWorkerSharedMemoryBootData, assertWorkerImportsResolved, } from "./startup.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const installPerformanceNowGuard: () => void;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export const installPerformanceNowGuard = () => {
|
|
2
|
-
const g = globalThis;
|
|
3
|
-
if (g.__knittingPerformanceNowGuardInstalled === true)
|
|
4
|
-
return;
|
|
5
|
-
g.__knittingPerformanceNowGuardInstalled = true;
|
|
6
|
-
const perf = globalThis.performance;
|
|
7
|
-
if (!perf || typeof perf.now !== "function")
|
|
8
|
-
return;
|
|
9
|
-
// Non-intrusive guard: ensure a high-resolution clock exists.
|
|
10
|
-
// Internal timing paths capture a bound `performance.now` reference and
|
|
11
|
-
// do not require freezing global objects.
|
|
12
|
-
try {
|
|
13
|
-
void perf.now();
|
|
14
|
-
}
|
|
15
|
-
catch {
|
|
16
|
-
}
|
|
17
|
-
};
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { getNodeProcess } from "../../common/node-compat.js";
|
|
2
|
-
const toErrorMessage = (error) => error instanceof Error ? error.message : String(error);
|
|
3
|
-
const failProcessGuardInstall = (target, reason, cause) => {
|
|
4
|
-
const suffix = cause === undefined ? "" : `: ${toErrorMessage(cause)}`;
|
|
5
|
-
throw new Error(`KNT_ERROR_PROCESS_GUARD_INSTALL: ${target} ${reason}${suffix}`);
|
|
6
|
-
};
|
|
7
|
-
export const installTerminationGuard = () => {
|
|
8
|
-
const proc = getNodeProcess();
|
|
9
|
-
if (!proc)
|
|
10
|
-
return;
|
|
11
|
-
if (proc.__knittingTerminationGuard === true)
|
|
12
|
-
return;
|
|
13
|
-
const blocked = (name) => {
|
|
14
|
-
throw new Error(`KNT_ERROR_PROCESS_GUARD: ${name} is disabled in worker tasks`);
|
|
15
|
-
};
|
|
16
|
-
const guardMethod = (name) => {
|
|
17
|
-
try {
|
|
18
|
-
Object.defineProperty(proc, name, {
|
|
19
|
-
configurable: false,
|
|
20
|
-
writable: false,
|
|
21
|
-
value: (..._args) => blocked(`process.${name}`),
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
catch (defineError) {
|
|
25
|
-
try {
|
|
26
|
-
proc[name] = (..._args) => blocked(`process.${name}`);
|
|
27
|
-
}
|
|
28
|
-
catch (assignError) {
|
|
29
|
-
failProcessGuardInstall(`process.${name}`, "install failed", [
|
|
30
|
-
toErrorMessage(defineError),
|
|
31
|
-
toErrorMessage(assignError),
|
|
32
|
-
].join("; "));
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
if (typeof proc[name] !== "function") {
|
|
36
|
-
failProcessGuardInstall(`process.${name}`, "install verification failed");
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
guardMethod("exit");
|
|
40
|
-
guardMethod("kill");
|
|
41
|
-
guardMethod("abort");
|
|
42
|
-
guardMethod("reallyExit");
|
|
43
|
-
const globalScope = globalThis;
|
|
44
|
-
if (globalScope.Deno && typeof globalScope.Deno.exit === "function") {
|
|
45
|
-
try {
|
|
46
|
-
Object.defineProperty(globalScope.Deno, "exit", {
|
|
47
|
-
configurable: false,
|
|
48
|
-
writable: false,
|
|
49
|
-
value: (_code) => blocked("Deno.exit"),
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
catch (defineError) {
|
|
53
|
-
try {
|
|
54
|
-
globalScope.Deno.exit = (_code) => blocked("Deno.exit");
|
|
55
|
-
}
|
|
56
|
-
catch (assignError) {
|
|
57
|
-
failProcessGuardInstall("Deno.exit", "install failed", [
|
|
58
|
-
toErrorMessage(defineError),
|
|
59
|
-
toErrorMessage(assignError),
|
|
60
|
-
].join("; "));
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if (typeof globalScope.Deno.exit !== "function") {
|
|
64
|
-
failProcessGuardInstall("Deno.exit", "install verification failed");
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
proc.__knittingTerminationGuard = true;
|
|
68
|
-
};
|
|
69
|
-
export const installUnhandledRejectionSilencer = () => {
|
|
70
|
-
const proc = getNodeProcess();
|
|
71
|
-
if (!proc || typeof proc.on !== "function") {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
if (proc.__knittingUnhandledRejectionSilencer === true)
|
|
75
|
-
return;
|
|
76
|
-
proc.__knittingUnhandledRejectionSilencer = true;
|
|
77
|
-
// Worker task code may create detached promises; keep workers alive.
|
|
78
|
-
proc.on("unhandledRejection", () => { });
|
|
79
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { type SharedBufferSource } from "../../common/shared-buffer-region.js";
|
|
2
|
-
import type { LockBuffers } from "../../types.js";
|
|
3
|
-
type SharedMemoryBootData = {
|
|
4
|
-
sab: SharedBufferSource | undefined;
|
|
5
|
-
lock: LockBuffers | undefined;
|
|
6
|
-
returnLock: LockBuffers | undefined;
|
|
7
|
-
};
|
|
8
|
-
type ImportedFunctionsState = {
|
|
9
|
-
list: string[];
|
|
10
|
-
ids: number[];
|
|
11
|
-
names?: string[];
|
|
12
|
-
listOfFunctions: readonly unknown[];
|
|
13
|
-
};
|
|
14
|
-
export declare const assertWorkerSharedMemoryBootData: ({ sab, lock, returnLock }: SharedMemoryBootData) => void;
|
|
15
|
-
export declare const assertWorkerImportsResolved: ({ list, ids, names, listOfFunctions }: ImportedFunctionsState) => void;
|
|
16
|
-
export {};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { isSharedBufferSource, } from "../../common/shared-buffer-region.js";
|
|
2
|
-
import { isLockBufferTextCompat } from "../../common/shared-buffer-text.js";
|
|
3
|
-
const hasLockBuffers = (value) => isSharedBufferSource(value?.headers) &&
|
|
4
|
-
isSharedBufferSource(value?.lockSector) &&
|
|
5
|
-
isSharedBufferSource(value?.payload) &&
|
|
6
|
-
isSharedBufferSource(value?.payloadSector) &&
|
|
7
|
-
(value?.textCompat === undefined ||
|
|
8
|
-
isLockBufferTextCompat(value.textCompat));
|
|
9
|
-
export const assertWorkerSharedMemoryBootData = ({ sab, lock, returnLock }) => {
|
|
10
|
-
if (!isSharedBufferSource(sab)) {
|
|
11
|
-
throw new Error("worker missing transport SAB");
|
|
12
|
-
}
|
|
13
|
-
if (!hasLockBuffers(lock)) {
|
|
14
|
-
throw new Error("worker missing lock SABs");
|
|
15
|
-
}
|
|
16
|
-
if (!hasLockBuffers(returnLock)) {
|
|
17
|
-
throw new Error("worker missing return lock SABs");
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
export const assertWorkerImportsResolved = ({ list, ids, names, listOfFunctions }) => {
|
|
21
|
-
if (listOfFunctions.length > 0 &&
|
|
22
|
-
(names === undefined || listOfFunctions.length === names.length))
|
|
23
|
-
return;
|
|
24
|
-
console.log(list);
|
|
25
|
-
console.log(ids);
|
|
26
|
-
if (names !== undefined)
|
|
27
|
-
console.log(names);
|
|
28
|
-
console.log(listOfFunctions);
|
|
29
|
-
throw new Error("No imports were found.");
|
|
30
|
-
};
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
export const scrubWorkerDataSensitiveBuffers = (value) => {
|
|
2
|
-
const data = value;
|
|
3
|
-
try {
|
|
4
|
-
data.sab = undefined;
|
|
5
|
-
data.lock = undefined;
|
|
6
|
-
data.returnLock = undefined;
|
|
7
|
-
data.permission = undefined;
|
|
8
|
-
}
|
|
9
|
-
catch {
|
|
10
|
-
}
|
|
11
|
-
try {
|
|
12
|
-
delete data.sab;
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
}
|
|
16
|
-
try {
|
|
17
|
-
delete data.lock;
|
|
18
|
-
}
|
|
19
|
-
catch {
|
|
20
|
-
}
|
|
21
|
-
try {
|
|
22
|
-
delete data.returnLock;
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
}
|
|
26
|
-
try {
|
|
27
|
-
delete data.permission;
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
}
|
|
31
|
-
try {
|
|
32
|
-
Object.freeze(data);
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
}
|
|
36
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { ComposedWithKey } from "../types.js";
|
|
2
|
-
import type { ResolvedPermissionProtocol } from "../permission/protocol.js";
|
|
3
|
-
type GetFunctionParams = {
|
|
4
|
-
list: string[];
|
|
5
|
-
ids: number[];
|
|
6
|
-
names: string[];
|
|
7
|
-
at: number[];
|
|
8
|
-
isWorker: boolean;
|
|
9
|
-
permission?: ResolvedPermissionProtocol;
|
|
10
|
-
};
|
|
11
|
-
type WorkerCallable = (args: unknown, abortToolkit?: unknown) => unknown;
|
|
12
|
-
export declare const enum TimeoutKind {
|
|
13
|
-
Reject = 0,
|
|
14
|
-
Resolve = 1
|
|
15
|
-
}
|
|
16
|
-
export type TimeoutSpec = {
|
|
17
|
-
ms: number;
|
|
18
|
-
kind: TimeoutKind;
|
|
19
|
-
value: unknown;
|
|
20
|
-
};
|
|
21
|
-
export type WorkerComposedWithKey = ComposedWithKey & {
|
|
22
|
-
run: WorkerCallable;
|
|
23
|
-
timeout?: TimeoutSpec;
|
|
24
|
-
};
|
|
25
|
-
export declare const getFunctions: ({ list, ids, names, at, permission }: GetFunctionParams) => Promise<WorkerComposedWithKey[]>;
|
|
26
|
-
export type GetFunctions = ReturnType<typeof getFunctions>;
|
|
27
|
-
export {};
|
|
@@ -1,78 +0,0 @@
|
|
|
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 { endpointSymbol } from "../common/task-symbol.js";
|
|
10
|
-
import { toModuleUrl } from "../common/module-url.js";
|
|
11
|
-
const normalizeTimeout = (timeout) => {
|
|
12
|
-
if (timeout == null)
|
|
13
|
-
return undefined;
|
|
14
|
-
if (typeof timeout === "number") {
|
|
15
|
-
const ms = Math.floor(timeout);
|
|
16
|
-
return ms >= 0
|
|
17
|
-
? { ms, kind: 0 /* TimeoutKind.Reject */, value: new Error("Task timeout") }
|
|
18
|
-
: undefined;
|
|
19
|
-
}
|
|
20
|
-
const ms = Math.floor(timeout.time);
|
|
21
|
-
if (!(ms >= 0))
|
|
22
|
-
return undefined;
|
|
23
|
-
if ("default" in timeout) {
|
|
24
|
-
return { ms, kind: 1 /* TimeoutKind.Resolve */, value: timeout.default };
|
|
25
|
-
}
|
|
26
|
-
if (timeout.maybe === true) {
|
|
27
|
-
return { ms, kind: 1 /* TimeoutKind.Resolve */, value: undefined };
|
|
28
|
-
}
|
|
29
|
-
if ("error" in timeout) {
|
|
30
|
-
return { ms, kind: 0 /* TimeoutKind.Reject */, value: timeout.error };
|
|
31
|
-
}
|
|
32
|
-
return { ms, kind: 0 /* TimeoutKind.Reject */, value: new Error("Task timeout") };
|
|
33
|
-
};
|
|
34
|
-
const composeWorkerCallable = (fixed, _permission) => {
|
|
35
|
-
return fixed.f;
|
|
36
|
-
};
|
|
37
|
-
export const getFunctions = async ({ list, ids, names, at, permission }) => {
|
|
38
|
-
const modules = list.map((specifier) => toModuleUrl(specifier));
|
|
39
|
-
const nameSet = new Set(names);
|
|
40
|
-
const results = await Promise.all(modules.map(async (imports) => {
|
|
41
|
-
const module = (await import(__rewriteRelativeImportExtension(imports)));
|
|
42
|
-
const fixedTasks = Object.entries(module)
|
|
43
|
-
.filter(([_, value]) => value != null && typeof value === "object" &&
|
|
44
|
-
//@ts-ignore Reason -> trust me
|
|
45
|
-
value?.[endpointSymbol] === true)
|
|
46
|
-
.map(([name, value]) => ({
|
|
47
|
-
//@ts-ignore Reason -> trust me
|
|
48
|
-
...value,
|
|
49
|
-
name,
|
|
50
|
-
}));
|
|
51
|
-
const functionTasks = Object.entries(module)
|
|
52
|
-
.filter(([name, value]) => nameSet.has(name) && typeof value === "function")
|
|
53
|
-
.map(([name, value]) => ({
|
|
54
|
-
f: value,
|
|
55
|
-
id: -1,
|
|
56
|
-
importedFrom: imports,
|
|
57
|
-
at: -1,
|
|
58
|
-
name,
|
|
59
|
-
[endpointSymbol]: true,
|
|
60
|
-
}));
|
|
61
|
-
return [...fixedTasks, ...functionTasks];
|
|
62
|
-
}));
|
|
63
|
-
// Flatten the results, filter by IDs, and sort
|
|
64
|
-
const flattened = results.flat();
|
|
65
|
-
const useAtFilter = modules.length === 1 && at.length > 0;
|
|
66
|
-
const atSet = useAtFilter ? new Set(at) : null;
|
|
67
|
-
const targetModule = useAtFilter ? modules[0] : null;
|
|
68
|
-
const flattenedResults = flattened
|
|
69
|
-
.filter((obj) => useAtFilter
|
|
70
|
-
? obj.importedFrom === targetModule && atSet.has(obj.at)
|
|
71
|
-
: ids.includes(obj.id))
|
|
72
|
-
.sort((a, b) => a.name.localeCompare(b.name));
|
|
73
|
-
return flattenedResults.map((fixed) => ({
|
|
74
|
-
...fixed,
|
|
75
|
-
run: composeWorkerCallable(fixed, permission),
|
|
76
|
-
timeout: normalizeTimeout(fixed.timeout),
|
|
77
|
-
}));
|
|
78
|
-
};
|
package/src/worker/timers.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
type PauseOptions = {
|
|
2
|
-
pauseInNanoseconds?: number;
|
|
3
|
-
};
|
|
4
|
-
export type NativeWaitU32 = (buffer: ArrayBuffer | SharedArrayBuffer, byteOffset: number, expected: number, timeoutMs?: number) => unknown;
|
|
5
|
-
export declare const whilePausing: ({ pauseInNanoseconds }: PauseOptions) => () => void;
|
|
6
|
-
export declare const pauseGeneric: () => void;
|
|
7
|
-
export declare const sleepUntilChanged: ({ at, opView, pauseInNanoseconds, rxStatus, txStatus, enqueueLock, write, nativeWaitU32, useSharedMemoryWait, }: {
|
|
8
|
-
opView: Int32Array;
|
|
9
|
-
rxStatus: Int32Array;
|
|
10
|
-
txStatus: Int32Array;
|
|
11
|
-
pauseInNanoseconds?: number;
|
|
12
|
-
at: number;
|
|
13
|
-
enqueueLock: () => boolean;
|
|
14
|
-
write?: () => number | boolean;
|
|
15
|
-
nativeWaitU32?: NativeWaitU32;
|
|
16
|
-
useSharedMemoryWait?: boolean;
|
|
17
|
-
}) => (value: number, spinMicroseconds: number, parkMs?: number) => void;
|
|
18
|
-
export {};
|
package/src/worker/timers.js
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
var Comment;
|
|
2
|
-
(function (Comment) {
|
|
3
|
-
Comment[Comment["thisIsAHint"] = 0] = "thisIsAHint";
|
|
4
|
-
})(Comment || (Comment = {}));
|
|
5
|
-
const maybeGc = (() => {
|
|
6
|
-
const host = globalThis;
|
|
7
|
-
const gc = typeof host.gc === "function"
|
|
8
|
-
? (() => host.gc())
|
|
9
|
-
: undefined;
|
|
10
|
-
if (gc) {
|
|
11
|
-
try {
|
|
12
|
-
delete host.gc;
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
host.gc = undefined;
|
|
16
|
-
}
|
|
17
|
-
if (host.global) {
|
|
18
|
-
try {
|
|
19
|
-
delete host.global.gc;
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
host.global.gc = undefined;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return gc ?? (() => { });
|
|
27
|
-
})();
|
|
28
|
-
const DEFAULT_PAUSE_TIME = 250;
|
|
29
|
-
const a_load = Atomics.load;
|
|
30
|
-
const a_store = Atomics.store;
|
|
31
|
-
const a_wait = typeof Atomics.wait === "function" ? Atomics.wait : undefined;
|
|
32
|
-
const p_now = performance.now.bind(performance);
|
|
33
|
-
const waitFallbackView = a_wait === undefined
|
|
34
|
-
? undefined
|
|
35
|
-
: new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
|
|
36
|
-
const a_pause = "pause" in Atomics
|
|
37
|
-
? Atomics.pause
|
|
38
|
-
: undefined;
|
|
39
|
-
const runtimeGlobals = globalThis;
|
|
40
|
-
const isPlainNodeWindows = runtimeGlobals.process?.platform === "win32" &&
|
|
41
|
-
typeof runtimeGlobals.process?.versions?.node === "string" &&
|
|
42
|
-
runtimeGlobals.process?.versions?.bun === undefined &&
|
|
43
|
-
runtimeGlobals.Deno === undefined;
|
|
44
|
-
// Windows has no working cross-process wake. The native wake (WakeByAddress)
|
|
45
|
-
// is keyed to a virtual address, so a host cannot wake a process worker parked
|
|
46
|
-
// on the same physical page mapped at a different address in the child — the
|
|
47
|
-
// addon's FutexWake is a no-op there. A parked Windows Node process worker can
|
|
48
|
-
// therefore never be signalled and must rediscover work by polling. Cap the
|
|
49
|
-
// native wait at 1ms so it re-checks every millisecond instead of sleeping the
|
|
50
|
-
// full parkMs (up to seconds); the long park with no wake is what made CI
|
|
51
|
-
// runners appear to hang. The native wait already polls internally, so this is
|
|
52
|
-
// just bounding each poll slice.
|
|
53
|
-
const nativeWaitTimeoutMs = (parkMs) => isPlainNodeWindows ? 1 : Number.isFinite(parkMs) ? parkMs : Infinity;
|
|
54
|
-
export const whilePausing = ({ pauseInNanoseconds }) => {
|
|
55
|
-
const forNanoseconds = pauseInNanoseconds ?? DEFAULT_PAUSE_TIME;
|
|
56
|
-
if (!a_pause || forNanoseconds <= 0)
|
|
57
|
-
return () => { };
|
|
58
|
-
return () => a_pause(forNanoseconds);
|
|
59
|
-
};
|
|
60
|
-
export const pauseGeneric = whilePausing({});
|
|
61
|
-
export const sleepUntilChanged = ({ at, opView, pauseInNanoseconds, rxStatus, txStatus, enqueueLock, write, nativeWaitU32, useSharedMemoryWait = true, }) => {
|
|
62
|
-
const pause = pauseInNanoseconds === undefined
|
|
63
|
-
? pauseGeneric
|
|
64
|
-
: whilePausing({ pauseInNanoseconds });
|
|
65
|
-
const tryProgress = () => {
|
|
66
|
-
let progressed = false;
|
|
67
|
-
if (enqueueLock())
|
|
68
|
-
progressed = true;
|
|
69
|
-
if (write) {
|
|
70
|
-
const wrote = write();
|
|
71
|
-
if (typeof wrote === "number") {
|
|
72
|
-
if (wrote > 0)
|
|
73
|
-
progressed = true;
|
|
74
|
-
}
|
|
75
|
-
else if (wrote === true) {
|
|
76
|
-
progressed = true;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return progressed;
|
|
80
|
-
};
|
|
81
|
-
return (value, spinMicroseconds, parkMs) => {
|
|
82
|
-
const until = p_now() + (spinMicroseconds / 1000);
|
|
83
|
-
maybeGc();
|
|
84
|
-
let spinChecks = 0;
|
|
85
|
-
while (true) {
|
|
86
|
-
if (a_load(opView, at) !== value ||
|
|
87
|
-
txStatus[Comment.thisIsAHint] === 1)
|
|
88
|
-
return;
|
|
89
|
-
if (tryProgress())
|
|
90
|
-
return;
|
|
91
|
-
pause();
|
|
92
|
-
if ((spinChecks++ & 63) === 0 && p_now() >= until)
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
if (tryProgress())
|
|
96
|
-
return;
|
|
97
|
-
a_store(rxStatus, 0, 0);
|
|
98
|
-
if (nativeWaitU32 !== undefined) {
|
|
99
|
-
nativeWaitU32(opView.buffer, opView.byteOffset + (at * Int32Array.BYTES_PER_ELEMENT), value >>> 0, nativeWaitTimeoutMs(parkMs));
|
|
100
|
-
}
|
|
101
|
-
else if (useSharedMemoryWait &&
|
|
102
|
-
a_wait &&
|
|
103
|
-
opView.buffer instanceof SharedArrayBuffer) {
|
|
104
|
-
// This is the notify-able path: a host Atomics.notify on opView wakes it.
|
|
105
|
-
// An infinite parkMs (debug) is intentional here — the worker blocks until
|
|
106
|
-
// a real signal instead of re-polling on a timeout.
|
|
107
|
-
a_wait(opView, at, value, parkMs ?? Infinity);
|
|
108
|
-
}
|
|
109
|
-
else if (a_wait && waitFallbackView) {
|
|
110
|
-
// waitFallbackView is never notified — this wait only ever times out and
|
|
111
|
-
// re-polls, so it must stay finite or the worker would hang forever.
|
|
112
|
-
a_wait(waitFallbackView, 0, 0, Number.isFinite(parkMs) ? parkMs : Infinity);
|
|
113
|
-
}
|
|
114
|
-
a_store(rxStatus, 0, 1);
|
|
115
|
-
};
|
|
116
|
-
};
|