UNPKG

jinaga

Version:

Data management for web and mobile applications.

62 lines (54 loc) 2.67 kB
import { testSpecificationForCompliance } from "../purge/purgeCompliance"; import { SpecificationInverse, invertSpecification } from "../specification/inverse"; import { Specification } from "../specification/specification"; import { FactEnvelope, FactReference, ProjectedResult, Storage } from "../storage"; import { Trace } from "../util/trace"; export class PurgeManager { private purgeInverses: SpecificationInverse[]; constructor(private readonly store: Storage, private readonly purgeConditions: Specification[]) { this.purgeInverses = purgeConditions.map(pc => invertSpecification(pc)).flat(); } async purge(): Promise<void> { const count = await this.store.purge(this.purgeConditions); if (count > 0) { Trace.counter("facts_purged", count); } } async triggerPurge(factsAdded: FactEnvelope[]): Promise<void> { for (const envelope of factsAdded) { const fact = envelope.fact; for (const purgeInverse of this.purgeInverses) { // Only run the purge inverse if the given type matches the fact type if (purgeInverse.inverseSpecification.given[0].type !== fact.type) { continue; } const givenReference = { type: fact.type, hash: fact.hash }; const results: ProjectedResult[] = await this.store.read([givenReference], purgeInverse.inverseSpecification); for (const result of results) { const givenName = purgeInverse.givenSubset[0]; // The given is the purge root const purgeRoot: FactReference = result.tuple[givenName]; // All other members of the result tuple are triggers const triggers: FactReference[] = Object.keys(result.tuple) .filter(k => k !== givenName) .map(k => result.tuple[k]); // Purge all descendants of the purge root except for the triggers const count = await this.store.purgeDescendants(purgeRoot, triggers); if (count > 0) { Trace.counter("facts_purged", count); } } } } } public checkCompliance(specification: Specification): void { const failures = testSpecificationForCompliance(specification, this.purgeConditions); if (failures.length > 0) { const message = failures.join("\n"); throw new Error(message); } } }