/// SPDX-License-Identifier: GPL-3.0-or-later /// SPDX-FileCopyrightText: Copyright © 2016-2021 Tony Garnock-Jones import { IdentityMap } from '@preserves/core'; import { Index } from './skeleton.js'; import { Assertion, Entity, Facet, Handle, LocalAction, Ref, Turn } from './actor.js'; import { fromObserve, Observe, toObserve } from '../gen/dataspace.js'; import * as P from '../gen/dataspacePatterns.js'; export class Dataspace implements Partial { readonly index = new Index(); readonly handleMap = new IdentityMap(); assert(v: Assertion, handle: Handle): void { this.index.addAssertion(v); const o = toObserve(v); if (o !== void 0) { this.index.addObserver(o.pattern, o.observer); } this.handleMap.set(handle, [v, o]); } retract(handle: Handle): void { const entry = this.handleMap.get(handle); if (entry === void 0) return; const [v, o] = entry; if (o !== void 0) { this.index.removeObserver(o.pattern, o.observer); } this.index.removeAssertion(v); } message(v: Assertion): void { this.index.deliverMessage(v); } } export function assertionObserver(f: (a: Assertion) => LocalAction | undefined): Partial { const assertionMap = new IdentityMap(); return { assert(a: Assertion, h: Handle): void { const g = f(a) ?? null; if (g !== null) { assertionMap.set(h, g); } }, retract(h: Handle): void { assertionMap.get(h)?.(); assertionMap.delete(h); }, }; } export function assertionFacetObserver(f: (a: Assertion) => void, inertOk: boolean = true): Partial { const facetMap = new IdentityMap(); return { assert(a: Assertion, h: Handle): void { facetMap.set(h, Turn.active.facet(() => { if (inertOk) Turn.activeFacet.preventInertCheck(); f(a); })); }, retract(h: Handle): void { const facet = facetMap.get(h); if (facet) Turn.active.stop(facet); facetMap.delete(h); }, }; } export function assertObserve(ds: Ref, pattern: P.Pattern, e: Partial): Handle { return Turn.active.assert(ds, fromObserve(Observe({ pattern, observer: Turn.ref(e) }))); }