import type { disposeState, editRelations, findRelations, findState, getInternalRelations, getState, resetState, setState, TransactionToken, } from "atom.io" import { MapOverlay } from "atom.io/foundations/overlays" import { arbitrary } from "../arbitrary.ts" import { disposeFromStore, findInStore } from "../families/index.ts" import { getEnvironmentData } from "../get-environment-data.ts" import { getFromStore } from "../get-state/index.ts" import { editRelationsInStore, findRelationsInStore, getInternalRelationsFromStore, } from "../join/index.ts" import { newest } from "../lineage.ts" import { getJsonTokenFromStore } from "../mutable/index.ts" import { resetInStore, setIntoStore } from "../set-state/index.ts" import type { Fn } from "../utility-types.ts" import { actUponStore } from "./act-upon-store.ts" import type { ChildStore, RootStore } from "./is-root-store.ts" import type { TransactionProgress } from "./transaction-meta-progress.ts" export function buildTransaction( store: RootStore, token: TransactionToken, params: any[], id: string, ): ChildStore { const parent = newest(store) const childBase: Omit = { parent, child: null, on: parent.on, loggers: parent.loggers, logger: parent.logger, config: parent.config, atoms: new MapOverlay(parent.atoms), atomsThatAreDefault: new Set(parent.atomsThatAreDefault), families: new MapOverlay(parent.families), joins: new MapOverlay(parent.joins), operation: { open: false }, readonlySelectors: new MapOverlay(parent.readonlySelectors), timelineFamilies: new MapOverlay(parent.timelineFamilies), timelines: new MapOverlay(parent.timelines), timelineTopics: parent.timelineTopics.overlay(), trackers: new Map(), transactions: new MapOverlay(parent.transactions), selectorAtoms: parent.selectorAtoms.overlay(), selectorGraph: parent.selectorGraph.overlay(), writableSelectors: new MapOverlay(parent.writableSelectors), valueMap: new MapOverlay(parent.valueMap), defaults: parent.defaults, disposalTraces: store.disposalTraces.copy(), molecules: new MapOverlay(parent.molecules), moleculeGraph: parent.moleculeGraph.overlay(), moleculeData: parent.moleculeData.overlay(), keyRefsInJoins: parent.keyRefsInJoins.overlay(), miscResources: new MapOverlay(parent.miscResources), } const transactionMeta: TransactionProgress = { phase: `building`, update: { type: `transaction_outcome`, token, id, timestamp: Date.now(), subEvents: [], params, output: undefined, }, toolkit: { get: ((...ps: Parameters) => getFromStore(child, ...ps)) as typeof getState, set: ((...ps: Parameters) => { setIntoStore(child, ...ps) }) as typeof setState, reset: ((...ps: Parameters) => { resetInStore(child, ...ps) }) as typeof resetState, run: (t, identifier = arbitrary()) => actUponStore(child, t, identifier), find: ((...ps: Parameters) => findInStore(store, ...ps)) as typeof findState, json: (t) => getJsonTokenFromStore(child, t), dispose: ((...ps: Parameters) => { disposeFromStore(child, ...ps) }) as typeof disposeState, env: () => getEnvironmentData(child), relations: { edit: ((...ps: Parameters) => { editRelationsInStore(child, ...ps) }) as typeof editRelations, find: ((...ps: Parameters) => { return findRelationsInStore(child, ...ps) }) as typeof findRelations, internal: ((...ps: Parameters) => { return getInternalRelationsFromStore(child, ...ps) }) as typeof getInternalRelations, }, }, } const child: ChildStore = Object.assign(childBase, { transactionMeta, }) parent.child = child store.logger.info( `🛫`, `transaction`, token.key, `building with params:`, params, ) return child }