Add Syndicate.suspend

This commit is contained in:
Tony Garnock-Jones 2024-05-28 22:50:10 +02:00
parent 4c5c93820b
commit 63ae985d83
1 changed files with 28 additions and 0 deletions

View File

@ -282,6 +282,30 @@ export class Facet {
}
}
export function suspend(asyncFn: (resume: <T>(v: T) => T) => void) {
const facet = Turn.activeFacet;
const resume = <T>(v: T) => {
if (!facet.actor.space.isRunning()) {
throw new Error('Cannot resume into inactive actor space'); // TODO
}
const t = Turn.___new(facet);
queueMicrotask(() => {
try {
facet.actor.repairDataflowGraph();
t.deliver();
} catch (err) {
Turn.for(facet.actor.root, () => facet.actor._terminateWith({ ok: false, err }));
}
if (Turn.active === t) Turn.active = void 0 as unknown as Turn;
});
Turn.active = t;
return v;
};
return asyncFn(resume);
}
export const STOP_ON_RETRACT = Symbol('stop-on-retract'); // NB. NOT A GLOBAL SYMBOL
export class StopOnRetract implements Partial<Entity> {
@ -341,6 +365,10 @@ export class Turn {
}
}
static ___new(facet: Facet): Turn {
return new Turn(facet);
}
private constructor(facet: Facet, queues = new Map<Actor, StructuredTask<TaskAction>[]>()) {
this._activeFacet = facet;
this.queues = queues;