mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-08 08:44:37 +08:00
Scope-B milestone NI-1, API side: the explicit call API that replaces the build container's hand-written node subprocess (api patch 09). - The new package @scriptc/node exports callSync(specifier, name, ...args) and call(...). The module loads with require() from the calling module; arguments and results cross as JSON copies; a thrown Error crosses as its nearest intrinsic class with its message and string code, other thrown values as JSON copies; callSync refuses a function that returns a promise. Its Node implementation runs the calls in-process with the same copies, so a program prints the same under Node and compiled. - The compiler lowers calls to the named or namespace imports (node-api-import.ts, lower-node-island.ts) to the nodeIsland.callSync and nodeIsland.call libCalls: the calling module's real path, the specifier, the export name and the boxed argument array, with the result checked against the declared type like `JSON.parse(s) as T`. Arguments and results whose types are not JSON data are refused at build time, and the functions and the namespace refuse as values. - Corpus programs 6800-6803 (sync and async results, errors, process.exit from Node with the program's exit listeners, Node's pending timers keeping the program alive) run under Node and as binaries that load libnode; `// @requires-libnode` skips them where SCRIPTC_LIBNODE names no pack (until the pack CI matrix publishes packs). The node-island harness covers loading Node only on the first call, the beside packaging, a missing pack, a pack of another Node version or bridge ABI, and the executable's symbols. - Release tooling publishes @scriptc/node with the other packages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
40 lines
1.5 KiB
TypeScript
40 lines
1.5 KiB
TypeScript
// @requires-libnode
|
|
// Synchronous calls into Node.js through @scriptc/node: arguments and
|
|
// results cross as JSON copies, module state lives on between calls, and
|
|
// output from both sides interleaves in program order.
|
|
import { callSync } from "@scriptc/node";
|
|
import * as node from "@scriptc/node";
|
|
import { callSync as runInNode } from "@scriptc/node";
|
|
|
|
interface Point {
|
|
x: number;
|
|
y: number;
|
|
label: string;
|
|
}
|
|
|
|
console.log("before");
|
|
const sum = callSync<number>("./math.cjs", "add", 2, 3);
|
|
console.log("sum", sum, sum + 1);
|
|
console.log(callSync<string>("./math.cjs", "greet", "wörld ☃ 🌍"));
|
|
const p = callSync<Point>("./math.cjs", "point", 1.5, -2);
|
|
console.log(p.x + p.y, p.label, JSON.stringify(p));
|
|
const squares = callSync<number[]>("./math.cjs", "squares", 5);
|
|
console.log(squares.length, squares.join(","));
|
|
const nothing = callSync<undefined>("./math.cjs", "nothing");
|
|
console.log(nothing === undefined);
|
|
const echoed = callSync(
|
|
"./math.cjs",
|
|
"echo",
|
|
{ a: [1, "two", null, true], b: { c: "d" } },
|
|
undefined,
|
|
[undefined, 0.1],
|
|
);
|
|
console.log(JSON.stringify(echoed));
|
|
const flags = callSync<boolean[]>("./math.cjs", "flags", 3);
|
|
console.log(flags.map((f) => (f ? "y" : "n")).join(""));
|
|
console.log(node.callSync<string>("pkg-esm", "shout", "an es module, loaded with require"));
|
|
console.log(runInNode<number>("./math.cjs", "add", 40, 2));
|
|
console.log(callSync<number>("./math.cjs", "count"), callSync<number>("./math.cjs", "count"));
|
|
callSync("./math.cjs", "say", "from node");
|
|
console.log("after");
|