import type { AtomCreationEvent, AtomDisposalEvent, MoleculeCreationEvent, MoleculeDisposalEvent, MoleculeTransferEvent, } from "atom.io" import { parseJson, stringifyJson } from "atom.io/foundations/json" import { disposeFromStore } from "../families/index.ts" import { ensureState } from "../get-state/ensure-state.ts" import { getFromStore } from "../get-state/index.ts" import { allocateIntoStore, claimWithinStore, deallocateFromStore, } from "../molecule.ts" import { setIntoStore } from "../set-state/index.ts" import type { Store } from "../store/index.ts" export function ingestCreationEvent( store: Store, event: AtomCreationEvent, applying: `newValue` | `oldValue`, ): void { switch (applying) { case `newValue`: { createInStore(store, event) break } case `oldValue`: { disposeFromStore(store, event.token) break } } } export function ingestDisposalEvent( store: Store, event: AtomDisposalEvent, applying: `newValue` | `oldValue`, ): void { switch (applying) { case `newValue`: { disposeFromStore(store, event.token) break } case `oldValue`: { createInStore(store, event) break } } } function createInStore( store: Store, event: AtomCreationEvent | AtomDisposalEvent, ): void { const { token } = event if (`value` in event) { setIntoStore(store, token, event.value) } else { ensureState(store, token) } } export function ingestMoleculeCreationEvent( store: Store, event: MoleculeCreationEvent, applying: `newValue` | `oldValue`, ): void { switch (applying) { case `newValue`: allocateIntoStore(store, event.provenance, event.key) break case `oldValue`: deallocateFromStore(store, event.key) break } } export function ingestMoleculeDisposalEvent( store: Store, event: MoleculeDisposalEvent, applying: `newValue` | `oldValue`, ): void { switch (applying) { case `newValue`: deallocateFromStore(store, event.key) break case `oldValue`: { const provenanceJson = event.provenance.map(parseJson) allocateIntoStore(store, provenanceJson, event.key) for (const [familyKey, value] of event.values) { const family = store.families.get(familyKey) if (family) { getFromStore(store, family, event.key) const memberKey = `${familyKey}(${stringifyJson(event.key)})` store.valueMap.set(memberKey, value) } } } break } } export function ingestMoleculeTransferEvent( store: Store, event: MoleculeTransferEvent, applying: `newValue` | `oldValue`, ): void { switch (applying) { case `newValue`: { for (const newOwner of event.to) { claimWithinStore( store, newOwner, event.key, event.exclusive ? `exclusive` : undefined, ) } } break case `oldValue`: { let exclusivity: `exclusive` | undefined = `exclusive` for (const previousOwner of event.from) { claimWithinStore( store, previousOwner, event.key, exclusivity, ) exclusivity = undefined } } break } }