io-v2-private.ts (2220B)
1 // Private native-adapter validation runner, not RuntimeSession IO dispatch. 2 // Bare computations only; no facility implementation/capability advertisement. 3 import { Core, type Trees } from './io-v2-core.js'; 4 import { canonicalNat, type Reader } from './io-v2-protocol.js'; 5 export function constructors<H>(base: Reader<H> & Pick<Trees<H>, 'leaf' | 'fork' | 'stem' | 'app'>): Trees<H> { 6 const natural = (value: bigint): H => { 7 const bits: H[] = []; 8 if (value < 0n) throw new Error('negative natural'); 9 for (; value; value >>= 1n) bits.push(value & 1n ? base.stem(base.leaf) : base.leaf); 10 let out = base.leaf; for (let i = bits.length - 1; i >= 0; i--) out = base.fork(bits[i]!, out); return out; 11 }; 12 return { ...base, natural, text(value: string): H { 13 let out = base.leaf; const chars = Array.from(value); 14 for (let i = chars.length - 1; i >= 0; i--) out = base.fork(natural(BigInt(chars[i]!.codePointAt(0)!)), out); 15 return out; 16 } }; 17 } 18 export async function runPrivate<H>(tree: Trees<H>, action: H, identity: bigint, sweep: (roots: Iterable<H>) => void) { 19 const engine = new Core(tree, identity, action, [null, null, null], { 20 request: (core, _scope, request) => () => core.wire.result(false, core.wire.problem('unsupported', `${request.group}/${request.operation}`)), 21 release: () => { throw new Error('unexpected owned backend in private core probe'); } }); 22 sweep(engine.roots()); 23 for (let turns = 0; !engine.result; turns++) { 24 const progress = engine.advance(); sweep(engine.roots()); 25 if (!progress) { 26 if (!engine.work.counts.pending) throw new Error('private interpreter stalled'); 27 await engine.wait(); 28 } 29 if (turns % 32 === 0) await new Promise<void>(resolve => setTimeout(resolve, 0)); 30 } 31 if (engine.hasFault) throw engine.fault; 32 const out = engine.result; 33 // Terminal diagnostics stay opaque, including when the test requests a number. 34 const value = out.kind === 'completed' ? canonicalNat(tree, out.value, 64)?.toString() ?? null : null; 35 return { kind: out.kind, value, cleanup: out.cleanup?.items.length ?? 0, 36 tasks: engine.lifecycle.tasks.counts, resources: engine.lifecycle.resources.counts, host: engine.work.counts }; 37 }