knitting 0.1.55 → 0.1.60

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 (157) hide show
  1. package/README.md +254 -40
  2. package/knitting.d.ts +7 -797
  3. package/knitting.js +6 -9780
  4. package/map.md +31 -15
  5. package/package.json +20 -6
  6. package/process-shared-buffer.d.ts +1 -0
  7. package/process-shared-buffer.js +1 -0
  8. package/scripts/build-compiled-worker.ts +276 -0
  9. package/scripts/compiled-worker/porffor.d.ts +5 -0
  10. package/scripts/compiled-worker/runtime.ts +529 -0
  11. package/scripts/compiled-worker/task-shim.ts +32 -0
  12. package/shared-memory.d.ts +1 -155
  13. package/shared-memory.js +1 -1342
  14. package/src/api.d.ts +92 -0
  15. package/src/api.js +798 -0
  16. package/src/common/envelope.d.ts +17 -0
  17. package/src/common/envelope.js +22 -0
  18. package/src/common/module-url.d.ts +2 -0
  19. package/src/common/module-url.js +52 -0
  20. package/src/common/node-compat.d.ts +22 -0
  21. package/src/common/node-compat.js +24 -0
  22. package/src/common/path-canonical.d.ts +6 -0
  23. package/src/common/path-canonical.js +55 -0
  24. package/src/common/runtime.d.ts +16 -0
  25. package/src/common/runtime.js +105 -0
  26. package/src/common/shared-buffer-region.d.ts +11 -0
  27. package/src/common/shared-buffer-region.js +21 -0
  28. package/src/common/shared-buffer-text.d.ts +16 -0
  29. package/src/common/shared-buffer-text.js +65 -0
  30. package/src/common/task-source.d.ts +5 -0
  31. package/src/common/task-source.js +100 -0
  32. package/src/common/task-symbol.d.ts +1 -0
  33. package/src/common/task-symbol.js +1 -0
  34. package/src/common/with-resolvers.d.ts +9 -0
  35. package/src/common/with-resolvers.js +23 -0
  36. package/src/common/worker-runtime.d.ts +42 -0
  37. package/src/common/worker-runtime.js +70 -0
  38. package/src/connections/buffer-reference-native.d.ts +56 -0
  39. package/src/connections/buffer-reference-native.js +241 -0
  40. package/src/connections/buffer-reference.d.ts +99 -0
  41. package/src/connections/buffer-reference.js +575 -0
  42. package/src/connections/bun.d.ts +22 -0
  43. package/src/connections/bun.js +225 -0
  44. package/src/connections/deno.d.ts +24 -0
  45. package/src/connections/deno.js +226 -0
  46. package/src/connections/external-array-buffer.d.ts +2 -0
  47. package/src/connections/external-array-buffer.js +33 -0
  48. package/src/connections/file-descriptor.d.ts +39 -0
  49. package/src/connections/file-descriptor.js +161 -0
  50. package/src/connections/index.d.ts +4 -0
  51. package/src/connections/index.js +4 -0
  52. package/src/connections/node-addons.d.ts +16 -0
  53. package/src/connections/node-addons.js +92 -0
  54. package/src/connections/node-buffer-pointer.d.ts +20 -0
  55. package/src/connections/node-buffer-pointer.js +16 -0
  56. package/src/connections/node-ffi-api.d.ts +19 -0
  57. package/src/connections/node-ffi-api.js +28 -0
  58. package/src/connections/node-ffi.d.ts +27 -0
  59. package/src/connections/node-ffi.js +262 -0
  60. package/src/connections/node.d.ts +30 -0
  61. package/src/connections/node.js +62 -0
  62. package/src/connections/numeric-array.d.ts +5 -0
  63. package/src/connections/numeric-array.js +17 -0
  64. package/src/connections/package-assets.d.ts +2 -0
  65. package/src/connections/package-assets.js +55 -0
  66. package/src/connections/posix.d.ts +74 -0
  67. package/src/connections/posix.js +178 -0
  68. package/src/connections/process-shared-buffer.d.ts +76 -0
  69. package/src/connections/process-shared-buffer.js +245 -0
  70. package/src/connections/shared-array-buffer-payload.d.ts +36 -0
  71. package/src/connections/shared-array-buffer-payload.js +235 -0
  72. package/src/connections/types.d.ts +54 -0
  73. package/src/connections/types.js +37 -0
  74. package/src/connections/windows.d.ts +37 -0
  75. package/src/connections/windows.js +245 -0
  76. package/src/debug/env-diff.d.ts +26 -0
  77. package/src/debug/env-diff.js +49 -0
  78. package/src/debug/gate.d.ts +18 -0
  79. package/src/debug/gate.js +69 -0
  80. package/src/debug/handle.d.ts +23 -0
  81. package/src/debug/handle.js +48 -0
  82. package/src/error.d.ts +14 -0
  83. package/src/error.js +50 -0
  84. package/src/ipc/tools/ring-queue.d.ts +33 -0
  85. package/src/ipc/tools/ring-queue.js +159 -0
  86. package/src/ipc/transport/shared-memory.d.ts +23 -0
  87. package/src/ipc/transport/shared-memory.js +35 -0
  88. package/src/memory/byte-carpet.d.ts +73 -0
  89. package/src/memory/byte-carpet.js +157 -0
  90. package/src/memory/lock.d.ts +213 -0
  91. package/src/memory/lock.js +760 -0
  92. package/src/memory/payload-config.d.ts +31 -0
  93. package/src/memory/payload-config.js +67 -0
  94. package/src/memory/payloadCodec.d.ts +55 -0
  95. package/src/memory/payloadCodec.js +1473 -0
  96. package/src/memory/regionRegistry.d.ts +17 -0
  97. package/src/memory/regionRegistry.js +285 -0
  98. package/src/memory/shared-buffer-io.d.ts +55 -0
  99. package/src/memory/shared-buffer-io.js +403 -0
  100. package/src/permission/compatibility.d.ts +28 -0
  101. package/src/permission/compatibility.js +239 -0
  102. package/src/permission/index.d.ts +4 -0
  103. package/src/permission/index.js +3 -0
  104. package/src/permission/protocol.d.ts +167 -0
  105. package/src/permission/protocol.js +690 -0
  106. package/src/runtime/balancer.d.ts +19 -0
  107. package/src/runtime/balancer.js +149 -0
  108. package/src/runtime/compiled-artifact.d.ts +21 -0
  109. package/src/runtime/compiled-artifact.js +260 -0
  110. package/src/runtime/compiled-builder.d.ts +8 -0
  111. package/src/runtime/compiled-builder.js +42 -0
  112. package/src/runtime/compiled-worker.d.ts +27 -0
  113. package/src/runtime/compiled-worker.js +562 -0
  114. package/src/runtime/dispatcher.d.ts +40 -0
  115. package/src/runtime/dispatcher.js +142 -0
  116. package/src/runtime/inline-executor.d.ts +10 -0
  117. package/src/runtime/inline-executor.js +294 -0
  118. package/src/runtime/pool.d.ts +44 -0
  119. package/src/runtime/pool.js +472 -0
  120. package/src/runtime/process-worker.d.ts +92 -0
  121. package/src/runtime/process-worker.js +713 -0
  122. package/src/runtime/tx-queue.d.ts +28 -0
  123. package/src/runtime/tx-queue.js +158 -0
  124. package/src/shared/abortSignal.d.ts +23 -0
  125. package/src/shared/abortSignal.js +134 -0
  126. package/src/types.d.ts +399 -0
  127. package/src/types.js +2 -0
  128. package/src/utils/http.d.ts +29 -0
  129. package/src/utils/http.js +100 -0
  130. package/src/worker/bootstrap.d.ts +5 -0
  131. package/src/worker/bootstrap.js +78 -0
  132. package/src/worker/composable-runners.d.ts +12 -0
  133. package/src/worker/composable-runners.js +98 -0
  134. package/src/worker/loop.d.ts +3 -0
  135. package/src/worker/loop.js +395 -0
  136. package/src/worker/process-worker-bootstrap.d.ts +8 -0
  137. package/src/worker/process-worker-bootstrap.js +160 -0
  138. package/src/worker/rx-queue.d.ts +25 -0
  139. package/src/worker/rx-queue.js +173 -0
  140. package/src/worker/safety/index.d.ts +4 -0
  141. package/src/worker/safety/index.js +4 -0
  142. package/src/worker/safety/performance.d.ts +1 -0
  143. package/src/worker/safety/performance.js +17 -0
  144. package/src/worker/safety/process.d.ts +2 -0
  145. package/src/worker/safety/process.js +79 -0
  146. package/src/worker/safety/startup.d.ts +16 -0
  147. package/src/worker/safety/startup.js +30 -0
  148. package/src/worker/safety/worker-data.d.ts +2 -0
  149. package/src/worker/safety/worker-data.js +36 -0
  150. package/src/worker/task-loader.d.ts +28 -0
  151. package/src/worker/task-loader.js +76 -0
  152. package/src/worker/timers.d.ts +18 -0
  153. package/src/worker/timers.js +118 -0
  154. package/unsafe.d.ts +1 -71
  155. package/unsafe.js +1 -878
  156. package/utils.d.ts +1 -31
  157. package/utils.js +1 -116
@@ -0,0 +1,159 @@
1
+ ;
2
+ export default class RingQueue {
3
+ #buf;
4
+ #mask;
5
+ #head = 0;
6
+ #tail = 0;
7
+ #size = 0;
8
+ constructor(capacity = 512) {
9
+ let cap = 2;
10
+ while (cap < capacity)
11
+ cap <<= 1;
12
+ // Keep the array packed (avoid holey elements in hot queue paths).
13
+ this.#buf = new Array(cap).fill(null);
14
+ this.#mask = cap - 1;
15
+ }
16
+ get size() {
17
+ return this.#size;
18
+ }
19
+ get isEmpty() {
20
+ return this.#size === 0;
21
+ }
22
+ get capacity() {
23
+ return this.#mask + 1;
24
+ }
25
+ clear() {
26
+ // Keep buffer allocated; reset pointers (fast)
27
+ // (optional) also drop references to help GC if you want:
28
+ // for (let i = 0; i < this.#size; i++) this.#buf[(this.#head + i) & this.#mask] = null;
29
+ this.#head = 0;
30
+ this.#tail = 0;
31
+ this.#size = 0;
32
+ }
33
+ peek() {
34
+ return this.#size === 0 ? undefined : this.#buf[this.#head];
35
+ }
36
+ /** Ensure internal capacity >= requested (rounds up to next power of two). */
37
+ reserve(minCapacity) {
38
+ if (minCapacity <= this.capacity)
39
+ return;
40
+ let cap = this.capacity;
41
+ while (cap < minCapacity)
42
+ cap <<= 1;
43
+ this.#growTo(cap);
44
+ }
45
+ // --- hot path internal ---
46
+ #growIfFull() {
47
+ if (this.#size !== (this.#mask + 1))
48
+ return;
49
+ this.#growTo((this.#mask + 1) << 1);
50
+ }
51
+ #growTo(newCap) {
52
+ const oldBuf = this.#buf;
53
+ const oldCap = this.#mask + 1;
54
+ const n = this.#size;
55
+ const next = new Array(newCap).fill(null);
56
+ const head = this.#head;
57
+ const firstLen = Math.min(n, oldCap - head);
58
+ // copy [head..end)
59
+ for (let i = 0; i < firstLen; i++) {
60
+ next[i] = oldBuf[head + i];
61
+ }
62
+ // copy [0..remaining)
63
+ for (let i = firstLen; i < n; i++) {
64
+ next[i] = oldBuf[i - firstLen];
65
+ }
66
+ this.#buf = next;
67
+ this.#mask = newCap - 1;
68
+ this.#head = 0;
69
+ this.#tail = n;
70
+ }
71
+ /**
72
+ * Push to back
73
+ * Always succeeds (grows if full)
74
+ */
75
+ push(value) {
76
+ this.#growIfFull();
77
+ const buf = this.#buf;
78
+ const mask = this.#mask;
79
+ const tail = this.#tail;
80
+ buf[tail] = value;
81
+ this.#tail = (tail + 1) & mask;
82
+ this.#size++;
83
+ return true;
84
+ }
85
+ /**
86
+ * Push to front (unshift)
87
+ * Always succeeds (grows if full)
88
+ */
89
+ unshift(value) {
90
+ this.#growIfFull();
91
+ const buf = this.#buf;
92
+ const mask = this.#mask;
93
+ const head = (this.#head - 1) & mask;
94
+ this.#head = head;
95
+ buf[head] = value;
96
+ this.#size++;
97
+ return true;
98
+ }
99
+ /**
100
+ * Pop from front (shift)
101
+ */
102
+ shift() {
103
+ const size = this.#size;
104
+ if (size === 0)
105
+ return undefined;
106
+ const head = this.#head;
107
+ const buf = this.#buf;
108
+ const v = buf[head];
109
+ buf[head] = null; // help GC while keeping packed elements
110
+ this.#head = (head + 1) & this.#mask;
111
+ this.#size = size - 1;
112
+ return v;
113
+ }
114
+ /**
115
+ * Pop from front (shift) without clearing the slot.
116
+ * Use only for internal pooled-object queues where retaining references is acceptable.
117
+ */
118
+ shiftNoClear() {
119
+ const size = this.#size;
120
+ if (size === 0)
121
+ return undefined;
122
+ const head = this.#head;
123
+ const v = this.#buf[head];
124
+ this.#head = (head + 1) & this.#mask;
125
+ this.#size = size - 1;
126
+ return v;
127
+ }
128
+ *[Symbol.iterator]() {
129
+ const buf = this.#buf;
130
+ const mask = this.#mask;
131
+ let idx = this.#head;
132
+ let i = 0;
133
+ const n = this.#size;
134
+ while (i < n) {
135
+ // values should never be null inside active range, but keep it safe
136
+ const v = buf[idx];
137
+ if (v !== null)
138
+ yield v;
139
+ idx = (idx + 1) & mask;
140
+ i++;
141
+ }
142
+ }
143
+ toArray() {
144
+ // faster than Array.from(this) in some cases because it avoids iterator overhead,
145
+ // but keep iterator version if you prefer simplicity.
146
+ const out = new Array(this.#size);
147
+ const buf = this.#buf;
148
+ const mask = this.#mask;
149
+ let idx = this.#head;
150
+ for (let i = 0; i < out.length; i++) {
151
+ out[i] = buf[idx];
152
+ idx = (idx + 1) & mask;
153
+ }
154
+ return out;
155
+ }
156
+ get [Symbol.toStringTag]() {
157
+ return `RingQueue(size=${this.#size}, cap=${this.capacity})`;
158
+ }
159
+ }
@@ -0,0 +1,23 @@
1
+ export type SignalArguments = ReturnType<typeof createSharedMemoryTransport>;
2
+ import { type SharedBufferSource } from "../../common/shared-buffer-region.js";
3
+ export declare const TRANSPORT_SIGNAL_BYTES: number;
4
+ export type Sab = {
5
+ size?: number;
6
+ sharedSab?: SharedBufferSource;
7
+ };
8
+ type SignalForWorker = {
9
+ sabObject?: Sab;
10
+ isMain: boolean;
11
+ thread: number;
12
+ startTime?: number;
13
+ };
14
+ export declare const createSharedMemoryTransport: ({ sabObject, isMain, startTime }: SignalForWorker) => {
15
+ sab: import("../../common/shared-buffer-region.js").SharedBufferRegion;
16
+ op: Int32Array<import("../../common/shared-buffer-region.js").SharedBuffer>;
17
+ startAt: number;
18
+ opView: Int32Array<import("../../common/shared-buffer-region.js").SharedBuffer>;
19
+ rxStatus: Int32Array<import("../../common/shared-buffer-region.js").SharedBuffer>;
20
+ txStatus: Int32Array<import("../../common/shared-buffer-region.js").SharedBuffer>;
21
+ };
22
+ export type MainSignal = Pick<SignalArguments, "opView" | "startAt" | "rxStatus" | "txStatus">;
23
+ export {};
@@ -0,0 +1,35 @@
1
+ import { createSharedArrayBuffer } from "../../common/runtime.js";
2
+ import { toSharedBufferRegion, } from "../../common/shared-buffer-region.js";
3
+ const page = 1024 * 4;
4
+ const CACHE_LINE_BYTES = 64;
5
+ // Keep hot signals on separate cache lines to avoid false sharing.
6
+ const SIGNAL_OFFSETS = {
7
+ op: 0,
8
+ rxStatus: CACHE_LINE_BYTES,
9
+ txStatus: CACHE_LINE_BYTES * 2,
10
+ };
11
+ export const TRANSPORT_SIGNAL_BYTES = CACHE_LINE_BYTES * 3;
12
+ const a_store = Atomics.store;
13
+ export const createSharedMemoryTransport = ({ sabObject, isMain, startTime }) => {
14
+ const toGrow = sabObject?.size ?? page;
15
+ const roundedSize = toGrow + ((page - (toGrow % page)) % page);
16
+ const signalRegion = toSharedBufferRegion(sabObject?.sharedSab
17
+ ? sabObject.sharedSab
18
+ : createSharedArrayBuffer(roundedSize, page * page));
19
+ const sab = signalRegion.sab;
20
+ const baseByteOffset = signalRegion.byteOffset;
21
+ const startAt = startTime ?? performance.now();
22
+ const opView = new Int32Array(sab, baseByteOffset + SIGNAL_OFFSETS.op, 1);
23
+ if (isMain)
24
+ a_store(opView, 0, 0);
25
+ const rxStatus = new Int32Array(sab, baseByteOffset + SIGNAL_OFFSETS.rxStatus, 1);
26
+ a_store(rxStatus, 0, 1);
27
+ return {
28
+ sab: signalRegion,
29
+ op: opView,
30
+ startAt,
31
+ opView,
32
+ rxStatus,
33
+ txStatus: new Int32Array(sab, baseByteOffset + SIGNAL_OFFSETS.txStatus, 1),
34
+ };
35
+ };
@@ -0,0 +1,73 @@
1
+ import type { SharedBuffer, SharedBufferRegion } from "../common/shared-buffer-region.js";
2
+ export declare const BYTE_CARPET_ALIGN_BYTES = 64;
3
+ export declare const alignBytes: (value: number, alignment?: number) => number;
4
+ export declare const makeSharedBufferRegion: (sab: SharedBuffer, byteOffset: number, byteLength: number) => SharedBufferRegion;
5
+ export type ByteCarpetSlice = {
6
+ name: string;
7
+ byteOffset: number;
8
+ byteLength: number;
9
+ reservedByteLength: number;
10
+ };
11
+ export declare const createByteCarpet: ({ alignTo, startByteOffset, }?: {
12
+ alignTo?: number;
13
+ startByteOffset?: number;
14
+ }) => {
15
+ slices: ByteCarpetSlice[];
16
+ take: (name: string, byteLength: number, { alignTo: sliceAlignment, reserveByteLength, }?: {
17
+ alignTo?: number;
18
+ reserveByteLength?: number;
19
+ }) => ByteCarpetSlice;
20
+ byteLength: () => number;
21
+ bind: (sab: SharedBuffer, slice: ByteCarpetSlice) => SharedBufferRegion;
22
+ };
23
+ export declare const getStridedSlotOffsetU32: ({ slotIndex, slotStrideU32, baseU32, extraU32, }: {
24
+ slotIndex: number;
25
+ slotStrideU32: number;
26
+ baseU32?: number;
27
+ extraU32?: number;
28
+ }) => number;
29
+ export declare const getStridedSlotByteOffset: ({ slotIndex, slotStrideU32, baseByteOffset, baseU32, extraU32, }: {
30
+ slotIndex: number;
31
+ slotStrideU32: number;
32
+ baseByteOffset?: number;
33
+ baseU32?: number;
34
+ extraU32?: number;
35
+ }) => number;
36
+ export declare const getStridedRegionSpanBytes: ({ slotCount, slotStrideU32, slotLengthU32, baseU32, }: {
37
+ slotCount: number;
38
+ slotStrideU32: number;
39
+ slotLengthU32: number;
40
+ baseU32?: number;
41
+ }) => number;
42
+ export declare const getInterleavedSlotStrideU32: (slotStrideU32: number) => number;
43
+ export declare const getHeaderBlockByteLength: ({ slotCount, slotStrideU32, queues, alignTo, }: {
44
+ slotCount: number;
45
+ slotStrideU32: number;
46
+ queues?: number;
47
+ alignTo?: number;
48
+ }) => number;
49
+ export type HeaderLayoutMode = "split" | "interleaved";
50
+ export type QueueControlByteLayout = {
51
+ headers: SharedBufferRegion;
52
+ headerSlotStrideU32: number;
53
+ lockSector: SharedBufferRegion;
54
+ payloadSector: SharedBufferRegion;
55
+ };
56
+ export type LockControlCarpet = {
57
+ controlSAB: SharedBuffer;
58
+ signals: SharedBufferRegion;
59
+ abortSignals: SharedBufferRegion;
60
+ lock: QueueControlByteLayout;
61
+ returnLock: QueueControlByteLayout;
62
+ slices: readonly ByteCarpetSlice[];
63
+ };
64
+ export declare const createLockControlCarpet: ({ signalBytes, abortBytes, lockSectorBytes, headerSlotStrideU32, slotCount, headerLayout, alignTo, createBuffer, }: {
65
+ signalBytes: number;
66
+ abortBytes: number;
67
+ lockSectorBytes: number;
68
+ headerSlotStrideU32: number;
69
+ slotCount: number;
70
+ headerLayout?: HeaderLayoutMode;
71
+ alignTo?: number;
72
+ createBuffer?: (byteLength: number) => SharedBuffer;
73
+ }) => LockControlCarpet;
@@ -0,0 +1,157 @@
1
+ export const BYTE_CARPET_ALIGN_BYTES = 64;
2
+ const U32_BYTES = Uint32Array.BYTES_PER_ELEMENT;
3
+ const toNonNegativeInteger = (value, label) => {
4
+ if (!Number.isInteger(value) || value < 0) {
5
+ throw new RangeError(`${label} must be a non-negative integer`);
6
+ }
7
+ return value;
8
+ };
9
+ export const alignBytes = (value, alignment = BYTE_CARPET_ALIGN_BYTES) => {
10
+ const safeValue = toNonNegativeInteger(value, "value");
11
+ const safeAlignment = toNonNegativeInteger(alignment, "alignment");
12
+ if (safeAlignment === 0) {
13
+ throw new RangeError("alignment must be greater than zero");
14
+ }
15
+ return Math.ceil(safeValue / safeAlignment) * safeAlignment;
16
+ };
17
+ export const makeSharedBufferRegion = (sab, byteOffset, byteLength) => ({
18
+ sab,
19
+ byteOffset: toNonNegativeInteger(byteOffset, "byteOffset"),
20
+ byteLength: toNonNegativeInteger(byteLength, "byteLength"),
21
+ });
22
+ export const createByteCarpet = ({ alignTo = BYTE_CARPET_ALIGN_BYTES, startByteOffset = 0, } = {}) => {
23
+ const defaultAlignment = toNonNegativeInteger(alignTo, "alignTo");
24
+ if (defaultAlignment === 0) {
25
+ throw new RangeError("alignTo must be greater than zero");
26
+ }
27
+ let cursor = toNonNegativeInteger(startByteOffset, "startByteOffset");
28
+ const slices = [];
29
+ const take = (name, byteLength, { alignTo: sliceAlignment = defaultAlignment, reserveByteLength, } = {}) => {
30
+ const logicalByteLength = toNonNegativeInteger(byteLength, `${name} byteLength`);
31
+ const safeSliceAlignment = toNonNegativeInteger(sliceAlignment, `${name} alignTo`);
32
+ if (safeSliceAlignment === 0) {
33
+ throw new RangeError(`${name} alignTo must be greater than zero`);
34
+ }
35
+ const reserved = reserveByteLength == null
36
+ ? alignBytes(logicalByteLength, safeSliceAlignment)
37
+ : toNonNegativeInteger(reserveByteLength, `${name} reserveByteLength`);
38
+ if (reserved < logicalByteLength) {
39
+ throw new RangeError(`${name} reserveByteLength must cover byteLength`);
40
+ }
41
+ const byteOffset = alignBytes(cursor, safeSliceAlignment);
42
+ const slice = {
43
+ name,
44
+ byteOffset,
45
+ byteLength: logicalByteLength,
46
+ reservedByteLength: reserved,
47
+ };
48
+ slices.push(slice);
49
+ cursor = byteOffset + reserved;
50
+ return slice;
51
+ };
52
+ return {
53
+ slices,
54
+ take,
55
+ byteLength: () => cursor,
56
+ bind: (sab, slice) => makeSharedBufferRegion(sab, slice.byteOffset, slice.byteLength),
57
+ };
58
+ };
59
+ export const getStridedSlotOffsetU32 = ({ slotIndex, slotStrideU32, baseU32 = 0, extraU32 = 0, }) => (slotIndex * slotStrideU32) + baseU32 + extraU32;
60
+ export const getStridedSlotByteOffset = ({ slotIndex, slotStrideU32, baseByteOffset = 0, baseU32 = 0, extraU32 = 0, }) => baseByteOffset +
61
+ (getStridedSlotOffsetU32({
62
+ slotIndex,
63
+ slotStrideU32,
64
+ baseU32,
65
+ extraU32,
66
+ }) * U32_BYTES);
67
+ export const getStridedRegionSpanBytes = ({ slotCount, slotStrideU32, slotLengthU32, baseU32 = 0, }) => {
68
+ const safeSlotCount = toNonNegativeInteger(slotCount, "slotCount");
69
+ if (safeSlotCount === 0)
70
+ return 0;
71
+ return (getStridedSlotOffsetU32({
72
+ slotIndex: safeSlotCount - 1,
73
+ slotStrideU32,
74
+ baseU32,
75
+ }) + slotLengthU32) * U32_BYTES;
76
+ };
77
+ export const getInterleavedSlotStrideU32 = (slotStrideU32) => slotStrideU32 * 2;
78
+ export const getHeaderBlockByteLength = ({ slotCount, slotStrideU32, queues = 1, alignTo = BYTE_CARPET_ALIGN_BYTES, }) => alignBytes(slotCount * slotStrideU32 * U32_BYTES * queues, alignTo);
79
+ const createInterleavedHeaderPair = ({ sab, byteOffset, slotCount, slotStrideU32, }) => {
80
+ const headerSlotStrideU32 = getInterleavedSlotStrideU32(slotStrideU32);
81
+ const slotBytes = slotStrideU32 * U32_BYTES;
82
+ const spanBytes = getStridedRegionSpanBytes({
83
+ slotCount,
84
+ slotStrideU32: headerSlotStrideU32,
85
+ slotLengthU32: slotStrideU32,
86
+ });
87
+ return {
88
+ headerSlotStrideU32,
89
+ requestHeaders: makeSharedBufferRegion(sab, byteOffset, spanBytes),
90
+ returnHeaders: makeSharedBufferRegion(sab, byteOffset + slotBytes, spanBytes),
91
+ };
92
+ };
93
+ export const createLockControlCarpet = ({ signalBytes, abortBytes, lockSectorBytes, headerSlotStrideU32, slotCount, headerLayout = "interleaved", alignTo = BYTE_CARPET_ALIGN_BYTES, createBuffer = (byteLength) => new SharedArrayBuffer(byteLength), }) => {
94
+ const carpet = createByteCarpet({ alignTo });
95
+ const signalsSlice = carpet.take("signals", signalBytes);
96
+ const requestLockSlice = carpet.take("requestLockSector", lockSectorBytes);
97
+ const returnLockSlice = carpet.take("returnLockSector", lockSectorBytes);
98
+ let requestHeadersSlice;
99
+ let returnHeadersSlice;
100
+ let interleavedHeadersSlice;
101
+ if (headerLayout === "interleaved") {
102
+ interleavedHeadersSlice = carpet.take("interleavedHeaders", getHeaderBlockByteLength({
103
+ slotCount,
104
+ slotStrideU32: headerSlotStrideU32,
105
+ queues: 2,
106
+ alignTo,
107
+ }));
108
+ }
109
+ else {
110
+ requestHeadersSlice = carpet.take("requestHeaders", getHeaderBlockByteLength({
111
+ slotCount,
112
+ slotStrideU32: headerSlotStrideU32,
113
+ alignTo,
114
+ }));
115
+ returnHeadersSlice = carpet.take("returnHeaders", getHeaderBlockByteLength({
116
+ slotCount,
117
+ slotStrideU32: headerSlotStrideU32,
118
+ alignTo,
119
+ }));
120
+ }
121
+ const abortSignalsSlice = carpet.take("abortSignals", abortBytes);
122
+ const controlSAB = createBuffer(carpet.byteLength());
123
+ const signals = carpet.bind(controlSAB, signalsSlice);
124
+ const abortSignals = carpet.bind(controlSAB, abortSignalsSlice);
125
+ const requestLockSector = carpet.bind(controlSAB, requestLockSlice);
126
+ const returnLockSector = carpet.bind(controlSAB, returnLockSlice);
127
+ const headerPair = headerLayout === "interleaved"
128
+ ? createInterleavedHeaderPair({
129
+ sab: controlSAB,
130
+ byteOffset: interleavedHeadersSlice.byteOffset,
131
+ slotCount,
132
+ slotStrideU32: headerSlotStrideU32,
133
+ })
134
+ : {
135
+ headerSlotStrideU32,
136
+ requestHeaders: carpet.bind(controlSAB, requestHeadersSlice),
137
+ returnHeaders: carpet.bind(controlSAB, returnHeadersSlice),
138
+ };
139
+ return {
140
+ controlSAB,
141
+ signals,
142
+ abortSignals,
143
+ lock: {
144
+ headers: headerPair.requestHeaders,
145
+ headerSlotStrideU32: headerPair.headerSlotStrideU32,
146
+ lockSector: requestLockSector,
147
+ payloadSector: requestLockSector,
148
+ },
149
+ returnLock: {
150
+ headers: headerPair.returnHeaders,
151
+ headerSlotStrideU32: headerPair.headerSlotStrideU32,
152
+ lockSector: returnLockSector,
153
+ payloadSector: returnLockSector,
154
+ },
155
+ slices: carpet.slices,
156
+ };
157
+ };
@@ -0,0 +1,213 @@
1
+ import RingQueue from "../ipc/tools/ring-queue.js";
2
+ type EncodePayloadFactory = typeof import("./payloadCodec.js").encodePayload;
3
+ type DecodePayloadFactory = typeof import("./payloadCodec.js").decodePayload;
4
+ export declare const registerLockPayloadCodec: (encode: EncodePayloadFactory, decode: DecodePayloadFactory) => void;
5
+ import { type SharedBufferSource } from "../common/shared-buffer-region.js";
6
+ import { type LockBufferTextCompat } from "../common/shared-buffer-text.js";
7
+ import { type PayloadBufferOptions } from "./payload-config.js";
8
+ /**
9
+ * TODO: Compose all the instance where the array is passed as argument
10
+ */
11
+ export declare const PayloadSignal: {
12
+ readonly UNREACHABLE: 0;
13
+ readonly BigInt: 2;
14
+ readonly True: 3;
15
+ readonly False: 4;
16
+ readonly Undefined: 5;
17
+ readonly NaN: 6;
18
+ readonly Float64: 9;
19
+ readonly Null: 10;
20
+ };
21
+ export type PayloadSignal = typeof PayloadSignal[keyof typeof PayloadSignal];
22
+ export declare const PayloadBuffer: {
23
+ readonly BORDER_SIGNAL_BUFFER: 11;
24
+ readonly String: 11;
25
+ readonly Json: 12;
26
+ readonly StaticString: 15;
27
+ readonly StaticJson: 16;
28
+ readonly Binary: 17;
29
+ readonly StaticBinary: 18;
30
+ readonly Int32Array: 19;
31
+ readonly Float64Array: 20;
32
+ readonly BigInt64Array: 21;
33
+ readonly BigUint64Array: 22;
34
+ readonly DataView: 23;
35
+ readonly Error: 24;
36
+ readonly Date: 25;
37
+ readonly Symbol: 26;
38
+ readonly StaticSymbol: 27;
39
+ readonly BigInt: 28;
40
+ readonly StaticBigInt: 29;
41
+ readonly StaticInt32Array: 31;
42
+ readonly StaticFloat64Array: 32;
43
+ readonly StaticBigInt64Array: 33;
44
+ readonly StaticBigUint64Array: 34;
45
+ readonly StaticDataView: 35;
46
+ readonly ArrayBuffer: 36;
47
+ readonly StaticArrayBuffer: 37;
48
+ readonly Buffer: 38;
49
+ readonly StaticBuffer: 39;
50
+ readonly EnvelopeStaticHeader: 40;
51
+ readonly EnvelopeDynamicHeader: 41;
52
+ readonly EnvelopeStaticHeaderString: 42;
53
+ readonly EnvelopeDynamicHeaderString: 43;
54
+ readonly ExternalPayload: 44;
55
+ readonly StaticExternalPayload: 45;
56
+ readonly ProcessSharedBuffer: 46;
57
+ readonly BufferReference: 47;
58
+ readonly SharedArrayBuffer: 48;
59
+ readonly EnvelopeStaticHeaderExternal: 49;
60
+ readonly EnvelopeDynamicHeaderExternal: 50;
61
+ readonly EnvelopeStaticHeaderStringExternal: 51;
62
+ readonly EnvelopeDynamicHeaderStringExternal: 52;
63
+ readonly NumericArray: 53;
64
+ readonly StaticNumericArray: 54;
65
+ };
66
+ export type PayloadBuffer = typeof PayloadBuffer[keyof typeof PayloadBuffer];
67
+ export declare const payloadBufferName: (value: number) => string;
68
+ export declare const LockBound: {
69
+ readonly paddingLock: 0;
70
+ readonly padding: 0;
71
+ readonly slots: 32;
72
+ readonly header: 0;
73
+ };
74
+ export type LockBound = typeof LockBound[keyof typeof LockBound];
75
+ export declare const LOCK_CACHE_LINE_BYTES = 64;
76
+ export declare const LOCK_SECTOR_BYTES = 256;
77
+ export type Task = [
78
+ number,
79
+ number,
80
+ PayloadSignal | PayloadBuffer,
81
+ number,
82
+ number,
83
+ number,
84
+ number,
85
+ number
86
+ ] & {
87
+ value: unknown;
88
+ finalize?: (() => void) | undefined;
89
+ resolve: (value?: unknown) => void;
90
+ reject: (reason?: unknown) => void;
91
+ };
92
+ export declare const PayloadTransportFinalizer: unique symbol;
93
+ export declare const PromisePayloadMarker: unique symbol;
94
+ export type PromisePayloadHandler = (task: Task, isRejected: boolean, value: unknown) => void;
95
+ export declare const beginPromisePayload: (task: Task) => boolean;
96
+ export declare const finishPromisePayload: (task: Task) => void;
97
+ export declare const isPromisePayloadPending: (task: Task) => boolean;
98
+ export declare const resetTaskLocalFlags: (task: Task) => void;
99
+ export declare const addTaskFinalizer: (task: Task, finalizer: () => void) => void;
100
+ export declare const attachPayloadTransportFinalizer: (task: Task, value: unknown) => void;
101
+ export declare const runTaskFinalizers: (task: Task) => void;
102
+ export declare const TaskIndex: {
103
+ /**
104
+ * Worker -> host response flags word.
105
+ */
106
+ readonly FlagsToHost: 0;
107
+ /**
108
+ * Host -> worker request function id (low 16 bits).
109
+ * High 16 bits are reserved for caller metadata on request path.
110
+ * NOTE: shares the same storage word as `FlagsToHost`.
111
+ */
112
+ readonly FunctionID: 0;
113
+ readonly ID: 1;
114
+ readonly Type: 2;
115
+ readonly Start: 3;
116
+ readonly End: 4;
117
+ readonly PayloadLen: 5;
118
+ /**
119
+ * Low 5 bits: region slot index (0..31).
120
+ * High 27 bits: reserved for caller metadata (e.g. enqueue timing).
121
+ */
122
+ readonly slotBuffer: 6;
123
+ readonly Size: 8;
124
+ /**
125
+ * Total slot length in Uint32 words, including the task header.
126
+ */
127
+ readonly TotalBuff: 144;
128
+ };
129
+ export type TaskIndex = typeof TaskIndex[keyof typeof TaskIndex];
130
+ export declare const TASK_SLOT_INDEX_BITS = 5;
131
+ export declare const TASK_SLOT_INDEX_MASK: number;
132
+ export declare const TASK_SLOT_META_BITS: number;
133
+ export declare const TASK_SLOT_META_VALUE_MASK: number;
134
+ export declare const TASK_FUNCTION_ID_BITS = 16;
135
+ export declare const TASK_FUNCTION_ID_MASK: number;
136
+ export declare const TASK_FUNCTION_META_BITS: number;
137
+ export declare const TASK_FUNCTION_META_VALUE_MASK: number;
138
+ export declare const getTaskFunctionID: (task: ArrayLike<number>) => number;
139
+ export declare const setTaskFunctionID: (task: Task, functionID: number) => void;
140
+ export declare const getTaskFunctionMeta: (task: ArrayLike<number>) => number;
141
+ export declare const setTaskFunctionMeta: (task: Task, value: number) => void;
142
+ export declare const getTaskSlotIndex: (task: ArrayLike<number>) => number;
143
+ export declare const setTaskSlotIndex: (task: Task, slotIndex: number) => void;
144
+ export declare const getTaskSlotMeta: (task: ArrayLike<number>) => number;
145
+ export declare const setTaskSlotMeta: (task: Task, value: number) => void;
146
+ export declare const TaskFlag: {
147
+ readonly Reject: 1;
148
+ };
149
+ export type TaskFlag = typeof TaskFlag[keyof typeof TaskFlag];
150
+ export declare const LOCK_WORD_BYTES: number;
151
+ export declare const LOCK_HOST_BITS_OFFSET_BYTES: 0;
152
+ export declare const LOCK_WORKER_BITS_OFFSET_BYTES = 64;
153
+ export declare const LOCK_SECTOR_BYTE_LENGTH = 256;
154
+ export declare const PAYLOAD_LOCK_HOST_BITS_OFFSET_BYTES: number;
155
+ export declare const PAYLOAD_LOCK_WORKER_BITS_OFFSET_BYTES: number;
156
+ export declare const PAYLOAD_LOCK_SECTOR_BYTE_LENGTH = 256;
157
+ export declare const HEADER_SLOT_STRIDE_U32: number;
158
+ export declare const HEADER_SLOT_STRIDE_BYTES: number;
159
+ export declare const HEADER_TASK_LINE_U32: number;
160
+ export declare const HEADER_STATIC_PAYLOAD_U32: number;
161
+ export declare const HEADER_TASK_OFFSET_IN_SLOT_U32: number;
162
+ export declare const HEADER_U32_LENGTH: number;
163
+ export declare const HEADER_BYTE_LENGTH: number;
164
+ export declare const makeTask: () => Task;
165
+ type ResolveHostOptions = {
166
+ queue: Task[];
167
+ onResolved?: (task: Task) => void;
168
+ shouldSettle?: (task: Task) => boolean;
169
+ activeRejectPlaceholder?: Task["reject"];
170
+ };
171
+ /**
172
+ * Complexity: 7 / 10
173
+ *
174
+ * SAFETY:
175
+ * - Single producer/consumer; do not call encode/decode concurrently.
176
+ * - Shared buffers must be the same between host/worker.
177
+ * - encode/decode are not re-entrant; payload codec uses a shared scratch buffer.
178
+ */
179
+ export type Lock2 = ReturnType<typeof lock2>;
180
+ export declare const lock2: ({ headers, headerSlotStrideU32, LockBoundSector, payload, payloadConfig, payloadSector, textCompat, resultList, toSentList, recycleList, processBoundary, }: {
181
+ headers?: SharedBufferSource;
182
+ headerSlotStrideU32?: number;
183
+ LockBoundSector?: SharedBufferSource;
184
+ payload?: SharedBufferSource;
185
+ payloadConfig?: PayloadBufferOptions;
186
+ payloadSector?: SharedBufferSource;
187
+ textCompat?: LockBufferTextCompat;
188
+ toSentList?: RingQueue<Task>;
189
+ resultList?: RingQueue<Task>;
190
+ recycleList?: RingQueue<Task>;
191
+ processBoundary?: boolean;
192
+ }) => {
193
+ enlist: (task: Task) => true;
194
+ encode: (task: Task, state?: number) => boolean;
195
+ encodeManyFrom: (list: RingQueue<Task>) => number;
196
+ encodeAll: () => boolean;
197
+ publish: (task: Task) => boolean;
198
+ flushPending: () => boolean;
199
+ decode: () => boolean;
200
+ hasSpace: () => boolean;
201
+ resolved: RingQueue<Task>;
202
+ hostBits: Int32Array<import("../common/shared-buffer-region.js").SharedBuffer>;
203
+ workerBits: Int32Array<import("../common/shared-buffer-region.js").SharedBuffer>;
204
+ recyclecList: RingQueue<Task>;
205
+ resolveHost: ({ queue, onResolved, shouldSettle, activeRejectPlaceholder, }: ResolveHostOptions) => () => number;
206
+ hasPendingFrames: () => boolean;
207
+ getPendingFrameCount: () => number;
208
+ getPendingPromiseCount: () => number;
209
+ resetPendingState: () => void;
210
+ takeDeferredCount: () => number;
211
+ setPromiseHandler: (handler?: PromisePayloadHandler) => void;
212
+ };
213
+ export {};