diff --git a/packages/core/src/runtime/dataspace.ts b/packages/core/src/runtime/dataspace.ts index c88b225..bea3d18 100644 --- a/packages/core/src/runtime/dataspace.ts +++ b/packages/core/src/runtime/dataspace.ts @@ -8,44 +8,51 @@ import { fromObserve, Observe, toObserve } from '../gen/dataspace.js'; import * as P from '../gen/dataspacePatterns.js'; export type DataspaceOptions = { - tracer?: (event: '+' | '-' | '!', assertion: Assertion, dataspace: Dataspace) => void, + tracer?: (event: '+' | '-' | '!', + assertion: Assertion, + dataspace: Dataspace, + is_significant: boolean) => void, dumpIndex?: boolean, }; export class Dataspace implements Partial { readonly options: DataspaceOptions; readonly index = new Index(); - readonly handleMap = new IdentityMap(); + readonly handleMap = new IdentityMap(); constructor(options?: DataspaceOptions) { this.options = options ?? {}; } assert(v: Assertion, handle: Handle): void { - this.options.tracer?.('+', v, this); - this.index.addAssertion(v); - const o = toObserve(v); - if (o !== void 0) { - this.index.addObserver(o.pattern, o.observer); + const is_new = this.index.addAssertion(v); + this.options.tracer?.('+', v, this, is_new); + if (is_new) { + const o = toObserve(v); + if (o !== void 0) { + this.index.addObserver(o.pattern, o.observer); + } + if (this.options.dumpIndex ?? false) this.index.dump(); } - if (this.options.dumpIndex ?? false) this.index.dump(); - this.handleMap.set(handle, [v, o]); + this.handleMap.set(handle, v); } retract(handle: Handle): void { - const entry = this.handleMap.get(handle); - if (entry === void 0) return; - const [v, o] = entry; - this.options.tracer?.('-', v, this); - if (o !== void 0) { - this.index.removeObserver(o.pattern, o.observer); + const v = this.handleMap.get(handle); + if (v === void 0) return; + const is_last = this.index.removeAssertion(v); + this.options.tracer?.('-', v, this, is_last); + if (is_last) { + const o = toObserve(v); + if (o !== void 0) { + this.index.removeObserver(o.pattern, o.observer); + } + if (this.options.dumpIndex ?? false) this.index.dump(); } - this.index.removeAssertion(v); - if (this.options.dumpIndex ?? false) this.index.dump(); } message(v: Assertion): void { - this.options.tracer?.('!', v, this); + this.options.tracer?.('!', v, this, true); this.index.deliverMessage(v); } diff --git a/packages/core/src/runtime/skeleton.ts b/packages/core/src/runtime/skeleton.ts index bfb7f4a..ba2f2b5 100644 --- a/packages/core/src/runtime/skeleton.ts +++ b/packages/core/src/runtime/skeleton.ts @@ -83,9 +83,8 @@ export class Index { } } - adjustAssertion(outerValue: Assertion, delta: number): ChangeDescription { - let net = this.allAssertions.change(outerValue, delta); - switch (net) { + adjustAssertion(outerValue: Assertion, delta: number): boolean { + switch (this.allAssertions.change(outerValue, delta)) { case ChangeDescription.ABSENT_TO_PRESENT: this.root.modify( EventType.ADDED, @@ -97,7 +96,7 @@ export class Index { h.observers.forEach((captureMap, observer) => captureMap.set(vs, Turn.active.assert(observer, vs))); }); - break; + return true; case ChangeDescription.PRESENT_TO_ABSENT: this.root.modify( @@ -112,17 +111,19 @@ export class Index { captureMap.delete(vs); }); }); - break; + return true; + + default: + return false; } - return net; } - addAssertion(v: Assertion) { - this.adjustAssertion(v, +1); + addAssertion(v: Assertion): boolean { + return this.adjustAssertion(v, +1); } - removeAssertion(v: Assertion) { - this.adjustAssertion(v, -1); + removeAssertion(v: Assertion): boolean { + return this.adjustAssertion(v, -1); } deliverMessage(v: Assertion, leafCallback: (l: Leaf, v: Assertion) => void = _nop) {