knitting 0.1.55 → 0.1.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +254 -40
- package/knitting.d.ts +7 -797
- package/knitting.js +6 -9780
- package/map.md +31 -15
- package/package.json +20 -6
- package/process-shared-buffer.d.ts +1 -0
- package/process-shared-buffer.js +1 -0
- package/scripts/build-compiled-worker.ts +276 -0
- package/scripts/compiled-worker/porffor.d.ts +5 -0
- package/scripts/compiled-worker/runtime.ts +529 -0
- package/scripts/compiled-worker/task-shim.ts +32 -0
- package/shared-memory.d.ts +1 -155
- package/shared-memory.js +1 -1342
- package/src/api.d.ts +92 -0
- package/src/api.js +798 -0
- package/src/common/envelope.d.ts +17 -0
- package/src/common/envelope.js +22 -0
- package/src/common/module-url.d.ts +2 -0
- package/src/common/module-url.js +52 -0
- package/src/common/node-compat.d.ts +22 -0
- package/src/common/node-compat.js +24 -0
- package/src/common/path-canonical.d.ts +6 -0
- package/src/common/path-canonical.js +55 -0
- package/src/common/runtime.d.ts +16 -0
- package/src/common/runtime.js +105 -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 +5 -0
- package/src/common/task-source.js +100 -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 +42 -0
- package/src/common/worker-runtime.js +70 -0
- package/src/connections/buffer-reference-native.d.ts +56 -0
- package/src/connections/buffer-reference-native.js +241 -0
- package/src/connections/buffer-reference.d.ts +99 -0
- package/src/connections/buffer-reference.js +575 -0
- package/src/connections/bun.d.ts +22 -0
- package/src/connections/bun.js +225 -0
- package/src/connections/deno.d.ts +24 -0
- package/src/connections/deno.js +226 -0
- package/src/connections/external-array-buffer.d.ts +2 -0
- package/src/connections/external-array-buffer.js +33 -0
- package/src/connections/file-descriptor.d.ts +39 -0
- package/src/connections/file-descriptor.js +161 -0
- package/src/connections/index.d.ts +4 -0
- package/src/connections/index.js +4 -0
- package/src/connections/node-addons.d.ts +16 -0
- package/src/connections/node-addons.js +92 -0
- package/src/connections/node-buffer-pointer.d.ts +20 -0
- package/src/connections/node-buffer-pointer.js +16 -0
- package/src/connections/node-ffi-api.d.ts +19 -0
- package/src/connections/node-ffi-api.js +28 -0
- package/src/connections/node-ffi.d.ts +27 -0
- package/src/connections/node-ffi.js +262 -0
- package/src/connections/node.d.ts +30 -0
- package/src/connections/node.js +62 -0
- package/src/connections/numeric-array.d.ts +5 -0
- package/src/connections/numeric-array.js +17 -0
- package/src/connections/package-assets.d.ts +2 -0
- package/src/connections/package-assets.js +55 -0
- package/src/connections/posix.d.ts +74 -0
- package/src/connections/posix.js +178 -0
- package/src/connections/process-shared-buffer.d.ts +76 -0
- package/src/connections/process-shared-buffer.js +245 -0
- package/src/connections/shared-array-buffer-payload.d.ts +36 -0
- package/src/connections/shared-array-buffer-payload.js +235 -0
- package/src/connections/types.d.ts +54 -0
- package/src/connections/types.js +37 -0
- package/src/connections/windows.d.ts +37 -0
- package/src/connections/windows.js +245 -0
- package/src/debug/env-diff.d.ts +26 -0
- package/src/debug/env-diff.js +49 -0
- package/src/debug/gate.d.ts +18 -0
- package/src/debug/gate.js +69 -0
- package/src/debug/handle.d.ts +23 -0
- package/src/debug/handle.js +48 -0
- package/src/error.d.ts +14 -0
- package/src/error.js +50 -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 +23 -0
- package/src/ipc/transport/shared-memory.js +35 -0
- package/src/memory/byte-carpet.d.ts +73 -0
- package/src/memory/byte-carpet.js +157 -0
- package/src/memory/lock.d.ts +213 -0
- package/src/memory/lock.js +760 -0
- package/src/memory/payload-config.d.ts +31 -0
- package/src/memory/payload-config.js +67 -0
- package/src/memory/payloadCodec.d.ts +55 -0
- package/src/memory/payloadCodec.js +1473 -0
- package/src/memory/regionRegistry.d.ts +17 -0
- package/src/memory/regionRegistry.js +285 -0
- package/src/memory/shared-buffer-io.d.ts +55 -0
- package/src/memory/shared-buffer-io.js +403 -0
- package/src/permission/compatibility.d.ts +28 -0
- package/src/permission/compatibility.js +239 -0
- package/src/permission/index.d.ts +4 -0
- package/src/permission/index.js +3 -0
- package/src/permission/protocol.d.ts +167 -0
- package/src/permission/protocol.js +690 -0
- package/src/runtime/balancer.d.ts +19 -0
- package/src/runtime/balancer.js +149 -0
- package/src/runtime/compiled-artifact.d.ts +21 -0
- package/src/runtime/compiled-artifact.js +260 -0
- package/src/runtime/compiled-builder.d.ts +8 -0
- package/src/runtime/compiled-builder.js +42 -0
- package/src/runtime/compiled-worker.d.ts +27 -0
- package/src/runtime/compiled-worker.js +562 -0
- package/src/runtime/dispatcher.d.ts +40 -0
- package/src/runtime/dispatcher.js +142 -0
- package/src/runtime/inline-executor.d.ts +10 -0
- package/src/runtime/inline-executor.js +294 -0
- package/src/runtime/pool.d.ts +44 -0
- package/src/runtime/pool.js +472 -0
- package/src/runtime/process-worker.d.ts +92 -0
- package/src/runtime/process-worker.js +713 -0
- package/src/runtime/tx-queue.d.ts +28 -0
- package/src/runtime/tx-queue.js +158 -0
- package/src/shared/abortSignal.d.ts +23 -0
- package/src/shared/abortSignal.js +134 -0
- package/src/types.d.ts +399 -0
- package/src/types.js +2 -0
- package/src/utils/http.d.ts +29 -0
- package/src/utils/http.js +100 -0
- package/src/worker/bootstrap.d.ts +5 -0
- package/src/worker/bootstrap.js +78 -0
- package/src/worker/composable-runners.d.ts +12 -0
- package/src/worker/composable-runners.js +98 -0
- package/src/worker/loop.d.ts +3 -0
- package/src/worker/loop.js +395 -0
- package/src/worker/process-worker-bootstrap.d.ts +8 -0
- package/src/worker/process-worker-bootstrap.js +160 -0
- package/src/worker/rx-queue.d.ts +25 -0
- package/src/worker/rx-queue.js +173 -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 +28 -0
- package/src/worker/task-loader.js +76 -0
- package/src/worker/timers.d.ts +18 -0
- package/src/worker/timers.js +118 -0
- package/unsafe.d.ts +1 -71
- package/unsafe.js +1 -878
- package/utils.d.ts +1 -31
- package/utils.js +1 -116
package/map.md
CHANGED
|
@@ -20,6 +20,8 @@ The core flow is:
|
|
|
20
20
|
`importTask`, `isMain`, `Envelope`, and `workerMainLoop`.
|
|
21
21
|
- `shared-memory.ts`: Secondary public export for process-safe shared-memory
|
|
22
22
|
helpers.
|
|
23
|
+
- `process-shared-buffer.ts`: Backward-compatible alias for the shared-memory
|
|
24
|
+
public export.
|
|
23
25
|
- `unsafe.ts`: Public export for experimental lower-level capabilities such as
|
|
24
26
|
`BufferReference`.
|
|
25
27
|
- `utils.ts`: Public export for request/response buffer conversion helpers.
|
|
@@ -34,11 +36,13 @@ The core flow is:
|
|
|
34
36
|
|
|
35
37
|
## Build And Scripts
|
|
36
38
|
|
|
37
|
-
- `build.ts`:
|
|
38
|
-
|
|
39
|
-
- `
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
- `build.ts`: Runs the generated-output cleaner, then compiles public entries
|
|
40
|
+
and `src/**/*.ts` to `.js` and `.d.ts` files with TypeScript.
|
|
41
|
+
- `scripts/clean-generated.ts`: Removes npm-generated root entry files and
|
|
42
|
+
generated `.js`/`.d.ts` files under `src/`; exposed as `npm run clean`.
|
|
43
|
+
- `tsconfig.npm.json`: TypeScript config used by the npm release build.
|
|
44
|
+
- `scripts/rewrite-declaration-imports.mjs`: Rewrites generated declaration
|
|
45
|
+
imports from `.ts` to `.js` so npm consumers resolve the compiled files.
|
|
42
46
|
- `scripts/build-native-addons.ts`: Compiles the native Node addons into
|
|
43
47
|
`build/Release/` on Linux, macOS, and Windows. It finds Node headers/libs,
|
|
44
48
|
splits user flags, builds the shared-memory and futex addons, and emits the
|
|
@@ -63,8 +67,8 @@ The core flow is:
|
|
|
63
67
|
- `docs/AGENTS.md`: Agent/contributor orientation, invariants, and workflow
|
|
64
68
|
notes.
|
|
65
69
|
- `docs/CLAUDE.md`: Pointer to the shared agent guidance.
|
|
66
|
-
- `docs/buffer-reference-ownership-move.md`: Design record for
|
|
67
|
-
|
|
70
|
+
- `docs/buffer-reference-ownership-move.md`: Design record for `BufferReference`
|
|
71
|
+
ownership transfer.
|
|
68
72
|
- `docs/knitting.pdf`: Longer-form project design/theory document.
|
|
69
73
|
|
|
70
74
|
## Public API Layer
|
|
@@ -118,6 +122,12 @@ The core flow is:
|
|
|
118
122
|
- `src/runtime/process-worker.ts`: Process-worker spawning, command/runtime
|
|
119
123
|
selection, process shared-memory layout, inherited/named mapping metadata, and
|
|
120
124
|
child boot payload construction.
|
|
125
|
+
- `src/runtime/compiled-artifact.ts`: Resolves `.knt` executables and validates
|
|
126
|
+
their versioned manifests, source/task identity, target platform, and execute
|
|
127
|
+
permission without launching them.
|
|
128
|
+
- `src/runtime/compiled-worker.ts`: Experimental host adapter for compiled
|
|
129
|
+
worker executables. Spawns the artifact and maps pool calls onto the current
|
|
130
|
+
numeric framed-pipe protocol.
|
|
121
131
|
|
|
122
132
|
## Worker Side
|
|
123
133
|
|
|
@@ -194,14 +204,16 @@ The core flow is:
|
|
|
194
204
|
parsing, mapping support, and descriptor lifecycle helpers.
|
|
195
205
|
- `src/connections/node-addons.ts`: Native addon specifier resolution for
|
|
196
206
|
committed Node ABI prebuilds with `build/Release` fallback loading.
|
|
197
|
-
- `src/connections/node.ts`:
|
|
198
|
-
|
|
207
|
+
- `src/connections/node.ts`: Selects the Node 22/24 addon backend or the Node 26
|
|
208
|
+
FFI backend and exposes shared-memory and futex primitives.
|
|
209
|
+
- `src/connections/node-ffi.ts`: Node 26 `node:ffi` implementation for POSIX
|
|
210
|
+
shared-memory creation, mapping, cleanup, and buffer-pointer aliases.
|
|
199
211
|
- `src/connections/bun.ts`: Bun FFI implementation for POSIX shared memory.
|
|
200
212
|
- `src/connections/deno.ts`: Deno FFI implementation for POSIX shared memory.
|
|
201
213
|
- `src/connections/posix.ts`: POSIX constants, shared-memory naming, libc path
|
|
202
214
|
detection, and close-on-exec helpers.
|
|
203
215
|
- `src/connections/windows.ts`: Windows FFI loader and named file-mapping
|
|
204
|
-
primitives used by Deno and Bun.
|
|
216
|
+
primitives used by Node 26, Deno, and Bun.
|
|
205
217
|
- `src/knitting_shared_memory.cc`: Native Node addon for shared-memory create,
|
|
206
218
|
map, unlink, and descriptor operations, including Windows named mappings.
|
|
207
219
|
- `src/knitting_shm.cc`: Native Node addon for futex/wait helpers used by parked
|
|
@@ -211,8 +223,8 @@ The core flow is:
|
|
|
211
223
|
FFI runtimes.
|
|
212
224
|
- `prebuilds/*/*.node`: Tracked Node native-addon prebuilds for supported
|
|
213
225
|
platform/Node ABI combinations.
|
|
214
|
-
- `prebuilds/win32-x64/*.dll`: Tracked Windows FFI DLL prebuild used by
|
|
215
|
-
Deno shared-memory primitives on Windows.
|
|
226
|
+
- `prebuilds/win32-x64/*.dll`: Tracked Windows FFI DLL prebuild used by Node 26,
|
|
227
|
+
Bun, and Deno shared-memory primitives on Windows.
|
|
216
228
|
|
|
217
229
|
## Permissions
|
|
218
230
|
|
|
@@ -269,6 +281,8 @@ The core flow is:
|
|
|
269
281
|
- `test/_runner.ts`: Runtime-neutral test runner shim used by the test suite.
|
|
270
282
|
- `test/abortSignal.test.ts`: Shared abort bitset behavior.
|
|
271
283
|
- `test/api-cap.test.ts`: API limits such as maximum task id count.
|
|
284
|
+
- `test/compiled-worker.test.ts`: Compiled-artifact validation, public pool
|
|
285
|
+
integration, source-derived `.knt` paths, and unsupported-feature guards.
|
|
272
286
|
- `test/shared-buffer-io.test.ts`: Shared-buffer IO read/write behavior.
|
|
273
287
|
- `test/file-descriptor.test.ts`: File descriptor metadata and mapping behavior.
|
|
274
288
|
- `test/inliner.test.ts`: Inline executor behavior and thresholds.
|
|
@@ -309,9 +323,11 @@ The core flow is:
|
|
|
309
323
|
|
|
310
324
|
- `build/Release/*.node`: Native addon output produced by
|
|
311
325
|
`scripts/build-native-addons.ts`.
|
|
312
|
-
- `knitting.js`, `knitting.d.ts`, `shared-
|
|
313
|
-
`
|
|
314
|
-
|
|
326
|
+
- `knitting.js`, `knitting.d.ts`, `process-shared-buffer.js`,
|
|
327
|
+
`process-shared-buffer.d.ts`, `shared-memory.js`, `shared-memory.d.ts`,
|
|
328
|
+
`unsafe.js`, `unsafe.d.ts`, `utils.js`, `utils.d.ts`, and generated
|
|
329
|
+
`src/**/*.js`/`src/**/*.d.ts`: npm release build artifacts produced by
|
|
330
|
+
`build.ts` and `scripts/rewrite-declaration-imports.mjs`.
|
|
315
331
|
- `results/`: Benchmark output produced by `run.sh`.
|
|
316
332
|
- `log/`, `logs`, and `*.log`: Local runtime/log output.
|
|
317
333
|
- `node_modules/`: Installed dependencies. Not part of the source map.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knitting",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.60",
|
|
4
4
|
"description": "Shared-memory IPC runtime for Node.js, Deno, and Bun.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
"types": "./knitting.d.ts",
|
|
21
21
|
"default": "./knitting.js"
|
|
22
22
|
},
|
|
23
|
+
"./process-shared-buffer": {
|
|
24
|
+
"types": "./process-shared-buffer.d.ts",
|
|
25
|
+
"default": "./process-shared-buffer.js"
|
|
26
|
+
},
|
|
23
27
|
"./shared-memory": {
|
|
24
28
|
"types": "./shared-memory.d.ts",
|
|
25
29
|
"default": "./shared-memory.js"
|
|
@@ -40,9 +44,16 @@
|
|
|
40
44
|
"prebuilds/**/*.node",
|
|
41
45
|
"prebuilds/**/*.dll",
|
|
42
46
|
"scripts/build-native-addons.ts",
|
|
47
|
+
"scripts/build-compiled-worker.ts",
|
|
48
|
+
"scripts/compiled-worker/**/*.ts",
|
|
49
|
+
"scripts/compiled-worker/**/*.d.ts",
|
|
43
50
|
"src/**/*.cc",
|
|
51
|
+
"src/**/*.d.ts",
|
|
52
|
+
"src/**/*.js",
|
|
44
53
|
"knitting.d.ts",
|
|
45
54
|
"knitting.js",
|
|
55
|
+
"process-shared-buffer.d.ts",
|
|
56
|
+
"process-shared-buffer.js",
|
|
46
57
|
"shared-memory.d.ts",
|
|
47
58
|
"shared-memory.js",
|
|
48
59
|
"unsafe.d.ts",
|
|
@@ -51,19 +62,22 @@
|
|
|
51
62
|
"utils.js"
|
|
52
63
|
],
|
|
53
64
|
"scripts": {
|
|
54
|
-
"
|
|
55
|
-
"build
|
|
56
|
-
"build:
|
|
57
|
-
"build:
|
|
65
|
+
"clean": "bun run scripts/clean-generated.ts",
|
|
66
|
+
"build": "bun run build.ts && node scripts/rewrite-declaration-imports.mjs",
|
|
67
|
+
"build:js": "bun run build.ts && node scripts/rewrite-declaration-imports.mjs",
|
|
68
|
+
"build:types": "bun run build.ts && node scripts/rewrite-declaration-imports.mjs",
|
|
69
|
+
"build:npm": "bun run build.ts && node scripts/rewrite-declaration-imports.mjs",
|
|
58
70
|
"build:native": "bun run scripts/build-native-addons.ts",
|
|
71
|
+
"build:compiled": "bun run scripts/build-compiled-worker.ts",
|
|
59
72
|
"build:release": "bun run build:native && npm run build",
|
|
60
|
-
"build:node": "
|
|
73
|
+
"build:node": "bun run build.ts && node scripts/rewrite-declaration-imports.mjs",
|
|
61
74
|
"prepack": "npm run build",
|
|
62
75
|
"release:npm": "npm run test:all && npm publish",
|
|
63
76
|
"release:npm:dry-run": "npm publish --dry-run",
|
|
64
77
|
"test": "npm run test:deno",
|
|
65
78
|
"test:deno": "deno test -A --ignore=test/runtime.node.test.ts --ignore=test/runtime.process.test.ts",
|
|
66
79
|
"test:node": "node --no-warnings --experimental-transform-types --test \"./test/*.test.ts\"",
|
|
80
|
+
"test:node:26": "node --no-warnings --experimental-ffi test/node26-ffi.integration.mjs",
|
|
67
81
|
"test:bun": "bun test ./test/*.test.ts --path-ignore-patterns=**/tx-queue.test.ts",
|
|
68
82
|
"test:runtimes": "npm run test:node && npm run test:bun",
|
|
69
83
|
"test:all": "npm run test:deno && npm run test:runtimes",
|
|
@@ -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,276 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/// <reference types="bun" />
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
chmodSync,
|
|
6
|
+
existsSync,
|
|
7
|
+
mkdirSync,
|
|
8
|
+
renameSync,
|
|
9
|
+
rmSync,
|
|
10
|
+
statSync,
|
|
11
|
+
} from "node:fs";
|
|
12
|
+
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
13
|
+
import { homedir } from "node:os";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
|
|
16
|
+
type Options = {
|
|
17
|
+
modulePath: string;
|
|
18
|
+
outputPath: string;
|
|
19
|
+
manifestPath: string;
|
|
20
|
+
tasks: string[];
|
|
21
|
+
compiler?: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
25
|
+
const runtime = resolve(here, "compiled-worker/runtime.ts");
|
|
26
|
+
const taskShim = resolve(here, "compiled-worker/task-shim.ts");
|
|
27
|
+
const repositoryEntry = resolve(here, "../knitting.ts");
|
|
28
|
+
const PORFFOR_REPOSITORY = "https://github.com/CanadaHonk/porffor.git";
|
|
29
|
+
const PORFFOR_REVISION = "747d551844750fc5ed32cf88cdf0b3854aee267e";
|
|
30
|
+
|
|
31
|
+
const usage = (): never => {
|
|
32
|
+
console.error(
|
|
33
|
+
"Usage: bun scripts/build-compiled-worker.ts --module tasks.ts " +
|
|
34
|
+
"--out tasks.knt --tasks taskA,taskB [--porf /path/to/porf]",
|
|
35
|
+
);
|
|
36
|
+
process.exit(2);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const readOptions = (): Options => {
|
|
40
|
+
const args = process.argv.slice(2);
|
|
41
|
+
let modulePath: string | undefined;
|
|
42
|
+
let outputPath: string | undefined;
|
|
43
|
+
let manifestPath: string | undefined;
|
|
44
|
+
let tasks: string[] | undefined;
|
|
45
|
+
let compiler: string | undefined;
|
|
46
|
+
for (let index = 0; index < args.length; index++) {
|
|
47
|
+
const argument = args[index]!;
|
|
48
|
+
const value = args[index + 1];
|
|
49
|
+
if (value === undefined) usage();
|
|
50
|
+
if (argument === "--module") modulePath = value;
|
|
51
|
+
else if (argument === "--out") outputPath = value;
|
|
52
|
+
else if (argument === "--manifest") manifestPath = value;
|
|
53
|
+
else if (argument === "--tasks") tasks = value.split(",").filter(Boolean);
|
|
54
|
+
else if (argument === "--porf") compiler = value;
|
|
55
|
+
else usage();
|
|
56
|
+
index++;
|
|
57
|
+
}
|
|
58
|
+
if (modulePath === undefined || outputPath === undefined || !tasks?.length) {
|
|
59
|
+
usage();
|
|
60
|
+
}
|
|
61
|
+
for (const name of tasks) {
|
|
62
|
+
if (!/^[$A-Z_a-z][$\w]*$/.test(name) && name !== "default") {
|
|
63
|
+
throw new Error("Compiled task name is not an export identifier: " + name);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
modulePath: resolve(modulePath),
|
|
68
|
+
outputPath: resolve(outputPath),
|
|
69
|
+
manifestPath: manifestPath === undefined
|
|
70
|
+
? resolve(outputPath) + ".json"
|
|
71
|
+
: resolve(manifestPath),
|
|
72
|
+
tasks,
|
|
73
|
+
compiler,
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const commandWorks = (command: string): boolean => {
|
|
78
|
+
try {
|
|
79
|
+
const result = Bun.spawnSync([command, "--version"], {
|
|
80
|
+
stdout: "pipe",
|
|
81
|
+
stderr: "pipe",
|
|
82
|
+
});
|
|
83
|
+
return result.exitCode === 0 &&
|
|
84
|
+
new TextDecoder().decode(result.stdout).startsWith("alpha ");
|
|
85
|
+
} catch {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const compilerPath = (input: string): string => {
|
|
91
|
+
const decoded = input.startsWith("file:") ? fileURLToPath(input) : input;
|
|
92
|
+
const path = decoded.includes("/") || decoded.includes("\\")
|
|
93
|
+
? resolve(decoded)
|
|
94
|
+
: decoded;
|
|
95
|
+
return existsSync(path) && statSync(path).isDirectory()
|
|
96
|
+
? join(path, "porf")
|
|
97
|
+
: path;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const installCompiler = (): string => {
|
|
101
|
+
const cacheRoot = process.env.XDG_CACHE_HOME ?? join(homedir(), ".cache");
|
|
102
|
+
const cache = join(
|
|
103
|
+
cacheRoot,
|
|
104
|
+
"knitting",
|
|
105
|
+
"porffor-" + PORFFOR_REVISION.slice(0, 12),
|
|
106
|
+
);
|
|
107
|
+
const executable = join(cache, "porf");
|
|
108
|
+
if (commandWorks(executable)) return executable;
|
|
109
|
+
|
|
110
|
+
const temporary = cache + ".tmp-" + process.pid;
|
|
111
|
+
rmSync(temporary, { recursive: true, force: true });
|
|
112
|
+
mkdirSync(temporary, { recursive: true });
|
|
113
|
+
const commands = [
|
|
114
|
+
["git", "-C", temporary, "init", "--quiet"],
|
|
115
|
+
["git", "-C", temporary, "remote", "add", "origin", PORFFOR_REPOSITORY],
|
|
116
|
+
[
|
|
117
|
+
"git",
|
|
118
|
+
"-C",
|
|
119
|
+
temporary,
|
|
120
|
+
"fetch",
|
|
121
|
+
"--quiet",
|
|
122
|
+
"--depth",
|
|
123
|
+
"1",
|
|
124
|
+
"origin",
|
|
125
|
+
PORFFOR_REVISION,
|
|
126
|
+
],
|
|
127
|
+
["git", "-C", temporary, "checkout", "--quiet", "--detach", "FETCH_HEAD"],
|
|
128
|
+
];
|
|
129
|
+
console.error("Knitting: downloading the pinned Porffor compiler (first run only)");
|
|
130
|
+
try {
|
|
131
|
+
for (const command of commands) {
|
|
132
|
+
const result = Bun.spawnSync(command, { stdout: "inherit", stderr: "inherit" });
|
|
133
|
+
if (result.exitCode !== 0) {
|
|
134
|
+
throw new Error(command[0] + " exited with code " + result.exitCode);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
rmSync(cache, { recursive: true, force: true });
|
|
138
|
+
renameSync(temporary, cache);
|
|
139
|
+
} catch (error) {
|
|
140
|
+
rmSync(temporary, { recursive: true, force: true });
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
if (!commandWorks(executable)) {
|
|
144
|
+
throw new Error("Downloaded Porffor compiler is unavailable");
|
|
145
|
+
}
|
|
146
|
+
return executable;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const resolveCompiler = (options: Options): string => {
|
|
150
|
+
const configured = options.compiler ?? process.env.PORFFOR_MAIN ??
|
|
151
|
+
process.env.PORF;
|
|
152
|
+
if (configured !== undefined) {
|
|
153
|
+
const candidate = compilerPath(configured);
|
|
154
|
+
if (!commandWorks(candidate)) {
|
|
155
|
+
throw new Error("Porffor main compiler is unavailable: " + candidate);
|
|
156
|
+
}
|
|
157
|
+
return candidate;
|
|
158
|
+
}
|
|
159
|
+
if (commandWorks("porf")) return "porf";
|
|
160
|
+
return installCompiler();
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const quote = (value: string): string => JSON.stringify(value);
|
|
164
|
+
|
|
165
|
+
const makeEntry = (modulePath: string, tasks: string[]): string => {
|
|
166
|
+
const imports = tasks.map((name, index) =>
|
|
167
|
+
name === "default"
|
|
168
|
+
? `import __knitExport${index} from ${quote(modulePath)};`
|
|
169
|
+
: `import { ${name} as __knitExport${index} } from ${quote(modulePath)};`
|
|
170
|
+
);
|
|
171
|
+
const functions = tasks.map((_, index) =>
|
|
172
|
+
`typeof __knitExport${index} === "function" ` +
|
|
173
|
+
`? __knitExport${index} : __knitExport${index}.f`
|
|
174
|
+
);
|
|
175
|
+
return [
|
|
176
|
+
...imports,
|
|
177
|
+
`import { runJsonWorker } from ${quote(runtime)};`,
|
|
178
|
+
`runJsonWorker([${functions.join(", ")}]);`,
|
|
179
|
+
"",
|
|
180
|
+
].join("\n");
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const resolvesToKnitting = (specifier: string, resolveDir: string): boolean => {
|
|
184
|
+
if (specifier === "knitting" || specifier === "@vixeny/knitting") return true;
|
|
185
|
+
if (!specifier.startsWith(".") && !isAbsolute(specifier)) return false;
|
|
186
|
+
const candidate = resolve(resolveDir, specifier).replace(/\.(?:js|ts)$/, "");
|
|
187
|
+
return candidate === repositoryEntry.replace(/\.ts$/, "");
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const run = async (): Promise<void> => {
|
|
191
|
+
const options = readOptions();
|
|
192
|
+
const outputDirectory = dirname(options.outputPath);
|
|
193
|
+
const workDirectory = join(outputDirectory, ".knitting-compiled");
|
|
194
|
+
const entryPath = join(workDirectory, "entry.ts");
|
|
195
|
+
const bundlePath = join(workDirectory, "worker.bundle.js");
|
|
196
|
+
mkdirSync(workDirectory, { recursive: true });
|
|
197
|
+
mkdirSync(dirname(options.manifestPath), { recursive: true });
|
|
198
|
+
await Bun.write(entryPath, makeEntry(options.modulePath, options.tasks));
|
|
199
|
+
|
|
200
|
+
const build = await Bun.build({
|
|
201
|
+
entrypoints: [entryPath],
|
|
202
|
+
format: "esm",
|
|
203
|
+
target: "browser",
|
|
204
|
+
minify: { syntax: true, whitespace: false, identifiers: false },
|
|
205
|
+
plugins: [{
|
|
206
|
+
name: "knitting-compiled-worker-api",
|
|
207
|
+
setup(builder) {
|
|
208
|
+
builder.onResolve({ filter: /.*/ }, (args) =>
|
|
209
|
+
resolvesToKnitting(args.path, args.resolveDir)
|
|
210
|
+
? { path: taskShim }
|
|
211
|
+
: undefined
|
|
212
|
+
);
|
|
213
|
+
},
|
|
214
|
+
}],
|
|
215
|
+
});
|
|
216
|
+
if (!build.success || build.outputs[0] === undefined) {
|
|
217
|
+
for (const log of build.logs) console.error(log);
|
|
218
|
+
throw new Error("Bun could not bundle the compiled worker");
|
|
219
|
+
}
|
|
220
|
+
await Bun.write(bundlePath, build.outputs[0]);
|
|
221
|
+
|
|
222
|
+
const porf = resolveCompiler(options);
|
|
223
|
+
const versionResult = Bun.spawnSync([porf, "--version"], {
|
|
224
|
+
stdout: "pipe",
|
|
225
|
+
stderr: "pipe",
|
|
226
|
+
});
|
|
227
|
+
const version = new TextDecoder().decode(versionResult.stdout).trim();
|
|
228
|
+
console.error("Knitting: compiling " + relative(process.cwd(), options.modulePath));
|
|
229
|
+
const compilerEnvironment = { ...process.env };
|
|
230
|
+
if (process.platform === "linux" && compilerEnvironment.CC === undefined) {
|
|
231
|
+
compilerEnvironment.CC = "cc -Wno-stringop-overflow";
|
|
232
|
+
}
|
|
233
|
+
const compile = Bun.spawnSync([
|
|
234
|
+
porf,
|
|
235
|
+
"native",
|
|
236
|
+
"--module",
|
|
237
|
+
"--quiet",
|
|
238
|
+
"-O3",
|
|
239
|
+
"--flto=auto",
|
|
240
|
+
bundlePath,
|
|
241
|
+
"-o",
|
|
242
|
+
options.outputPath,
|
|
243
|
+
], {
|
|
244
|
+
stdout: "inherit",
|
|
245
|
+
stderr: "inherit",
|
|
246
|
+
env: compilerEnvironment,
|
|
247
|
+
});
|
|
248
|
+
if (compile.exitCode !== 0) {
|
|
249
|
+
throw new Error("Porffor exited with code " + compile.exitCode);
|
|
250
|
+
}
|
|
251
|
+
chmodSync(options.outputPath, 0o755);
|
|
252
|
+
|
|
253
|
+
await Bun.write(
|
|
254
|
+
options.manifestPath,
|
|
255
|
+
JSON.stringify({
|
|
256
|
+
format: "knitting-compiled-worker",
|
|
257
|
+
version: 1,
|
|
258
|
+
protocol: "knitting-json-v1",
|
|
259
|
+
compiler: { name: "porffor", version },
|
|
260
|
+
target: { platform: process.platform, arch: process.arch },
|
|
261
|
+
source: relative(outputDirectory, options.modulePath).replaceAll("\\", "/"),
|
|
262
|
+
sourceMtimeMs: statSync(options.modulePath).mtimeMs,
|
|
263
|
+
capabilities: {
|
|
264
|
+
input: "json",
|
|
265
|
+
output: "json",
|
|
266
|
+
async: false,
|
|
267
|
+
abortSignal: true,
|
|
268
|
+
binaryValues: true,
|
|
269
|
+
},
|
|
270
|
+
tasks: options.tasks.map((exportName, index) => ({ index, exportName })),
|
|
271
|
+
}, null, 2) + "\n",
|
|
272
|
+
);
|
|
273
|
+
rmSync(workDirectory, { recursive: true, force: true });
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
await run();
|