knitting 0.1.55 → 0.1.56

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 (138) hide show
  1. package/knitting.d.ts +6 -797
  2. package/knitting.js +6 -9780
  3. package/map.md +12 -8
  4. package/package.json +14 -6
  5. package/process-shared-buffer.d.ts +1 -0
  6. package/process-shared-buffer.js +1 -0
  7. package/shared-memory.d.ts +1 -155
  8. package/shared-memory.js +1 -1342
  9. package/src/api.d.ts +69 -0
  10. package/src/api.js +619 -0
  11. package/src/common/envelope.d.ts +17 -0
  12. package/src/common/envelope.js +22 -0
  13. package/src/common/module-url.d.ts +1 -0
  14. package/src/common/module-url.js +24 -0
  15. package/src/common/node-compat.d.ts +20 -0
  16. package/src/common/node-compat.js +24 -0
  17. package/src/common/path-canonical.d.ts +6 -0
  18. package/src/common/path-canonical.js +41 -0
  19. package/src/common/runtime.d.ts +15 -0
  20. package/src/common/runtime.js +91 -0
  21. package/src/common/shared-buffer-region.d.ts +11 -0
  22. package/src/common/shared-buffer-region.js +21 -0
  23. package/src/common/shared-buffer-text.d.ts +16 -0
  24. package/src/common/shared-buffer-text.js +65 -0
  25. package/src/common/task-source.d.ts +3 -0
  26. package/src/common/task-source.js +84 -0
  27. package/src/common/task-symbol.d.ts +1 -0
  28. package/src/common/task-symbol.js +1 -0
  29. package/src/common/with-resolvers.d.ts +9 -0
  30. package/src/common/with-resolvers.js +23 -0
  31. package/src/common/worker-runtime.d.ts +42 -0
  32. package/src/common/worker-runtime.js +61 -0
  33. package/src/connections/buffer-reference-native.d.ts +56 -0
  34. package/src/connections/buffer-reference-native.js +217 -0
  35. package/src/connections/buffer-reference.d.ts +78 -0
  36. package/src/connections/buffer-reference.js +461 -0
  37. package/src/connections/bun.d.ts +22 -0
  38. package/src/connections/bun.js +214 -0
  39. package/src/connections/deno.d.ts +22 -0
  40. package/src/connections/deno.js +205 -0
  41. package/src/connections/file-descriptor.d.ts +39 -0
  42. package/src/connections/file-descriptor.js +161 -0
  43. package/src/connections/index.d.ts +4 -0
  44. package/src/connections/index.js +4 -0
  45. package/src/connections/node-addons.d.ts +5 -0
  46. package/src/connections/node-addons.js +44 -0
  47. package/src/connections/node-buffer-pointer.d.ts +20 -0
  48. package/src/connections/node-buffer-pointer.js +16 -0
  49. package/src/connections/node.d.ts +30 -0
  50. package/src/connections/node.js +62 -0
  51. package/src/connections/numeric-array.d.ts +5 -0
  52. package/src/connections/numeric-array.js +17 -0
  53. package/src/connections/package-assets.d.ts +2 -0
  54. package/src/connections/package-assets.js +45 -0
  55. package/src/connections/posix.d.ts +32 -0
  56. package/src/connections/posix.js +77 -0
  57. package/src/connections/process-shared-buffer.d.ts +75 -0
  58. package/src/connections/process-shared-buffer.js +279 -0
  59. package/src/connections/shared-array-buffer-payload.d.ts +36 -0
  60. package/src/connections/shared-array-buffer-payload.js +235 -0
  61. package/src/connections/types.d.ts +50 -0
  62. package/src/connections/types.js +37 -0
  63. package/src/connections/windows.d.ts +28 -0
  64. package/src/connections/windows.js +224 -0
  65. package/src/debug/env-diff.d.ts +26 -0
  66. package/src/debug/env-diff.js +49 -0
  67. package/src/debug/gate.d.ts +18 -0
  68. package/src/debug/gate.js +69 -0
  69. package/src/debug/handle.d.ts +23 -0
  70. package/src/debug/handle.js +48 -0
  71. package/src/error.d.ts +13 -0
  72. package/src/error.js +49 -0
  73. package/src/ipc/tools/ring-queue.d.ts +33 -0
  74. package/src/ipc/tools/ring-queue.js +159 -0
  75. package/src/ipc/transport/shared-memory.d.ts +23 -0
  76. package/src/ipc/transport/shared-memory.js +35 -0
  77. package/src/memory/byte-carpet.d.ts +73 -0
  78. package/src/memory/byte-carpet.js +157 -0
  79. package/src/memory/lock.d.ts +203 -0
  80. package/src/memory/lock.js +741 -0
  81. package/src/memory/payload-config.d.ts +31 -0
  82. package/src/memory/payload-config.js +67 -0
  83. package/src/memory/payloadCodec.d.ts +46 -0
  84. package/src/memory/payloadCodec.js +1377 -0
  85. package/src/memory/regionRegistry.d.ts +17 -0
  86. package/src/memory/regionRegistry.js +285 -0
  87. package/src/memory/shared-buffer-io.d.ts +55 -0
  88. package/src/memory/shared-buffer-io.js +403 -0
  89. package/src/permission/index.d.ts +2 -0
  90. package/src/permission/index.js +2 -0
  91. package/src/permission/protocol.d.ts +166 -0
  92. package/src/permission/protocol.js +650 -0
  93. package/src/runtime/balancer.d.ts +19 -0
  94. package/src/runtime/balancer.js +149 -0
  95. package/src/runtime/dispatcher.d.ts +40 -0
  96. package/src/runtime/dispatcher.js +142 -0
  97. package/src/runtime/inline-executor.d.ts +10 -0
  98. package/src/runtime/inline-executor.js +282 -0
  99. package/src/runtime/pool.d.ts +39 -0
  100. package/src/runtime/pool.js +404 -0
  101. package/src/runtime/process-worker.d.ts +92 -0
  102. package/src/runtime/process-worker.js +673 -0
  103. package/src/runtime/tx-queue.d.ts +26 -0
  104. package/src/runtime/tx-queue.js +155 -0
  105. package/src/shared/abortSignal.d.ts +23 -0
  106. package/src/shared/abortSignal.js +134 -0
  107. package/src/types.d.ts +357 -0
  108. package/src/types.js +2 -0
  109. package/src/utils/http.d.ts +29 -0
  110. package/src/utils/http.js +100 -0
  111. package/src/worker/bootstrap.d.ts +5 -0
  112. package/src/worker/bootstrap.js +78 -0
  113. package/src/worker/composable-runners.d.ts +12 -0
  114. package/src/worker/composable-runners.js +97 -0
  115. package/src/worker/loop.d.ts +2 -0
  116. package/src/worker/loop.js +382 -0
  117. package/src/worker/process-worker-bootstrap.d.ts +8 -0
  118. package/src/worker/process-worker-bootstrap.js +160 -0
  119. package/src/worker/rx-queue.d.ts +25 -0
  120. package/src/worker/rx-queue.js +173 -0
  121. package/src/worker/safety/index.d.ts +4 -0
  122. package/src/worker/safety/index.js +4 -0
  123. package/src/worker/safety/performance.d.ts +1 -0
  124. package/src/worker/safety/performance.js +17 -0
  125. package/src/worker/safety/process.d.ts +2 -0
  126. package/src/worker/safety/process.js +79 -0
  127. package/src/worker/safety/startup.d.ts +16 -0
  128. package/src/worker/safety/startup.js +30 -0
  129. package/src/worker/safety/worker-data.d.ts +2 -0
  130. package/src/worker/safety/worker-data.js +36 -0
  131. package/src/worker/task-loader.d.ts +27 -0
  132. package/src/worker/task-loader.js +70 -0
  133. package/src/worker/timers.d.ts +18 -0
  134. package/src/worker/timers.js +116 -0
  135. package/unsafe.d.ts +1 -71
  136. package/unsafe.js +1 -878
  137. package/utils.d.ts +1 -31
  138. package/utils.js +1 -116
@@ -0,0 +1,404 @@
1
+ import { createHostTxQueue } from "./tx-queue.js";
2
+ import { cleanupProcessWorkerMemoryQuietly, createProcessSharedMemoryAllocator, createProcessWorkerMemoryLayout, createProcessWorkerNativeSignalNotifier, readProcessSharedMemorySettings, readProcessWorkerCommandPrefix, readProcessWorkerRuntime, serializeWorkerBootstrapData, spawnProcessWorker, terminateWorkerQuietly, toProcessWorkerBootPayload, toWorkerCompatExecArgv, toWorkerSafeExecArgv, } from "./process-worker.js";
3
+ import { createSharedMemoryTransport, TRANSPORT_SIGNAL_BYTES, } from "../ipc/transport/shared-memory.js";
4
+ import { ChannelHandler, hostDispatcherLoop, } from "./dispatcher.js";
5
+ import { HEADER_SLOT_STRIDE_U32, lock2, LOCK_SECTOR_BYTE_LENGTH, LockBound, } from "../memory/lock.js";
6
+ import "../worker/loop.js";
7
+ import { createSharedArrayBuffer, createWasmSharedArrayBuffer, } from "../common/runtime.js";
8
+ import { HAS_NODE_WORKER_THREADS, RUNTIME_WORKER, } from "../common/worker-runtime.js";
9
+ import { probeLockBufferTextCompat } from "../common/shared-buffer-text.js";
10
+ import { signalAbortFactory } from "../shared/abortSignal.js";
11
+ import { createLockControlCarpet } from "../memory/byte-carpet.js";
12
+ import { resolvePayloadBufferOptions, } from "../memory/payload-config.js";
13
+ import { createBufferReferenceReturnReleaseMessage } from "../connections/buffer-reference.js";
14
+ const WORKER_FATAL_MESSAGE_KEY = "__knittingWorkerFatal";
15
+ const isWorkerFatalMessage = (value) => !!value &&
16
+ typeof value === "object" &&
17
+ typeof value[WORKER_FATAL_MESSAGE_KEY] === "string";
18
+ // Keep idle workers self-healing if an Atomics.notify wake is missed.
19
+ const DEFAULT_WORKER_PARK_MS = 1;
20
+ const withDefaultWorkerTimers = (options) => {
21
+ const parkMs = options?.timers?.parkMs ?? DEFAULT_WORKER_PARK_MS;
22
+ if (options === undefined)
23
+ return { timers: { parkMs } };
24
+ return {
25
+ ...options,
26
+ timers: {
27
+ ...options.timers,
28
+ parkMs,
29
+ },
30
+ };
31
+ };
32
+ const withFixedPayloadConfig = (config) => ({
33
+ ...config,
34
+ mode: "fixed",
35
+ payloadInitialBytes: config.payloadMaxByteLength,
36
+ });
37
+ export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, hostDebug, totalNumberOfThread, source, at, workerOptions, workerExecArgv, permission, host, payload, bufferReferenceReturn, abortSignalCapacity, usesAbortSignal, sharedChannelHandler, }) => {
38
+ const tsFileUrl = new URL(import.meta.url);
39
+ const poliWorker = RUNTIME_WORKER;
40
+ const resolvedWorkerOptions = serializeWorkerBootstrapData(withDefaultWorkerTimers(workerOptions));
41
+ const useProcessWorkerRuntime = resolvedWorkerOptions.runtime === "process";
42
+ const processWorkerRuntime = useProcessWorkerRuntime
43
+ ? readProcessWorkerRuntime(resolvedWorkerOptions)
44
+ : undefined;
45
+ const processWorkerCommandPrefix = useProcessWorkerRuntime
46
+ ? readProcessWorkerCommandPrefix(resolvedWorkerOptions)
47
+ : undefined;
48
+ const processSharedMemorySettings = useProcessWorkerRuntime
49
+ ? readProcessSharedMemorySettings(resolvedWorkerOptions)
50
+ : undefined;
51
+ if (!useProcessWorkerRuntime && typeof poliWorker !== "function") {
52
+ throw new Error("Worker is not available in this runtime");
53
+ }
54
+ const WorkerCtor = poliWorker;
55
+ // Lock buffers must be shared between host and worker.
56
+ const sanitizeBytes = (value) => {
57
+ if (!Number.isFinite(value))
58
+ return undefined;
59
+ const bytes = Math.floor(value);
60
+ return bytes > 0 ? bytes : undefined;
61
+ };
62
+ const basePayloadConfig = resolvePayloadBufferOptions({
63
+ options: payload,
64
+ });
65
+ const resolvedPayloadConfig = useProcessWorkerRuntime
66
+ ? withFixedPayloadConfig(basePayloadConfig)
67
+ : basePayloadConfig;
68
+ const defaultAbortSignalCapacity = 258;
69
+ const requestedAbortSignalCapacity = sanitizeBytes(abortSignalCapacity);
70
+ const resolvedAbortSignalCapacity = requestedAbortSignalCapacity ??
71
+ defaultAbortSignalCapacity;
72
+ const abortSignalWords = Math.max(1, Math.ceil(resolvedAbortSignalCapacity / 32));
73
+ const requestedSignalBytes = sanitizeBytes(sab?.size);
74
+ const externalSignalSab = sab?.sharedSab;
75
+ if (useProcessWorkerRuntime && externalSignalSab != null) {
76
+ throw new Error("process worker runtime cannot use an external signal buffer");
77
+ }
78
+ const signalBytes = Math.max(TRANSPORT_SIGNAL_BYTES, requestedSignalBytes ?? TRANSPORT_SIGNAL_BYTES);
79
+ const abortBytes = abortSignalWords * Uint32Array.BYTES_PER_ELEMENT;
80
+ const processWorkerMemory = useProcessWorkerRuntime
81
+ ? createProcessWorkerMemoryLayout({
82
+ signalBytes,
83
+ abortBytes,
84
+ payloadBytes: resolvedPayloadConfig.payloadMaxByteLength,
85
+ thread,
86
+ sharedMemory: processSharedMemorySettings,
87
+ })
88
+ : undefined;
89
+ const processSharedMemory = processWorkerMemory === undefined
90
+ ? createProcessSharedMemoryAllocator(debug)
91
+ : undefined;
92
+ const createControlBuffer = processSharedMemory?.createBuffer ??
93
+ createWasmSharedArrayBuffer;
94
+ const createPayloadBuffer = processSharedMemory?.createBuffer;
95
+ const makePayloadBuffer = () => createPayloadBuffer
96
+ // ProcessSharedBuffer is fixed-size today, so reserve the configured
97
+ // payload ceiling instead of relying on SAB growth.
98
+ ? createPayloadBuffer(resolvedPayloadConfig.payloadMaxByteLength)
99
+ : resolvedPayloadConfig.mode === "growable"
100
+ ? createSharedArrayBuffer(resolvedPayloadConfig.payloadInitialBytes, resolvedPayloadConfig.payloadMaxByteLength)
101
+ : createSharedArrayBuffer(resolvedPayloadConfig.payloadInitialBytes);
102
+ const makeLockControlLayout = () => {
103
+ // Keep the hottest control words in one compact front strip:
104
+ // transport signals -> request lock -> return lock.
105
+ // Request/return headers stay in separate contiguous slabs to preserve
106
+ // sequential batching locality.
107
+ // Abort bitmap stays at the tail.
108
+ return createLockControlCarpet({
109
+ signalBytes,
110
+ abortBytes,
111
+ lockSectorBytes: LOCK_SECTOR_BYTE_LENGTH,
112
+ headerSlotStrideU32: HEADER_SLOT_STRIDE_U32,
113
+ slotCount: LockBound.slots,
114
+ headerLayout: "split",
115
+ createBuffer: createControlBuffer,
116
+ });
117
+ };
118
+ const controlLayout = processWorkerMemory?.controlLayout ??
119
+ makeLockControlLayout();
120
+ const lockPayload = processWorkerMemory?.lockPayload ?? makePayloadBuffer();
121
+ const lockBuffers = {
122
+ ...controlLayout.lock,
123
+ payload: lockPayload,
124
+ textCompat: probeLockBufferTextCompat({
125
+ headers: controlLayout.lock.headers,
126
+ payload: lockPayload,
127
+ }),
128
+ };
129
+ const returnPayload = processWorkerMemory?.returnPayload ??
130
+ makePayloadBuffer();
131
+ const returnLockBuffers = {
132
+ ...controlLayout.returnLock,
133
+ payload: returnPayload,
134
+ textCompat: probeLockBufferTextCompat({
135
+ headers: controlLayout.returnLock.headers,
136
+ payload: returnPayload,
137
+ }),
138
+ };
139
+ const lock = lock2({
140
+ headers: lockBuffers.headers,
141
+ headerSlotStrideU32: lockBuffers.headerSlotStrideU32,
142
+ LockBoundSector: lockBuffers.lockSector,
143
+ payload: lockBuffers.payload,
144
+ payloadSector: lockBuffers.payloadSector,
145
+ payloadConfig: resolvedPayloadConfig,
146
+ textCompat: lockBuffers.textCompat,
147
+ });
148
+ const returnLock = lock2({
149
+ headers: returnLockBuffers.headers,
150
+ headerSlotStrideU32: returnLockBuffers.headerSlotStrideU32,
151
+ LockBoundSector: returnLockBuffers.lockSector,
152
+ payload: returnLockBuffers.payload,
153
+ payloadSector: returnLockBuffers.payloadSector,
154
+ payloadConfig: resolvedPayloadConfig,
155
+ textCompat: returnLockBuffers.textCompat,
156
+ });
157
+ const abortSignalSAB = usesAbortSignal === true
158
+ ? controlLayout.abortSignals
159
+ : undefined;
160
+ const abortSignals = abortSignalSAB
161
+ ? signalAbortFactory({
162
+ sab: abortSignalSAB,
163
+ maxSignals: resolvedAbortSignalCapacity,
164
+ })
165
+ : undefined;
166
+ const signals = createSharedMemoryTransport({
167
+ sabObject: externalSignalSab == null
168
+ ? {
169
+ size: requestedSignalBytes,
170
+ sharedSab: controlLayout.signals,
171
+ }
172
+ : sab,
173
+ isMain: true,
174
+ thread,
175
+ });
176
+ const signalBox = signals;
177
+ const nativeNotifySignal = createProcessWorkerNativeSignalNotifier({
178
+ processRuntime: processWorkerRuntime,
179
+ signal: signalBox.opView,
180
+ });
181
+ const queue = createHostTxQueue({
182
+ lock,
183
+ returnLock,
184
+ abortSignals,
185
+ releaseBufferReferenceReturn: bufferReferenceReturn === "borrow"
186
+ ? (token) => {
187
+ worker?.postMessage?.(createBufferReferenceReturnReleaseMessage(token));
188
+ }
189
+ : undefined,
190
+ });
191
+ const { enqueue, rejectAll, txIdle, } = queue;
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({
213
+ signalBox,
214
+ queue,
215
+ channelHandler: ownChannel,
216
+ dispatcherOptions: host,
217
+ notifySignal: nativeNotifySignal,
218
+ });
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
+ }
230
+ let worker;
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)}`);
240
+ const workerDataPayload = {
241
+ sab: signals.sab,
242
+ abortSignalSAB,
243
+ abortSignalMax: usesAbortSignal === true
244
+ ? resolvedAbortSignalCapacity
245
+ : undefined,
246
+ list,
247
+ ids,
248
+ names,
249
+ at,
250
+ thread,
251
+ debug,
252
+ workerOptions: resolvedWorkerOptions,
253
+ totalNumberOfThread,
254
+ startAt: signalBox.startAt,
255
+ lock: lockBuffers,
256
+ returnLock: returnLockBuffers,
257
+ payloadConfig: resolvedPayloadConfig,
258
+ bufferReferenceReturn,
259
+ permission,
260
+ };
261
+ const baseWorkerOptions = {
262
+ //@ts-ignore Reason
263
+ type: "module",
264
+ //@ts-ignore
265
+ workerData: workerDataPayload,
266
+ };
267
+ const withExecArgv = workerExecArgv && workerExecArgv.length > 0
268
+ ? { ...baseWorkerOptions, execArgv: workerExecArgv }
269
+ : baseWorkerOptions;
270
+ if (processWorkerMemory !== undefined) {
271
+ worker = spawnProcessWorker({
272
+ workerUrl,
273
+ bootPayload: toProcessWorkerBootPayload(workerDataPayload, processWorkerMemory),
274
+ memory: processWorkerMemory,
275
+ processRuntime: processWorkerRuntime,
276
+ commandPrefix: processWorkerCommandPrefix,
277
+ permission,
278
+ });
279
+ }
280
+ else if (HAS_NODE_WORKER_THREADS) {
281
+ try {
282
+ worker = new WorkerCtor(workerUrl, withExecArgv);
283
+ }
284
+ catch (error) {
285
+ if (error?.code === "ERR_WORKER_INVALID_EXEC_ARGV") {
286
+ const fallbackExecArgv = toWorkerSafeExecArgv(withExecArgv.execArgv);
287
+ if (fallbackExecArgv && fallbackExecArgv.length > 0) {
288
+ try {
289
+ worker = new WorkerCtor(workerUrl, { ...baseWorkerOptions, execArgv: fallbackExecArgv });
290
+ }
291
+ catch (fallbackError) {
292
+ if (fallbackError?.code ===
293
+ "ERR_WORKER_INVALID_EXEC_ARGV") {
294
+ const compatExecArgv = toWorkerCompatExecArgv(fallbackExecArgv);
295
+ if (compatExecArgv && compatExecArgv.length > 0) {
296
+ try {
297
+ worker = new WorkerCtor(workerUrl, { ...baseWorkerOptions, execArgv: compatExecArgv });
298
+ }
299
+ catch {
300
+ worker = new WorkerCtor(workerUrl, baseWorkerOptions);
301
+ }
302
+ }
303
+ else {
304
+ worker = new WorkerCtor(workerUrl, baseWorkerOptions);
305
+ }
306
+ }
307
+ else {
308
+ throw fallbackError;
309
+ }
310
+ }
311
+ }
312
+ else {
313
+ worker = new WorkerCtor(workerUrl, baseWorkerOptions);
314
+ }
315
+ }
316
+ else {
317
+ throw error;
318
+ }
319
+ }
320
+ }
321
+ else {
322
+ worker = new WorkerCtor(workerUrl, {
323
+ type: "module",
324
+ });
325
+ worker.postMessage?.(workerDataPayload);
326
+ }
327
+ let closedReason;
328
+ const markWorkerClosed = (reason) => {
329
+ if (closedReason)
330
+ return;
331
+ closedReason = reason;
332
+ rejectAll(reason);
333
+ channelHandler?.close();
334
+ };
335
+ const onWorkerMessage = (message) => {
336
+ if (!isWorkerFatalMessage(message))
337
+ return;
338
+ markWorkerClosed(`Worker startup failed: ${message[WORKER_FATAL_MESSAGE_KEY]}`);
339
+ terminateWorkerQuietly(worker);
340
+ };
341
+ const onWorkerError = (error) => {
342
+ const message = String(error?.message ?? error);
343
+ markWorkerClosed(`Worker crashed: ${message}`);
344
+ };
345
+ const nodeWorker = worker;
346
+ if (typeof nodeWorker.on === "function") {
347
+ nodeWorker.on("message", onWorkerMessage);
348
+ nodeWorker.on("error", onWorkerError);
349
+ nodeWorker.on("exit", (code) => {
350
+ if (typeof code === "number" && code === 0)
351
+ return;
352
+ const normalized = typeof code === "number" ? code : -1;
353
+ markWorkerClosed(`Worker exited with code ${normalized}`);
354
+ });
355
+ }
356
+ else {
357
+ const eventWorker = worker;
358
+ if (typeof eventWorker.addEventListener === "function") {
359
+ eventWorker.addEventListener("message", (event) => {
360
+ onWorkerMessage(event?.data);
361
+ });
362
+ eventWorker.addEventListener("error", (event) => {
363
+ onWorkerError(event?.error ?? event?.message ?? event);
364
+ });
365
+ }
366
+ else {
367
+ eventWorker.onmessage = (event) => {
368
+ onWorkerMessage(event?.data);
369
+ };
370
+ eventWorker.onerror = (event) => {
371
+ onWorkerError(event);
372
+ };
373
+ }
374
+ }
375
+ lock.setPromiseHandler((task, isRejected, value) => {
376
+ queue.settlePromisePayload(task, isRejected, value);
377
+ send();
378
+ });
379
+ const call = ({ fnNumber, timeout, abortSignal }) => {
380
+ const enqueues = enqueue(fnNumber, timeout, abortSignal);
381
+ return (args) => {
382
+ const pending = enqueues(args);
383
+ send();
384
+ return pending;
385
+ };
386
+ };
387
+ const context = {
388
+ txIdle,
389
+ call,
390
+ kills: async () => {
391
+ markWorkerClosed("Thread closed");
392
+ terminateWorkerQuietly(worker);
393
+ cleanupProcessWorkerMemoryQuietly(processWorkerMemory);
394
+ },
395
+ lock,
396
+ processSharedMemoryBackings: processSharedMemory?.backings,
397
+ dispatcherCheck,
398
+ laneWake: sharedChannelHandler !== undefined ? laneWake : undefined,
399
+ bindSend: sharedChannelHandler !== undefined
400
+ ? ((fn) => void (dispatchSend = fn))
401
+ : undefined,
402
+ };
403
+ return context;
404
+ };
@@ -0,0 +1,92 @@
1
+ import { type LockControlCarpet } from "../memory/byte-carpet.js";
2
+ import type { DebugOptions, LockBuffers, WorkerData, WorkerSettings } from "../types.js";
3
+ import { RUNTIME_PROCESS_WORKER_BOOT_VERSION } from "../common/worker-runtime.js";
4
+ import { type SharedBufferSource } from "../common/shared-buffer-region.js";
5
+ import { FileDescriptor, type ProcessSharedBufferMetadata } from "../connections/index.js";
6
+ import type { SharedMemoryBuffer, SharedMemoryMapping } from "../connections/types.js";
7
+ export type SpawnedWorker = {
8
+ terminate: () => unknown;
9
+ unref?: () => unknown;
10
+ postMessage?: (message: unknown) => void;
11
+ };
12
+ export type NodeWorkerLike = {
13
+ on?: (event: "error" | "exit" | "message", listener: (...args: unknown[]) => void) => void;
14
+ };
15
+ type ProcessWorkerWireLockBuffers = Omit<LockBuffers, "headers" | "lockSector" | "payload" | "payloadSector"> & {
16
+ headers: ProcessSharedBufferMetadata;
17
+ lockSector: ProcessSharedBufferMetadata;
18
+ payload: ProcessSharedBufferMetadata;
19
+ payloadSector: ProcessSharedBufferMetadata;
20
+ };
21
+ type ProcessWorkerWireData = Omit<WorkerData, "sab" | "abortSignalSAB" | "lock" | "returnLock"> & {
22
+ sab: ProcessSharedBufferMetadata;
23
+ abortSignalSAB?: ProcessSharedBufferMetadata;
24
+ lock: ProcessWorkerWireLockBuffers;
25
+ returnLock: ProcessWorkerWireLockBuffers;
26
+ };
27
+ export type ProcessWorkerBootPayload = {
28
+ version: typeof RUNTIME_PROCESS_WORKER_BOOT_VERSION;
29
+ workerData: ProcessWorkerWireData;
30
+ };
31
+ export type ProcessWorkerMemoryLayout = {
32
+ mapping: SharedMemoryMapping<SharedMemoryBuffer>;
33
+ descriptor: FileDescriptor;
34
+ controlLayout: LockControlCarpet;
35
+ lockPayload: SharedBufferSource;
36
+ returnPayload: SharedBufferSource;
37
+ cleanup: () => void;
38
+ };
39
+ export type ProcessWorkerRuntime = NonNullable<WorkerSettings["processRuntime"]>;
40
+ export type ProcessWorkerCommandPrefix = NonNullable<WorkerSettings["processCommandPrefix"]>;
41
+ export type ResolvedProcessSharedMemorySettings = {
42
+ mode: "inherit" | "named";
43
+ namePrefix?: string;
44
+ unlinkOnShutdown: boolean;
45
+ };
46
+ type ProcessSharedMemoryNativeMapping = {
47
+ sab: SharedArrayBuffer;
48
+ fd: number;
49
+ name?: string;
50
+ size: number;
51
+ baseAddressMod64?: number;
52
+ };
53
+ export type ProcessSharedMemoryBacking = ProcessSharedMemoryNativeMapping & {
54
+ runtime: "node";
55
+ buffer: SharedArrayBuffer;
56
+ kind: "shared-array-buffer";
57
+ byteLength: number;
58
+ };
59
+ type ProcessSharedMemoryAllocator = {
60
+ createBuffer: (byteLength: number) => SharedArrayBuffer;
61
+ backings: ProcessSharedMemoryBacking[];
62
+ };
63
+ export declare const toWorkerSafeExecArgv: (flags: string[] | undefined) => string[] | undefined;
64
+ export declare const toWorkerCompatExecArgv: (flags: string[] | undefined) => string[] | undefined;
65
+ export declare const createProcessSharedMemoryAllocator: (debug: DebugOptions | undefined) => ProcessSharedMemoryAllocator | undefined;
66
+ export declare const createProcessWorkerMemoryLayout: ({ signalBytes, abortBytes, payloadBytes, thread, sharedMemory, }: {
67
+ signalBytes: number;
68
+ abortBytes: number;
69
+ payloadBytes: number;
70
+ thread: number;
71
+ sharedMemory: ResolvedProcessSharedMemorySettings;
72
+ }) => ProcessWorkerMemoryLayout;
73
+ export declare const serializeWorkerBootstrapData: (options: WorkerSettings) => WorkerSettings;
74
+ export declare const toProcessWorkerBootPayload: (workerData: WorkerData, memory: ProcessWorkerMemoryLayout) => ProcessWorkerBootPayload;
75
+ export declare const readProcessWorkerRuntime: (options: WorkerSettings | undefined) => ProcessWorkerRuntime;
76
+ export declare const readProcessWorkerCommandPrefix: (options: WorkerSettings | undefined) => ProcessWorkerCommandPrefix | undefined;
77
+ export declare const readProcessSharedMemorySettings: (options: WorkerSettings | undefined) => ResolvedProcessSharedMemorySettings;
78
+ export declare const createProcessWorkerNativeSignalNotifier: ({ processRuntime, signal, }: {
79
+ processRuntime: ProcessWorkerRuntime | undefined;
80
+ signal: Int32Array;
81
+ }) => (() => void) | undefined;
82
+ export declare const spawnProcessWorker: (options: {
83
+ workerUrl: string | URL;
84
+ bootPayload: ProcessWorkerBootPayload;
85
+ memory: ProcessWorkerMemoryLayout;
86
+ processRuntime: ProcessWorkerRuntime;
87
+ commandPrefix?: ProcessWorkerCommandPrefix;
88
+ permission?: WorkerData["permission"];
89
+ }) => SpawnedWorker & NodeWorkerLike;
90
+ export declare const terminateWorkerQuietly: (worker: SpawnedWorker) => void;
91
+ export declare const cleanupProcessWorkerMemoryQuietly: (memory: ProcessWorkerMemoryLayout | undefined) => void;
92
+ export {};