@genroc/eval-node 0.16.0 → 0.17.0
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 +3 -3
- package/dist/import.js +17 -15
- package/import.ts +23 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
TypeScript script tasks for [genroc](https://genroc.org). The package provides two binaries:
|
|
4
4
|
|
|
5
|
-
* **`genroc-import`**: the bundler. `genctl` runs it on every `apply` and `
|
|
5
|
+
* **`genroc-import`**: the bundler. `genctl` runs it on every `apply` and `generate` to turn
|
|
6
6
|
`$import: ./script.ts` into one typechecked, self-contained module string.
|
|
7
7
|
* **`genroc-eval-node`**: the worker. It claims script tasks from genroc's queue and runs each
|
|
8
8
|
one in a fresh worker thread.
|
|
@@ -27,7 +27,7 @@ Register the resolver in the `.genroc` beside your definitions:
|
|
|
27
27
|
```yaml
|
|
28
28
|
resolvers:
|
|
29
29
|
- name: import
|
|
30
|
-
phase:
|
|
30
|
+
phase: typed
|
|
31
31
|
ext: [.ts]
|
|
32
32
|
command: [npx, genroc-import]
|
|
33
33
|
types:
|
|
@@ -65,7 +65,7 @@ export default function (input: Input): Output {
|
|
|
65
65
|
}
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
* `genctl
|
|
68
|
+
* `genctl generate` writes `greet.genroc.d.ts` beside the script. `Input` and `Output` come from
|
|
69
69
|
the definition, so a mismatch fails the typecheck.
|
|
70
70
|
* `genctl apply` typechecks and bundles. **A type error or a missing default export fails the
|
|
71
71
|
apply.**
|
package/dist/import.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// The
|
|
3
|
-
// with a non-zero exit (specs/source-resolution.md). Two modes share one `tsc` pass: "
|
|
4
|
-
// writes declarations only, "
|
|
2
|
+
// The typed-phase resolver: manifest on stdin, `{"values": [...]}` on stdout, diagnostic on stderr
|
|
3
|
+
// with a non-zero exit (specs/source-resolution.md). Two modes share one `tsc` pass: "generate"
|
|
4
|
+
// writes declarations only, "resolve" typechecks and bundles.
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { access, writeFile } from "node:fs/promises";
|
|
7
7
|
import { builtinModules } from "node:module";
|
|
@@ -116,7 +116,7 @@ function declarations(at) {
|
|
|
116
116
|
emitted.push(`export type ${identifier(next)} = ${body};`);
|
|
117
117
|
}
|
|
118
118
|
return [
|
|
119
|
-
"// Generated by genroc. Do not edit - regenerate with `genctl
|
|
119
|
+
"// Generated by genroc. Do not edit - regenerate with `genctl generate`.",
|
|
120
120
|
`// ${where.name} (${address(site.pointer)})`,
|
|
121
121
|
"",
|
|
122
122
|
...emitted,
|
|
@@ -307,11 +307,14 @@ function address(pointer) {
|
|
|
307
307
|
.join("")
|
|
308
308
|
.replace(/^\./, "");
|
|
309
309
|
}
|
|
310
|
-
const located = manifest.processes.flatMap((where) => where.sites.map((site) =>
|
|
311
|
-
site
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
})
|
|
310
|
+
const located = manifest.processes.flatMap((where) => where.sites.map((site) => {
|
|
311
|
+
const [script, ...rest] = site.args;
|
|
312
|
+
if (script === undefined || rest.length > 0) {
|
|
313
|
+
die(`${join(where.dir, where.file)}: ${address(site.pointer)}: $import takes one script, ` +
|
|
314
|
+
`and is given ${site.args.length} arguments`);
|
|
315
|
+
}
|
|
316
|
+
return { site, where, file: resolve(where.dir, script) };
|
|
317
|
+
}));
|
|
315
318
|
// The `code`-field contract is this resolver's, not genctl's, so it checks the directive landed
|
|
316
319
|
// there: in a child call (the scaffold's shape) or an external task's input.
|
|
317
320
|
for (const at of located) {
|
|
@@ -328,7 +331,7 @@ for (const at of located) {
|
|
|
328
331
|
for (const at of located) {
|
|
329
332
|
if (!existsSync(at.file)) {
|
|
330
333
|
die(`${join(at.where.dir, at.where.file)}: ${address(at.site.pointer)}: ` +
|
|
331
|
-
`"$import: ${at.site.
|
|
334
|
+
`"$import: ${at.site.args[0]}" names no file (looked at ${at.file})`);
|
|
332
335
|
}
|
|
333
336
|
}
|
|
334
337
|
// One script at two sites with different input types is a refusal, not a union: the union
|
|
@@ -347,13 +350,12 @@ for (const at of located) {
|
|
|
347
350
|
for (const at of byPath.values()) {
|
|
348
351
|
await writeFile(typesPathFor(at.file), declarations(at));
|
|
349
352
|
}
|
|
350
|
-
if (manifest.mode === "
|
|
351
|
-
console.log(JSON.stringify(manifest, null, 2));
|
|
353
|
+
if (manifest.mode === "generate") {
|
|
352
354
|
process.exit(0);
|
|
353
355
|
}
|
|
354
356
|
await typecheck([...byPath.values()]);
|
|
355
|
-
const
|
|
357
|
+
const values = [];
|
|
356
358
|
for (const at of located) {
|
|
357
|
-
|
|
359
|
+
values.push(await bundle(at));
|
|
358
360
|
}
|
|
359
|
-
process.stdout.write(JSON.stringify({
|
|
361
|
+
process.stdout.write(JSON.stringify({ values }));
|
package/import.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// The
|
|
3
|
-
// with a non-zero exit (specs/source-resolution.md). Two modes share one `tsc` pass: "
|
|
4
|
-
// writes declarations only, "
|
|
2
|
+
// The typed-phase resolver: manifest on stdin, `{"values": [...]}` on stdout, diagnostic on stderr
|
|
3
|
+
// with a non-zero exit (specs/source-resolution.md). Two modes share one `tsc` pass: "generate"
|
|
4
|
+
// writes declarations only, "resolve" typechecks and bundles.
|
|
5
5
|
|
|
6
6
|
import { existsSync } from "node:fs";
|
|
7
7
|
import { access, writeFile } from "node:fs/promises";
|
|
@@ -25,9 +25,9 @@ type Site = {
|
|
|
25
25
|
child?: string;
|
|
26
26
|
// The slot as a path of keys and indices, so nothing has to unescape a JSON Pointer.
|
|
27
27
|
pointer: (string | number)[];
|
|
28
|
-
//
|
|
29
|
-
// this resolver's reading of
|
|
30
|
-
|
|
28
|
+
// The argument's words, split as sh splits single quotes. genctl does not read them as paths —
|
|
29
|
+
// that is this resolver's reading of them.
|
|
30
|
+
args: string[];
|
|
31
31
|
// What .genroc asked genctl to type, keyed by the name it chose. This resolver reads Input
|
|
32
32
|
// and Output; which ADDRESS each came from is the config's business, not ours.
|
|
33
33
|
types?: Record<string, Schema>;
|
|
@@ -45,8 +45,7 @@ type ManifestProcess = {
|
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
type Manifest = {
|
|
48
|
-
mode: "
|
|
49
|
-
root: string;
|
|
48
|
+
mode: "generate" | "resolve";
|
|
50
49
|
processes: ManifestProcess[];
|
|
51
50
|
};
|
|
52
51
|
|
|
@@ -170,7 +169,7 @@ function declarations(at: Located): string {
|
|
|
170
169
|
}
|
|
171
170
|
|
|
172
171
|
return [
|
|
173
|
-
"// Generated by genroc. Do not edit - regenerate with `genctl
|
|
172
|
+
"// Generated by genroc. Do not edit - regenerate with `genctl generate`.",
|
|
174
173
|
`// ${where.name} (${address(site.pointer)})`,
|
|
175
174
|
"",
|
|
176
175
|
...emitted,
|
|
@@ -401,11 +400,16 @@ function address(pointer: (string | number)[]): string {
|
|
|
401
400
|
.replace(/^\./, "");
|
|
402
401
|
}
|
|
403
402
|
const located: Located[] = manifest.processes.flatMap((where) =>
|
|
404
|
-
where.sites.map((site) =>
|
|
405
|
-
site
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
403
|
+
where.sites.map((site) => {
|
|
404
|
+
const [script, ...rest] = site.args;
|
|
405
|
+
if (script === undefined || rest.length > 0) {
|
|
406
|
+
die(
|
|
407
|
+
`${join(where.dir, where.file)}: ${address(site.pointer)}: $import takes one script, ` +
|
|
408
|
+
`and is given ${site.args.length} arguments`,
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
return { site, where, file: resolve(where.dir, script) };
|
|
412
|
+
}),
|
|
409
413
|
);
|
|
410
414
|
|
|
411
415
|
// The `code`-field contract is this resolver's, not genctl's, so it checks the directive landed
|
|
@@ -428,7 +432,7 @@ for (const at of located) {
|
|
|
428
432
|
if (!existsSync(at.file)) {
|
|
429
433
|
die(
|
|
430
434
|
`${join(at.where.dir, at.where.file)}: ${address(at.site.pointer)}: ` +
|
|
431
|
-
`"$import: ${at.site.
|
|
435
|
+
`"$import: ${at.site.args[0]}" names no file (looked at ${at.file})`,
|
|
432
436
|
);
|
|
433
437
|
}
|
|
434
438
|
}
|
|
@@ -455,15 +459,14 @@ for (const at of byPath.values()) {
|
|
|
455
459
|
await writeFile(typesPathFor(at.file), declarations(at));
|
|
456
460
|
}
|
|
457
461
|
|
|
458
|
-
if (manifest.mode === "
|
|
459
|
-
console.log(JSON.stringify(manifest, null, 2));
|
|
462
|
+
if (manifest.mode === "generate") {
|
|
460
463
|
process.exit(0);
|
|
461
464
|
}
|
|
462
465
|
|
|
463
466
|
await typecheck([...byPath.values()]);
|
|
464
467
|
|
|
465
|
-
const
|
|
468
|
+
const values: string[] = [];
|
|
466
469
|
for (const at of located) {
|
|
467
|
-
|
|
470
|
+
values.push(await bundle(at));
|
|
468
471
|
}
|
|
469
|
-
process.stdout.write(JSON.stringify({
|
|
472
|
+
process.stdout.write(JSON.stringify({ values }));
|