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
package/map.md ADDED
@@ -0,0 +1,264 @@
1
+ # Knitting Project Map
2
+
3
+ This is the quick compass for the repo. It lists the files that matter for
4
+ understanding, building, testing, and benchmarking the runtime.
5
+
6
+ ## Runtime Shape
7
+
8
+ The core flow is:
9
+
10
+ 1. A user defines tasks with `task()` or `importTask()`.
11
+ 2. `createPool()` turns those tasks into callable worker lanes.
12
+ 3. The host writes calls into shared-memory queues.
13
+ 4. Workers read calls, execute task functions, and write results back.
14
+ 5. Payloads move through shared buffers, with special handling for larger or
15
+ non-inline values.
16
+
17
+ ## Public Entry Points
18
+
19
+ - `knitting.ts`: Main package entry. Re-exports `createPool`, `task`,
20
+ `importTask`, `isMain`, `Envelope`, and `workerMainLoop`.
21
+ - `process-shared-buffer.ts`: Secondary public export for process-shared-buffer
22
+ helpers.
23
+ - `README.md`: User-facing documentation, examples, configuration, and command
24
+ reference.
25
+ - `package.json`: Package metadata, export map, shipped files, scripts, runtime
26
+ engine requirements, and dev dependencies.
27
+ - `deno.json`: Deno config used by Deno tests/checks.
28
+ - `deno.lock`: Deno dependency lockfile.
29
+ - `bun.lockb`: Bun dependency lockfile.
30
+ - `LICENSE`: Project license.
31
+
32
+ ## Build And Scripts
33
+
34
+ - `build.ts`: Bundles `knitting.ts` to `out/` with Bun for a Node ESM target.
35
+ - `scripts/build-native-addons.ts`: Compiles the native Node addons into
36
+ `build/Release/` on Linux and macOS. It finds Node headers/libs, splits user
37
+ flags, and builds the shared-memory and futex addons.
38
+ - `run.sh`: Runs every top-level benchmark in `bench/` across Node, Deno, and
39
+ Bun. `--json` writes JSON result files.
40
+
41
+ ## Public API Layer
42
+
43
+ - `src/api.ts`: Defines `task`, `importTask`, `createPool`, `isMain`, task id
44
+ collection, imported task resolution, single-task pool helpers, and typed call
45
+ surfaces.
46
+ - `src/types.ts`: Central type model for tasks, pools, worker settings, payload
47
+ settings, permissions, balancing, abort signals, and exported runtime types.
48
+ - `src/error.ts`: Shared encoder/runtime error enum and error-construction
49
+ helper.
50
+
51
+ ## Common Utilities
52
+
53
+ - `src/common/envelope.ts`: `Envelope` wrapper for metadata plus binary
54
+ payloads.
55
+ - `src/common/module-url.ts`: Converts file paths and specifiers into importable
56
+ module URLs across platforms.
57
+ - `src/common/node-compat.ts`: Safe accessors for Node-only globals and built-in
58
+ modules.
59
+ - `src/common/task-source.ts`: Task id generation and caller-file discovery from
60
+ stack frames.
61
+ - `src/common/path-canonical.ts`: Canonicalizes paths for permission checks.
62
+ - `src/common/runtime.ts`: Runtime detection plus shared-array-buffer creation,
63
+ growth, and WebAssembly-backed fallback support.
64
+ - `src/common/shared-buffer-region.ts`: Normalizes whole buffers and sliced
65
+ buffer regions.
66
+ - `src/common/shared-buffer-text.ts`: Text encode/decode compatibility probes
67
+ for shared-buffer-backed views.
68
+ - `src/common/task-symbol.ts`: Shared symbol used to mark task definitions.
69
+ - `src/common/with-resolvers.ts`: `Promise.withResolvers` compatibility helper.
70
+ - `src/common/worker-runtime.ts`: Runtime-neutral worker/thread/process-worker
71
+ detection, parent-port access, and message-channel creation.
72
+
73
+ ## Runtime Host Side
74
+
75
+ - `src/runtime/pool.ts`: Worker spawning and pool construction internals.
76
+ Handles thread workers, process workers, shared-memory layout, child process
77
+ boot, permission propagation, worker errors, and pool shutdown.
78
+ - `src/runtime/tx-queue.ts`: Host transmit queue. Encodes calls, tracks pending
79
+ promises, handles backpressure, timeouts, abort metadata, and response
80
+ settlement.
81
+ - `src/runtime/dispatcher.ts`: Host dispatcher loop and channel handler. Flushes
82
+ work to workers and drains completed results.
83
+ - `src/runtime/balancer.ts`: Lane-selection strategies such as round-robin,
84
+ first-idle, random, and first-idle-random.
85
+ - `src/runtime/inline-executor.ts`: Optional in-process executor used by the
86
+ inliner path to run tasks without crossing the worker boundary.
87
+
88
+ ## Worker Side
89
+
90
+ - `src/worker/loop.ts`: Worker entrypoint and main loop. Boots worker contexts,
91
+ installs safety guards, receives tasks, executes batches, writes completions,
92
+ and supports process-worker bootstrapping.
93
+ - `src/worker/task-loader.ts`: Imports task modules inside workers, finds
94
+ exported task definitions, filters by id/caller position, and normalizes
95
+ timeout metadata.
96
+ - `src/worker/rx-queue.ts`: Worker receive queue. Decodes pending calls from the
97
+ shared lock and stages them for execution.
98
+ - `src/worker/composable-runners.ts`: Builds callable worker runners with abort
99
+ toolkit support, timeout handling, promise handling, and queue-wait budget
100
+ accounting.
101
+ - `src/worker/timers.ts`: Worker pause/spin/sleep helpers, including
102
+ `Atomics.wait`, `Atomics.pause`, and native futex integration.
103
+
104
+ ## Worker Safety
105
+
106
+ - `src/worker/safety/index.ts`: Barrel export for worker safety helpers.
107
+ - `src/worker/safety/process.ts`: Blocks direct process termination APIs inside
108
+ workers and silences guarded unhandled rejections.
109
+ - `src/worker/safety/performance.ts`: Protects `performance.now()` from worker
110
+ tampering.
111
+ - `src/worker/safety/startup.ts`: Validates worker boot data and imported task
112
+ resolution during startup.
113
+ - `src/worker/safety/worker-data.ts`: Scrubs sensitive shared-memory references
114
+ from exposed worker data.
115
+
116
+ ## Memory And Payloads
117
+
118
+ - `src/memory/lock.ts`: Core shared-memory lock protocol. Defines task slots,
119
+ payload markers, bit packing, encode/decode, host resolution, and queue
120
+ mechanics.
121
+ - `src/memory/payloadCodec.ts`: Encodes and decodes task inputs/results,
122
+ including strings, binary values, JSON-ish values, errors, promises, symbols,
123
+ `Envelope`, and external payload codecs.
124
+ - `src/memory/payload-config.ts`: Normalizes payload-buffer options and enforces
125
+ capacity limits.
126
+ - `src/memory/shared-buffer-io.ts`: Low-level binary/text read-write helpers
127
+ over shared buffers.
128
+ - `src/memory/regionRegistry.ts`: Allocator/registry for variable-sized dynamic
129
+ payload regions.
130
+ - `src/memory/byte-carpet.ts`: Shared-buffer layout helper for aligned regions,
131
+ lock control sectors, and split/interleaved header layouts.
132
+
133
+ ## Shared Abort Support
134
+
135
+ - `src/shared/abortSignal.ts`: Shared abort-signal bitset helpers used by host
136
+ and worker code to reserve, set, check, and reset abort slots.
137
+
138
+ ## IPC Transport
139
+
140
+ - `src/ipc/transport/shared-memory.ts`: Small signal channel around shared
141
+ memory. Creates host/worker views and exposes wake/check signals.
142
+ - `src/ipc/tools/ring-queue.ts`: Ring queue utility used by queue tests and
143
+ lower-level queue experiments.
144
+
145
+ ## Process And Native Shared Memory
146
+
147
+ - `src/connections/index.ts`: Barrel export for connection primitives and
148
+ process-shared-buffer types.
149
+ - `src/connections/types.ts`: Shared-memory connection contracts, validation,
150
+ alignment helpers, and runtime names.
151
+ - `src/connections/process-shared-buffer.ts`: `ProcessSharedBuffer` class,
152
+ metadata serialization, subbuffer views, default primitive selection, and
153
+ payload-codec registration.
154
+ - `src/connections/file-descriptor.ts`: File descriptor wrapper, metadata
155
+ parsing, mapping support, and descriptor lifecycle helpers.
156
+ - `src/connections/node.ts`: Loads POSIX Node native addons and exposes Node
157
+ shared memory, mapping, unlink, and futex primitives.
158
+ - `src/connections/bun.ts`: Bun FFI implementation for POSIX shared memory.
159
+ - `src/connections/deno.ts`: Deno FFI implementation for POSIX shared memory.
160
+ - `src/connections/posix.ts`: POSIX constants, shared-memory naming, libc path
161
+ detection, and close-on-exec helpers.
162
+ - `src/knitting_shared_memory.cc`: Native Node addon for shared-memory create,
163
+ map, unlink, and descriptor operations.
164
+ - `src/knitting_shm.cc`: Native Node addon for futex/wait helpers used by parked
165
+ workers.
166
+
167
+ ## Permissions
168
+
169
+ - `src/permission/index.ts`: Barrel export for permission protocol helpers.
170
+ - `src/permission/protocol.ts`: Resolves cross-runtime permission settings into
171
+ Node/Deno/Bun process-worker behavior, including read/write/env/import/process
172
+ policies.
173
+
174
+ ## Benchmarks
175
+
176
+ - `bench/latency.ts`: Compares basic task-call latency against a direct worker
177
+ postMessage baseline.
178
+ - `bench/types.ts`: Compares payload-type behavior between knitting and worker
179
+ messaging.
180
+ - `bench/types_knitting.ts`: Knitting-only payload-type benchmark with broader
181
+ type coverage.
182
+ - `bench/ipc.ts`: Larger IPC comparison benchmark covering local calls,
183
+ postMessage, HTTP, WebSocket, and knitting.
184
+ - `bench/withload.ts`: Measures behavior under main-thread load.
185
+ - `bench/call-growth.ts`: Measures call cost as payload size grows.
186
+ - `bench/call-growth-batch.ts`: Batch-focused version of call-growth tests.
187
+ - `bench/tokio-mpsc-knitting.ts`: Batch latency benchmark for string, number,
188
+ and Uint8Array echo tasks.
189
+ - `bench/payload-sweep.ts`: Uint8Array payload-size sweep promoted from the old
190
+ scratch file. Supports table output and `--json`.
191
+ - `bench/postmessage/single.ts`: Worker-thread postMessage baseline helper.
192
+ - `bench/postmessage/test.go`: Go comparison/experiment for postMessage-style
193
+ IPC.
194
+ - `bench/util/json-parse.ts`: Mitata JSON output reducer used by benchmark
195
+ scripts.
196
+ - `bench/util/type-payloads.ts`: Shared payload cases and size estimation for
197
+ type benchmarks.
198
+
199
+ ## Core Microbenchmarks
200
+
201
+ - `bench/core/lock.ts`: Microbenchmarks lock encode/decode/resolve paths.
202
+ - `bench/core/loop.ts`: Worker loop behavior under sync, async, and idle gaps.
203
+ - `bench/core/inliner.ts`: Inliner threshold and worker-only comparison.
204
+ - `bench/core/task-shell.ts`: Task object/shell construction costs.
205
+ - `bench/core/regionRegistry.ts`: Dynamic payload region allocator costs.
206
+ - `bench/core/object-vs-class.ts`: Object-vs-class shape experiments.
207
+ - `bench/core/payload-buffer-vs-uint8array.ts`: Payload backing-store
208
+ comparison.
209
+ - `bench/core/payload-hardening.ts`: Payload hardening and strict-object-policy
210
+ costs.
211
+ - `bench/core/memory-alloc.ts`: Buffer/ArrayBuffer/Uint8Array allocation
212
+ benchmark.
213
+
214
+ ## Tests
215
+
216
+ - `test/abortSignal.test.ts`: Shared abort bitset behavior.
217
+ - `test/api-cap.test.ts`: API limits such as maximum task id count.
218
+ - `test/shared-buffer-io.test.ts`: Shared-buffer IO read/write behavior.
219
+ - `test/file-descriptor.test.ts`: File descriptor metadata and mapping behavior.
220
+ - `test/inliner.test.ts`: Inline executor behavior and thresholds.
221
+ - `test/lock.test.ts`: Core lock protocol, bit packing, encode/decode, and
222
+ allocator behavior.
223
+ - `test/loop.test.ts`: Worker loop progress, shutdown delay, and oversized
224
+ batches.
225
+ - `test/moduleUrl.test.ts`: Cross-platform module URL normalization.
226
+ - `test/parameters.test.ts`: Task parameter passing.
227
+ - `test/payload-config.test.ts`: Payload option normalization and limits.
228
+ - `test/payloadCodec.test.ts`: Payload codec coverage across primitives,
229
+ buffers, errors, promises, symbols, envelopes, and strict object handling.
230
+ - `test/permission.test.ts`: Permission protocol resolution.
231
+ - `test/process-shared-buffer.test.ts`: `ProcessSharedBuffer` API and metadata.
232
+ - `test/readme-types.test.ts`: README example type-check coverage.
233
+ - `test/regionRegistry.test.ts`: Dynamic region registry behavior.
234
+ - `test/registerDesync.test.ts`: Register allocator desync stress cases.
235
+ - `test/ring-queue.test.ts`: Ring queue behavior.
236
+ - `test/runtime.node.test.ts`: Node worker runtime integration and safety tests.
237
+ - `test/runtime.process.test.ts`: Process-worker integration across Node, Deno,
238
+ and Bun.
239
+ - `test/runtime.shared-buffer.test.ts`: Runtime shared-buffer creation/growth.
240
+ - `test/rx-queue.test.ts`: Worker receive queue behavior.
241
+ - `test/safety-coverage.test.ts`: Direct safety-guard probe coverage.
242
+ - `test/shared-memory-transport.test.ts`: Shared-memory transport offsets.
243
+ - `test/task-abort-api.test.ts`: Public abort-signal task API behavior.
244
+ - `test/task-abort-context-api.test.ts`: Worker abort toolkit/context behavior.
245
+ - `test/tx-queue.test.ts`: Host transmit queue behavior and late-result safety.
246
+ - `test/type-inference.test.ts`: Public type inference guarantees.
247
+ - `test/fixtures/*.ts`: Task modules used by tests.
248
+ - `test/fixtures/probes/*.ts`: Probe programs for crash, permission, process,
249
+ file-descriptor, and shared-memory-corruption safety cases.
250
+
251
+ ## Generated Or External Output
252
+
253
+ - `build/Release/*.node`: Native addon output produced by
254
+ `scripts/build-native-addons.ts`.
255
+ - `out/`: Bundled output produced by `build.ts`.
256
+ - `results/`: Benchmark output produced by `run.sh`.
257
+ - `node_modules/`: Installed dependencies. Not part of the source map.
258
+
259
+ ## Deleted Or Intentionally Absent
260
+
261
+ - Browser-mode build/smoke files are no longer part of the project.
262
+ - The old top-level scratch files `uwu.ts` and `examples.ts` are removed.
263
+ - Python graph scripts under `graphs/` were removed; current benchmark output is
264
+ kept in the TypeScript benchmark suite.
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "knitting",
3
+ "version": "0.1.46",
4
+ "description": "Shared-memory IPC runtime for Node.js, Deno, and Bun.",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/mimiMonads/knitting.git"
9
+ },
10
+ "bugs": {
11
+ "url": "https://github.com/mimiMonads/knitting/issues"
12
+ },
13
+ "homepage": "https://github.com/mimiMonads/knitting#readme",
14
+ "type": "module",
15
+ "main": "./knitting.js",
16
+ "module": "./knitting.js",
17
+ "types": "./knitting.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./knitting.d.ts",
21
+ "default": "./knitting.js"
22
+ },
23
+ "./process-shared-buffer": {
24
+ "types": "./process-shared-buffer.d.ts",
25
+ "default": "./process-shared-buffer.js"
26
+ }
27
+ },
28
+ "files": [
29
+ "README.md",
30
+ "map.md",
31
+ "LICENSE",
32
+ "prebuilds/**/*.node",
33
+ "scripts/build-native-addons.ts",
34
+ "src/**/*.cc",
35
+ "src/**/*.d.ts",
36
+ "src/**/*.js",
37
+ "knitting.d.ts",
38
+ "knitting.js",
39
+ "process-shared-buffer.d.ts",
40
+ "process-shared-buffer.js"
41
+ ],
42
+ "scripts": {
43
+ "build": "bun run build.ts",
44
+ "build:npm": "tsc -p tsconfig.npm.json && node scripts/rewrite-declaration-imports.mjs",
45
+ "build:native": "bun run scripts/build-native-addons.ts",
46
+ "build:release": "bun run build:native && bun run build && npm run build:npm",
47
+ "build:node": "bun build knitting.ts --outdir dest --target node --format esm",
48
+ "prepack": "npm run build:npm",
49
+ "release:npm": "npm run test:all && npm publish",
50
+ "release:npm:dry-run": "npm publish --dry-run",
51
+ "test": "npm run test:deno",
52
+ "test:deno": "deno test -A --ignore=test/runtime.node.test.ts --ignore=test/runtime.process.test.ts",
53
+ "test:node": "node --no-warnings --experimental-transform-types --test \"./test/*.test.ts\"",
54
+ "test:bun": "bun test ./test/*.test.ts --path-ignore-patterns=**/tx-queue.test.ts",
55
+ "test:runtimes": "npm run test:node && npm run test:bun",
56
+ "test:all": "npm run test:deno && npm run test:runtimes",
57
+ "coverage:node": "node --no-warnings --experimental-transform-types --experimental-test-coverage --test \"./test/*.test.ts\"",
58
+ "coverage:node:90": "node --no-warnings --experimental-transform-types --experimental-test-coverage --test-coverage-lines=90 --test-coverage-exclude=src/common/task-source.ts --test-coverage-exclude=src/ipc/protocol/parsers/NumericBuffer.ts --test-coverage-exclude=src/runtime/balancer.ts --test-coverage-exclude=src/worker/task-loader.ts --test \"./test/*.test.ts\"",
59
+ "bench": "./run.sh",
60
+ "bench:json": "./run.sh --json"
61
+ },
62
+ "engines": {
63
+ "node": ">=22.0.0",
64
+ "deno": ">=2.0.0",
65
+ "bun": ">=1.0.0"
66
+ },
67
+ "peerDependencies": {
68
+ "typescript": "^5.0.0"
69
+ },
70
+ "devDependencies": {
71
+ "@types/bun": "latest",
72
+ "@types/deno": "latest",
73
+ "@types/node": "latest",
74
+ "mitata": "^1.0.34",
75
+ "typescript": "^5.0.0"
76
+ }
77
+ }
@@ -0,0 +1 @@
1
+ export { getDefaultProcessSharedBufferPrimitives, parseProcessSharedBufferMetadata, PROCESS_SHARED_BUFFER_BRAND, ProcessSharedBuffer, setDefaultProcessSharedBufferPrimitives, type ProcessSharedBufferCreator, type ProcessSharedBufferMapper, type ProcessSharedBufferMetadata, type ProcessSharedBufferPrimitives, type ProcessSharedBufferRange, type ProcessSharedBufferView, type ProcessSharedBufferViewConstructor, } from "./src/connections/process-shared-buffer.js";
@@ -0,0 +1 @@
1
+ export { getDefaultProcessSharedBufferPrimitives, parseProcessSharedBufferMetadata, PROCESS_SHARED_BUFFER_BRAND, ProcessSharedBuffer, setDefaultProcessSharedBufferPrimitives, } from "./src/connections/process-shared-buffer.js";
@@ -0,0 +1,295 @@
1
+ import { copyFileSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { dirname, join, resolve } from "node:path";
4
+
5
+ declare const Bun: {
6
+ env: Record<string, string | undefined>;
7
+ spawnSync: (options: {
8
+ cmd: string[];
9
+ stdout?: "pipe";
10
+ stderr?: "pipe";
11
+ }) => {
12
+ exitCode: number;
13
+ stdout: Uint8Array;
14
+ stderr: Uint8Array;
15
+ };
16
+ };
17
+
18
+ type NodeInfo = {
19
+ arch: string;
20
+ execPath: string;
21
+ modules: string;
22
+ nodedir: string | null;
23
+ platform: string;
24
+ version: string;
25
+ };
26
+
27
+ const textDecode = new TextDecoder();
28
+ const root = resolve(import.meta.dirname ?? ".", "..");
29
+ const outDir = join(root, "build", "Release");
30
+ const nodeBinary = Bun.env.NODE_BINARY ?? "node";
31
+
32
+ const splitFlags = (value: string | undefined): string[] =>
33
+ value?.split(/\s+/).filter(Boolean) ?? [];
34
+
35
+ const runCapture = (cmd: string, args: string[]): string => {
36
+ const result = Bun.spawnSync({
37
+ cmd: [cmd, ...args],
38
+ stdout: "pipe",
39
+ stderr: "pipe",
40
+ });
41
+
42
+ if (result.exitCode !== 0) {
43
+ const stderr = textDecode.decode(result.stderr).trim();
44
+ throw new Error(`${cmd} ${args.join(" ")} failed\n${stderr}`);
45
+ }
46
+
47
+ return textDecode.decode(result.stdout).trim();
48
+ };
49
+
50
+ const run = (cmd: string, args: string[]): void => {
51
+ console.log(`$ ${[cmd, ...args].join(" ")}`);
52
+ const result = Bun.spawnSync({
53
+ cmd: [cmd, ...args],
54
+ stdout: "pipe",
55
+ stderr: "pipe",
56
+ });
57
+
58
+ const stdout = textDecode.decode(result.stdout);
59
+ const stderr = textDecode.decode(result.stderr);
60
+ if (stdout.length > 0) console.log(stdout.trimEnd());
61
+ if (stderr.length > 0) console.error(stderr.trimEnd());
62
+
63
+ if (result.exitCode !== 0) {
64
+ throw new Error(`${cmd} exited with code ${result.exitCode}`);
65
+ }
66
+ };
67
+
68
+ const nodeInfo = JSON.parse(runCapture(nodeBinary, [
69
+ "-p",
70
+ "JSON.stringify({arch:process.arch,execPath:process.execPath,modules:process.versions.modules,nodedir:process.config.variables.nodedir||null,platform:process.platform,version:process.versions.node})",
71
+ ])) as NodeInfo;
72
+ const isWindows = nodeInfo.platform === "win32";
73
+ if (isWindows) {
74
+ throw new Error(
75
+ "Knitting native shared-memory addons are supported on Linux and macOS only",
76
+ );
77
+ }
78
+ const cacheRoot = join(
79
+ resolve(
80
+ Bun.env.KNITTING_NODE_CACHE_DIR ??
81
+ Bun.env.RUNNER_TEMP ??
82
+ Bun.env.TEMP ??
83
+ Bun.env.TMPDIR ??
84
+ tmpdir(),
85
+ ),
86
+ "knitting-node",
87
+ );
88
+
89
+ const downloadFile = async (url: string, outputPath: string): Promise<void> => {
90
+ console.log(`Downloading ${url}`);
91
+ const response = await fetch(url);
92
+ if (!response.ok) {
93
+ throw new Error(
94
+ `Download failed (${response.status} ${response.statusText}): ${url}`,
95
+ );
96
+ }
97
+
98
+ mkdirSync(dirname(outputPath), { recursive: true });
99
+ writeFileSync(outputPath, new Uint8Array(await response.arrayBuffer()));
100
+ };
101
+
102
+ const ensureDownloadedNodeHeaders = async (): Promise<string> => {
103
+ const version = `v${nodeInfo.version}`;
104
+ const headersRoot = join(cacheRoot, "headers", version);
105
+ const headersDir = join(
106
+ headersRoot,
107
+ `node-${version}`,
108
+ "include",
109
+ "node",
110
+ );
111
+
112
+ if (existsSync(join(headersDir, "node.h"))) {
113
+ return headersDir;
114
+ }
115
+
116
+ const archive = join(headersRoot, `node-${version}-headers.tar.gz`);
117
+ if (!existsSync(archive)) {
118
+ await downloadFile(
119
+ `https://nodejs.org/download/release/${version}/node-${version}-headers.tar.gz`,
120
+ archive,
121
+ );
122
+ }
123
+
124
+ mkdirSync(headersRoot, { recursive: true });
125
+ run("tar", ["-xzf", archive, "-C", headersRoot]);
126
+
127
+ if (!existsSync(join(headersDir, "node.h"))) {
128
+ throw new Error(`Downloaded Node headers did not contain ${headersDir}`);
129
+ }
130
+
131
+ return headersDir;
132
+ };
133
+
134
+ const nodeLibDownloadArch = (arch: string): string => {
135
+ if (arch === "x64" || arch === "arm64") return arch;
136
+ if (arch === "ia32") return "x86";
137
+ throw new Error(`Unsupported Windows Node architecture: ${arch}`);
138
+ };
139
+
140
+ const ensureDownloadedNodeLib = async (): Promise<string> => {
141
+ const version = `v${nodeInfo.version}`;
142
+ const arch = nodeLibDownloadArch(nodeInfo.arch);
143
+ const nodeLib = join(cacheRoot, "lib", version, `win-${arch}`, "node.lib");
144
+
145
+ if (!existsSync(nodeLib)) {
146
+ await downloadFile(
147
+ `https://nodejs.org/download/release/${version}/win-${arch}/node.lib`,
148
+ nodeLib,
149
+ );
150
+ }
151
+
152
+ return nodeLib;
153
+ };
154
+
155
+ const includeCandidates = [
156
+ Bun.env.NODE_INCLUDE_DIR,
157
+ nodeInfo.nodedir ? join(nodeInfo.nodedir, "include", "node") : undefined,
158
+ join(dirname(dirname(nodeInfo.execPath)), "include", "node"),
159
+ join(dirname(nodeInfo.execPath), "..", "include", "node"),
160
+ "/usr/include/node",
161
+ "/usr/local/include/node",
162
+ ].filter((value): value is string => typeof value === "string");
163
+
164
+ let includeDir = includeCandidates.find((candidate) =>
165
+ existsSync(join(candidate, "node.h"))
166
+ );
167
+
168
+ if (includeDir === undefined) {
169
+ includeDir = await ensureDownloadedNodeHeaders();
170
+ }
171
+
172
+ const nodeLibCandidates = isWindows
173
+ ? [
174
+ Bun.env.NODE_LIB_FILE,
175
+ join(dirname(nodeInfo.execPath), "node.lib"),
176
+ join(dirname(dirname(nodeInfo.execPath)), "node.lib"),
177
+ join(dirname(dirname(nodeInfo.execPath)), "lib", "node.lib"),
178
+ nodeInfo.nodedir
179
+ ? join(nodeInfo.nodedir, "Release", "node.lib")
180
+ : undefined,
181
+ nodeInfo.nodedir
182
+ ? join(nodeInfo.nodedir, nodeInfo.arch, "node.lib")
183
+ : undefined,
184
+ nodeInfo.nodedir ? join(nodeInfo.nodedir, "x64", "node.lib") : undefined,
185
+ nodeInfo.nodedir ? join(nodeInfo.nodedir, "ia32", "node.lib") : undefined,
186
+ ].filter((value): value is string => typeof value === "string")
187
+ : [];
188
+ let nodeLib = isWindows
189
+ ? nodeLibCandidates.find((candidate) => existsSync(candidate))
190
+ : undefined;
191
+
192
+ if (isWindows && nodeLib === undefined) {
193
+ nodeLib = await ensureDownloadedNodeLib();
194
+ }
195
+
196
+ mkdirSync(outDir, { recursive: true });
197
+
198
+ const cxx = Bun.env.CXX ??
199
+ (isWindows ? "cl" : nodeInfo.platform === "darwin" ? "c++" : "g++");
200
+ const compileFlags = isWindows
201
+ ? [
202
+ "/nologo",
203
+ "/std:c++20",
204
+ "/Zc:__cplusplus",
205
+ "/O2",
206
+ "/EHsc",
207
+ "/LD",
208
+ `/I${includeDir}`,
209
+ ...splitFlags(Bun.env.CXXFLAGS),
210
+ ]
211
+ : [
212
+ "-std=c++20",
213
+ "-O2",
214
+ "-Wall",
215
+ "-Wextra",
216
+ "-Wno-unused-parameter",
217
+ "-Wno-cast-function-type",
218
+ "-fPIC",
219
+ `-I${includeDir}`,
220
+ ...splitFlags(Bun.env.CXXFLAGS),
221
+ ];
222
+ const linkFlags = nodeInfo.platform === "darwin"
223
+ ? ["-bundle", "-undefined", "dynamic_lookup"]
224
+ : isWindows
225
+ ? []
226
+ : ["-shared"];
227
+ const extraLdFlags = splitFlags(Bun.env.LDFLAGS);
228
+
229
+ const addons = [
230
+ {
231
+ name: "knitting_shared_memory",
232
+ source: "src/knitting_shared_memory.cc",
233
+ output: "build/Release/knitting_shared_memory.node",
234
+ },
235
+ {
236
+ name: "knitting_shm",
237
+ source: "src/knitting_shm.cc",
238
+ output: "build/Release/knitting_shm.node",
239
+ },
240
+ ];
241
+ const prebuildDir = join(
242
+ root,
243
+ "prebuilds",
244
+ `${nodeInfo.platform}-${nodeInfo.arch}-node-${nodeInfo.modules}`,
245
+ );
246
+
247
+ console.log(`Using Node: ${nodeInfo.execPath}`);
248
+ console.log(`Using Node module ABI: ${nodeInfo.modules}`);
249
+ console.log(`Using headers: ${includeDir}`);
250
+ console.log(`Using compiler: ${cxx}`);
251
+ if (nodeLib !== undefined) console.log(`Using node.lib: ${nodeLib}`);
252
+
253
+ const builtAddons: string[] = [];
254
+ const copiedPrebuilds: string[] = [];
255
+
256
+ for (const addon of addons) {
257
+ const outputPath = join(root, addon.output);
258
+ if (isWindows) {
259
+ run(cxx, [
260
+ ...compileFlags,
261
+ join(root, addon.source),
262
+ "/link",
263
+ `/OUT:${outputPath}`,
264
+ nodeLib!,
265
+ ...extraLdFlags,
266
+ ]);
267
+ } else {
268
+ run(cxx, [
269
+ ...compileFlags,
270
+ ...linkFlags,
271
+ ...extraLdFlags,
272
+ "-o",
273
+ outputPath,
274
+ join(root, addon.source),
275
+ ]);
276
+ }
277
+ builtAddons.push(addon.output);
278
+
279
+ mkdirSync(prebuildDir, { recursive: true });
280
+ const prebuildPath = join(prebuildDir, `${addon.name}.node`);
281
+ copyFileSync(outputPath, prebuildPath);
282
+ copiedPrebuilds.push(prebuildPath);
283
+ }
284
+
285
+ console.log(
286
+ `Built ${builtAddons.length} native addon${
287
+ builtAddons.length === 1 ? "" : "s"
288
+ } ` +
289
+ `for ${nodeInfo.platform}: ${builtAddons.join(", ")}`,
290
+ );
291
+ console.log(
292
+ `Updated ${copiedPrebuilds.length} prebuild${
293
+ copiedPrebuilds.length === 1 ? "" : "s"
294
+ } in ${prebuildDir}`,
295
+ );