knitting 0.1.56 → 0.1.61
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/BROWSER.md +134 -0
- package/README.md +347 -46
- package/knitting.browser.d.ts +6 -0
- package/knitting.browser.js +1 -0
- package/knitting.d.ts +3 -2
- package/knitting.js +3 -3
- package/map.md +21 -9
- package/package.json +17 -2
- package/prebuilds/darwin-arm64-node-127/knitting_buffer_pointer.node +0 -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_buffer_pointer.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/win32-x64/knitting_windows_shared_memory.dll +0 -0
- package/prebuilds/win32-x64-node-127/knitting_buffer_pointer.node +0 -0
- package/prebuilds/win32-x64-node-127/knitting_shared_memory.node +0 -0
- package/prebuilds/win32-x64-node-127/knitting_shm.node +0 -0
- package/prebuilds/win32-x64-node-137/knitting_buffer_pointer.node +0 -0
- package/prebuilds/win32-x64-node-137/knitting_shared_memory.node +0 -0
- package/prebuilds/win32-x64-node-137/knitting_shm.node +0 -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/src/api.d.ts +24 -1
- package/src/api.js +311 -27
- package/src/common/module-url.d.ts +1 -0
- package/src/common/module-url.js +30 -2
- package/src/common/node-compat.d.ts +2 -0
- package/src/common/path-canonical.js +20 -6
- package/src/common/runtime.d.ts +3 -1
- package/src/common/runtime.js +25 -4
- package/src/common/task-source.d.ts +2 -0
- package/src/common/task-source.js +17 -1
- package/src/common/worker-runtime.js +16 -7
- package/src/connections/buffer-reference-native.js +25 -1
- package/src/connections/buffer-reference.d.ts +23 -2
- package/src/connections/buffer-reference.js +143 -29
- package/src/connections/bun.d.ts +1 -1
- package/src/connections/bun.js +25 -14
- package/src/connections/deno.d.ts +3 -1
- package/src/connections/deno.js +35 -14
- package/src/connections/external-array-buffer.d.ts +2 -0
- package/src/connections/external-array-buffer.js +33 -0
- package/src/connections/node-addons.d.ts +11 -0
- package/src/connections/node-addons.js +49 -1
- 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 +1 -1
- package/src/connections/node.js +20 -20
- package/src/connections/package-assets.js +25 -15
- package/src/connections/posix.d.ts +42 -0
- package/src/connections/posix.js +101 -0
- package/src/connections/process-shared-buffer.d.ts +1 -0
- package/src/connections/process-shared-buffer.js +11 -45
- package/src/connections/types.d.ts +4 -0
- package/src/connections/windows.d.ts +19 -10
- package/src/connections/windows.js +87 -66
- package/src/error.d.ts +7 -6
- package/src/error.js +8 -7
- package/src/memory/lock.d.ts +112 -77
- package/src/memory/lock.js +314 -87
- package/src/memory/payloadCodec.d.ts +11 -2
- package/src/memory/payloadCodec.js +129 -37
- package/src/memory/regionRegistry.d.ts +1 -3
- package/src/memory/regionRegistry.js +16 -14
- package/src/permission/compatibility.d.ts +28 -0
- package/src/permission/compatibility.js +239 -0
- package/src/permission/index.d.ts +2 -0
- package/src/permission/index.js +1 -0
- package/src/permission/protocol.d.ts +1 -0
- package/src/permission/protocol.js +59 -15
- 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.js +9 -0
- package/src/runtime/inline-executor.js +27 -15
- package/src/runtime/pool.d.ts +121 -5
- package/src/runtime/pool.js +263 -49
- package/src/runtime/process-worker.d.ts +3 -13
- package/src/runtime/process-worker.js +97 -101
- package/src/runtime/tx-queue.d.ts +18 -2
- package/src/runtime/tx-queue.js +56 -16
- package/src/runtime/worker-common.d.ts +13 -0
- package/src/runtime/worker-common.js +102 -0
- package/src/types.d.ts +89 -9
- package/src/worker/composable-runners.js +3 -2
- package/src/worker/loop.d.ts +1 -0
- package/src/worker/loop.js +52 -17
- package/src/worker/rx-queue.d.ts +11 -1
- package/src/worker/rx-queue.js +4 -1
- package/src/worker/task-loader.d.ts +5 -4
- package/src/worker/task-loader.js +13 -7
- package/src/worker/timers.d.ts +8 -1
- package/src/worker/timers.js +28 -23
|
@@ -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();
|