refactor(spec): installRuntime accepts a lazy root resolver

The web bundle imports the runtime before the spec, so the action root
on globalThis.actions only exists after the spec evaluates. Accept a
function form so the goja and web hosts resolve the root per tick.
This commit is contained in:
pj committed 2026-06-01 16:37:30 +05:30
1 parent 26e27832a2
commit b6a706699b
1 file changed
+9 -5
+9 -5
View File
@@ -102,18 +102,22 @@ export function serializeAction(action: ActionDescriptor | null): SerializedActi
} }
// installRuntime defines the next-action and extractor globals for one engine. // installRuntime defines the next-action and extractor globals for one engine.
// root is the generator the spec assigned (globalThis.actions); evaluateExtractors // root is the generator the spec assigned; pass a function when the spec runs
// is the engine's snapshot of the spec's extract() handles. // AFTER this call (the web bundle imports the runtime before the spec, so the
// root only exists on globalThis.actions once the spec has evaluated).
// evaluateExtractors is the engine's snapshot of the spec's extract() handles.
export function installRuntime( export function installRuntime(
host: Host, host: Host,
root: GeneratorNode | null, root: GeneratorNode | null | (() => GeneratorNode | null),
evaluateExtractors: () => Record<number, unknown>, evaluateExtractors: () => Record<number, unknown>,
): void { ): void {
const rng = new Pcg(host.seedHi(), host.seedLo()); const rng = new Pcg(host.seedHi(), host.seedLo());
const resolveRoot = typeof root === "function" ? root : () => root;
defineLockedGlobal("__sanderlingExtractors__", () => evaluateExtractors()); defineLockedGlobal("__sanderlingExtractors__", () => evaluateExtractors());
defineLockedGlobal("__sanderlingNextAction__", () => { defineLockedGlobal("__sanderlingNextAction__", () => {
if (!root) return null; const current = resolveRoot();
return serializeAction(nextAction(root, rng, host)); if (!current) return null;
return serializeAction(nextAction(current, rng, host));
}); });
} }