// Web Worker loader import { Actor, Turn, Assertion, Handle, Ref } from './actor.js'; import { IdentityMap, Record } from 'preserves'; import { parentPort } from 'worker_threads'; import { Relay, spawnRelay } from './relay.js'; import { Dataspace, Observe } from './dataspace.js'; const _Instance = Symbol.for('Instance'); const Instance = Record.makeConstructor<{moduleName: string, arg: Assertion}>()( _Instance, ['moduleName', 'arg']); Turn.for(new Actor(), t => { const p = parentPort!; const ds = t.ref(new Dataspace()); spawnRelay(t, { packetWriter: bs => p.postMessage(bs), setup(t: Turn, r: Relay) { p.on('message', bs => r.accept(bs)); p.on('close', () => Turn.for(t.actor, t => t.quit())); }, initialRef: ds, // debug: true, }); t.assert(ds, Observe(Instance.constructorInfo.label, t.ref({ handleMap: new IdentityMap(), async assert(t, inst0, handle) { // console.log('+Factory:', handle, inst0); const inst = inst0 as ReturnType; const m = await import(Instance._.moduleName(inst)); t.freshen(t => t.spawn(t => { const q = (t: Turn) => { this.handleMap.delete(handle); t.quit(); }; if (this.handleMap.has(handle)) { q(t); } else { this.handleMap.set(handle, t.ref({ message: q })); m.default(t, Instance._.arg(inst)); } })); }, retract(t, handle) { // console.log('-Factory:', handle); const r = this.handleMap.get(handle); if (r === void 0) { this.handleMap.set(handle, false); } else { t.message(r as Ref, true); } } }))); });