Tighten and simplify
This commit is contained in:
parent
5d49794d88
commit
6a5cac5328
84
main.ts
84
main.ts
|
@ -15,71 +15,55 @@ import { Bag, ChangeDescription } from './bag';
|
||||||
const Observe = Record.makeConstructor<Ref<Entity>>('Observe', ['label', 'observer']);
|
const Observe = Record.makeConstructor<Ref<Entity>>('Observe', ['label', 'observer']);
|
||||||
|
|
||||||
function makeDataspace(): Entity {
|
function makeDataspace(): Entity {
|
||||||
const handleMap: IdentityMap<Handle, Assertion> = new IdentityMap();
|
const handleMap: IdentityMap<Handle, Record<Ref<Entity>>> = new IdentityMap();
|
||||||
const assertions = new Bag<Ref<Entity>>();
|
const assertions = new Bag<Ref<Entity>>();
|
||||||
const subscriptions: Dictionary<Map<Ref<Entity>, Dictionary<Handle>>> = new Dictionary();
|
const subscriptions: Dictionary<Map<Ref<Entity>, Dictionary<Handle>>> = new Dictionary();
|
||||||
|
|
||||||
function forEachSubscription(assertion: Assertion, f: (handleMap: Dictionary<Handle>, peer: Ref<Entity>) => void): void {
|
function forEachSubscription(assertion: Record<Ref<Entity>>, f: (seen: Dictionary<Handle>, peer: Ref<Entity>) => void): void {
|
||||||
if (!Record.isRecord(assertion)) return;
|
|
||||||
subscriptions.get(assertion.label)?.forEach(f);
|
subscriptions.get(assertion.label)?.forEach(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[assert](turn: Turn, assertion: Assertion, handle: Handle): void {
|
[assert](turn: Turn, rec: Assertion, handle: Handle): void {
|
||||||
// console.log(`DS: assert ${assertion.asPreservesText()} :: ${handle}`);
|
if (!Record.isRecord<Ref<Entity>>(rec)) return;
|
||||||
handleMap.set(handle, assertion);
|
handleMap.set(handle, rec);
|
||||||
if (assertions.change(assertion, +1) === ChangeDescription.ABSENT_TO_PRESENT) {
|
if (assertions.change(rec, +1) !== ChangeDescription.ABSENT_TO_PRESENT) return;
|
||||||
if (Observe.isClassOf(assertion)) {
|
if (Observe.isClassOf(rec)) {
|
||||||
const observedLabel = Observe._.label(assertion)!;
|
const label = Observe._.label(rec)!;
|
||||||
const observer = Observe._.observer(assertion) as Ref<Entity>;
|
const observer = Observe._.observer(rec) as Ref<Entity>;
|
||||||
let peerMap = subscriptions.get(observedLabel);
|
const seen = new Dictionary<Handle>();
|
||||||
if (peerMap === void 0) {
|
if (!subscriptions.has(label)) subscriptions.set(label, new Map());
|
||||||
peerMap = new Map();
|
subscriptions.get(label)!.set(observer, seen);
|
||||||
subscriptions.set(observedLabel, peerMap);
|
assertions.forEach((_count, prev) =>
|
||||||
}
|
is((prev as Record<Ref<Entity>>).label, label)
|
||||||
const handleMap: Dictionary<Handle> = new Dictionary();
|
&& seen.set(prev, turn.assert(observer, prev)));
|
||||||
peerMap.set(observer, handleMap);
|
|
||||||
assertions.forEach((_count, assertion) => {
|
|
||||||
if (Record.isRecord(assertion)) {
|
|
||||||
if (is(assertion.label, observedLabel)) {
|
|
||||||
handleMap.set(assertion, turn.assert(observer, assertion));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
forEachSubscription(assertion, (handleMap, peer) => {
|
|
||||||
if (!handleMap.has(assertion)) {
|
|
||||||
handleMap.set(assertion, turn.assert(peer, assertion));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
forEachSubscription(rec, (seen, peer) =>
|
||||||
|
seen.has(rec) || seen.set(rec, turn.assert(peer, rec)));
|
||||||
},
|
},
|
||||||
|
|
||||||
[retract](turn: Turn, upstreamHandle: Handle): void {
|
[retract](turn: Turn, upstreamHandle: Handle): void {
|
||||||
const assertion = handleMap.get(upstreamHandle);
|
const rec = handleMap.get(upstreamHandle);
|
||||||
// console.log(`DS: retract ${(assertion ?? Symbol.for('missing')).asPreservesText()} :: ${upstreamHandle}`);
|
if (rec === void 0) return;
|
||||||
if (assertion !== void 0) {
|
handleMap.delete(upstreamHandle);
|
||||||
handleMap.delete(upstreamHandle);
|
if (assertions.change(rec, -1) !== ChangeDescription.PRESENT_TO_ABSENT) return;
|
||||||
if (assertions.change(assertion, -1) === ChangeDescription.PRESENT_TO_ABSENT) {
|
forEachSubscription(rec, (seen, _peer) => {
|
||||||
forEachSubscription(assertion, (handleMap, _peer) => {
|
const downstreamHandle = seen.get(rec);
|
||||||
const downstreamHandle = handleMap.get(assertion);
|
if (downstreamHandle !== void 0) {
|
||||||
if (downstreamHandle !== void 0) {
|
turn.retract(downstreamHandle);
|
||||||
turn.retract(downstreamHandle);
|
seen.delete(rec);
|
||||||
handleMap.delete(assertion);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (Observe.isClassOf(assertion)) {
|
|
||||||
let peerMap = subscriptions.get(Observe._.label(assertion)!)!;
|
|
||||||
peerMap.delete(Observe._.observer(assertion)! as Ref<Entity>);
|
|
||||||
if (peerMap.size === 0) subscriptions.delete(Observe._.label(assertion)!);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
if (Observe.isClassOf(rec)) {
|
||||||
|
let peerMap = subscriptions.get(Observe._.label(rec)!)!;
|
||||||
|
peerMap.delete(Observe._.observer(rec) as Ref<Entity>);
|
||||||
|
if (peerMap.size === 0) subscriptions.delete(Observe._.label(rec)!);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
[message](turn: Turn, message: Assertion): void {
|
[message](turn: Turn, rec: Assertion): void {
|
||||||
// console.log(`DS: message ${message.asPreservesText()}`);
|
if (!Record.isRecord<Ref<Entity>>(rec)) return;
|
||||||
forEachSubscription(message, (_handleMap, peer) => turn.message(peer, message));
|
forEachSubscription(rec, (_seen, peer) => turn.message(peer, rec));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue