wai/wai-ui becomes wai/wai-app, the library `wai_app`, with no binary and no `cli` feature: `wai`, built with its feature `app`, is its command line and its MCP server. Its served files are named wai-app-* (the WebAssembly package wai_app), the recordings wai-app-*.json. - export.rs gives the files of a starter project for a program and the facts its project file holds (title, summary, `wai dev`'s mode for the app's room, a watch room's file, a show's audience); `wai create --from app.oui` writes them, the project file and the licence. The export no longer writes app.json, room.toml, relay.toml, package.json, check.mjs or serve.mjs: wai.json names the room, `wai dev` runs it and `wai app check` checks the project. Its README and AGENTS.md say so, and the README its licence. - runtime.rs reads a Create runtime by its listing (create/wai-app-runtime.json), checking each file's SHA-256. - bridge.rs keeps the bridge on 127.0.0.1 a coding agent streams a program into the page through, with a stream helper; the stdio server, its tools and the binary's test go (`wai mcp --toolset app` serves them). - The page's Export hands over app.oui, the program in its canonical form, and the command that makes it a project; the ZIP writer and the page's export in WebAssembly go. The page names `wai mcp --toolset app` for the coding agent. - joule-ui/docs/create.md §4 and §5: the export as `wai create --from app.oui`, and the agent's tools app_guide, app_check, app_stream and app_export. Co-Authored-By: Claude Opus 5.5 <[email protected]>
58 lines
2.4 KiB
JavaScript
58 lines
2.4 KiB
JavaScript
// The page's session: wai-app's WebAssembly build, the program as it streams, and the log
|
|
// every action a person takes on the page is sealed into (joule-ui SPEC §6, §7).
|
|
//
|
|
// `fire(action, inputs, handler)` is the interaction lifecycle around an asynchronous
|
|
// handler: authorized first (a denied action's handler never runs), the handler run and
|
|
// timed on the page's clock, then sealed as the next link of the log under the page's own
|
|
// key. A page has no energy meter: the figure is the estimator's, from the handler's wall
|
|
// time, and the log says so (`Estimator`).
|
|
import init, { Session, verifyLog, registry, guide, check } from "./pkg/wai_app.js";
|
|
|
|
export { verifyLog, registry, guide, check };
|
|
|
|
export async function openSession() {
|
|
await init();
|
|
const seed = crypto.getRandomValues(new Uint8Array(32));
|
|
const s = new Session(seed);
|
|
seed.fill(0);
|
|
return new PageSession(s);
|
|
}
|
|
|
|
export class PageSession {
|
|
constructor(wasm) {
|
|
this.w = wasm;
|
|
this.listeners = new Set();
|
|
this.actor = wasm.actor();
|
|
}
|
|
push(chunk) { return JSON.parse(this.w.push(chunk)); }
|
|
finish() { return JSON.parse(this.w.finish()); }
|
|
reset() { this.w.reset(); }
|
|
program() { return this.w.program(); }
|
|
canonical() { return this.w.canonical(); }
|
|
log() { return JSON.parse(this.w.log()); }
|
|
logRaw() { return this.w.logRaw(); }
|
|
verify() { return JSON.parse(this.w.verify()); }
|
|
totalUj() { return this.w.totalUj(); }
|
|
on(f) { this.listeners.add(f); return () => this.listeners.delete(f); }
|
|
note(entry) { for (const f of this.listeners) { try { f(entry); } catch { /* a view's own fault */ } } }
|
|
|
|
async fire(action, inputs, handler) {
|
|
const b = JSON.parse(this.w.beginAction(action, JSON.stringify(inputs === undefined ? null : inputs)));
|
|
if (b.sealed) {
|
|
this.note(b.sealed);
|
|
throw new Error(`${action} was denied: ${b.sealed.reason}`);
|
|
}
|
|
const t0 = performance.now();
|
|
let out;
|
|
let err = null;
|
|
try { out = await handler(); } catch (e) { err = e; }
|
|
const wall = performance.now() - t0;
|
|
const output = err ? { error: String((err && err.message) || err) } : out === undefined ? null : out;
|
|
let text;
|
|
try { text = JSON.stringify(output); } catch { text = JSON.stringify(String(output)); }
|
|
const entry = JSON.parse(this.w.finishAction(b.pending, text === undefined ? "null" : text, wall));
|
|
this.note(entry);
|
|
if (err) throw err;
|
|
return out;
|
|
}
|
|
}
|