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.
Files changed (135) hide show
  1. package/README.md +3 -3
  2. package/knitting.d.ts +797 -5
  3. package/knitting.js +9780 -5
  4. package/map.md +9 -12
  5. package/package.json +14 -13
  6. package/shared-memory.d.ts +155 -0
  7. package/shared-memory.js +1342 -0
  8. package/unsafe.d.ts +71 -1
  9. package/unsafe.js +878 -1
  10. package/utils.d.ts +31 -1
  11. package/utils.js +116 -1
  12. package/process-shared-buffer.d.ts +0 -1
  13. package/process-shared-buffer.js +0 -1
  14. package/src/api.d.ts +0 -69
  15. package/src/api.js +0 -627
  16. package/src/common/envelope.d.ts +0 -17
  17. package/src/common/envelope.js +0 -22
  18. package/src/common/module-url.d.ts +0 -1
  19. package/src/common/module-url.js +0 -24
  20. package/src/common/node-compat.d.ts +0 -20
  21. package/src/common/node-compat.js +0 -24
  22. package/src/common/path-canonical.d.ts +0 -6
  23. package/src/common/path-canonical.js +0 -41
  24. package/src/common/runtime.d.ts +0 -15
  25. package/src/common/runtime.js +0 -91
  26. package/src/common/shared-buffer-region.d.ts +0 -11
  27. package/src/common/shared-buffer-region.js +0 -21
  28. package/src/common/shared-buffer-text.d.ts +0 -16
  29. package/src/common/shared-buffer-text.js +0 -65
  30. package/src/common/task-source.d.ts +0 -3
  31. package/src/common/task-source.js +0 -84
  32. package/src/common/task-symbol.d.ts +0 -1
  33. package/src/common/task-symbol.js +0 -1
  34. package/src/common/with-resolvers.d.ts +0 -9
  35. package/src/common/with-resolvers.js +0 -23
  36. package/src/common/worker-runtime.d.ts +0 -42
  37. package/src/common/worker-runtime.js +0 -61
  38. package/src/connections/buffer-reference-native.d.ts +0 -56
  39. package/src/connections/buffer-reference-native.js +0 -217
  40. package/src/connections/buffer-reference.d.ts +0 -78
  41. package/src/connections/buffer-reference.js +0 -461
  42. package/src/connections/bun.d.ts +0 -22
  43. package/src/connections/bun.js +0 -214
  44. package/src/connections/deno.d.ts +0 -22
  45. package/src/connections/deno.js +0 -205
  46. package/src/connections/file-descriptor.d.ts +0 -39
  47. package/src/connections/file-descriptor.js +0 -161
  48. package/src/connections/index.d.ts +0 -4
  49. package/src/connections/index.js +0 -4
  50. package/src/connections/node-addons.d.ts +0 -5
  51. package/src/connections/node-addons.js +0 -43
  52. package/src/connections/node-buffer-pointer.d.ts +0 -20
  53. package/src/connections/node-buffer-pointer.js +0 -16
  54. package/src/connections/node.d.ts +0 -30
  55. package/src/connections/node.js +0 -62
  56. package/src/connections/posix.d.ts +0 -32
  57. package/src/connections/posix.js +0 -77
  58. package/src/connections/process-shared-buffer.d.ts +0 -75
  59. package/src/connections/process-shared-buffer.js +0 -279
  60. package/src/connections/shared-array-buffer-payload.d.ts +0 -36
  61. package/src/connections/shared-array-buffer-payload.js +0 -235
  62. package/src/connections/types.d.ts +0 -50
  63. package/src/connections/types.js +0 -37
  64. package/src/connections/windows.d.ts +0 -28
  65. package/src/connections/windows.js +0 -224
  66. package/src/debug/env-diff.d.ts +0 -26
  67. package/src/debug/env-diff.js +0 -49
  68. package/src/debug/gate.d.ts +0 -18
  69. package/src/debug/gate.js +0 -69
  70. package/src/debug/handle.d.ts +0 -23
  71. package/src/debug/handle.js +0 -48
  72. package/src/error.d.ts +0 -13
  73. package/src/error.js +0 -49
  74. package/src/ipc/tools/ring-queue.d.ts +0 -33
  75. package/src/ipc/tools/ring-queue.js +0 -159
  76. package/src/ipc/transport/shared-memory.d.ts +0 -23
  77. package/src/ipc/transport/shared-memory.js +0 -35
  78. package/src/memory/byte-carpet.d.ts +0 -73
  79. package/src/memory/byte-carpet.js +0 -157
  80. package/src/memory/lock.d.ts +0 -201
  81. package/src/memory/lock.js +0 -739
  82. package/src/memory/payload-config.d.ts +0 -31
  83. package/src/memory/payload-config.js +0 -67
  84. package/src/memory/payloadCodec.d.ts +0 -46
  85. package/src/memory/payloadCodec.js +0 -1334
  86. package/src/memory/regionRegistry.d.ts +0 -17
  87. package/src/memory/regionRegistry.js +0 -285
  88. package/src/memory/shared-buffer-io.d.ts +0 -55
  89. package/src/memory/shared-buffer-io.js +0 -403
  90. package/src/permission/index.d.ts +0 -2
  91. package/src/permission/index.js +0 -2
  92. package/src/permission/protocol.d.ts +0 -166
  93. package/src/permission/protocol.js +0 -650
  94. package/src/runtime/balancer.d.ts +0 -19
  95. package/src/runtime/balancer.js +0 -149
  96. package/src/runtime/dispatcher.d.ts +0 -40
  97. package/src/runtime/dispatcher.js +0 -142
  98. package/src/runtime/inline-executor.d.ts +0 -10
  99. package/src/runtime/inline-executor.js +0 -282
  100. package/src/runtime/pool.d.ts +0 -39
  101. package/src/runtime/pool.js +0 -404
  102. package/src/runtime/process-worker.d.ts +0 -92
  103. package/src/runtime/process-worker.js +0 -673
  104. package/src/runtime/tx-queue.d.ts +0 -26
  105. package/src/runtime/tx-queue.js +0 -155
  106. package/src/shared/abortSignal.d.ts +0 -23
  107. package/src/shared/abortSignal.js +0 -134
  108. package/src/types.d.ts +0 -357
  109. package/src/types.js +0 -2
  110. package/src/utils/http.d.ts +0 -29
  111. package/src/utils/http.js +0 -100
  112. package/src/worker/bootstrap.d.ts +0 -5
  113. package/src/worker/bootstrap.js +0 -78
  114. package/src/worker/composable-runners.d.ts +0 -12
  115. package/src/worker/composable-runners.js +0 -97
  116. package/src/worker/loop.d.ts +0 -2
  117. package/src/worker/loop.js +0 -382
  118. package/src/worker/process-worker-bootstrap.d.ts +0 -8
  119. package/src/worker/process-worker-bootstrap.js +0 -160
  120. package/src/worker/rx-queue.d.ts +0 -25
  121. package/src/worker/rx-queue.js +0 -173
  122. package/src/worker/safety/index.d.ts +0 -4
  123. package/src/worker/safety/index.js +0 -4
  124. package/src/worker/safety/performance.d.ts +0 -1
  125. package/src/worker/safety/performance.js +0 -17
  126. package/src/worker/safety/process.d.ts +0 -2
  127. package/src/worker/safety/process.js +0 -79
  128. package/src/worker/safety/startup.d.ts +0 -16
  129. package/src/worker/safety/startup.js +0 -30
  130. package/src/worker/safety/worker-data.d.ts +0 -2
  131. package/src/worker/safety/worker-data.js +0 -36
  132. package/src/worker/task-loader.d.ts +0 -27
  133. package/src/worker/task-loader.js +0 -78
  134. package/src/worker/timers.d.ts +0 -18
  135. package/src/worker/timers.js +0 -116
@@ -1,382 +0,0 @@
1
- import { addRuntimeDataListener, createRuntimeMessageChannel, RUNTIME_IS_MAIN_THREAD, RUNTIME_IS_PROCESS_WORKER, RUNTIME_PARENT_PORT, RUNTIME_WORKER_DATA, } from "../common/worker-runtime.js";
2
- import { isSharedBufferSource } from "../common/shared-buffer-region.js";
3
- import { isLockBufferTextCompat } from "../common/shared-buffer-text.js";
4
- import { createWorkerRxQueue } from "./rx-queue.js";
5
- import { createSharedMemoryTransport } from "../ipc/transport/shared-memory.js";
6
- import { lock2 } from "../memory/lock.js";
7
- import { getFunctions } from "./task-loader.js";
8
- import { pauseGeneric, sleepUntilChanged, whilePausing } from "./timers.js";
9
- import { RUNTIME, SET_IMMEDIATE } from "../common/runtime.js";
10
- import { getNodeProcess } from "../common/node-compat.js";
11
- import { assertWorkerImportsResolved, assertWorkerSharedMemoryBootData, installPerformanceNowGuard, installTerminationGuard, installUnhandledRejectionSilencer, scrubWorkerDataSensitiveBuffers, } from "./safety/index.js";
12
- import { signalAbortFactory } from "../shared/abortSignal.js";
13
- import { runWorkerBootstrap } from "./bootstrap.js";
14
- import { getProcessWorkerNativeWaitU32, installProcessWorkerBootstrap, } from "./process-worker-bootstrap.js";
15
- import { readBufferReferenceReturnReleaseMessage, } from "../connections/buffer-reference.js";
16
- import { resolveDebugNamespaces } from "../debug/gate.js";
17
- const WORKER_FATAL_MESSAGE_KEY = "__knittingWorkerFatal";
18
- const reportWorkerStartupFatal = (error) => {
19
- const message = String(error?.message ?? error);
20
- const payload = {
21
- [WORKER_FATAL_MESSAGE_KEY]: message,
22
- };
23
- let reported = false;
24
- try {
25
- RUNTIME_PARENT_PORT?.postMessage?.(payload);
26
- reported = RUNTIME_PARENT_PORT !== undefined;
27
- }
28
- catch {
29
- }
30
- if (!reported) {
31
- try {
32
- globalThis.postMessage(payload);
33
- reported = true;
34
- }
35
- catch {
36
- }
37
- }
38
- if (!reported) {
39
- try {
40
- console.error(`Worker startup failed: ${message}`);
41
- }
42
- catch {
43
- }
44
- if (RUNTIME_IS_PROCESS_WORKER) {
45
- try {
46
- getNodeProcess()?.exit?.(1);
47
- }
48
- catch {
49
- }
50
- }
51
- }
52
- };
53
- const installBufferReferenceReleaseListener = (releaseReturnedBufferReference) => {
54
- const handleMessage = (message) => {
55
- const token = readBufferReferenceReturnReleaseMessage(message);
56
- if (token !== undefined)
57
- releaseReturnedBufferReference(token);
58
- };
59
- if (RUNTIME_PARENT_PORT !== undefined) {
60
- addRuntimeDataListener(RUNTIME_PARENT_PORT, handleMessage);
61
- return;
62
- }
63
- const scope = globalThis;
64
- scope.addEventListener?.("message", (event) => {
65
- handleMessage(event?.data);
66
- });
67
- };
68
- export const workerMainLoop = async (startupData) => {
69
- // Startup-only safety layer: no per-iteration checks in the hot loop.
70
- installTerminationGuard();
71
- installUnhandledRejectionSilencer();
72
- installPerformanceNowGuard();
73
- const { debug, sab, thread, startAt, workerOptions, lock, returnLock, abortSignalSAB, abortSignalMax, payloadConfig, bufferReferenceReturn, permission, totalNumberOfThread, list, ids, names, at, } = startupData;
74
- scrubWorkerDataSensitiveBuffers(startupData);
75
- assertWorkerSharedMemoryBootData({ sab, lock, returnLock });
76
- const debugNamespaces = resolveDebugNamespaces(debug);
77
- const dbg = debugNamespaces.size > 0
78
- ? await import("../debug/handle.js").then((module) => module.initDebug({
79
- name: `w${thread}`,
80
- runtime: RUNTIME,
81
- namespaces: debugNamespaces,
82
- }))
83
- : undefined;
84
- let Comment;
85
- (function (Comment) {
86
- Comment[Comment["thisIsAHint"] = 0] = "thisIsAHint";
87
- })(Comment || (Comment = {}));
88
- const signals = createSharedMemoryTransport({
89
- sabObject: {
90
- sharedSab: sab,
91
- },
92
- isMain: false,
93
- thread,
94
- startTime: startAt,
95
- });
96
- const lockState = lock2({
97
- headers: lock.headers,
98
- headerSlotStrideU32: lock.headerSlotStrideU32,
99
- LockBoundSector: lock.lockSector,
100
- payload: lock.payload,
101
- payloadSector: lock.payloadSector,
102
- payloadConfig,
103
- textCompat: lock.textCompat,
104
- });
105
- const returnLockState = lock2({
106
- headers: returnLock.headers,
107
- headerSlotStrideU32: returnLock.headerSlotStrideU32,
108
- LockBoundSector: returnLock.lockSector,
109
- payload: returnLock.payload,
110
- payloadSector: returnLock.payloadSector,
111
- payloadConfig,
112
- textCompat: returnLock.textCompat,
113
- });
114
- const timers = workerOptions?.timers;
115
- const spinMicroseconds = timers?.spinMicroseconds ??
116
- Math.max(1, totalNumberOfThread) * 50;
117
- const parkMs = dbg !== undefined
118
- ? Number.POSITIVE_INFINITY
119
- : (timers?.parkMs ??
120
- Math.max(1, totalNumberOfThread) * 50);
121
- const pauseSpin = (() => {
122
- const fn = typeof timers?.pauseNanoseconds === "number"
123
- ? whilePausing({ pauseInNanoseconds: timers.pauseNanoseconds })
124
- : pauseGeneric;
125
- return () => fn(); // always a closure wrapper
126
- })();
127
- const { opView, rxStatus, txStatus } = signals;
128
- const a_store = Atomics.store;
129
- const a_load = Atomics.load;
130
- const nativeWaitU32 = getProcessWorkerNativeWaitU32();
131
- await runWorkerBootstrap({
132
- bootstrap: workerOptions?.bootstrap,
133
- thread,
134
- totalNumberOfThread,
135
- });
136
- dbg?.envPhase("bootstrap");
137
- const listOfFunctions = await getFunctions({
138
- list,
139
- isWorker: true,
140
- ids,
141
- names,
142
- at,
143
- permission,
144
- });
145
- dbg?.envPhase("tasks");
146
- dbg?.log("imports", `${listOfFunctions.length} task(s) from ${list.map((spec) => spec.split(/[\\/]/).pop() || spec).join(", ")}`);
147
- assertWorkerImportsResolved({ list, ids, names, listOfFunctions });
148
- const abortSignals = abortSignalSAB
149
- ? signalAbortFactory({
150
- sab: abortSignalSAB,
151
- maxSignals: abortSignalMax,
152
- })
153
- : undefined;
154
- const { enqueueLock, serviceBatchImmediate, hasCompleted, writeBatch, hasPending, getAwaiting, drainReturnReleases, releaseReturnedBufferReference, } = createWorkerRxQueue({
155
- listOfFunctions,
156
- workerOptions,
157
- lock: lockState,
158
- returnLock: returnLockState,
159
- borrowReturnedBufferReferences: bufferReferenceReturn === "borrow",
160
- hasAborted: abortSignals?.hasAborted,
161
- });
162
- installBufferReferenceReleaseListener(releaseReturnedBufferReference);
163
- a_store(rxStatus, 0, 1);
164
- const WRITE_MAX = 64;
165
- const pauseUntil = sleepUntilChanged({
166
- opView,
167
- at: 0,
168
- rxStatus,
169
- txStatus,
170
- pauseInNanoseconds: timers?.pauseNanoseconds,
171
- enqueueLock,
172
- write: () => hasCompleted() ? writeBatch(WRITE_MAX) : 0,
173
- nativeWaitU32,
174
- useSharedMemoryWait: !(RUNTIME_IS_PROCESS_WORKER &&
175
- RUNTIME === "node" &&
176
- nativeWaitU32 === undefined),
177
- });
178
- const channel = createRuntimeMessageChannel();
179
- const port1 = channel.port1;
180
- const port2 = channel.port2;
181
- const post2 = (message) => port2.postMessage(message);
182
- let isInMacro = false;
183
- let awaitingSpins = 0;
184
- let lastAwaiting = 0;
185
- const MAX_AWAITING_MS = 10;
186
- let wakeToken = a_load(opView, 0);
187
- const scheduleMacro = () => {
188
- if (isInMacro)
189
- return;
190
- isInMacro = true;
191
- post2(null);
192
- };
193
- const scheduleTimer = (delayMs) => {
194
- if (isInMacro)
195
- return;
196
- isInMacro = true;
197
- if (delayMs <= 0 && typeof SET_IMMEDIATE === "function") {
198
- SET_IMMEDIATE(loop);
199
- return;
200
- }
201
- if (delayMs <= 0) {
202
- post2(null);
203
- return;
204
- }
205
- if (typeof setTimeout === "function") {
206
- setTimeout(loop, delayMs);
207
- return;
208
- }
209
- post2(null);
210
- };
211
- const traceSignals = dbg?.enabled("signals") === true;
212
- const _hasCompleted = hasCompleted;
213
- const _hasPending = hasPending;
214
- const _getAwaiting = getAwaiting;
215
- const _drainReturnReleases = drainReturnReleases;
216
- const _pauseSpin = pauseSpin;
217
- const _enqueueLock = traceSignals
218
- ? () => {
219
- const progressed = enqueueLock();
220
- if (progressed) {
221
- dbg.log("signals", "work from=host");
222
- }
223
- return progressed;
224
- }
225
- : enqueueLock;
226
- const _writeBatch = traceSignals
227
- ? (max) => {
228
- const wrote = writeBatch(max);
229
- if (wrote > 0)
230
- dbg.log("signals", `result count=${wrote}`);
231
- return wrote;
232
- }
233
- : writeBatch;
234
- const _serviceBatchImmediate = traceSignals
235
- ? () => {
236
- const ran = serviceBatchImmediate();
237
- if (ran > 0)
238
- dbg.log("signals", `run count=${ran}`);
239
- return ran;
240
- }
241
- : serviceBatchImmediate;
242
- const _pauseUntil = traceSignals
243
- ? (value, spinMicroseconds, parkMs) => {
244
- dbg.log("signals", `idle token=${value}`);
245
- pauseUntil(value, spinMicroseconds, parkMs);
246
- }
247
- : pauseUntil;
248
- const loop = () => {
249
- isInMacro = false;
250
- let progressed = true;
251
- let awaiting = 0;
252
- while (true) {
253
- progressed = _enqueueLock();
254
- if (_hasCompleted()) {
255
- if (_writeBatch(WRITE_MAX) > 0)
256
- progressed = true;
257
- }
258
- _drainReturnReleases();
259
- if (_hasPending()) {
260
- if (_serviceBatchImmediate() > 0)
261
- progressed = true;
262
- }
263
- if ((awaiting = _getAwaiting()) > 0) {
264
- if (awaiting !== lastAwaiting)
265
- awaitingSpins = 0;
266
- lastAwaiting = awaiting;
267
- awaitingSpins++;
268
- const delay = Math.min(MAX_AWAITING_MS, Math.max(0, awaitingSpins - 1));
269
- scheduleTimer(delay);
270
- return;
271
- }
272
- awaitingSpins = lastAwaiting = 0;
273
- if (!progressed) {
274
- if (txStatus[Comment.thisIsAHint] === 1) {
275
- _pauseSpin();
276
- continue;
277
- }
278
- _pauseUntil(wakeToken, spinMicroseconds, parkMs);
279
- wakeToken = a_load(opView, 0);
280
- }
281
- }
282
- };
283
- const port1Any = port1;
284
- if (typeof port1Any.on === "function") {
285
- port1Any.on("message", loop);
286
- }
287
- else {
288
- // @ts-ignore
289
- port1Any.onmessage = loop;
290
- }
291
- port1Any.start?.();
292
- port2.start?.();
293
- dbg?.log("lifecycle", `ready: ${listOfFunctions.length} task(s) on thread ${thread}/${totalNumberOfThread}, entering dispatch loop`);
294
- scheduleMacro();
295
- };
296
- const isWorkerGlobalScope = () => {
297
- const scopeCtor = globalThis.WorkerGlobalScope;
298
- if (typeof scopeCtor !== "function")
299
- return false;
300
- try {
301
- return globalThis instanceof
302
- scopeCtor;
303
- }
304
- catch {
305
- return false;
306
- }
307
- };
308
- const isLockBuffers = (value) => {
309
- if (!value || typeof value !== "object")
310
- return false;
311
- const candidate = value;
312
- return isSharedBufferSource(candidate.headers) &&
313
- isSharedBufferSource(candidate.lockSector) &&
314
- isSharedBufferSource(candidate.payload) &&
315
- isSharedBufferSource(candidate.payloadSector) &&
316
- (candidate.textCompat === undefined ||
317
- isLockBufferTextCompat(candidate.textCompat));
318
- };
319
- const isWorkerBootPayload = (value) => {
320
- if (!value || typeof value !== "object")
321
- return false;
322
- const candidate = value;
323
- return isSharedBufferSource(candidate.sab) &&
324
- Array.isArray(candidate.list) &&
325
- Array.isArray(candidate.ids) &&
326
- Array.isArray(candidate.names) &&
327
- Array.isArray(candidate.at) &&
328
- typeof candidate.thread === "number" &&
329
- typeof candidate.totalNumberOfThread === "number" &&
330
- typeof candidate.startAt === "number" &&
331
- (candidate.abortSignalSAB === undefined ||
332
- isSharedBufferSource(candidate.abortSignalSAB)) &&
333
- isLockBuffers(candidate.lock) &&
334
- isLockBuffers(candidate.returnLock);
335
- };
336
- const installWorkerGlobalBootstrap = () => {
337
- const g = globalThis;
338
- const start = (data) => {
339
- if (!isWorkerBootPayload(data))
340
- return;
341
- void workerMainLoop(data).catch(reportWorkerStartupFatal);
342
- };
343
- if (typeof g.addEventListener === "function" &&
344
- typeof g.removeEventListener === "function") {
345
- const onMessage = (event) => {
346
- const data = event?.data;
347
- if (!isWorkerBootPayload(data))
348
- return;
349
- try {
350
- g.removeEventListener?.("message", onMessage);
351
- }
352
- catch {
353
- }
354
- start(data);
355
- };
356
- g.addEventListener("message", onMessage);
357
- return;
358
- }
359
- g.onmessage = (event) => {
360
- const data = event?.data;
361
- if (!isWorkerBootPayload(data))
362
- return;
363
- g.onmessage = null;
364
- start(data);
365
- };
366
- };
367
- if (RUNTIME_IS_MAIN_THREAD === false &&
368
- isWorkerBootPayload(RUNTIME_WORKER_DATA)) {
369
- void workerMainLoop(RUNTIME_WORKER_DATA).catch(reportWorkerStartupFatal);
370
- }
371
- else if (RUNTIME_IS_PROCESS_WORKER) {
372
- installProcessWorkerBootstrap({
373
- isWorkerBootPayload,
374
- reportWorkerStartupFatal,
375
- startWorker: (data) => {
376
- void workerMainLoop(data).catch(reportWorkerStartupFatal);
377
- },
378
- });
379
- }
380
- else if (isWorkerGlobalScope()) {
381
- installWorkerGlobalBootstrap();
382
- }
@@ -1,8 +0,0 @@
1
- import type { WorkerData } from "../types.js";
2
- import type { NativeWaitU32 } from "./timers.js";
3
- export declare const getProcessWorkerNativeWaitU32: () => NativeWaitU32 | undefined;
4
- export declare const installProcessWorkerBootstrap: ({ isWorkerBootPayload, reportWorkerStartupFatal, startWorker, }: {
5
- isWorkerBootPayload: (value: unknown) => value is WorkerData;
6
- reportWorkerStartupFatal: (error: unknown) => void;
7
- startWorker: (data: WorkerData) => void;
8
- }) => void;
@@ -1,160 +0,0 @@
1
- import { RUNTIME } from "../common/runtime.js";
2
- import { RUNTIME_IS_PROCESS_WORKER, RUNTIME_PARENT_PORT, RUNTIME_PROCESS_WORKER_BOOT_ENV, RUNTIME_PROCESS_WORKER_BOOT_VERSION, } from "../common/worker-runtime.js";
3
- import { getNodeProcess } from "../common/node-compat.js";
4
- import { isLockBufferTextCompat } from "../common/shared-buffer-text.js";
5
- import { getDefaultProcessSharedBufferPrimitives, ProcessSharedBuffer, setDefaultProcessSharedBufferPrimitives, } from "../connections/process-shared-buffer.js";
6
- import { createBunConnectionPrimitives } from "../connections/bun.js";
7
- import { createDenoConnectionPrimitives } from "../connections/deno.js";
8
- import { loadNodeFutexAddon } from "../connections/node.js";
9
- export const getProcessWorkerNativeWaitU32 = () => {
10
- if (!RUNTIME_IS_PROCESS_WORKER || RUNTIME !== "node")
11
- return undefined;
12
- try {
13
- return loadNodeFutexAddon().waitU32;
14
- }
15
- catch {
16
- return undefined;
17
- }
18
- };
19
- const isProcessSharedBufferMetadata = (value) => {
20
- try {
21
- ProcessSharedBuffer.fromMetadata(value);
22
- return true;
23
- }
24
- catch {
25
- return false;
26
- }
27
- };
28
- const isProcessWorkerWireLockBuffers = (value) => {
29
- if (!value || typeof value !== "object")
30
- return false;
31
- const candidate = value;
32
- return isProcessSharedBufferMetadata(candidate.headers) &&
33
- isProcessSharedBufferMetadata(candidate.lockSector) &&
34
- isProcessSharedBufferMetadata(candidate.payload) &&
35
- isProcessSharedBufferMetadata(candidate.payloadSector) &&
36
- (candidate.textCompat === undefined ||
37
- isLockBufferTextCompat(candidate.textCompat));
38
- };
39
- const isProcessWorkerBootPayload = (value) => {
40
- if (!value || typeof value !== "object")
41
- return false;
42
- const candidate = value;
43
- const workerData = candidate.workerData;
44
- return candidate.version === RUNTIME_PROCESS_WORKER_BOOT_VERSION &&
45
- !!workerData &&
46
- isProcessSharedBufferMetadata(workerData.sab) &&
47
- Array.isArray(workerData.list) &&
48
- Array.isArray(workerData.ids) &&
49
- Array.isArray(workerData.names) &&
50
- Array.isArray(workerData.at) &&
51
- typeof workerData.thread === "number" &&
52
- typeof workerData.totalNumberOfThread === "number" &&
53
- typeof workerData.startAt === "number" &&
54
- (workerData.abortSignalSAB === undefined ||
55
- isProcessSharedBufferMetadata(workerData.abortSignalSAB)) &&
56
- isProcessWorkerWireLockBuffers(workerData.lock) &&
57
- isProcessWorkerWireLockBuffers(workerData.returnLock);
58
- };
59
- const getProcessWorkerPrimitives = () => {
60
- const primitives = RUNTIME === "bun"
61
- ? createBunConnectionPrimitives()
62
- : RUNTIME === "deno"
63
- ? createDenoConnectionPrimitives()
64
- : getDefaultProcessSharedBufferPrimitives();
65
- setDefaultProcessSharedBufferPrimitives(primitives);
66
- return primitives;
67
- };
68
- const reviveProcessWorkerData = (wire) => {
69
- const primitives = getProcessWorkerPrimitives();
70
- const mappings = new Map();
71
- const mappingKey = (descriptor) => descriptor.name === undefined
72
- ? `fd:${descriptor.fd}:${descriptor.size}:${descriptor.runtime ?? ""}`
73
- : `name:${descriptor.name}:${descriptor.size}:${descriptor.runtime ?? ""}`;
74
- const reviveRegion = (metadata) => {
75
- const processBuffer = ProcessSharedBuffer.fromMetadata(metadata);
76
- const descriptor = processBuffer.descriptor;
77
- const key = mappingKey(descriptor);
78
- let mapping = mappings.get(key);
79
- if (mapping === undefined) {
80
- mapping = descriptor.map(primitives);
81
- mappings.set(key, mapping);
82
- }
83
- else {
84
- descriptor.attach(mapping);
85
- }
86
- return {
87
- sab: mapping.buffer,
88
- byteOffset: processBuffer.byteOffset,
89
- byteLength: processBuffer.byteLength,
90
- };
91
- };
92
- const reviveLockBuffers = (lock) => ({
93
- ...lock,
94
- headers: reviveRegion(lock.headers),
95
- lockSector: reviveRegion(lock.lockSector),
96
- payload: reviveRegion(lock.payload),
97
- payloadSector: reviveRegion(lock.payloadSector),
98
- });
99
- return {
100
- ...wire,
101
- sab: reviveRegion(wire.sab),
102
- abortSignalSAB: wire.abortSignalSAB === undefined
103
- ? undefined
104
- : reviveRegion(wire.abortSignalSAB),
105
- lock: reviveLockBuffers(wire.lock),
106
- returnLock: reviveLockBuffers(wire.returnLock),
107
- };
108
- };
109
- export const installProcessWorkerBootstrap = ({ isWorkerBootPayload, reportWorkerStartupFatal, startWorker, }) => {
110
- const processLike = getNodeProcess();
111
- const start = (payload) => {
112
- const data = reviveProcessWorkerData(payload.workerData);
113
- if (!isWorkerBootPayload(data)) {
114
- throw new TypeError("invalid process worker boot payload");
115
- }
116
- startWorker(data);
117
- };
118
- const envBoot = processLike?.env?.[RUNTIME_PROCESS_WORKER_BOOT_ENV];
119
- if (typeof envBoot === "string" && envBoot.length > 0) {
120
- try {
121
- const payload = JSON.parse(envBoot);
122
- if (!isProcessWorkerBootPayload(payload)) {
123
- throw new TypeError("invalid process worker boot payload");
124
- }
125
- try {
126
- delete processLike?.env?.[RUNTIME_PROCESS_WORKER_BOOT_ENV];
127
- }
128
- catch {
129
- }
130
- start(payload);
131
- }
132
- catch (error) {
133
- reportWorkerStartupFatal(error);
134
- }
135
- return;
136
- }
137
- if (RUNTIME_PARENT_PORT === undefined) {
138
- reportWorkerStartupFatal(new TypeError("missing process worker boot payload"));
139
- return;
140
- }
141
- if (typeof processLike?.on !== "function")
142
- return;
143
- const onMessage = (message) => {
144
- if (!isProcessWorkerBootPayload(message))
145
- return;
146
- try {
147
- processLike.off?.("message", onMessage);
148
- processLike.removeListener?.("message", onMessage);
149
- }
150
- catch {
151
- }
152
- try {
153
- start(message);
154
- }
155
- catch (error) {
156
- reportWorkerStartupFatal(error);
157
- }
158
- };
159
- processLike.on("message", onMessage);
160
- };
@@ -1,25 +0,0 @@
1
- import { type Lock2 } from "../memory/lock.js";
2
- import type { WorkerComposedWithKey } from "./task-loader.js";
3
- import type { WorkerSettings } from "../types.js";
4
- type ArgumentsForCreateWorkerQueue = {
5
- listOfFunctions: WorkerComposedWithKey[];
6
- workerOptions?: WorkerSettings;
7
- lock: Lock2;
8
- returnLock: Lock2;
9
- borrowReturnedBufferReferences?: boolean;
10
- hasAborted?: (signal: number) => boolean;
11
- now?: () => number;
12
- };
13
- export type CreateWorkerRxQueue = ReturnType<typeof createWorkerRxQueue>;
14
- export declare const createWorkerRxQueue: ({ listOfFunctions, workerOptions, lock, returnLock, borrowReturnedBufferReferences, hasAborted, now, }: ArgumentsForCreateWorkerQueue) => {
15
- hasCompleted: () => boolean;
16
- hasPending: () => boolean;
17
- writeBatch: (max: number) => number;
18
- serviceBatchImmediate: () => number;
19
- enqueueLock: () => boolean;
20
- drainReturnReleases: () => void;
21
- releaseReturnedBufferReference: (token: bigint) => void;
22
- hasAwaiting: () => boolean;
23
- getAwaiting: () => number;
24
- };
25
- export {};