mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-22 05:59:31 +08:00
* Expand static three.js workflows and host integration * Preserve JavaScript class state in static three.js workflows * Preserve inferred JavaScript behavior across static workflows * Preserve inferred callables and native compatibility boundaries * Retain annotated JavaScript factory exports and bootstrap-safe call spreads * Preserve Buffer and child callback identities in static packages * Clarify JavaScript symbol spread support
38 lines
2.4 KiB
TypeScript
38 lines
2.4 KiB
TypeScript
import { spawnSync } from "node:child_process";
|
|
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { compileLibrary } from "@scriptc/compiler";
|
|
import { expect, test } from "vitest";
|
|
|
|
const fixture = join(import.meta.dirname, "../library-mode/wasm");
|
|
const hasClang = spawnSync("clang", ["--version"]).status === 0;
|
|
test.skipIf(!hasClang).each(["dev", "release"] as const)("three.js sends animated geometry, materials and resource lifecycle to a native host in %s", async (optimization) => {
|
|
const directory = await mkdtemp("/tmp/scriptc-three-library-");
|
|
const sanitize = process.env["SCRIPTC_SAN"] === "1";
|
|
try {
|
|
const profile = JSON.parse(await readFile(join(fixture, "three.json"), "utf8"));
|
|
const profilePath = join(directory, "profile.json");
|
|
await writeFile(profilePath, JSON.stringify({ ...profile, name: "three-native-embedding", entry: join(fixture, "three.mjs"), optimization }));
|
|
const built = await compileLibrary({ profilePath, outDir: directory, sanitize });
|
|
if (!built.ok) throw new Error(built.diagnostics.map((diagnostic) => `${diagnostic.code}: ${diagnostic.message}`).join("\n"));
|
|
const binary = join(directory, "host");
|
|
const linked = spawnSync("clang", ["-std=c11", ...(sanitize ? ["-fsanitize=address,undefined"] : []), join(fixture, "three-native.c"), built.archivePath, "-lm", "-o", binary], { encoding: "utf8" });
|
|
expect(linked.status, linked.stderr).toBe(0);
|
|
const actual = spawnSync(binary, [], { encoding: "utf8", timeout: 30_000 });
|
|
expect(actual.status, actual.stderr).toBe(0);
|
|
const reference = spawnSync(process.execPath, ["--no-warnings", "--input-type=module", "-e", `
|
|
const events=[];
|
|
for (const name of ["vertex","surface","resource"]) globalThis[name]=(...values)=>events.push([name,...values.map(value=>Number(value.toFixed(9)))]);
|
|
const {frame,dispose}=await import(${JSON.stringify(join(fixture, "three.mjs"))});
|
|
for (const time of [0,123,2000]) frame(time,1.5);
|
|
dispose();
|
|
console.log(JSON.stringify(events));
|
|
`], { encoding: "utf8" });
|
|
expect(reference.status, reference.stderr).toBe(0);
|
|
const events = JSON.parse(reference.stdout);
|
|
expect(actual.stdout.trim().split("\n").map((line) => JSON.parse(line))).toEqual([...events, ...events]);
|
|
} finally {
|
|
await rm(directory, { recursive: true, force: true });
|
|
}
|
|
}, 600_000);
|