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.
- package/LICENSE +202 -0
- package/README.md +632 -0
- package/knitting.d.ts +4 -0
- package/knitting.js +5 -0
- package/map.md +264 -0
- package/package.json +77 -0
- package/prebuilds/darwin-arm64-node-127/knitting_shared_memory.node +0 -0
- package/prebuilds/darwin-arm64-node-127/knitting_shm.node +0 -0
- package/prebuilds/darwin-arm64-node-137/knitting_shared_memory.node +0 -0
- package/prebuilds/darwin-arm64-node-137/knitting_shm.node +0 -0
- package/prebuilds/darwin-x64-node-127/knitting_shared_memory.node +0 -0
- package/prebuilds/darwin-x64-node-127/knitting_shm.node +0 -0
- package/prebuilds/darwin-x64-node-137/knitting_shared_memory.node +0 -0
- package/prebuilds/darwin-x64-node-137/knitting_shm.node +0 -0
- package/prebuilds/linux-x64-node-127/knitting_shared_memory.node +0 -0
- package/prebuilds/linux-x64-node-127/knitting_shm.node +0 -0
- package/prebuilds/linux-x64-node-137/knitting_shared_memory.node +0 -0
- package/prebuilds/linux-x64-node-137/knitting_shm.node +0 -0
- package/process-shared-buffer.d.ts +1 -0
- package/process-shared-buffer.js +1 -0
- package/scripts/build-native-addons.ts +295 -0
- package/src/api.d.ts +55 -0
- package/src/api.js +384 -0
- package/src/common/envelope.d.ts +11 -0
- package/src/common/envelope.js +8 -0
- package/src/common/module-url.d.ts +1 -0
- package/src/common/module-url.js +24 -0
- package/src/common/node-compat.d.ts +20 -0
- package/src/common/node-compat.js +24 -0
- package/src/common/path-canonical.d.ts +6 -0
- package/src/common/path-canonical.js +41 -0
- package/src/common/runtime.d.ts +15 -0
- package/src/common/runtime.js +91 -0
- package/src/common/shared-buffer-region.d.ts +11 -0
- package/src/common/shared-buffer-region.js +21 -0
- package/src/common/shared-buffer-text.d.ts +16 -0
- package/src/common/shared-buffer-text.js +65 -0
- package/src/common/task-source.d.ts +2 -0
- package/src/common/task-source.js +79 -0
- package/src/common/task-symbol.d.ts +1 -0
- package/src/common/task-symbol.js +1 -0
- package/src/common/with-resolvers.d.ts +9 -0
- package/src/common/with-resolvers.js +23 -0
- package/src/common/worker-runtime.d.ts +40 -0
- package/src/common/worker-runtime.js +52 -0
- package/src/connections/bun.d.ts +20 -0
- package/src/connections/bun.js +159 -0
- package/src/connections/deno.d.ts +20 -0
- package/src/connections/deno.js +150 -0
- package/src/connections/file-descriptor.d.ts +37 -0
- package/src/connections/file-descriptor.js +139 -0
- package/src/connections/index.d.ts +3 -0
- package/src/connections/index.js +3 -0
- package/src/connections/node-addons.d.ts +5 -0
- package/src/connections/node-addons.js +43 -0
- package/src/connections/node.d.ts +29 -0
- package/src/connections/node.js +59 -0
- package/src/connections/posix.d.ts +31 -0
- package/src/connections/posix.js +71 -0
- package/src/connections/process-shared-buffer.d.ts +67 -0
- package/src/connections/process-shared-buffer.js +267 -0
- package/src/connections/types.d.ts +48 -0
- package/src/connections/types.js +37 -0
- package/src/error.d.ts +13 -0
- package/src/error.js +49 -0
- package/src/ipc/tools/ring-queue.d.ts +33 -0
- package/src/ipc/tools/ring-queue.js +159 -0
- package/src/ipc/transport/shared-memory.d.ts +25 -0
- package/src/ipc/transport/shared-memory.js +35 -0
- package/src/knitting_shared_memory.cc +436 -0
- package/src/knitting_shm.cc +476 -0
- package/src/memory/byte-carpet.d.ts +73 -0
- package/src/memory/byte-carpet.js +157 -0
- package/src/memory/lock.d.ts +190 -0
- package/src/memory/lock.js +856 -0
- package/src/memory/payload-config.d.ts +22 -0
- package/src/memory/payload-config.js +67 -0
- package/src/memory/payloadCodec.d.ts +46 -0
- package/src/memory/payloadCodec.js +1157 -0
- package/src/memory/regionRegistry.d.ts +17 -0
- package/src/memory/regionRegistry.js +285 -0
- package/src/memory/shared-buffer-io.d.ts +53 -0
- package/src/memory/shared-buffer-io.js +380 -0
- package/src/permission/index.d.ts +2 -0
- package/src/permission/index.js +2 -0
- package/src/permission/protocol.d.ts +166 -0
- package/src/permission/protocol.js +640 -0
- package/src/runtime/balancer.d.ts +19 -0
- package/src/runtime/balancer.js +149 -0
- package/src/runtime/dispatcher.d.ts +34 -0
- package/src/runtime/dispatcher.js +142 -0
- package/src/runtime/inline-executor.d.ts +10 -0
- package/src/runtime/inline-executor.js +270 -0
- package/src/runtime/pool.d.ts +43 -0
- package/src/runtime/pool.js +922 -0
- package/src/runtime/tx-queue.d.ts +25 -0
- package/src/runtime/tx-queue.js +144 -0
- package/src/shared/abortSignal.d.ts +23 -0
- package/src/shared/abortSignal.js +126 -0
- package/src/types.d.ts +283 -0
- package/src/types.js +2 -0
- package/src/worker/composable-runners.d.ts +12 -0
- package/src/worker/composable-runners.js +105 -0
- package/src/worker/loop.d.ts +2 -0
- package/src/worker/loop.js +453 -0
- package/src/worker/rx-queue.d.ts +22 -0
- package/src/worker/rx-queue.js +124 -0
- package/src/worker/safety/index.d.ts +4 -0
- package/src/worker/safety/index.js +4 -0
- package/src/worker/safety/performance.d.ts +1 -0
- package/src/worker/safety/performance.js +17 -0
- package/src/worker/safety/process.d.ts +2 -0
- package/src/worker/safety/process.js +79 -0
- package/src/worker/safety/startup.d.ts +16 -0
- package/src/worker/safety/startup.js +30 -0
- package/src/worker/safety/worker-data.d.ts +2 -0
- package/src/worker/safety/worker-data.js +36 -0
- package/src/worker/task-loader.d.ts +26 -0
- package/src/worker/task-loader.js +66 -0
- package/src/worker/timers.d.ts +18 -0
- 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
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -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
|
+
);
|