55 lines
1.9 KiB
TypeScript
55 lines
1.9 KiB
TypeScript
// 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<Handle, false | Ref>(),
|
|
async assert(t, inst0, handle) {
|
|
// console.log('+Factory:', handle, inst0);
|
|
const inst = inst0 as ReturnType<typeof Instance>;
|
|
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);
|
|
}
|
|
}
|
|
})));
|
|
});
|