// 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 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 ` ${title}
`; }; 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' : ''}`);