import type { FamilyMetadata, ReadonlyPureSelectorOptions, ReadonlyPureSelectorToken, StateUpdate, } from "atom.io" import type { Canonical } from "atom.io/foundations/canonical" import { Subject } from "atom.io/foundations/subject" import { newest } from "../lineage.ts" import type { ReadonlyPureSelector } from "../state-types.ts" import type { Store } from "../store/index.ts" import type { RootStore } from "../transaction/index.ts" import { registerSelector } from "./register-selector.ts" export function createReadonlyPureSelector( store: Store, options: ReadonlyPureSelectorOptions, family: FamilyMetadata | undefined, ): ReadonlyPureSelectorToken { const target = newest(store) const subject = new Subject>() const covered = new Set() const key = options.key const type = `readonly_pure_selector` as const store.logger.info(`🔨`, type, key, `is being created`) const { get, find, json, relations } = registerSelector( target, type, key, covered, ) const getFrom = () => { const innerTarget = newest(store) const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key, }) for (const [downstreamSelectorKey, { source }] of upstreamStates) { if (source !== key) { innerTarget.selectorGraph.delete(downstreamSelectorKey, key) } } innerTarget.selectorAtoms.delete(key) const value = options.get({ get, find, json, relations }) store.logger.info(`✨`, type, key, `=`, value) covered.clear() return value } const readonlySelector: ReadonlyPureSelector = { ...options, type, subject, getFrom, install: (s: RootStore) => createReadonlyPureSelector(s, options, family), } if (family) readonlySelector.family = family target.readonlySelectors.set(key, readonlySelector) const token: ReadonlyPureSelectorToken = { key, type } if (family) token.family = family return token }