knitting 0.1.55 → 0.1.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/knitting.d.ts +6 -797
  2. package/knitting.js +6 -9780
  3. package/map.md +12 -8
  4. package/package.json +14 -6
  5. package/process-shared-buffer.d.ts +1 -0
  6. package/process-shared-buffer.js +1 -0
  7. package/shared-memory.d.ts +1 -155
  8. package/shared-memory.js +1 -1342
  9. package/src/api.d.ts +69 -0
  10. package/src/api.js +619 -0
  11. package/src/common/envelope.d.ts +17 -0
  12. package/src/common/envelope.js +22 -0
  13. package/src/common/module-url.d.ts +1 -0
  14. package/src/common/module-url.js +24 -0
  15. package/src/common/node-compat.d.ts +20 -0
  16. package/src/common/node-compat.js +24 -0
  17. package/src/common/path-canonical.d.ts +6 -0
  18. package/src/common/path-canonical.js +41 -0
  19. package/src/common/runtime.d.ts +15 -0
  20. package/src/common/runtime.js +91 -0
  21. package/src/common/shared-buffer-region.d.ts +11 -0
  22. package/src/common/shared-buffer-region.js +21 -0
  23. package/src/common/shared-buffer-text.d.ts +16 -0
  24. package/src/common/shared-buffer-text.js +65 -0
  25. package/src/common/task-source.d.ts +3 -0
  26. package/src/common/task-source.js +84 -0
  27. package/src/common/task-symbol.d.ts +1 -0
  28. package/src/common/task-symbol.js +1 -0
  29. package/src/common/with-resolvers.d.ts +9 -0
  30. package/src/common/with-resolvers.js +23 -0
  31. package/src/common/worker-runtime.d.ts +42 -0
  32. package/src/common/worker-runtime.js +61 -0
  33. package/src/connections/buffer-reference-native.d.ts +56 -0
  34. package/src/connections/buffer-reference-native.js +217 -0
  35. package/src/connections/buffer-reference.d.ts +78 -0
  36. package/src/connections/buffer-reference.js +461 -0
  37. package/src/connections/bun.d.ts +22 -0
  38. package/src/connections/bun.js +214 -0
  39. package/src/connections/deno.d.ts +22 -0
  40. package/src/connections/deno.js +205 -0
  41. package/src/connections/file-descriptor.d.ts +39 -0
  42. package/src/connections/file-descriptor.js +161 -0
  43. package/src/connections/index.d.ts +4 -0
  44. package/src/connections/index.js +4 -0
  45. package/src/connections/node-addons.d.ts +5 -0
  46. package/src/connections/node-addons.js +44 -0
  47. package/src/connections/node-buffer-pointer.d.ts +20 -0
  48. package/src/connections/node-buffer-pointer.js +16 -0
  49. package/src/connections/node.d.ts +30 -0
  50. package/src/connections/node.js +62 -0
  51. package/src/connections/numeric-array.d.ts +5 -0
  52. package/src/connections/numeric-array.js +17 -0
  53. package/src/connections/package-assets.d.ts +2 -0
  54. package/src/connections/package-assets.js +45 -0
  55. package/src/connections/posix.d.ts +32 -0
  56. package/src/connections/posix.js +77 -0
  57. package/src/connections/process-shared-buffer.d.ts +75 -0
  58. package/src/connections/process-shared-buffer.js +279 -0
  59. package/src/connections/shared-array-buffer-payload.d.ts +36 -0
  60. package/src/connections/shared-array-buffer-payload.js +235 -0
  61. package/src/connections/types.d.ts +50 -0
  62. package/src/connections/types.js +37 -0
  63. package/src/connections/windows.d.ts +28 -0
  64. package/src/connections/windows.js +224 -0
  65. package/src/debug/env-diff.d.ts +26 -0
  66. package/src/debug/env-diff.js +49 -0
  67. package/src/debug/gate.d.ts +18 -0
  68. package/src/debug/gate.js +69 -0
  69. package/src/debug/handle.d.ts +23 -0
  70. package/src/debug/handle.js +48 -0
  71. package/src/error.d.ts +13 -0
  72. package/src/error.js +49 -0
  73. package/src/ipc/tools/ring-queue.d.ts +33 -0
  74. package/src/ipc/tools/ring-queue.js +159 -0
  75. package/src/ipc/transport/shared-memory.d.ts +23 -0
  76. package/src/ipc/transport/shared-memory.js +35 -0
  77. package/src/memory/byte-carpet.d.ts +73 -0
  78. package/src/memory/byte-carpet.js +157 -0
  79. package/src/memory/lock.d.ts +203 -0
  80. package/src/memory/lock.js +741 -0
  81. package/src/memory/payload-config.d.ts +31 -0
  82. package/src/memory/payload-config.js +67 -0
  83. package/src/memory/payloadCodec.d.ts +46 -0
  84. package/src/memory/payloadCodec.js +1377 -0
  85. package/src/memory/regionRegistry.d.ts +17 -0
  86. package/src/memory/regionRegistry.js +285 -0
  87. package/src/memory/shared-buffer-io.d.ts +55 -0
  88. package/src/memory/shared-buffer-io.js +403 -0
  89. package/src/permission/index.d.ts +2 -0
  90. package/src/permission/index.js +2 -0
  91. package/src/permission/protocol.d.ts +166 -0
  92. package/src/permission/protocol.js +650 -0
  93. package/src/runtime/balancer.d.ts +19 -0
  94. package/src/runtime/balancer.js +149 -0
  95. package/src/runtime/dispatcher.d.ts +40 -0
  96. package/src/runtime/dispatcher.js +142 -0
  97. package/src/runtime/inline-executor.d.ts +10 -0
  98. package/src/runtime/inline-executor.js +282 -0
  99. package/src/runtime/pool.d.ts +39 -0
  100. package/src/runtime/pool.js +404 -0
  101. package/src/runtime/process-worker.d.ts +92 -0
  102. package/src/runtime/process-worker.js +673 -0
  103. package/src/runtime/tx-queue.d.ts +26 -0
  104. package/src/runtime/tx-queue.js +155 -0
  105. package/src/shared/abortSignal.d.ts +23 -0
  106. package/src/shared/abortSignal.js +134 -0
  107. package/src/types.d.ts +357 -0
  108. package/src/types.js +2 -0
  109. package/src/utils/http.d.ts +29 -0
  110. package/src/utils/http.js +100 -0
  111. package/src/worker/bootstrap.d.ts +5 -0
  112. package/src/worker/bootstrap.js +78 -0
  113. package/src/worker/composable-runners.d.ts +12 -0
  114. package/src/worker/composable-runners.js +97 -0
  115. package/src/worker/loop.d.ts +2 -0
  116. package/src/worker/loop.js +382 -0
  117. package/src/worker/process-worker-bootstrap.d.ts +8 -0
  118. package/src/worker/process-worker-bootstrap.js +160 -0
  119. package/src/worker/rx-queue.d.ts +25 -0
  120. package/src/worker/rx-queue.js +173 -0
  121. package/src/worker/safety/index.d.ts +4 -0
  122. package/src/worker/safety/index.js +4 -0
  123. package/src/worker/safety/performance.d.ts +1 -0
  124. package/src/worker/safety/performance.js +17 -0
  125. package/src/worker/safety/process.d.ts +2 -0
  126. package/src/worker/safety/process.js +79 -0
  127. package/src/worker/safety/startup.d.ts +16 -0
  128. package/src/worker/safety/startup.js +30 -0
  129. package/src/worker/safety/worker-data.d.ts +2 -0
  130. package/src/worker/safety/worker-data.js +36 -0
  131. package/src/worker/task-loader.d.ts +27 -0
  132. package/src/worker/task-loader.js +70 -0
  133. package/src/worker/timers.d.ts +18 -0
  134. package/src/worker/timers.js +116 -0
  135. package/unsafe.d.ts +1 -71
  136. package/unsafe.js +1 -878
  137. package/utils.d.ts +1 -31
  138. package/utils.js +1 -116
@@ -0,0 +1,17 @@
1
+ import type { BufferReference } from "../connections/buffer-reference.js";
2
+ import type { ProcessSharedBuffer } from "../connections/process-shared-buffer.js";
3
+ type EnvelopeHeaderPrimitive = string | number | boolean | null;
4
+ type EnvelopeHeaderValue = EnvelopeHeaderPrimitive | EnvelopeHeaderValue[] | {
5
+ [key: string]: EnvelopeHeaderValue;
6
+ };
7
+ export type EnvelopeHeader = EnvelopeHeaderValue;
8
+ export type EnvelopeBody = ArrayBuffer | SharedArrayBuffer | BufferReference | ProcessSharedBuffer;
9
+ declare const PayloadTransportFinalizer: unique symbol;
10
+ export declare class Envelope<H extends EnvelopeHeader = EnvelopeHeader, B extends EnvelopeBody = ArrayBuffer> {
11
+ readonly header: H;
12
+ readonly payload: B;
13
+ constructor(header: H, payload: B);
14
+ [Symbol.dispose](): void;
15
+ [PayloadTransportFinalizer](): (() => void) | undefined;
16
+ }
17
+ export {};
@@ -0,0 +1,22 @@
1
+ const PayloadTransportFinalizer = Symbol.for("knitting.payloadCodec.transportFinalizer");
2
+ export class Envelope {
3
+ header;
4
+ payload;
5
+ constructor(header, payload) {
6
+ this.header = header;
7
+ this.payload = payload;
8
+ }
9
+ [Symbol.dispose]() {
10
+ const body = this.payload;
11
+ if (body !== null && typeof body === "object") {
12
+ body[Symbol.dispose]?.();
13
+ }
14
+ }
15
+ [PayloadTransportFinalizer]() {
16
+ const body = this.payload;
17
+ if (body === null || typeof body !== "object")
18
+ return undefined;
19
+ const finalizer = body[PayloadTransportFinalizer];
20
+ return typeof finalizer === "function" ? finalizer.call(body) : undefined;
21
+ }
22
+ }
@@ -0,0 +1 @@
1
+ export declare const toModuleUrl: (specifier: string) => string;
@@ -0,0 +1,24 @@
1
+ import { pathToFileURL } from "node:url";
2
+ const WINDOWS_DRIVE_PATH = /^[A-Za-z]:[\\/]/;
3
+ const WINDOWS_UNC_PATH = /^\\\\[^\\/?]+\\[^\\/?]+/;
4
+ const encodeFilePath = (path) => encodeURI(path)
5
+ .replace(/\?/g, "%3F")
6
+ .replace(/#/g, "%23");
7
+ export const toModuleUrl = (specifier) => {
8
+ if (WINDOWS_DRIVE_PATH.test(specifier)) {
9
+ const normalized = specifier.replace(/\\/g, "/");
10
+ return `file:///${encodeFilePath(normalized)}`;
11
+ }
12
+ if (WINDOWS_UNC_PATH.test(specifier)) {
13
+ const normalized = specifier
14
+ .replace(/^\\\\+/, "")
15
+ .replace(/\\/g, "/");
16
+ return `file://${encodeFilePath(normalized)}`;
17
+ }
18
+ try {
19
+ return new URL(specifier).href;
20
+ }
21
+ catch {
22
+ return pathToFileURL(specifier).href;
23
+ }
24
+ };
@@ -0,0 +1,20 @@
1
+ export type NodeProcessLike = {
2
+ getBuiltinModule?: (id: string) => unknown;
3
+ versions?: {
4
+ node?: string;
5
+ };
6
+ platform?: string;
7
+ allowedNodeEnvironmentFlags?: ReadonlySet<string>;
8
+ execArgv?: string[];
9
+ execPath?: string;
10
+ cwd?: () => string;
11
+ env?: Record<string, string | undefined>;
12
+ on?: (event: string, handler: (...args: unknown[]) => void) => unknown;
13
+ };
14
+ export type NodeCallSiteLike = {
15
+ getFileName?: () => string | null | undefined;
16
+ getFunctionName?: () => string | null | undefined;
17
+ getMethodName?: () => string | null | undefined;
18
+ };
19
+ export declare const getNodeProcess: () => NodeProcessLike | undefined;
20
+ export declare const getNodeBuiltinModule: <T>(specifier: string) => T | undefined;
@@ -0,0 +1,24 @@
1
+ const nodeProcess = (() => {
2
+ const candidate = globalThis
3
+ .process;
4
+ return typeof candidate?.versions?.node === "string" ? candidate : undefined;
5
+ })();
6
+ export const getNodeProcess = () => nodeProcess;
7
+ export const getNodeBuiltinModule = (specifier) => {
8
+ const getter = nodeProcess?.getBuiltinModule;
9
+ if (typeof getter !== "function")
10
+ return undefined;
11
+ try {
12
+ return getter.call(nodeProcess, specifier);
13
+ }
14
+ catch {
15
+ }
16
+ if (!specifier.startsWith("node:"))
17
+ return undefined;
18
+ try {
19
+ return getter.call(nodeProcess, specifier.slice(5));
20
+ }
21
+ catch {
22
+ return undefined;
23
+ }
24
+ };
@@ -0,0 +1,6 @@
1
+ type CanonicalPathFsApi = {
2
+ existsSync?: (candidate: string) => boolean;
3
+ realpathSync?: (candidate: string) => string;
4
+ };
5
+ export declare const toCanonicalPath: (candidate: string, fsApi?: CanonicalPathFsApi) => string;
6
+ export {};
@@ -0,0 +1,41 @@
1
+ import { existsSync, realpathSync, } from "node:fs";
2
+ import { basename as pathBasename, dirname as pathDirname, join as pathJoin, resolve as pathResolve, } from "node:path";
3
+ export const toCanonicalPath = (candidate, fsApi = {
4
+ existsSync,
5
+ realpathSync: realpathSync.native ?? realpathSync,
6
+ }) => {
7
+ const absolute = pathResolve(candidate);
8
+ const { existsSync, realpathSync } = fsApi;
9
+ if (typeof realpathSync === "function") {
10
+ try {
11
+ return pathResolve(realpathSync(absolute));
12
+ }
13
+ catch {
14
+ }
15
+ }
16
+ else {
17
+ return absolute;
18
+ }
19
+ if (typeof existsSync !== "function")
20
+ return absolute;
21
+ const missingSegments = [];
22
+ let cursor = absolute;
23
+ while (!existsSync(cursor)) {
24
+ const parent = pathDirname(cursor);
25
+ if (parent === cursor)
26
+ return absolute;
27
+ missingSegments.push(pathBasename(cursor));
28
+ cursor = parent;
29
+ }
30
+ let base = cursor;
31
+ try {
32
+ base = realpathSync(cursor);
33
+ }
34
+ catch {
35
+ }
36
+ let rebuilt = base;
37
+ for (let i = missingSegments.length - 1; i >= 0; i--) {
38
+ rebuilt = pathJoin(rebuilt, missingSegments[i]);
39
+ }
40
+ return pathResolve(rebuilt);
41
+ };
@@ -0,0 +1,15 @@
1
+ type RuntimeName = "deno" | "bun" | "node" | "unknown";
2
+ export declare const IS_DENO: boolean;
3
+ export declare const IS_BUN: boolean;
4
+ export declare const IS_NODE: boolean;
5
+ export declare const RUNTIME: RuntimeName;
6
+ export declare const SET_IMMEDIATE: typeof setImmediate & ((cb: () => void) => void);
7
+ export declare const HAS_SHARED_WASM_MEMORY: boolean;
8
+ export declare const createWasmSharedArrayBuffer: (byteLength: number, maxByteLength?: number) => SharedArrayBuffer;
9
+ export declare const HAS_SAB_GROW: boolean;
10
+ export declare const createSharedArrayBuffer: (byteLength: number, maxByteLength?: number) => SharedArrayBuffer;
11
+ export declare const isWasmSharedArrayBuffer: (sab: SharedArrayBuffer) => boolean;
12
+ export declare const isGrowableSharedArrayBuffer: (sab: SharedArrayBuffer) => boolean;
13
+ export declare const sharedArrayBufferMaxByteLength: (sab: SharedArrayBuffer) => number;
14
+ export declare const growSharedArrayBuffer: (sab: SharedArrayBuffer, byteLength: number) => SharedArrayBuffer;
15
+ export {};
@@ -0,0 +1,91 @@
1
+ import { getNodeProcess } from "./node-compat.js";
2
+ const globals = globalThis;
3
+ const nodeProcess = getNodeProcess();
4
+ export const IS_DENO = typeof globals.Deno?.version?.deno === "string";
5
+ export const IS_BUN = typeof globals.Bun?.version === "string";
6
+ export const IS_NODE = typeof nodeProcess?.versions?.node === "string";
7
+ export const RUNTIME = (IS_DENO ? "deno" : IS_BUN ? "bun" : IS_NODE ? "node" : "unknown");
8
+ export const SET_IMMEDIATE = typeof globals.setImmediate === "function" ? globals.setImmediate : undefined;
9
+ const WASM_MEMORY_PAGE_BYTES = 64 * 1024;
10
+ const wasmSharedBufferMemory = new WeakMap();
11
+ const wasmSharedBufferMaxByteLength = new WeakMap();
12
+ const hasSharedWasmMemory = (() => {
13
+ if (typeof WebAssembly?.Memory !== "function")
14
+ return false;
15
+ try {
16
+ void new WebAssembly.Memory({ initial: 0, maximum: 1, shared: true });
17
+ return true;
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ })();
23
+ export const HAS_SHARED_WASM_MEMORY = hasSharedWasmMemory;
24
+ const roundupWasmPages = (byteLength) => Math.ceil(Math.max(0, byteLength) / WASM_MEMORY_PAGE_BYTES);
25
+ const createSharedWasmBuffer = (byteLength, maxByteLength) => {
26
+ const memory = new WebAssembly.Memory({
27
+ initial: roundupWasmPages(byteLength),
28
+ maximum: Math.max(roundupWasmPages(byteLength), roundupWasmPages(maxByteLength)),
29
+ shared: true,
30
+ });
31
+ const buffer = memory.buffer;
32
+ wasmSharedBufferMemory.set(buffer, memory);
33
+ wasmSharedBufferMaxByteLength.set(buffer, maxByteLength);
34
+ return buffer;
35
+ };
36
+ export const createWasmSharedArrayBuffer = (byteLength, maxByteLength = byteLength) => {
37
+ if (hasSharedWasmMemory) {
38
+ return createSharedWasmBuffer(byteLength, maxByteLength);
39
+ }
40
+ return new SharedArrayBuffer(byteLength);
41
+ };
42
+ const HAS_NATIVE_SAB_GROW = typeof SharedArrayBuffer === "function" &&
43
+ typeof SharedArrayBuffer.prototype.grow === "function";
44
+ export const HAS_SAB_GROW = HAS_NATIVE_SAB_GROW || hasSharedWasmMemory;
45
+ export const createSharedArrayBuffer = (byteLength, maxByteLength) => {
46
+ if (HAS_NATIVE_SAB_GROW && typeof maxByteLength === "number") {
47
+ return new SharedArrayBuffer(byteLength, { maxByteLength });
48
+ }
49
+ if (hasSharedWasmMemory && typeof maxByteLength === "number") {
50
+ return createSharedWasmBuffer(byteLength, maxByteLength);
51
+ }
52
+ return new SharedArrayBuffer(byteLength);
53
+ };
54
+ export const isWasmSharedArrayBuffer = (sab) => wasmSharedBufferMemory.has(sab);
55
+ export const isGrowableSharedArrayBuffer = (sab) => {
56
+ const value = sab;
57
+ return (HAS_NATIVE_SAB_GROW &&
58
+ typeof value.grow === "function" &&
59
+ value.growable === true) ||
60
+ wasmSharedBufferMemory.has(sab);
61
+ };
62
+ export const sharedArrayBufferMaxByteLength = (sab) => {
63
+ const value = sab;
64
+ if (typeof value.maxByteLength === "number") {
65
+ return value.maxByteLength;
66
+ }
67
+ return wasmSharedBufferMaxByteLength.get(sab) ?? sab.byteLength;
68
+ };
69
+ export const growSharedArrayBuffer = (sab, byteLength) => {
70
+ const native = sab;
71
+ if (typeof native.grow === "function") {
72
+ native.grow(byteLength);
73
+ return sab;
74
+ }
75
+ const memory = wasmSharedBufferMemory.get(sab);
76
+ if (memory == null) {
77
+ throw new TypeError("SharedArrayBuffer is not growable");
78
+ }
79
+ const currentBuffer = memory.buffer;
80
+ if (currentBuffer.byteLength >= byteLength) {
81
+ return currentBuffer;
82
+ }
83
+ const targetPages = roundupWasmPages(byteLength);
84
+ const currentPages = roundupWasmPages(currentBuffer.byteLength);
85
+ memory.grow(targetPages - currentPages);
86
+ const nextBuffer = memory.buffer;
87
+ const maxByteLength = wasmSharedBufferMaxByteLength.get(sab) ?? currentBuffer.byteLength;
88
+ wasmSharedBufferMemory.set(nextBuffer, memory);
89
+ wasmSharedBufferMaxByteLength.set(nextBuffer, maxByteLength);
90
+ return nextBuffer;
91
+ };
@@ -0,0 +1,11 @@
1
+ export type SharedBuffer = SharedArrayBuffer | ArrayBuffer;
2
+ export type SharedBufferRegion = {
3
+ sab: SharedBuffer;
4
+ byteOffset: number;
5
+ byteLength: number;
6
+ };
7
+ export type SharedBufferSource = SharedBuffer | SharedBufferRegion;
8
+ export declare const isSharedBuffer: (value: unknown) => value is SharedBuffer;
9
+ export declare const isSharedBufferRegion: (value: unknown) => value is SharedBufferRegion;
10
+ export declare const isSharedBufferSource: (value: unknown) => value is SharedBufferSource;
11
+ export declare const toSharedBufferRegion: (value: SharedBufferSource) => SharedBufferRegion;
@@ -0,0 +1,21 @@
1
+ export const isSharedBuffer = (value) => value instanceof SharedArrayBuffer || value instanceof ArrayBuffer;
2
+ export const isSharedBufferRegion = (value) => {
3
+ if (!value || typeof value !== "object")
4
+ return false;
5
+ const candidate = value;
6
+ return isSharedBuffer(candidate.sab) &&
7
+ typeof candidate.byteOffset === "number" &&
8
+ Number.isInteger(candidate.byteOffset) &&
9
+ candidate.byteOffset >= 0 &&
10
+ typeof candidate.byteLength === "number" &&
11
+ Number.isInteger(candidate.byteLength) &&
12
+ candidate.byteLength >= 0;
13
+ };
14
+ export const isSharedBufferSource = (value) => isSharedBuffer(value) || isSharedBufferRegion(value);
15
+ export const toSharedBufferRegion = (value) => isSharedBuffer(value)
16
+ ? {
17
+ sab: value,
18
+ byteOffset: 0,
19
+ byteLength: value.byteLength,
20
+ }
21
+ : value;
@@ -0,0 +1,16 @@
1
+ import { type SharedBufferSource } from "./shared-buffer-region.js";
2
+ export type SharedBufferTextCompat = {
3
+ encodeInto: boolean;
4
+ decode: boolean;
5
+ };
6
+ export type LockBufferTextCompat = {
7
+ headers: SharedBufferTextCompat;
8
+ payload: SharedBufferTextCompat;
9
+ };
10
+ export declare const isSharedBufferTextCompat: (value: unknown) => value is SharedBufferTextCompat;
11
+ export declare const isLockBufferTextCompat: (value: unknown) => value is LockBufferTextCompat;
12
+ export declare const probeSharedBufferTextCompat: (source: SharedBufferSource) => SharedBufferTextCompat;
13
+ export declare const probeLockBufferTextCompat: ({ headers, payload, }: {
14
+ headers: SharedBufferSource;
15
+ payload: SharedBufferSource;
16
+ }) => LockBufferTextCompat;
@@ -0,0 +1,65 @@
1
+ import { toSharedBufferRegion, } from "./shared-buffer-region.js";
2
+ const textEncode = new TextEncoder();
3
+ const textDecode = new TextDecoder();
4
+ const isSharedBufferTextCompatTypeError = (error) => error instanceof TypeError;
5
+ const makeProbeView = (source) => {
6
+ const region = toSharedBufferRegion(source);
7
+ const probeLength = Math.min(1, region.byteLength);
8
+ return new Uint8Array(region.sab, region.byteOffset, probeLength);
9
+ };
10
+ export const isSharedBufferTextCompat = (value) => {
11
+ if (!value || typeof value !== "object")
12
+ return false;
13
+ const candidate = value;
14
+ return typeof candidate.encodeInto === "boolean" &&
15
+ typeof candidate.decode === "boolean";
16
+ };
17
+ export const isLockBufferTextCompat = (value) => {
18
+ if (!value || typeof value !== "object")
19
+ return false;
20
+ const candidate = value;
21
+ return isSharedBufferTextCompat(candidate.headers) &&
22
+ isSharedBufferTextCompat(candidate.payload);
23
+ };
24
+ export const probeSharedBufferTextCompat = (source) => {
25
+ const view = makeProbeView(source);
26
+ const encodeInto = (() => {
27
+ if (typeof textEncode.encodeInto !== "function")
28
+ return false;
29
+ const probe = view.byteLength > 0 ? view : view.subarray(0, 0);
30
+ const restoredByte = probe.byteLength > 0 ? probe[0] : undefined;
31
+ try {
32
+ textEncode.encodeInto(probe.byteLength > 0 ? "a" : "", probe);
33
+ return true;
34
+ }
35
+ catch (error) {
36
+ if (!isSharedBufferTextCompatTypeError(error))
37
+ throw error;
38
+ return false;
39
+ }
40
+ finally {
41
+ if (restoredByte !== undefined) {
42
+ probe[0] = restoredByte;
43
+ }
44
+ }
45
+ })();
46
+ const decode = (() => {
47
+ try {
48
+ textDecode.decode(view);
49
+ return true;
50
+ }
51
+ catch (error) {
52
+ if (!isSharedBufferTextCompatTypeError(error))
53
+ throw error;
54
+ return false;
55
+ }
56
+ })();
57
+ return {
58
+ encodeInto,
59
+ decode,
60
+ };
61
+ };
62
+ export const probeLockBufferTextCompat = ({ headers, payload, }) => ({
63
+ headers: probeSharedBufferTextCompat(headers),
64
+ payload: probeSharedBufferTextCompat(payload),
65
+ });
@@ -0,0 +1,3 @@
1
+ export declare const genTaskID: () => number;
2
+ export declare const getCallerHref: (offset?: number) => string;
3
+ export declare const getCallerFilePath: (offset?: number) => [string, number];
@@ -0,0 +1,84 @@
1
+ import { toModuleUrl } from "./module-url.js";
2
+ export const genTaskID = ((counter) => () => counter++)(0);
3
+ const INTERNAL_CALLER_HINTS = [
4
+ "/src/common/task-source.ts",
5
+ "/src/common/task-source.js",
6
+ "\\src\\common\\task-source.ts",
7
+ "\\src\\common\\task-source.js",
8
+ "/src/api.ts",
9
+ "/src/api.js",
10
+ "\\src\\api.ts",
11
+ "\\src\\api.js",
12
+ ];
13
+ const INTERNAL_CALLER_FUNCTIONS = new Set([
14
+ "collectStackFrames",
15
+ "resolveCallerHref",
16
+ "getCallerFilePath",
17
+ "buildTaskDefinition",
18
+ "buildTaskDefinitionFromCaller",
19
+ "task",
20
+ "importTask",
21
+ ]);
22
+ const isDefined = (value) => value !== undefined;
23
+ const isInternalCallerFrame = (file) => INTERNAL_CALLER_HINTS.some((hint) => file.includes(hint));
24
+ const isRuntimeInternalFrame = (file) => file.startsWith("node:") ||
25
+ file.startsWith("native:") ||
26
+ file.startsWith("bun:") ||
27
+ file.startsWith("internal/");
28
+ const isInternalCallerFunction = (functionName, methodName) => (functionName !== undefined && INTERNAL_CALLER_FUNCTIONS.has(functionName)) ||
29
+ (methodName !== undefined && INTERNAL_CALLER_FUNCTIONS.has(methodName));
30
+ const collectStackFrames = () => {
31
+ const ErrorCtor = Error;
32
+ const original = ErrorCtor.prepareStackTrace;
33
+ try {
34
+ ErrorCtor.prepareStackTrace = (_error, stack) => stack;
35
+ const stack = new Error().stack;
36
+ if (!Array.isArray(stack))
37
+ return [];
38
+ const frames = stack
39
+ .map((site) => {
40
+ try {
41
+ const file = site?.getFileName?.();
42
+ if (typeof file !== "string" || file.length === 0)
43
+ return undefined;
44
+ return {
45
+ file,
46
+ functionName: site?.getFunctionName?.() ?? undefined,
47
+ methodName: site?.getMethodName?.() ?? undefined,
48
+ };
49
+ }
50
+ catch {
51
+ return undefined;
52
+ }
53
+ })
54
+ .filter(isDefined);
55
+ return frames;
56
+ }
57
+ finally {
58
+ ErrorCtor.prepareStackTrace = original;
59
+ }
60
+ };
61
+ const isInternalFrame = (frame) => isRuntimeInternalFrame(frame.file) ||
62
+ isInternalCallerFrame(frame.file) ||
63
+ isInternalCallerFunction(frame.functionName, frame.methodName);
64
+ const resolveCallerHref = (offset) => {
65
+ const frames = collectStackFrames();
66
+ const direct = frames[offset];
67
+ const caller = (direct && !isInternalFrame(direct)
68
+ ? direct.file
69
+ : undefined) ??
70
+ frames.find((frame) => !isInternalFrame(frame))?.file ??
71
+ frames.find((frame) => !isRuntimeInternalFrame(frame.file))?.file;
72
+ if (!caller) {
73
+ throw new Error("Unable to determine caller file.");
74
+ }
75
+ return toModuleUrl(caller);
76
+ };
77
+ const linkingMap = new Map();
78
+ export const getCallerHref = (offset = 3) => resolveCallerHref(offset);
79
+ export const getCallerFilePath = (offset = 3) => {
80
+ const href = resolveCallerHref(offset);
81
+ const at = linkingMap.get(href) ?? 0;
82
+ linkingMap.set(href, at + 1);
83
+ return [href, at];
84
+ };
@@ -0,0 +1 @@
1
+ export declare const endpointSymbol: unique symbol;
@@ -0,0 +1 @@
1
+ export const endpointSymbol = Symbol.for("task");
@@ -0,0 +1,9 @@
1
+ export type PromiseWithMaybeReject<T> = Promise<T> & {
2
+ reject: (reason?: unknown) => void;
3
+ };
4
+ export type Deferred<T> = {
5
+ promise: PromiseWithMaybeReject<T>;
6
+ resolve: (value: T | PromiseLike<T>) => void;
7
+ reject: (reason?: unknown) => void;
8
+ };
9
+ export declare const withResolvers: <T = unknown>() => Deferred<T>;
@@ -0,0 +1,23 @@
1
+ const attachReject = (promise, reject) => {
2
+ const deferredPromise = promise;
3
+ deferredPromise.reject = reject;
4
+ return deferredPromise;
5
+ };
6
+ export const withResolvers = () => {
7
+ const native = Promise.withResolvers;
8
+ if (typeof native === "function") {
9
+ const deferred = native.call(Promise);
10
+ return {
11
+ promise: attachReject(deferred.promise, deferred.reject),
12
+ resolve: deferred.resolve,
13
+ reject: deferred.reject,
14
+ };
15
+ }
16
+ let resolve;
17
+ let reject;
18
+ const promise = attachReject(new Promise((res, rej) => {
19
+ resolve = res;
20
+ reject = rej;
21
+ }), reject);
22
+ return { promise, resolve, reject };
23
+ };
@@ -0,0 +1,42 @@
1
+ type RuntimePortMessageHandler = (message: unknown) => void;
2
+ export type RuntimeMessagePortLike = {
3
+ postMessage: (message: unknown) => void;
4
+ close?: () => void;
5
+ start?: () => void;
6
+ on?: (event: string, handler: (...args: unknown[]) => void) => void;
7
+ onmessage?: ((event: {
8
+ data?: unknown;
9
+ }) => void) | null;
10
+ addEventListener?: (type: string, listener: (event: {
11
+ data?: unknown;
12
+ error?: unknown;
13
+ message?: unknown;
14
+ }) => void) => void;
15
+ removeEventListener?: (type: string, listener: (event: {
16
+ data?: unknown;
17
+ error?: unknown;
18
+ message?: unknown;
19
+ }) => void) => void;
20
+ };
21
+ export type RuntimeWorkerLike = RuntimeMessagePortLike & {
22
+ terminate: () => unknown;
23
+ };
24
+ export type RuntimeMessageChannelLike = {
25
+ port1: RuntimeMessagePortLike;
26
+ port2: RuntimeMessagePortLike;
27
+ };
28
+ export declare const RUNTIME_PROCESS_WORKER_ENV = "KNITTING_PROCESS_WORKER";
29
+ export declare const RUNTIME_PROCESS_WORKER_BOOT_ENV = "KNITTING_PROCESS_WORKER_BOOT";
30
+ export declare const RUNTIME_PROCESS_WORKER_BOOT_VERSION = 1;
31
+ export declare const RUNTIME_POOL_DEPTH_ENV = "KNITTING_POOL_DEPTH";
32
+ export declare const RUNTIME_IS_PROCESS_WORKER: boolean;
33
+ export declare const RUNTIME_POOL_DEPTH: number;
34
+ export declare const RUNTIME_WORKER: new (specifier: string | URL, options?: Record<string, unknown>) => RuntimeWorkerLike;
35
+ export declare const RUNTIME_MESSAGE_CHANNEL: new () => RuntimeMessageChannelLike;
36
+ export declare const HAS_NODE_WORKER_THREADS: boolean;
37
+ export declare const RUNTIME_IS_MAIN_THREAD: boolean;
38
+ export declare const RUNTIME_WORKER_DATA: unknown;
39
+ export declare const RUNTIME_PARENT_PORT: RuntimeMessagePortLike;
40
+ export declare const createRuntimeMessageChannel: () => RuntimeMessageChannelLike;
41
+ export declare const addRuntimeDataListener: (target: RuntimeMessagePortLike, handler: RuntimePortMessageHandler) => void;
42
+ export {};
@@ -0,0 +1,61 @@
1
+ import { getNodeBuiltinModule, getNodeProcess } from "./node-compat.js";
2
+ export const RUNTIME_PROCESS_WORKER_ENV = "KNITTING_PROCESS_WORKER";
3
+ export const RUNTIME_PROCESS_WORKER_BOOT_ENV = "KNITTING_PROCESS_WORKER_BOOT";
4
+ export const RUNTIME_PROCESS_WORKER_BOOT_VERSION = 1;
5
+ export const RUNTIME_POOL_DEPTH_ENV = "KNITTING_POOL_DEPTH";
6
+ const nodeProcess = getNodeProcess();
7
+ export const RUNTIME_IS_PROCESS_WORKER = nodeProcess?.env?.[RUNTIME_PROCESS_WORKER_ENV] === "1";
8
+ const readPoolDepth = () => {
9
+ const raw = nodeProcess?.env?.[RUNTIME_POOL_DEPTH_ENV];
10
+ if (typeof raw !== "string")
11
+ return 0;
12
+ const parsed = Number.parseInt(raw, 10);
13
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
14
+ };
15
+ export const RUNTIME_POOL_DEPTH = readPoolDepth();
16
+ const workerThreads = getNodeBuiltinModule("node:worker_threads");
17
+ const isWorkerGlobalScope = () => {
18
+ const scopeCtor = globalThis.WorkerGlobalScope;
19
+ if (typeof scopeCtor !== "function")
20
+ return false;
21
+ try {
22
+ return globalThis instanceof
23
+ scopeCtor;
24
+ }
25
+ catch {
26
+ return false;
27
+ }
28
+ };
29
+ export const RUNTIME_WORKER = workerThreads?.Worker ??
30
+ (globalThis.Worker);
31
+ export const RUNTIME_MESSAGE_CHANNEL = workerThreads?.MessageChannel ??
32
+ (globalThis
33
+ .MessageChannel);
34
+ export const HAS_NODE_WORKER_THREADS = workerThreads != null;
35
+ export const RUNTIME_IS_MAIN_THREAD = RUNTIME_IS_PROCESS_WORKER
36
+ ? false
37
+ : workerThreads?.isMainThread ?? !isWorkerGlobalScope();
38
+ export const RUNTIME_WORKER_DATA = workerThreads?.workerData;
39
+ export const RUNTIME_PARENT_PORT = workerThreads?.parentPort ??
40
+ (RUNTIME_IS_PROCESS_WORKER && typeof nodeProcess?.send === "function"
41
+ ? {
42
+ postMessage: (message) => nodeProcess.send(message),
43
+ }
44
+ : undefined);
45
+ export const createRuntimeMessageChannel = () => {
46
+ if (typeof RUNTIME_MESSAGE_CHANNEL !== "function") {
47
+ throw new Error("MessageChannel is not available in this runtime");
48
+ }
49
+ return new RUNTIME_MESSAGE_CHANNEL();
50
+ };
51
+ export const addRuntimeDataListener = (target, handler) => {
52
+ if (typeof target.on === "function") {
53
+ target.on("message", handler);
54
+ return;
55
+ }
56
+ if (typeof target.addEventListener === "function") {
57
+ target.addEventListener("message", (event) => handler(event?.data));
58
+ return;
59
+ }
60
+ target.onmessage = (event) => handler(event?.data);
61
+ };