knitting 0.1.46

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 (121) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +632 -0
  3. package/knitting.d.ts +4 -0
  4. package/knitting.js +5 -0
  5. package/map.md +264 -0
  6. package/package.json +77 -0
  7. package/prebuilds/darwin-arm64-node-127/knitting_shared_memory.node +0 -0
  8. package/prebuilds/darwin-arm64-node-127/knitting_shm.node +0 -0
  9. package/prebuilds/darwin-arm64-node-137/knitting_shared_memory.node +0 -0
  10. package/prebuilds/darwin-arm64-node-137/knitting_shm.node +0 -0
  11. package/prebuilds/darwin-x64-node-127/knitting_shared_memory.node +0 -0
  12. package/prebuilds/darwin-x64-node-127/knitting_shm.node +0 -0
  13. package/prebuilds/darwin-x64-node-137/knitting_shared_memory.node +0 -0
  14. package/prebuilds/darwin-x64-node-137/knitting_shm.node +0 -0
  15. package/prebuilds/linux-x64-node-127/knitting_shared_memory.node +0 -0
  16. package/prebuilds/linux-x64-node-127/knitting_shm.node +0 -0
  17. package/prebuilds/linux-x64-node-137/knitting_shared_memory.node +0 -0
  18. package/prebuilds/linux-x64-node-137/knitting_shm.node +0 -0
  19. package/process-shared-buffer.d.ts +1 -0
  20. package/process-shared-buffer.js +1 -0
  21. package/scripts/build-native-addons.ts +295 -0
  22. package/src/api.d.ts +55 -0
  23. package/src/api.js +384 -0
  24. package/src/common/envelope.d.ts +11 -0
  25. package/src/common/envelope.js +8 -0
  26. package/src/common/module-url.d.ts +1 -0
  27. package/src/common/module-url.js +24 -0
  28. package/src/common/node-compat.d.ts +20 -0
  29. package/src/common/node-compat.js +24 -0
  30. package/src/common/path-canonical.d.ts +6 -0
  31. package/src/common/path-canonical.js +41 -0
  32. package/src/common/runtime.d.ts +15 -0
  33. package/src/common/runtime.js +91 -0
  34. package/src/common/shared-buffer-region.d.ts +11 -0
  35. package/src/common/shared-buffer-region.js +21 -0
  36. package/src/common/shared-buffer-text.d.ts +16 -0
  37. package/src/common/shared-buffer-text.js +65 -0
  38. package/src/common/task-source.d.ts +2 -0
  39. package/src/common/task-source.js +79 -0
  40. package/src/common/task-symbol.d.ts +1 -0
  41. package/src/common/task-symbol.js +1 -0
  42. package/src/common/with-resolvers.d.ts +9 -0
  43. package/src/common/with-resolvers.js +23 -0
  44. package/src/common/worker-runtime.d.ts +40 -0
  45. package/src/common/worker-runtime.js +52 -0
  46. package/src/connections/bun.d.ts +20 -0
  47. package/src/connections/bun.js +159 -0
  48. package/src/connections/deno.d.ts +20 -0
  49. package/src/connections/deno.js +150 -0
  50. package/src/connections/file-descriptor.d.ts +37 -0
  51. package/src/connections/file-descriptor.js +139 -0
  52. package/src/connections/index.d.ts +3 -0
  53. package/src/connections/index.js +3 -0
  54. package/src/connections/node-addons.d.ts +5 -0
  55. package/src/connections/node-addons.js +43 -0
  56. package/src/connections/node.d.ts +29 -0
  57. package/src/connections/node.js +59 -0
  58. package/src/connections/posix.d.ts +31 -0
  59. package/src/connections/posix.js +71 -0
  60. package/src/connections/process-shared-buffer.d.ts +67 -0
  61. package/src/connections/process-shared-buffer.js +267 -0
  62. package/src/connections/types.d.ts +48 -0
  63. package/src/connections/types.js +37 -0
  64. package/src/error.d.ts +13 -0
  65. package/src/error.js +49 -0
  66. package/src/ipc/tools/ring-queue.d.ts +33 -0
  67. package/src/ipc/tools/ring-queue.js +159 -0
  68. package/src/ipc/transport/shared-memory.d.ts +25 -0
  69. package/src/ipc/transport/shared-memory.js +35 -0
  70. package/src/knitting_shared_memory.cc +436 -0
  71. package/src/knitting_shm.cc +476 -0
  72. package/src/memory/byte-carpet.d.ts +73 -0
  73. package/src/memory/byte-carpet.js +157 -0
  74. package/src/memory/lock.d.ts +190 -0
  75. package/src/memory/lock.js +856 -0
  76. package/src/memory/payload-config.d.ts +22 -0
  77. package/src/memory/payload-config.js +67 -0
  78. package/src/memory/payloadCodec.d.ts +46 -0
  79. package/src/memory/payloadCodec.js +1157 -0
  80. package/src/memory/regionRegistry.d.ts +17 -0
  81. package/src/memory/regionRegistry.js +285 -0
  82. package/src/memory/shared-buffer-io.d.ts +53 -0
  83. package/src/memory/shared-buffer-io.js +380 -0
  84. package/src/permission/index.d.ts +2 -0
  85. package/src/permission/index.js +2 -0
  86. package/src/permission/protocol.d.ts +166 -0
  87. package/src/permission/protocol.js +640 -0
  88. package/src/runtime/balancer.d.ts +19 -0
  89. package/src/runtime/balancer.js +149 -0
  90. package/src/runtime/dispatcher.d.ts +34 -0
  91. package/src/runtime/dispatcher.js +142 -0
  92. package/src/runtime/inline-executor.d.ts +10 -0
  93. package/src/runtime/inline-executor.js +270 -0
  94. package/src/runtime/pool.d.ts +43 -0
  95. package/src/runtime/pool.js +922 -0
  96. package/src/runtime/tx-queue.d.ts +25 -0
  97. package/src/runtime/tx-queue.js +144 -0
  98. package/src/shared/abortSignal.d.ts +23 -0
  99. package/src/shared/abortSignal.js +126 -0
  100. package/src/types.d.ts +283 -0
  101. package/src/types.js +2 -0
  102. package/src/worker/composable-runners.d.ts +12 -0
  103. package/src/worker/composable-runners.js +105 -0
  104. package/src/worker/loop.d.ts +2 -0
  105. package/src/worker/loop.js +453 -0
  106. package/src/worker/rx-queue.d.ts +22 -0
  107. package/src/worker/rx-queue.js +124 -0
  108. package/src/worker/safety/index.d.ts +4 -0
  109. package/src/worker/safety/index.js +4 -0
  110. package/src/worker/safety/performance.d.ts +1 -0
  111. package/src/worker/safety/performance.js +17 -0
  112. package/src/worker/safety/process.d.ts +2 -0
  113. package/src/worker/safety/process.js +79 -0
  114. package/src/worker/safety/startup.d.ts +16 -0
  115. package/src/worker/safety/startup.js +30 -0
  116. package/src/worker/safety/worker-data.d.ts +2 -0
  117. package/src/worker/safety/worker-data.js +36 -0
  118. package/src/worker/task-loader.d.ts +26 -0
  119. package/src/worker/task-loader.js +66 -0
  120. package/src/worker/timers.d.ts +18 -0
  121. package/src/worker/timers.js +97 -0
@@ -0,0 +1,1157 @@
1
+ import { beginPromisePayload, finishPromisePayload, getTaskSlotIndex, HEADER_BYTE_LENGTH, HEADER_SLOT_STRIDE_U32, HEADER_STATIC_PAYLOAD_U32, LockBound, PayloadBuffer, PayloadSignal, TaskIndex, } from "./lock.js";
2
+ import { register } from "./regionRegistry.js";
3
+ import { createSharedDynamicBufferIO, createSharedStaticBufferIO, } from "./shared-buffer-io.js";
4
+ import { getStridedRegionSpanBytes } from "./byte-carpet.js";
5
+ import { encoderError, ErrorKnitting } from "../error.js";
6
+ import { Envelope } from "../common/envelope.js";
7
+ import { resolvePayloadBufferOptions, } from "./payload-config.js";
8
+ const memory = new ArrayBuffer(8);
9
+ const Float64View = new Float64Array(memory);
10
+ const BigInt64View = new BigInt64Array(memory);
11
+ const Uint32View = new Uint32Array(memory);
12
+ const textEncode = new TextEncoder();
13
+ const runtimeBufferClass = globalThis.Buffer;
14
+ const runtimeBufferByteLength = typeof runtimeBufferClass?.byteLength ===
15
+ "function"
16
+ ? ((value, encoding) => runtimeBufferClass.byteLength(value, encoding))
17
+ : undefined;
18
+ const isRuntimeBuffer = (value) => typeof runtimeBufferClass?.isBuffer === "function" &&
19
+ runtimeBufferClass.isBuffer(value);
20
+ const isRuntimeUint8Array = (value) => value != null &&
21
+ typeof value === "object" &&
22
+ Object.getPrototypeOf(value) === Uint8Array.prototype;
23
+ const utf8ByteLength = !runtimeBufferByteLength
24
+ ? (text) => textEncode.encode(text).byteLength
25
+ : (text) => runtimeBufferByteLength(text, "utf8");
26
+ const BIGINT64_MIN = -(1n << 63n);
27
+ const BIGINT64_MAX = (1n << 63n) - 1n;
28
+ const { parse: parseJSON, stringify: stringifyJSON } = JSON;
29
+ const { for: symbolFor, keyFor: symbolKeyFor } = Symbol;
30
+ const EXTERNAL_PAYLOAD_BRAND = symbolFor("knitting.payloadCodec");
31
+ const PROCESS_SHARED_BUFFER_CODEC_ID = "knitting.processSharedBuffer";
32
+ const externalPayloadGlobal = globalThis;
33
+ const objectGetPrototypeOf = Object.getPrototypeOf;
34
+ const objectHasOwn = Object.prototype.hasOwnProperty;
35
+ const arrayIsArray = Array.isArray;
36
+ const objectPrototype = Object.prototype;
37
+ const UNSUPPORTED_OBJECT_DETAIL = "Unsupported object type. Allowed: plain object, array, Error, Date, Envelope, Buffer, ArrayBuffer, DataView, typed arrays, and registered external payloads. Serialize it yourself.";
38
+ const ENVELOPE_PAYLOAD_DETAIL = "Envelope payload must be an ArrayBuffer.";
39
+ const ENVELOPE_HEADER_DETAIL = "Envelope header must be a JSON-like value or string.";
40
+ const ENVELOPE_PROMISE_DETAIL = "Envelope header cannot contain Promise values.";
41
+ const DYNAMIC_PAYLOAD_LIMIT_DETAIL = "Dynamic payload exceeds maxPayloadBytes.";
42
+ const DYNAMIC_PAYLOAD_CAPACITY_DETAIL = "Dynamic payload buffer capacity exceeded.";
43
+ const isPlainJsonObject = (value) => {
44
+ const proto = objectGetPrototypeOf(value);
45
+ return proto === objectPrototype || proto === null;
46
+ };
47
+ const readExternalPayloadCodecId = (value) => {
48
+ const codecId = value[EXTERNAL_PAYLOAD_BRAND];
49
+ return typeof codecId === "string" ? codecId : undefined;
50
+ };
51
+ const runtimeCode = (value) => {
52
+ switch (value) {
53
+ case "node":
54
+ return 1;
55
+ case "deno":
56
+ return 2;
57
+ case "bun":
58
+ return 3;
59
+ default:
60
+ return 0;
61
+ }
62
+ };
63
+ const kindCode = (value) => {
64
+ switch (value) {
65
+ case "shared-array-buffer":
66
+ return 1;
67
+ case "external-array-buffer":
68
+ return 2;
69
+ default:
70
+ return 0;
71
+ }
72
+ };
73
+ const isU32 = (value) => typeof value === "number" &&
74
+ Number.isInteger(value) &&
75
+ value >= 0 &&
76
+ value <= 0xffffffff;
77
+ const isExternalPayloadLike = (value) => typeof value.toMetadata === "function" &&
78
+ typeof value[EXTERNAL_PAYLOAD_BRAND] ===
79
+ "string";
80
+ const decodeExternalPayload = (raw) => {
81
+ const payload = parseJSON(raw);
82
+ if (!arrayIsArray(payload) || payload.length !== 2)
83
+ return payload;
84
+ const codecId = payload[0];
85
+ const metadata = payload[1];
86
+ if (typeof codecId !== "string") {
87
+ return { codec: codecId, metadata };
88
+ }
89
+ const codec = externalPayloadGlobal.__KNITTING_PAYLOAD_CODECS__?.[codecId];
90
+ return typeof codec?.decode === "function"
91
+ ? codec.decode(metadata)
92
+ : { codec: codecId, metadata };
93
+ };
94
+ const PROCESS_SHARED_BUFFER_NUMERIC_WORDS = 8;
95
+ const PROCESS_SHARED_BUFFER_NUMERIC_BYTES = PROCESS_SHARED_BUFFER_NUMERIC_WORDS * Uint32Array.BYTES_PER_ELEMENT;
96
+ const NUMERIC_SENTINEL = 0xffffffff;
97
+ const readProcessSharedBufferNumericPayload = (bytes) => {
98
+ const out = new Uint32Array(PROCESS_SHARED_BUFFER_NUMERIC_WORDS);
99
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
100
+ for (let i = 0; i < PROCESS_SHARED_BUFFER_NUMERIC_WORDS; i++) {
101
+ out[i] = view.getUint32(i * Uint32Array.BYTES_PER_ELEMENT, true);
102
+ }
103
+ return out;
104
+ };
105
+ const decodeProcessSharedBufferNumeric = (bytes) => {
106
+ const metadata = readProcessSharedBufferNumericPayload(bytes);
107
+ const codec = externalPayloadGlobal.__KNITTING_PAYLOAD_CODECS__?.[PROCESS_SHARED_BUFFER_CODEC_ID];
108
+ return typeof codec?.decodeNumeric === "function"
109
+ ? codec.decodeNumeric(metadata)
110
+ : { codec: PROCESS_SHARED_BUFFER_CODEC_ID, metadata };
111
+ };
112
+ const tryEncodePrimitiveTask = (task) => {
113
+ const value = task.value;
114
+ switch (typeof value) {
115
+ case "number":
116
+ if (value !== value) {
117
+ task[TaskIndex.Type] = PayloadSignal.NaN;
118
+ return true;
119
+ }
120
+ Float64View[0] = value;
121
+ task[TaskIndex.Type] = PayloadSignal.Float64;
122
+ task[TaskIndex.Start] = Uint32View[0];
123
+ task[TaskIndex.End] = Uint32View[1];
124
+ return true;
125
+ case "boolean":
126
+ task[TaskIndex.Type] = value ? PayloadSignal.True : PayloadSignal.False;
127
+ return true;
128
+ case "undefined":
129
+ task[TaskIndex.Type] = PayloadSignal.Undefined;
130
+ return true;
131
+ case "bigint":
132
+ if (value < BIGINT64_MIN || value > BIGINT64_MAX)
133
+ return false;
134
+ BigInt64View[0] = value;
135
+ task[TaskIndex.Type] = PayloadSignal.BigInt;
136
+ task[TaskIndex.Start] = Uint32View[0];
137
+ task[TaskIndex.End] = Uint32View[1];
138
+ return true;
139
+ case "object":
140
+ if (value === null) {
141
+ task[TaskIndex.Type] = PayloadSignal.Null;
142
+ return true;
143
+ }
144
+ return false;
145
+ default:
146
+ return false;
147
+ }
148
+ };
149
+ const hasPromiseInEnvelopeHeader = (value, seen) => {
150
+ if (value instanceof Promise)
151
+ return true;
152
+ if (value === null || typeof value !== "object")
153
+ return false;
154
+ const objectValue = value;
155
+ const visited = seen ?? new Set();
156
+ if (visited.has(objectValue))
157
+ return false;
158
+ visited.add(objectValue);
159
+ if (arrayIsArray(objectValue)) {
160
+ const list = objectValue;
161
+ for (let i = 0; i < list.length; i++) {
162
+ if (hasPromiseInEnvelopeHeader(list[i], visited))
163
+ return true;
164
+ }
165
+ return false;
166
+ }
167
+ if (!isPlainJsonObject(objectValue))
168
+ return false;
169
+ const record = objectValue;
170
+ for (const key in record) {
171
+ if (!objectHasOwn.call(record, key))
172
+ continue;
173
+ if (hasPromiseInEnvelopeHeader(record[key], visited))
174
+ return true;
175
+ }
176
+ return false;
177
+ };
178
+ const toErrorCause = (cause) => {
179
+ if (cause === null || cause === undefined)
180
+ return cause;
181
+ switch (typeof cause) {
182
+ case "string":
183
+ case "number":
184
+ case "boolean":
185
+ return cause;
186
+ case "bigint":
187
+ return cause.toString();
188
+ case "symbol":
189
+ case "function":
190
+ return String(cause);
191
+ }
192
+ if (cause instanceof Error) {
193
+ const nested = {
194
+ name: cause.name,
195
+ message: cause.message,
196
+ };
197
+ if (typeof cause.stack === "string")
198
+ nested.stack = cause.stack;
199
+ if (objectHasOwn.call(cause, "cause")) {
200
+ nested.cause = toErrorCause(cause.cause);
201
+ }
202
+ return nested;
203
+ }
204
+ try {
205
+ return parseJSON(stringifyJSON(cause));
206
+ }
207
+ catch {
208
+ return String(cause);
209
+ }
210
+ };
211
+ const toErrorPayload = (error) => {
212
+ const payload = {
213
+ name: error.name,
214
+ message: error.message,
215
+ };
216
+ if (typeof error.stack === "string")
217
+ payload.stack = error.stack;
218
+ if (objectHasOwn.call(error, "cause")) {
219
+ payload.cause = toErrorCause(error.cause);
220
+ }
221
+ return payload;
222
+ };
223
+ const parseErrorPayload = (raw) => {
224
+ let parsed;
225
+ try {
226
+ parsed = parseJSON(raw);
227
+ }
228
+ catch {
229
+ return new Error(raw);
230
+ }
231
+ if (parsed == null || typeof parsed !== "object") {
232
+ return new Error(String(parsed));
233
+ }
234
+ const payload = parsed;
235
+ const err = new Error(typeof payload.message === "string" ? payload.message : "");
236
+ if (typeof payload.name === "string" && payload.name.length > 0) {
237
+ err.name = payload.name;
238
+ }
239
+ if (typeof payload.stack === "string") {
240
+ try {
241
+ err.stack = payload.stack;
242
+ }
243
+ catch {
244
+ }
245
+ }
246
+ if (objectHasOwn.call(payload, "cause")) {
247
+ err.cause = payload.cause;
248
+ }
249
+ return err;
250
+ };
251
+ const decodeBigIntBinary = (bytes) => {
252
+ const sign = bytes[0];
253
+ let value = 0n;
254
+ for (let i = bytes.length - 1; i >= 1; i--) {
255
+ value = (value << 8n) | BigInt(bytes[i]);
256
+ }
257
+ return sign === 1 ? -value : value;
258
+ };
259
+ const initStaticIO = (headersBuffer, headerSlotStrideU32, textCompat) => {
260
+ const slotStride = headerSlotStrideU32 ?? HEADER_SLOT_STRIDE_U32;
261
+ const requiredBytes = getStridedRegionSpanBytes({
262
+ slotCount: LockBound.slots,
263
+ slotStrideU32: slotStride,
264
+ slotLengthU32: HEADER_STATIC_PAYLOAD_U32,
265
+ baseU32: LockBound.header,
266
+ });
267
+ if (headersBuffer.byteLength < Math.max(requiredBytes, HEADER_BYTE_LENGTH)) {
268
+ return null;
269
+ }
270
+ return createSharedStaticBufferIO({
271
+ headersBuffer,
272
+ slotStrideU32: slotStride,
273
+ textCompat,
274
+ });
275
+ };
276
+ const requireStaticIO = (headersBuffer, headerSlotStrideU32, textCompat) => {
277
+ const staticIO = initStaticIO(headersBuffer, headerSlotStrideU32, textCompat);
278
+ if (staticIO === null) {
279
+ throw new RangeError("headersBuffer is too small for static payload IO");
280
+ }
281
+ return staticIO;
282
+ };
283
+ /**
284
+ * Returns `true` when the payload is encoded successfully.
285
+ * Returns `false` when dynamic payload space could not be reserved.
286
+ */
287
+ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headersBuffer, headerSlotStrideU32, textCompat, onPromise, }) => {
288
+ const payloadSab = payload?.sab ?? sab;
289
+ const resolvedPayloadConfig = resolvePayloadBufferOptions({
290
+ sab: payloadSab,
291
+ options: payload?.config ?? payloadConfig,
292
+ });
293
+ const maxPayloadBytes = resolvedPayloadConfig.maxPayloadBytes;
294
+ const { allocTask, setSlotLength, free } = register({
295
+ lockSector,
296
+ });
297
+ const { writeBinary: writeDynamicBinary, writeBuffer: writeDynamicBuffer, writeArrayBuffer: writeDynamicArrayBuffer, write8Binary: writeDynamic8Binary, writeUtf8: writeDynamicUtf8, } = createSharedDynamicBufferIO({
298
+ sab: payloadSab,
299
+ payloadConfig: resolvedPayloadConfig,
300
+ textCompat: textCompat?.payload,
301
+ });
302
+ const { maxBytes: staticMaxBytes, writeBinary: writeStaticBinary, writeBuffer: writeStaticBuffer, writeArrayBuffer: writeStaticArrayBuffer, writeExactUint8Array: writeStaticExactUint8Array, write8Binary: writeStatic8Binary, writeUtf8: writeStaticUtf8, } = requireStaticIO(headersBuffer, headerSlotStrideU32, textCompat?.headers);
303
+ const dynamicLimitError = (task, actualBytes, label) => encoderError({
304
+ task,
305
+ type: ErrorKnitting.Serializable,
306
+ onPromise,
307
+ detail: `${DYNAMIC_PAYLOAD_LIMIT_DETAIL} limit=${maxPayloadBytes}; ` +
308
+ `actual=${actualBytes}; type=${label}.`,
309
+ });
310
+ const dynamicCapacityError = (task) => encoderError({
311
+ task,
312
+ type: ErrorKnitting.Serializable,
313
+ onPromise,
314
+ detail: DYNAMIC_PAYLOAD_CAPACITY_DETAIL,
315
+ });
316
+ const ensureWithinDynamicLimit = (task, bytes, label) => {
317
+ if (bytes <= maxPayloadBytes)
318
+ return true;
319
+ return dynamicLimitError(task, bytes, label);
320
+ };
321
+ const dynamicUtf8ReserveBytesWithExtra = (task, text, extraBytes, label) => {
322
+ const estimatedBytes = text.length * 3;
323
+ const estimatedTotal = estimatedBytes + extraBytes;
324
+ if (estimatedTotal <= maxPayloadBytes)
325
+ return estimatedBytes;
326
+ const exactBytes = utf8ByteLength(text);
327
+ const exactTotal = exactBytes + extraBytes;
328
+ if (exactTotal > maxPayloadBytes) {
329
+ dynamicLimitError(task, exactTotal, label);
330
+ return -1;
331
+ }
332
+ return exactBytes;
333
+ };
334
+ const dynamicUtf8ReserveBytes = (task, text, label) => dynamicUtf8ReserveBytesWithExtra(task, text, 0, label);
335
+ const reserveDynamic = (task, bytes) => {
336
+ task[TaskIndex.PayloadLen] = bytes;
337
+ // PayloadCodec only reserves after the lock has guaranteed capacity.
338
+ return allocTask(task);
339
+ };
340
+ let objectDynamicSlot = -1;
341
+ const reserveDynamicObject = (task, bytes) => {
342
+ task[TaskIndex.PayloadLen] = bytes;
343
+ const reservedSlot = allocTask(task);
344
+ objectDynamicSlot = reservedSlot;
345
+ return reservedSlot;
346
+ };
347
+ const rollbackObjectDynamic = () => {
348
+ if (objectDynamicSlot !== -1) {
349
+ free(objectDynamicSlot);
350
+ objectDynamicSlot = -1;
351
+ }
352
+ };
353
+ const failDynamicWriteAfterReserve = (task, reservedSlot) => {
354
+ free(reservedSlot);
355
+ if (objectDynamicSlot === reservedSlot)
356
+ objectDynamicSlot = -1;
357
+ return dynamicCapacityError(task);
358
+ };
359
+ let bigintScratch = new Uint8Array(16);
360
+ const encodeBigIntIntoScratch = (value) => {
361
+ let sign = 0;
362
+ let abs = value;
363
+ if (value < 0n) {
364
+ sign = 1;
365
+ abs = -value;
366
+ }
367
+ let at = 1;
368
+ while (abs > 0n) {
369
+ if (at >= bigintScratch.byteLength) {
370
+ const next = new Uint8Array(bigintScratch.byteLength << 1);
371
+ next.set(bigintScratch, 0);
372
+ bigintScratch = next;
373
+ }
374
+ bigintScratch[at++] = Number(abs & 0xffn);
375
+ abs >>= 8n;
376
+ }
377
+ bigintScratch[0] = sign;
378
+ return at;
379
+ };
380
+ const clearBigIntScratch = (used) => {
381
+ bigintScratch.fill(0, 0, used);
382
+ };
383
+ const encodeErrorObject = (task, error) => {
384
+ let text;
385
+ try {
386
+ text = stringifyJSON(toErrorPayload(error));
387
+ }
388
+ catch (encodeErrorReason) {
389
+ const detail = encodeErrorReason instanceof Error
390
+ ? encodeErrorReason.message
391
+ : String(encodeErrorReason);
392
+ return encoderError({
393
+ task,
394
+ type: ErrorKnitting.Serializable,
395
+ onPromise,
396
+ detail,
397
+ });
398
+ }
399
+ const reserveBytes = dynamicUtf8ReserveBytes(task, text, "Error");
400
+ if (reserveBytes < 0)
401
+ return false;
402
+ task[TaskIndex.Type] = PayloadBuffer.Error;
403
+ const reservedSlot = reserveDynamicObject(task, reserveBytes);
404
+ const written = writeDynamicUtf8(text, task[TaskIndex.Start], reserveBytes);
405
+ if (written < 0)
406
+ return failDynamicWriteAfterReserve(task, reservedSlot);
407
+ task[TaskIndex.PayloadLen] = written;
408
+ setSlotLength(reservedSlot, written);
409
+ task.value = null;
410
+ return true;
411
+ };
412
+ const encodeObjectBinary = (task, slotIndex, bytesView, dynamicType, staticType) => {
413
+ const bytes = bytesView.byteLength;
414
+ if (bytes <= staticMaxBytes) {
415
+ const written = writeStaticBinary(bytesView, slotIndex);
416
+ if (written !== -1) {
417
+ task[TaskIndex.Type] = staticType;
418
+ task[TaskIndex.PayloadLen] = written;
419
+ task.value = null;
420
+ return true;
421
+ }
422
+ }
423
+ task[TaskIndex.Type] = dynamicType;
424
+ if (!ensureWithinDynamicLimit(task, bytes, PayloadBuffer[dynamicType])) {
425
+ return false;
426
+ }
427
+ const reservedSlot = reserveDynamicObject(task, bytes);
428
+ const written = writeDynamicBinary(bytesView, task[TaskIndex.Start]);
429
+ if (written < 0)
430
+ return failDynamicWriteAfterReserve(task, reservedSlot);
431
+ task[TaskIndex.PayloadLen] = written;
432
+ setSlotLength(reservedSlot, written);
433
+ task.value = null;
434
+ return true;
435
+ };
436
+ const encodeObjectUint8Array = (task, slotIndex, bytesView) => {
437
+ const bytes = bytesView.byteLength;
438
+ if (bytes <= staticMaxBytes) {
439
+ writeStaticExactUint8Array(bytesView, slotIndex);
440
+ task[TaskIndex.Type] = PayloadBuffer.StaticBinary;
441
+ task[TaskIndex.PayloadLen] = bytes;
442
+ task.value = null;
443
+ return true;
444
+ }
445
+ task[TaskIndex.Type] = PayloadBuffer.Binary;
446
+ if (!ensureWithinDynamicLimit(task, bytes, "Binary"))
447
+ return false;
448
+ const reservedSlot = reserveDynamicObject(task, bytes);
449
+ const written = writeDynamicBinary(bytesView, task[TaskIndex.Start]);
450
+ if (written < 0)
451
+ return failDynamicWriteAfterReserve(task, reservedSlot);
452
+ task[TaskIndex.PayloadLen] = written;
453
+ setSlotLength(reservedSlot, written);
454
+ task.value = null;
455
+ return true;
456
+ };
457
+ const encodeObjectBuffer = (task, slotIndex, buffer) => {
458
+ const bytes = buffer.byteLength;
459
+ if (bytes <= staticMaxBytes) {
460
+ const written = writeStaticBuffer(buffer, slotIndex);
461
+ if (written !== -1) {
462
+ task[TaskIndex.Type] = PayloadBuffer.StaticBuffer;
463
+ task[TaskIndex.PayloadLen] = written;
464
+ task.value = null;
465
+ return true;
466
+ }
467
+ }
468
+ task[TaskIndex.Type] = PayloadBuffer.Buffer;
469
+ if (!ensureWithinDynamicLimit(task, bytes, "Buffer"))
470
+ return false;
471
+ const reservedSlot = reserveDynamicObject(task, bytes);
472
+ const written = writeDynamicBuffer(buffer, task[TaskIndex.Start]);
473
+ if (written < 0)
474
+ return failDynamicWriteAfterReserve(task, reservedSlot);
475
+ task[TaskIndex.PayloadLen] = written;
476
+ setSlotLength(reservedSlot, written);
477
+ task.value = null;
478
+ return true;
479
+ };
480
+ const encodeObjectFloat64Array = (task, slotIndex, float64) => {
481
+ const bytes = float64.byteLength;
482
+ if (bytes <= staticMaxBytes) {
483
+ const written = writeStatic8Binary(float64, slotIndex);
484
+ if (written !== -1) {
485
+ task[TaskIndex.Type] = PayloadBuffer.StaticFloat64Array;
486
+ task[TaskIndex.PayloadLen] = written;
487
+ task.value = null;
488
+ return true;
489
+ }
490
+ }
491
+ task[TaskIndex.Type] = PayloadBuffer.Float64Array;
492
+ if (!ensureWithinDynamicLimit(task, bytes, "Float64Array"))
493
+ return false;
494
+ const reservedSlot = reserveDynamicObject(task, bytes);
495
+ const written = writeDynamic8Binary(float64, task[TaskIndex.Start]);
496
+ if (written < 0)
497
+ return failDynamicWriteAfterReserve(task, reservedSlot);
498
+ task[TaskIndex.PayloadLen] = written;
499
+ setSlotLength(reservedSlot, written);
500
+ task.value = null;
501
+ return true;
502
+ };
503
+ const encodeObjectArrayBuffer = (task, slotIndex, arrayBuffer) => {
504
+ const bytes = arrayBuffer.byteLength;
505
+ if (bytes <= staticMaxBytes) {
506
+ const written = writeStaticArrayBuffer(arrayBuffer, slotIndex);
507
+ if (written !== -1) {
508
+ task[TaskIndex.Type] = PayloadBuffer.StaticArrayBuffer;
509
+ task[TaskIndex.PayloadLen] = written;
510
+ task.value = null;
511
+ return true;
512
+ }
513
+ }
514
+ task[TaskIndex.Type] = PayloadBuffer.ArrayBuffer;
515
+ if (!ensureWithinDynamicLimit(task, bytes, "ArrayBuffer"))
516
+ return false;
517
+ const reservedSlot = reserveDynamicObject(task, bytes);
518
+ const written = writeDynamicArrayBuffer(arrayBuffer, task[TaskIndex.Start]);
519
+ if (written < 0)
520
+ return failDynamicWriteAfterReserve(task, reservedSlot);
521
+ task[TaskIndex.PayloadLen] = written;
522
+ setSlotLength(reservedSlot, written);
523
+ task.value = null;
524
+ return true;
525
+ };
526
+ const processSharedBufferScratch = new Uint8Array(PROCESS_SHARED_BUFFER_NUMERIC_BYTES);
527
+ const processSharedBufferScratchView = new DataView(processSharedBufferScratch.buffer);
528
+ const writeProcessSharedBufferWord = (index, value) => {
529
+ processSharedBufferScratchView.setUint32(index * Uint32Array.BYTES_PER_ELEMENT, value, true);
530
+ };
531
+ const tryEncodeProcessSharedBufferNumeric = (task, slotIndex, value) => {
532
+ const descriptor = value.descriptor;
533
+ if (descriptor === undefined ||
534
+ !isU32(descriptor.fd) ||
535
+ !isU32(descriptor.size) ||
536
+ !isU32(descriptor.byteLength) ||
537
+ !isU32(value.byteOffset) ||
538
+ !isU32(value.byteLength)) {
539
+ return false;
540
+ }
541
+ const baseAddressMod64 = descriptor.baseAddressMod64;
542
+ if (baseAddressMod64 !== undefined &&
543
+ !isU32(baseAddressMod64)) {
544
+ return false;
545
+ }
546
+ writeProcessSharedBufferWord(0, descriptor.fd);
547
+ writeProcessSharedBufferWord(1, descriptor.size);
548
+ writeProcessSharedBufferWord(2, descriptor.byteLength);
549
+ writeProcessSharedBufferWord(3, value.byteOffset);
550
+ writeProcessSharedBufferWord(4, value.byteLength);
551
+ writeProcessSharedBufferWord(5, runtimeCode(descriptor.runtime));
552
+ writeProcessSharedBufferWord(6, kindCode(descriptor.kind));
553
+ writeProcessSharedBufferWord(7, baseAddressMod64 === undefined ? NUMERIC_SENTINEL : baseAddressMod64);
554
+ const written = writeStaticBinary(processSharedBufferScratch, slotIndex);
555
+ if (written !== PROCESS_SHARED_BUFFER_NUMERIC_BYTES)
556
+ return false;
557
+ task[TaskIndex.Type] = PayloadBuffer.ProcessSharedBuffer;
558
+ task[TaskIndex.PayloadLen] = written;
559
+ task.value = null;
560
+ return true;
561
+ };
562
+ const encodeObjectExternalPayload = (task, slotIndex, externalPayload) => {
563
+ const codecId = readExternalPayloadCodecId(externalPayload);
564
+ if (codecId === undefined) {
565
+ return encoderError({
566
+ task,
567
+ type: ErrorKnitting.Serializable,
568
+ onPromise,
569
+ detail: UNSUPPORTED_OBJECT_DETAIL,
570
+ });
571
+ }
572
+ if (codecId === PROCESS_SHARED_BUFFER_CODEC_ID &&
573
+ tryEncodeProcessSharedBufferNumeric(task, slotIndex, externalPayload)) {
574
+ return true;
575
+ }
576
+ let text;
577
+ try {
578
+ text = stringifyJSON([codecId, externalPayload.toMetadata()]);
579
+ }
580
+ catch (error) {
581
+ const detail = error instanceof Error ? error.message : String(error);
582
+ return encoderError({
583
+ task,
584
+ type: ErrorKnitting.Serializable,
585
+ onPromise,
586
+ detail,
587
+ });
588
+ }
589
+ if (typeof text !== "string") {
590
+ return encoderError({
591
+ task,
592
+ type: ErrorKnitting.Serializable,
593
+ onPromise,
594
+ detail: "External payload metadata must be JSON serializable.",
595
+ });
596
+ }
597
+ if (text.length <= staticMaxBytes) {
598
+ const written = writeStaticUtf8(text, slotIndex);
599
+ if (written !== -1) {
600
+ task[TaskIndex.Type] = PayloadBuffer.StaticExternalPayload;
601
+ task[TaskIndex.PayloadLen] = written;
602
+ task.value = null;
603
+ return true;
604
+ }
605
+ }
606
+ task[TaskIndex.Type] = PayloadBuffer.ExternalPayload;
607
+ const reserveBytes = dynamicUtf8ReserveBytes(task, text, "ExternalPayload");
608
+ if (reserveBytes < 0)
609
+ return false;
610
+ const reservedSlot = reserveDynamicObject(task, reserveBytes);
611
+ const written = writeDynamicUtf8(text, task[TaskIndex.Start], reserveBytes);
612
+ if (written < 0)
613
+ return failDynamicWriteAfterReserve(task, reservedSlot);
614
+ task[TaskIndex.PayloadLen] = written;
615
+ setSlotLength(reservedSlot, written);
616
+ task.value = null;
617
+ return true;
618
+ };
619
+ const encodeObjectDate = (task, date) => {
620
+ Float64View[0] = date.getTime();
621
+ task[TaskIndex.Type] = PayloadBuffer.Date;
622
+ task[TaskIndex.Start] = Uint32View[0];
623
+ task[TaskIndex.End] = Uint32View[1];
624
+ task.value = null;
625
+ return true;
626
+ };
627
+ const encodeObjectEnvelope = (task, slotIndex, envelope) => {
628
+ const header = envelope.header;
629
+ const payload = envelope.payload;
630
+ const headerIsString = typeof header === "string";
631
+ if (!(payload instanceof ArrayBuffer)) {
632
+ return encoderError({
633
+ task,
634
+ type: ErrorKnitting.Serializable,
635
+ onPromise,
636
+ detail: ENVELOPE_PAYLOAD_DETAIL,
637
+ });
638
+ }
639
+ if (hasPromiseInEnvelopeHeader(header)) {
640
+ return encoderError({
641
+ task,
642
+ type: ErrorKnitting.Serializable,
643
+ onPromise,
644
+ detail: ENVELOPE_PROMISE_DETAIL,
645
+ });
646
+ }
647
+ let headerText;
648
+ if (headerIsString) {
649
+ headerText = header;
650
+ }
651
+ else {
652
+ try {
653
+ headerText = stringifyJSON(header);
654
+ }
655
+ catch (error) {
656
+ const detail = error instanceof Error ? error.message : String(error);
657
+ return encoderError({
658
+ task,
659
+ type: ErrorKnitting.Json,
660
+ onPromise,
661
+ detail,
662
+ });
663
+ }
664
+ }
665
+ if (typeof headerText !== "string") {
666
+ return encoderError({
667
+ task,
668
+ type: ErrorKnitting.Serializable,
669
+ onPromise,
670
+ detail: ENVELOPE_HEADER_DETAIL,
671
+ });
672
+ }
673
+ const payloadBytes = new Uint8Array(payload);
674
+ const payloadLength = payloadBytes.byteLength;
675
+ const payloadReserveBytes = payloadLength > 0 ? payloadLength : 1;
676
+ const staticHeaderWritten = writeStaticUtf8(headerText, slotIndex);
677
+ if (staticHeaderWritten !== -1) {
678
+ if (!ensureWithinDynamicLimit(task, payloadReserveBytes, "EnvelopeStaticHeaderPayload"))
679
+ return false;
680
+ const reservedSlot = reserveDynamicObject(task, payloadReserveBytes);
681
+ task[TaskIndex.Type] = headerIsString
682
+ ? PayloadBuffer.EnvelopeStaticHeaderString
683
+ : PayloadBuffer.EnvelopeStaticHeader;
684
+ task[TaskIndex.PayloadLen] = staticHeaderWritten;
685
+ task[TaskIndex.End] = payloadLength;
686
+ if (payloadLength > 0) {
687
+ const payloadWritten = writeDynamicBinary(payloadBytes, task[TaskIndex.Start]);
688
+ if (payloadWritten < 0) {
689
+ return failDynamicWriteAfterReserve(task, reservedSlot);
690
+ }
691
+ setSlotLength(reservedSlot, payloadWritten);
692
+ }
693
+ task.value = null;
694
+ return true;
695
+ }
696
+ const headerReserveBytes = dynamicUtf8ReserveBytesWithExtra(task, headerText, payloadLength, headerIsString ? "EnvelopeDynamicHeaderString" : "EnvelopeDynamicHeader");
697
+ if (headerReserveBytes < 0)
698
+ return false;
699
+ task[TaskIndex.Type] = headerIsString
700
+ ? PayloadBuffer.EnvelopeDynamicHeaderString
701
+ : PayloadBuffer.EnvelopeDynamicHeader;
702
+ const reservedSlot = reserveDynamicObject(task, headerReserveBytes + payloadLength);
703
+ const baseStart = task[TaskIndex.Start];
704
+ const writtenHeaderBytes = writeDynamicUtf8(headerText, baseStart, headerReserveBytes);
705
+ if (writtenHeaderBytes < 0) {
706
+ return failDynamicWriteAfterReserve(task, reservedSlot);
707
+ }
708
+ if (payloadLength > 0) {
709
+ const payloadWritten = writeDynamicBinary(payloadBytes, baseStart + writtenHeaderBytes);
710
+ if (payloadWritten < 0) {
711
+ return failDynamicWriteAfterReserve(task, reservedSlot);
712
+ }
713
+ }
714
+ task[TaskIndex.PayloadLen] = writtenHeaderBytes;
715
+ task[TaskIndex.End] = payloadLength;
716
+ setSlotLength(reservedSlot, writtenHeaderBytes + payloadLength);
717
+ task.value = null;
718
+ return true;
719
+ };
720
+ const encodeObjectPromise = (task, promise) => {
721
+ if (beginPromisePayload(task)) {
722
+ promise.then((value) => {
723
+ finishPromisePayload(task);
724
+ task.value = value;
725
+ onPromise(task, false, value);
726
+ }, (reason) => {
727
+ finishPromisePayload(task);
728
+ task.value = reason;
729
+ onPromise(task, true, reason);
730
+ });
731
+ }
732
+ return false;
733
+ };
734
+ // Named function so V8/TurboFan can compile it independently from the
735
+ // encodePayload factory closure. Anonymous returns prevent full optimization
736
+ // because the outer factory is too large for TurboFan's bytecode limit.
737
+ const encodeDispatch = (task, slotIndex) => {
738
+ const args = task.value;
739
+ if (tryEncodePrimitiveTask(task))
740
+ return true;
741
+ switch (typeof args) {
742
+ case "bigint": {
743
+ const binaryBytes = encodeBigIntIntoScratch(args);
744
+ const binary = bigintScratch.subarray(0, binaryBytes);
745
+ if (binaryBytes <= staticMaxBytes) {
746
+ const written = writeStaticBinary(binary, slotIndex);
747
+ if (written !== -1) {
748
+ task[TaskIndex.Type] = PayloadBuffer.StaticBigInt;
749
+ task[TaskIndex.PayloadLen] = written;
750
+ clearBigIntScratch(binaryBytes);
751
+ task.value = null;
752
+ return true;
753
+ }
754
+ }
755
+ task[TaskIndex.Type] = PayloadBuffer.BigInt;
756
+ if (!ensureWithinDynamicLimit(task, binaryBytes, "BigInt")) {
757
+ clearBigIntScratch(binaryBytes);
758
+ return false;
759
+ }
760
+ const reservedSlot = reserveDynamic(task, binaryBytes);
761
+ const written = writeDynamicBinary(binary, task[TaskIndex.Start]);
762
+ if (written < 0) {
763
+ clearBigIntScratch(binaryBytes);
764
+ return failDynamicWriteAfterReserve(task, reservedSlot);
765
+ }
766
+ task[TaskIndex.PayloadLen] = written;
767
+ setSlotLength(reservedSlot, written);
768
+ clearBigIntScratch(binaryBytes);
769
+ task.value = null;
770
+ return true;
771
+ }
772
+ case "function":
773
+ return encoderError({
774
+ task,
775
+ type: ErrorKnitting.Function,
776
+ onPromise,
777
+ });
778
+ case "object":
779
+ objectDynamicSlot = -1;
780
+ try {
781
+ const objectValue = args;
782
+ const objectProto = objectGetPrototypeOf(objectValue);
783
+ if (isRuntimeUint8Array(objectValue)) {
784
+ return encodeObjectUint8Array(task, slotIndex, objectValue);
785
+ }
786
+ if (arrayIsArray(objectValue) ||
787
+ objectProto === objectPrototype ||
788
+ objectProto === null) {
789
+ let text;
790
+ try {
791
+ text = stringifyJSON(objectValue);
792
+ }
793
+ catch (error) {
794
+ const detail = error instanceof Error
795
+ ? error.message
796
+ : String(error);
797
+ return encoderError({
798
+ task,
799
+ type: ErrorKnitting.Json,
800
+ onPromise,
801
+ detail,
802
+ });
803
+ }
804
+ if (text.length <= staticMaxBytes) {
805
+ const written = writeStaticUtf8(text, slotIndex);
806
+ if (written !== -1) {
807
+ task[TaskIndex.Type] = PayloadBuffer.StaticJson;
808
+ task[TaskIndex.PayloadLen] = written;
809
+ task.value = null;
810
+ return true;
811
+ }
812
+ }
813
+ task[TaskIndex.Type] = PayloadBuffer.Json;
814
+ const reserveBytes = dynamicUtf8ReserveBytes(task, text, "Json");
815
+ if (reserveBytes < 0)
816
+ return false;
817
+ const reservedSlot = reserveDynamicObject(task, reserveBytes);
818
+ const written = writeDynamicUtf8(text, task[TaskIndex.Start], reserveBytes);
819
+ if (written < 0) {
820
+ return failDynamicWriteAfterReserve(task, reservedSlot);
821
+ }
822
+ task[TaskIndex.PayloadLen] = written;
823
+ setSlotLength(reservedSlot, written);
824
+ task.value = null;
825
+ return true;
826
+ }
827
+ const objectCtor = objectValue
828
+ .constructor;
829
+ if (isRuntimeBuffer(objectValue)) {
830
+ return encodeObjectBuffer(task, slotIndex, objectValue);
831
+ }
832
+ switch (objectCtor) {
833
+ case ArrayBuffer:
834
+ return encodeObjectArrayBuffer(task, slotIndex, objectValue);
835
+ case Int32Array: {
836
+ const int32 = objectValue;
837
+ return encodeObjectBinary(task, slotIndex, new Uint8Array(int32.buffer, int32.byteOffset, int32.byteLength), PayloadBuffer.Int32Array, PayloadBuffer.StaticInt32Array);
838
+ }
839
+ case Float64Array:
840
+ return encodeObjectFloat64Array(task, slotIndex, objectValue);
841
+ case BigInt64Array: {
842
+ const bigInt64 = objectValue;
843
+ return encodeObjectBinary(task, slotIndex, new Uint8Array(bigInt64.buffer, bigInt64.byteOffset, bigInt64.byteLength), PayloadBuffer.BigInt64Array, PayloadBuffer.StaticBigInt64Array);
844
+ }
845
+ case BigUint64Array: {
846
+ const bigUint64 = objectValue;
847
+ return encodeObjectBinary(task, slotIndex, new Uint8Array(bigUint64.buffer, bigUint64.byteOffset, bigUint64.byteLength), PayloadBuffer.BigUint64Array, PayloadBuffer.StaticBigUint64Array);
848
+ }
849
+ case DataView: {
850
+ const dataView = objectValue;
851
+ return encodeObjectBinary(task, slotIndex, new Uint8Array(dataView.buffer, dataView.byteOffset, dataView.byteLength), PayloadBuffer.DataView, PayloadBuffer.StaticDataView);
852
+ }
853
+ case Date:
854
+ return encodeObjectDate(task, objectValue);
855
+ case Envelope:
856
+ return encodeObjectEnvelope(task, slotIndex, objectValue);
857
+ case Promise:
858
+ return encodeObjectPromise(task, objectValue);
859
+ case Error:
860
+ return encodeErrorObject(task, objectValue);
861
+ }
862
+ if (objectValue instanceof Date) {
863
+ return encodeObjectDate(task, objectValue);
864
+ }
865
+ if (objectValue instanceof Envelope) {
866
+ return encodeObjectEnvelope(task, slotIndex, objectValue);
867
+ }
868
+ if (objectValue instanceof Promise) {
869
+ return encodeObjectPromise(task, objectValue);
870
+ }
871
+ if (objectValue instanceof Error) {
872
+ return encodeErrorObject(task, objectValue);
873
+ }
874
+ if (isExternalPayloadLike(objectValue)) {
875
+ return encodeObjectExternalPayload(task, slotIndex, objectValue);
876
+ }
877
+ return encoderError({
878
+ task,
879
+ type: ErrorKnitting.Serializable,
880
+ onPromise,
881
+ detail: UNSUPPORTED_OBJECT_DETAIL,
882
+ });
883
+ }
884
+ catch (error) {
885
+ rollbackObjectDynamic();
886
+ const detail = error instanceof Error ? error.message : String(error);
887
+ return encoderError({
888
+ task,
889
+ type: ErrorKnitting.Serializable,
890
+ onPromise,
891
+ detail,
892
+ });
893
+ }
894
+ case "string": {
895
+ const text = args;
896
+ if (text.length <= staticMaxBytes) {
897
+ const written = writeStaticUtf8(text, slotIndex);
898
+ if (written !== -1) {
899
+ task[TaskIndex.Type] = PayloadBuffer.StaticString;
900
+ task[TaskIndex.PayloadLen] = written;
901
+ task.value = null;
902
+ return true;
903
+ }
904
+ }
905
+ task[TaskIndex.Type] = PayloadBuffer.String;
906
+ const reserveBytes = dynamicUtf8ReserveBytes(task, text, "String");
907
+ if (reserveBytes < 0)
908
+ return false;
909
+ const reservedSlot = reserveDynamic(task, reserveBytes);
910
+ const written = writeDynamicUtf8(text, task[TaskIndex.Start], reserveBytes);
911
+ if (written < 0) {
912
+ return failDynamicWriteAfterReserve(task, reservedSlot);
913
+ }
914
+ task[TaskIndex.PayloadLen] = written;
915
+ setSlotLength(reservedSlot, written);
916
+ task.value = null;
917
+ return true;
918
+ }
919
+ case "symbol": {
920
+ const key = symbolKeyFor(args);
921
+ if (key === undefined) {
922
+ return encoderError({
923
+ task,
924
+ type: ErrorKnitting.Symbol,
925
+ onPromise,
926
+ });
927
+ }
928
+ if (key.length * 3 <= staticMaxBytes) {
929
+ const written = writeStaticUtf8(key, slotIndex);
930
+ if (written !== -1) {
931
+ task[TaskIndex.Type] = PayloadBuffer.StaticSymbol;
932
+ task[TaskIndex.PayloadLen] = written;
933
+ task.value = null;
934
+ return true;
935
+ }
936
+ }
937
+ task[TaskIndex.Type] = PayloadBuffer.Symbol;
938
+ const reserveBytes = dynamicUtf8ReserveBytes(task, key, "Symbol");
939
+ if (reserveBytes < 0)
940
+ return false;
941
+ const reservedSlot = reserveDynamic(task, reserveBytes);
942
+ const written = writeDynamicUtf8(key, task[TaskIndex.Start], reserveBytes);
943
+ if (written < 0) {
944
+ return failDynamicWriteAfterReserve(task, reservedSlot);
945
+ }
946
+ task[TaskIndex.PayloadLen] = written;
947
+ setSlotLength(reservedSlot, written);
948
+ task.value = null;
949
+ return true;
950
+ }
951
+ }
952
+ return false;
953
+ };
954
+ return encodeDispatch;
955
+ };
956
+ export const decodePayload = ({ lockSector, payload, sab, payloadConfig, headersBuffer, headerSlotStrideU32, textCompat, host, }) => {
957
+ const payloadSab = payload?.sab ?? sab;
958
+ const resolvedPayloadConfig = resolvePayloadBufferOptions({
959
+ sab: payloadSab,
960
+ options: payload?.config ?? payloadConfig,
961
+ });
962
+ const { free } = register({
963
+ lockSector,
964
+ });
965
+ const freeTaskSlot = (task) => free(getTaskSlotIndex(task));
966
+ const { readUtf8: readDynamicUtf8, readBytesCopy: readDynamicBytesCopy, readBytesBufferCopy: readDynamicBufferCopy, readBufferCopy: readDynamicBuffer, readBytesArrayBufferCopy: readDynamicArrayBufferCopy, readArrayBufferCopy: readDynamicArrayBuffer, read8BytesFloatCopy: readDynamic8BytesFloatCopy, read8BytesFloatView: readDynamic8BytesFloatView, } = createSharedDynamicBufferIO({
967
+ sab: payloadSab,
968
+ payloadConfig: resolvedPayloadConfig,
969
+ textCompat: textCompat?.payload,
970
+ });
971
+ const { readUtf8: readStaticUtf8, readBytesCopy: readStaticBytesCopy, readBytesBufferCopy: readStaticBufferCopy, readBufferCopy: readStaticBuffer, readUint8ArrayCopy: readStaticUint8ArrayCopy, readBytesArrayBufferCopy: readStaticArrayBufferCopy, readArrayBufferCopy: readStaticArrayBuffer, read8BytesFloatCopy: readStatic8BytesFloatCopy, } = requireStaticIO(headersBuffer, headerSlotStrideU32, textCompat?.headers);
972
+ // TODO: remove slotIndex and make that all their callers
973
+ // store the slot in their Task, to just get it when it comes
974
+ // to the static versions of decoding
975
+ return (task, slotIndex, specialFlags) => {
976
+ switch (task[TaskIndex.Type]) {
977
+ case PayloadSignal.BigInt:
978
+ Uint32View[0] = task[TaskIndex.Start];
979
+ Uint32View[1] = task[TaskIndex.End];
980
+ task.value = BigInt64View[0];
981
+ return;
982
+ case PayloadSignal.True:
983
+ task.value = true;
984
+ return;
985
+ case PayloadSignal.False:
986
+ task.value = false;
987
+ return;
988
+ case PayloadSignal.Float64:
989
+ Uint32View[0] = task[TaskIndex.Start];
990
+ Uint32View[1] = task[TaskIndex.End];
991
+ task.value = Float64View[0];
992
+ return;
993
+ case PayloadSignal.NaN:
994
+ task.value = NaN;
995
+ return;
996
+ case PayloadSignal.Null:
997
+ task.value = null;
998
+ return;
999
+ case PayloadSignal.Undefined:
1000
+ task.value = undefined;
1001
+ return;
1002
+ case PayloadBuffer.String:
1003
+ task.value = readDynamicUtf8(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]);
1004
+ freeTaskSlot(task);
1005
+ return;
1006
+ case PayloadBuffer.StaticString:
1007
+ task.value = readStaticUtf8(0, task[TaskIndex.PayloadLen], slotIndex);
1008
+ return;
1009
+ case PayloadBuffer.Json:
1010
+ task.value = parseJSON(readDynamicUtf8(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]));
1011
+ freeTaskSlot(task);
1012
+ return;
1013
+ case PayloadBuffer.StaticJson:
1014
+ task.value = parseJSON(readStaticUtf8(0, task[TaskIndex.PayloadLen], slotIndex));
1015
+ return;
1016
+ case PayloadBuffer.EnvelopeStaticHeader:
1017
+ case PayloadBuffer.EnvelopeStaticHeaderString: {
1018
+ const rawHeader = readStaticUtf8(0, task[TaskIndex.PayloadLen], slotIndex);
1019
+ const header = task[TaskIndex.Type] === PayloadBuffer.EnvelopeStaticHeaderString
1020
+ ? rawHeader
1021
+ : parseJSON(rawHeader);
1022
+ const payloadLength = task[TaskIndex.End];
1023
+ const payload = payloadLength > 0
1024
+ ? readDynamicArrayBufferCopy(task[TaskIndex.Start], task[TaskIndex.Start] + payloadLength)
1025
+ : new ArrayBuffer(0);
1026
+ task.value = new Envelope(header, payload);
1027
+ freeTaskSlot(task);
1028
+ return;
1029
+ }
1030
+ case PayloadBuffer.EnvelopeDynamicHeader:
1031
+ case PayloadBuffer.EnvelopeDynamicHeaderString: {
1032
+ const headerStart = task[TaskIndex.Start];
1033
+ const payloadStart = headerStart + task[TaskIndex.PayloadLen];
1034
+ const payloadLength = task[TaskIndex.End];
1035
+ const rawHeader = readDynamicUtf8(headerStart, payloadStart);
1036
+ const header = task[TaskIndex.Type] === PayloadBuffer.EnvelopeDynamicHeaderString
1037
+ ? rawHeader
1038
+ : parseJSON(rawHeader);
1039
+ const payload = payloadLength > 0
1040
+ ? readDynamicArrayBufferCopy(payloadStart, payloadStart + payloadLength)
1041
+ : new ArrayBuffer(0);
1042
+ task.value = new Envelope(header, payload);
1043
+ freeTaskSlot(task);
1044
+ return;
1045
+ }
1046
+ case PayloadBuffer.BigInt:
1047
+ task.value = decodeBigIntBinary(readDynamicBufferCopy(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]));
1048
+ freeTaskSlot(task);
1049
+ return;
1050
+ case PayloadBuffer.StaticBigInt:
1051
+ task.value = decodeBigIntBinary(readStaticBufferCopy(0, task[TaskIndex.PayloadLen], slotIndex));
1052
+ return;
1053
+ case PayloadBuffer.Symbol:
1054
+ task.value = symbolFor(readDynamicUtf8(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]));
1055
+ freeTaskSlot(task);
1056
+ return;
1057
+ case PayloadBuffer.StaticSymbol:
1058
+ task.value = symbolFor(readStaticUtf8(0, task[TaskIndex.PayloadLen], slotIndex));
1059
+ return;
1060
+ case PayloadBuffer.Int32Array: {
1061
+ const bytes = readDynamicBufferCopy(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]);
1062
+ task.value = new Int32Array(bytes.buffer, bytes.byteOffset, bytes.byteLength >>> 2);
1063
+ freeTaskSlot(task);
1064
+ return;
1065
+ }
1066
+ case PayloadBuffer.StaticInt32Array: {
1067
+ const bytes = readStaticBufferCopy(0, task[TaskIndex.PayloadLen], slotIndex);
1068
+ task.value = new Int32Array(bytes.buffer, bytes.byteOffset, bytes.byteLength >>> 2);
1069
+ return;
1070
+ }
1071
+ case PayloadBuffer.Float64Array: {
1072
+ task.value = readDynamic8BytesFloatCopy(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]);
1073
+ freeTaskSlot(task);
1074
+ return;
1075
+ }
1076
+ case PayloadBuffer.StaticFloat64Array:
1077
+ task.value = readStatic8BytesFloatCopy(0, task[TaskIndex.PayloadLen], slotIndex);
1078
+ return;
1079
+ case PayloadBuffer.BigInt64Array: {
1080
+ const bytes = readDynamicBufferCopy(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]);
1081
+ task.value = new BigInt64Array(bytes.buffer, bytes.byteOffset, bytes.byteLength >>> 3);
1082
+ freeTaskSlot(task);
1083
+ return;
1084
+ }
1085
+ case PayloadBuffer.StaticBigInt64Array: {
1086
+ const bytes = readStaticBufferCopy(0, task[TaskIndex.PayloadLen], slotIndex);
1087
+ task.value = new BigInt64Array(bytes.buffer, bytes.byteOffset, bytes.byteLength >>> 3);
1088
+ return;
1089
+ }
1090
+ case PayloadBuffer.BigUint64Array: {
1091
+ const bytes = readDynamicBufferCopy(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]);
1092
+ task.value = new BigUint64Array(bytes.buffer, bytes.byteOffset, bytes.byteLength >>> 3);
1093
+ freeTaskSlot(task);
1094
+ return;
1095
+ }
1096
+ case PayloadBuffer.StaticBigUint64Array: {
1097
+ const bytes = readStaticBufferCopy(0, task[TaskIndex.PayloadLen], slotIndex);
1098
+ task.value = new BigUint64Array(bytes.buffer, bytes.byteOffset, bytes.byteLength >>> 3);
1099
+ return;
1100
+ }
1101
+ case PayloadBuffer.DataView: {
1102
+ const bytes = readDynamicBufferCopy(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]);
1103
+ task.value = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
1104
+ freeTaskSlot(task);
1105
+ return;
1106
+ }
1107
+ case PayloadBuffer.StaticDataView: {
1108
+ const bytes = readStaticBufferCopy(0, task[TaskIndex.PayloadLen], slotIndex);
1109
+ task.value = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
1110
+ return;
1111
+ }
1112
+ case PayloadBuffer.ExternalPayload:
1113
+ task.value = decodeExternalPayload(readDynamicUtf8(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]));
1114
+ freeTaskSlot(task);
1115
+ return;
1116
+ case PayloadBuffer.StaticExternalPayload:
1117
+ task.value = decodeExternalPayload(readStaticUtf8(0, task[TaskIndex.PayloadLen], slotIndex));
1118
+ return;
1119
+ case PayloadBuffer.ProcessSharedBuffer:
1120
+ task.value = decodeProcessSharedBufferNumeric(readStaticBytesCopy(0, task[TaskIndex.PayloadLen], slotIndex));
1121
+ return;
1122
+ case PayloadBuffer.Date:
1123
+ Uint32View[0] = task[TaskIndex.Start];
1124
+ Uint32View[1] = task[TaskIndex.End];
1125
+ task.value = new Date(Float64View[0]);
1126
+ return;
1127
+ case PayloadBuffer.Error:
1128
+ task.value = parseErrorPayload(readDynamicUtf8(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]));
1129
+ freeTaskSlot(task);
1130
+ return;
1131
+ case PayloadBuffer.Binary:
1132
+ {
1133
+ const buffer = readDynamicBufferCopy(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]);
1134
+ task.value = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
1135
+ }
1136
+ freeTaskSlot(task);
1137
+ return;
1138
+ case PayloadBuffer.StaticBinary:
1139
+ task.value = readStaticUint8ArrayCopy(0, task[TaskIndex.PayloadLen], slotIndex);
1140
+ return;
1141
+ case PayloadBuffer.ArrayBuffer:
1142
+ task.value = readDynamicArrayBuffer(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]);
1143
+ freeTaskSlot(task);
1144
+ return;
1145
+ case PayloadBuffer.StaticArrayBuffer:
1146
+ task.value = readStaticArrayBuffer(0, task[TaskIndex.PayloadLen], slotIndex);
1147
+ return;
1148
+ case PayloadBuffer.Buffer:
1149
+ task.value = readDynamicBuffer(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]);
1150
+ freeTaskSlot(task);
1151
+ return;
1152
+ case PayloadBuffer.StaticBuffer:
1153
+ task.value = readStaticBuffer(0, task[TaskIndex.PayloadLen], slotIndex);
1154
+ return;
1155
+ }
1156
+ };
1157
+ };