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,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,2 +0,0 @@
1
- export declare const installTerminationGuard: () => void;
2
- export declare const installUnhandledRejectionSilencer: () => void;
@@ -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,2 +0,0 @@
1
- import type { WorkerData } from "../../types.js";
2
- export declare const scrubWorkerDataSensitiveBuffers: (value: WorkerData) => void;
@@ -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
- };
@@ -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 {};
@@ -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
- };