import type { AtomLifecycleEvent, MutableAtomToken } from "atom.io" import type { Canonical } from "atom.io/foundations/canonical" import { parseJson } from "atom.io/foundations/json" import { createRegularAtomFamily } from "../families/index.ts" import type { MutableAtomFamily, RegularAtomFamily } from "../state-types.ts" import { withdraw } from "../store/index.ts" import type { RootStore } from "../transaction/index.ts" import { Tracker } from "./tracker.ts" import type { SignalFrom, Transceiver } from "./transceiver.ts" export class FamilyTracker< T extends Transceiver, K extends Canonical, > { private trackers: Map> = new Map() public readonly latestSignalAtoms: RegularAtomFamily | null, K> public readonly mutableAtoms: MutableAtomFamily public constructor(mutableAtoms: MutableAtomFamily, store: RootStore) { const latestSignalAtoms = createRegularAtomFamily< SignalFrom | null, K, never >( store, { key: `*${mutableAtoms.key}`, default: null, }, [`mutable`, `updates`], ) this.latestSignalAtoms = withdraw(store, latestSignalAtoms) this.mutableAtoms = mutableAtoms const trackerFamilyWatchesForCreationAndDisposalEvents = ( event: AtomLifecycleEvent>, ) => { const { type, token } = event if (token.family) { const key = parseJson(token.family.subKey) switch (type) { case `atom_creation`: this.trackers.set(key, new Tracker(token, store)) break case `atom_disposal`: { const tracker = this.trackers.get(key) if (tracker) { tracker[Symbol.dispose]() this.trackers.delete(key) } } } } } this.mutableAtoms.subject.subscribe( `store=${store.config.name}::tracker-atom-family`, trackerFamilyWatchesForCreationAndDisposalEvents, ) } }