wai/wai-studio: the panels (Inspect, Verify and receipts, Encode/decode/package, Rooms, Run, Quantum) and the command palette; actions generated from the operation catalogue with a drift check; the core (wai-studio-core) binding the wai crate for the tab. wai dev serves Studio at /_wai/ on its own origin, with the dev stack's routes for it under /_wai/api/. Co-Authored-By: Claude Opus 5.5 <[email protected]>
85 lines
4.7 KiB
JavaScript
85 lines
4.7 KiB
JavaScript
// Build WAI Studio into dist/, one front end for both hosts:
|
|
//
|
|
// node build.mjs [--core-pkg DIR] [--quantum DIR]
|
|
//
|
|
// wai-studio.js the interface, bundled
|
|
// wai-studio-worker.js the core's worker
|
|
// wai-studio.css Studio's styles; tokens.css, the site's design tokens, for a page alone
|
|
// index.html the local host: the page `wai dev` serves at /_wai/
|
|
// hosted.html the hosted host standing alone, on an origin that serves the room
|
|
// client at /room/ and its modules at /moq/ and /pkg/ (as `wai dev` does)
|
|
// pkg/ --core-pkg: the core built for the web (core/, wasm-bindgen --target
|
|
// web --out-name wai_studio_core)
|
|
// quantum/ --quantum: Quantum Studio's dist (wai/quantum-studio: node build.mjs
|
|
// --pkg <its engine package>), its engine in quantum/pkg/
|
|
// BUILD.json each file's SHA-256
|
|
//
|
|
// The site hosts the same files at /studio/ (its scripts/sync-wai-studio.mjs) with a page of
|
|
// its own. Every served name is distinct from the site's other files: its deploy names files
|
|
// by their content, keyed by basename.
|
|
import { build } from 'esbuild';
|
|
import { createHash } from 'node:crypto';
|
|
import { copyFileSync, cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
import { dirname, join, relative } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
const dist = join(here, 'dist');
|
|
const arg = (name) => { const i = process.argv.indexOf(name); return i > 0 ? process.argv[i + 1] : null; };
|
|
const corePkg = arg('--core-pkg');
|
|
const quantum = arg('--quantum');
|
|
|
|
rmSync(dist, { recursive: true, force: true });
|
|
mkdirSync(dist, { recursive: true });
|
|
const common = { bundle: true, format: 'esm', target: ['es2022'], minify: true, legalComments: 'eof', logLevel: 'warning' };
|
|
await build({ ...common, entryPoints: [join(here, 'src/main.js')], outfile: join(dist, 'wai-studio.js') });
|
|
await build({ ...common, entryPoints: [join(here, 'src/worker.js')], outfile: join(dist, 'wai-studio-worker.js') });
|
|
copyFileSync(join(here, 'src/studio.css'), join(dist, 'wai-studio.css'));
|
|
copyFileSync(join(here, 'src/tokens.css'), join(dist, 'tokens.css'));
|
|
|
|
if (corePkg) {
|
|
mkdirSync(join(dist, 'pkg'));
|
|
for (const f of ['wai_studio_core.js', 'wai_studio_core_bg.wasm']) copyFileSync(join(corePkg, f), join(dist, 'pkg', f));
|
|
}
|
|
if (quantum) {
|
|
mkdirSync(join(dist, 'quantum'));
|
|
for (const f of ['studio.js', 'worker.js', 'studio.css']) copyFileSync(join(quantum, f), join(dist, 'quantum', f));
|
|
if (existsSync(join(quantum, 'pkg'))) cpSync(join(quantum, 'pkg'), join(dist, 'quantum', 'pkg'), { recursive: true });
|
|
}
|
|
|
|
// A page: the mount element with its host's attributes. Quantum's attributes only where its
|
|
// files are, so a build without them shows no Quantum panel.
|
|
const page = (title, host, extra) => {
|
|
const q = quantum
|
|
? ` data-quantum-script="quantum/studio.js" data-quantum-css="quantum/studio.css" data-quantum-pkg="quantum/pkg/wai_quantum_ide.js" data-quantum-worker="quantum/worker.js"`
|
|
: '';
|
|
return `<!doctype html>
|
|
<html lang="en" data-theme="auto">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>${title}</title>
|
|
<link rel="icon" href="data:," />
|
|
<link rel="stylesheet" href="tokens.css" />
|
|
<link rel="stylesheet" href="wai-studio.css" />
|
|
<style>
|
|
html, body { margin: 0; background: var(--bg-base); color: var(--text-primary); }
|
|
body { padding: 12px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<main id="wai-studio" data-host="${host}" data-core-pkg="pkg/wai_studio_core.js" data-worker="wai-studio-worker.js"${extra}${q}></main>
|
|
<script type="module" src="wai-studio.js"></script>
|
|
</body>
|
|
</html>
|
|
`;
|
|
};
|
|
writeFileSync(join(dist, 'index.html'), page('WAI Studio', 'local', ' data-api="/_wai/api" data-service="/room-api" data-room-page="/room/"'));
|
|
writeFileSync(join(dist, 'hosted.html'), page('WAI Studio', 'hosted', ' data-service="/room-api" data-room-page="/room/"'));
|
|
|
|
const files = [];
|
|
const walk = (d) => { for (const n of readdirSync(d)) { const p = join(d, n); if (statSync(p).isDirectory()) walk(p); else files.push(p); } };
|
|
walk(dist);
|
|
const sha256 = Object.fromEntries(files.sort().map((p) => [relative(dist, p), createHash('sha256').update(readFileSync(p)).digest('hex')]));
|
|
writeFileSync(join(dist, 'BUILD.json'), `${JSON.stringify({ source: 'open-standards wai/wai-studio', core: !!corePkg, quantum: !!quantum, sha256 }, null, 2)}\n`);
|
|
console.log(`built ${dist}${corePkg ? ', with the core' : ''}${quantum ? ', with Quantum Studio' : ''}`);
|