diff --git a/actor.ts b/actor.ts index b5d1424..232da3f 100644 --- a/actor.ts +++ b/actor.ts @@ -1,6 +1,6 @@ import { IdentitySet, Value } from 'preserves'; -export type Assertion = Value>; +export type Assertion = Value; export type Handle = number; @@ -16,21 +16,21 @@ export interface Entity { [message]?(turn: Turn, message: Assertion): void; } -export class Ref { +export class Ref { readonly actor: Actor; - readonly target: T; + readonly target: Entity; - constructor(actor: Actor, target: T) { + constructor(actor: Actor, target: Entity) { this.actor = actor; this.target = target; } - sync(turn: Turn, syncable: Ref) { - turn.enqueue(syncable.actor, t => syncable.target(t)); + sync(turn: Turn, syncable: Ref) { + turn.enqueue(syncable.actor, t => t.message(syncable, true)); } } -export type OutboundMap = Map>; +export type OutboundMap = Map; export class Actor { readonly outbound: OutboundMap; @@ -79,7 +79,7 @@ export class Turn { this.actor = actor; } - ref(t: T): Ref { + ref(t: Entity): Ref { return new Ref(this.actor, t); } @@ -99,7 +99,7 @@ export class Turn { this.tasks.push(t => this.actor.terminateWith(t, { ok: true })); } - assert(location: Ref, assertion: Assertion): Handle { + assert(location: Ref, assertion: Assertion): Handle { const h = nextHandle++; this.enqueue(location.actor, t => { this.actor.outbound.set(h, location); @@ -112,24 +112,25 @@ export class Turn { this._retract(this.actor.outbound.get(h)!, h); } - replace(location: Ref, h: Handle | undefined, assertion: Assertion): Handle { + replace(location: Ref, h: Handle | undefined, assertion: Assertion): Handle { const newHandle = this.assert(location, assertion); if (h !== void 0) this.retract(h); return newHandle; } - _retract(location: Ref, handle: Handle): void { + _retract(location: Ref, handle: Handle): void { this.enqueue(location.actor, t => { this.actor.outbound.delete(handle); location.target[retract]?.(t, handle); }); } - sync(loc: Ref): Promise { - return new Promise(resolve => this.enqueue(loc.actor, t => loc.sync(t, this.ref(resolve)))); + sync(loc: Ref): Promise { + return new Promise(resolve => this.enqueue(loc.actor, t => + loc.sync(t, this.ref({ [message]: resolve })))); } - message(location: Ref, assertion: Assertion): void { + message(location: Ref, assertion: Assertion): void { this.enqueue(location.actor, t => location.target[message]?.(t, assertion)); } diff --git a/main.ts b/main.ts index adae0e5..1874e5a 100644 --- a/main.ts +++ b/main.ts @@ -2,25 +2,25 @@ import { Actor, Assertion, Entity, Handle, Ref, Turn, assert, message, retract } import { Dictionary, IdentityMap, is, Record } from 'preserves'; import { Bag, ChangeDescription } from './bag'; -const Observe = Record.makeConstructor>('Observe', ['label', 'observer']); +const Observe = Record.makeConstructor('Observe', ['label', 'observer']); class Dataspace implements Entity { - readonly handleMap: IdentityMap>> = new IdentityMap(); - readonly assertions = new Bag>(); - readonly subscriptions: Dictionary, Dictionary>> = new Dictionary(); + readonly handleMap: IdentityMap> = new IdentityMap(); + readonly assertions = new Bag(); + readonly subscriptions: Dictionary>> = new Dictionary(); [assert](turn: Turn, rec: Assertion, handle: Handle): void { - if (!Record.isRecord>(rec)) return; + if (!Record.isRecord(rec)) return; this.handleMap.set(handle, rec); if (this.assertions.change(rec, +1) !== ChangeDescription.ABSENT_TO_PRESENT) return; if (Observe.isClassOf(rec)) { const label = Observe._.label(rec)!; - const observer = Observe._.observer(rec) as Ref; + const observer = Observe._.observer(rec) as Ref; const seen = new Dictionary(); if (!this.subscriptions.has(label)) this.subscriptions.set(label, new Map()); this.subscriptions.get(label)!.set(observer, seen); this.assertions.forEach((_count, prev) => - is((prev as Record>).label, label) + is((prev as Record).label, label) && seen.set(prev, turn.assert(observer, prev))); } this.subscriptions.get(rec.label)?.forEach((seen, peer) => @@ -41,19 +41,19 @@ class Dataspace implements Entity { }); if (Observe.isClassOf(rec)) { let peerMap = this.subscriptions.get(Observe._.label(rec)!)!; - peerMap.delete(Observe._.observer(rec) as Ref); + peerMap.delete(Observe._.observer(rec) as Ref); if (peerMap.size === 0) this.subscriptions.delete(Observe._.label(rec)!); } } [message](turn: Turn, rec: Assertion): void { - if (!Record.isRecord>(rec)) return; + if (!Record.isRecord(rec)) return; this.subscriptions.get(rec.label)?.forEach((_seen, peer) => turn.message(peer, rec)); } } -const BoxState = Record.makeConstructor>('BoxState', ['value']); -const SetBox = Record.makeConstructor>('SetBox', ['newValue']); +const BoxState = Record.makeConstructor('BoxState', ['value']); +const SetBox = Record.makeConstructor('SetBox', ['newValue']); let startTime = Date.now(); let prevValue = 0;