backends.mjs (1803B)
1 import {decodeBundle} from '../demo-site/dist/bundle.js'; 2 /** 3 * Experimental session boundary. Each method may return a value or Promise. 4 * Public values are cloneable data, never runtime handles or heap checkpoints. 5 * runText(string) -> string 6 * compile(source) -> string[] (retains definitions; failure preserves old ones) 7 * inspect(name, ternaryArguments) -> ternary result 8 * preview(name, limit) -> bounded snapshot 9 * runTree(ternaryProgram, ternaryArguments) -> ternary result (harness probe) 10 * collect(), stats() -> backend-specific diagnostics, dispose() -> idempotent 11 * New implementations need not use Graph, Koffi, the Zig ABI, or treeSession. 12 */ 13 export const backendFactories=Object.freeze({ 14 js: async config=>(await import('./backends/js.mjs')).create(config), 15 'zig-wasm': async config=>(await import('./backends/zig-wasm.mjs')).create(config), 16 }); 17 const hash=async bytes=>Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256',bytes)),x=>x.toString(16).padStart(2,'0')).join(''); 18 // factories is a trusted host/test injection point, never a Worker message field. 19 export async function openSession({backend,bundle:input,hash:pin,name,artifacts},factories=backendFactories) { 20 if(typeof backend!=='string'||!Object.hasOwn(factories,backend))throw new Error('Unknown backend'); 21 const bytes=new Uint8Array(input); 22 if(await hash(bytes)!==pin)throw new Error('Bundle hash mismatch'); 23 const bundle=decodeBundle(bytes); 24 name ??= bundle.exports[0].name; 25 if(!bundle.exports.some(e=>e.name===name))throw new Error('Missing export'); 26 // Authentication and profile checks are shared. Artifact interpretation and 27 // ownership belong to the selected implementation. Never fall back on failure. 28 return factories[backend]({bytes,bundle,name,artifacts}); 29 }