@reatom/core
Version:
The ultimate state manager
1 lines • 33.9 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../src/atom.ts"],"sourcesContent":["//#region TYPE UTILS\n\nexport interface Rec<Values = any> extends Record<string, Values> {}\n\nexport interface Fn<Args extends any[] = any[], Return = any> {\n (...a: Args): Return\n}\n\nexport type AllTypes = undefined | null | boolean | number | string | Record<keyof any, any> | Fn | symbol | bigint\n\nexport interface Pipe<This> {\n <T1>(operator1: Fn<[This], T1>): T1\n <T1, T2>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>): T2\n /* prettier-ignore */ <T1, T2, T3>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>): T3\n /* prettier-ignore */ <T1, T2, T3, T4>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>): T4\n /* prettier-ignore */ <T1, T2, T3, T4, T5>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>): T5\n /* prettier-ignore */ <T1, T2, T3, T4, T5, T6>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>, operator6: Fn<[T5], T6>): T6\n /* prettier-ignore */ <T1, T2, T3, T4, T5, T6, T7>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>, operator6: Fn<[T5], T6>, operator7: Fn<[T6], T7>): T7\n /* prettier-ignore */ <T1, T2, T3, T4, T5, T6, T7, T8>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>, operator6: Fn<[T5], T6>, operator7: Fn<[T6], T7>, operator8: Fn<[T7], T8>): T8\n /* prettier-ignore */ <T1, T2, T3, T4, T5, T6, T7, T8, T9>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>, operator6: Fn<[T5], T6>, operator7: Fn<[T6], T7>, operator8: Fn<[T7], T8>, operator9: Fn<[T8], T9>): T9\n /* prettier-ignore */ <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>, operator6: Fn<[T5], T6>, operator7: Fn<[T6], T7>, operator8: Fn<[T7], T8>, operator9: Fn<[T8], T9>, operator10: Fn<[T9], T10>): T10\n /* prettier-ignore */ <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>, operator6: Fn<[T5], T6>, operator7: Fn<[T6], T7>, operator8: Fn<[T7], T8>, operator9: Fn<[T8], T9>, operator10: Fn<[T9], T10>, operator11: Fn<[T10], T11>): T11\n /* prettier-ignore */ <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(operator1: Fn<[This], T1>, operator2: Fn<[T1], T2>, operator3: Fn<[T2], T3>, operator4: Fn<[T3], T4>, operator5: Fn<[T4], T5>, operator6: Fn<[T5], T6>, operator7: Fn<[T6], T7>, operator8: Fn<[T7], T8>, operator9: Fn<[T8], T9>, operator10: Fn<[T9], T10>, operator11: Fn<[T10], T11>, operator12: Fn<[T11], T12>): T12\n}\n\n//#endregion\n\n//#region UTILS\n\nconst impossibleValue: any = Symbol()\n\nexport const callSafely = <I extends any[], O>(fn: (...a: I) => O, ...args: I): O | Error => {\n try {\n return fn(...args)\n } catch (err: any) {\n setTimeout(() => {\n throw err\n })\n return err instanceof Error ? err : (err = new Error(err))\n }\n}\n\n//#endregion\n\n//#region DOMAIN TYPES\n\nexport type AtomMaybe<T = unknown> = Atom<T> | T\n\n/** Main context of data storing and effects processing */\nexport interface Ctx {\n get<T>(atom: Atom<T>): T\n get<T>(\n cb: Fn<\n [\n read: Fn<[proto: AtomProto], AtomCache<any> | undefined>,\n // this is `actualize` function and\n // the types intentionally awkward\n // coz it only for internal usage\n fn?: Fn,\n ],\n T\n >,\n ): T\n spy?: {\n <T>(anAtom: Atom<T>): T\n <Params extends any[] = any[], Payload = any>(\n anAction: Action<Params, Payload>,\n cb: Fn<[call: { params: Params; payload: Payload }]>,\n ): void\n <T>(atom: Atom<T>, cb: Fn<[newState: T, prevState: undefined | T]>): void\n }\n\n schedule<T = void>(cb: Fn<[Ctx], T>, step?: -1 | 0 | 1 | 2): Promise<Awaited<T>>\n\n subscribe<T>(atom: Atom<T>, cb: Fn<[T]>): Unsubscribe\n subscribe(cb: Fn<[patches: Logs, error?: Error]>): Unsubscribe\n\n cause: AtomCache\n}\n\nexport interface CtxSpy extends Required<Ctx> {}\n\nexport interface Logs extends Array<AtomCache> {}\n\nexport interface Atom<State = any> {\n __reatom: AtomProto<State>\n pipe: Pipe<this>\n\n onChange: (\n cb: (\n ctx: Ctx,\n newState: State,\n // TODO there could be different `prevState` for each ctx\n // prevState: State,\n // patch: AtomCache<State>,\n ) => any,\n ) => Unsubscribe\n}\n\ntype Update<State> = State | Fn<[State, Ctx], State>\nexport interface AtomMut<State = any> extends Atom<State> {\n (ctx: Ctx, update: Update<State>): State\n}\n\nexport interface AtomProto<State = any> {\n name: undefined | string\n isAction: boolean\n /** temporal cache of the last patch during transaction */\n patch: null | AtomCache\n initState: Fn<[Ctx], State>\n computer: null | Fn<[CtxSpy, unknown], unknown>\n connectHooks: null | Set<Fn<[Ctx]>>\n disconnectHooks: null | Set<Fn<[Ctx]>>\n updateHooks: null | Set<Fn<[Ctx, AtomCache]>>\n actual: boolean\n}\n\nexport interface AtomCache<State = any> {\n state: State\n readonly proto: AtomProto\n // nullable state mean cache is dirty (has updated pubs, which could produce new state)\n cause: null | AtomCache\n pubs: Array<AtomCache>\n readonly subs: Set<AtomProto>\n readonly listeners: Set<Fn>\n error?: unknown\n}\n\nexport interface Action<Params extends any[] = any[], Payload = any>\n extends Atom<Array<{ params: Params; payload: Payload }>> {\n (ctx: Ctx, ...params: Params): Payload\n\n onCall: (cb: (ctx: Ctx, payload: Payload, params: Params) => any) => Unsubscribe\n}\n\nexport type AtomState<T> = T extends Atom<infer State> ? State : never\n\nexport type ActionParams<T> = T extends Action<infer Params, any> ? Params : never\nexport type ActionPayload<T> = T extends Action<any, infer Payload> ? Payload : never\n\ntype DefinitelyReturnType<T> = T extends Fn<any[], infer T> ? T : never\nexport type IsAction<T> = T extends Fn & Atom<infer State extends Array<{ payload: DefinitelyReturnType<T> }>>\n ? true\n : false\n\nexport type AtomReturn<T extends Atom> = T extends Fn ? ReturnType<T> : AtomState<T>\n\nexport type CtxParams<T, Else = never> = T extends Fn<[Ctx, ...infer Params]>\n ? Params\n : T extends [Ctx, ...infer Params]\n ? Params\n : Else\n\nexport interface Unsubscribe {\n (): void\n}\n\n//#endregion\n\n//#region DOMAIN UTILS\n\n// We don't have type literal for NaN but other values are presented here\n// https://stackoverflow.com/a/51390763\ntype Falsy = false | 0 | '' | null | undefined\n// Can't be an arrow function due to\n// https://github.com/microsoft/TypeScript/issues/34523\n/** Throws `Reatom error: ${message}` */\nexport function throwReatomError(condition: any, message: string): asserts condition is Falsy {\n if (condition) throw new Error(`Reatom error: ${message}`)\n}\n\nexport const isAtom = (thing: any): thing is Atom => {\n return thing?.__reatom !== undefined\n}\n\nexport const isAction = (thing: any): thing is Action => {\n return thing?.__reatom?.isAction === true\n}\n\n// export const getCache = <T>(ctx: Ctx, anAtom: Atom<T>): AtomCache<T> =>\n// ctx.get((read) => (ctx.get(anAtom), read(anAtom.__reatom)!))\n\nconst isConnected = (cache: AtomCache): boolean => {\n return cache.subs.size + cache.listeners.size > 0\n}\n\nfunction assertFunction(thing: any): asserts thing is Fn {\n throwReatomError(typeof thing !== 'function', `invalid \"${typeof thing}\", function expected`)\n}\n\n//#endregion\n\nexport interface CtxOptions {\n /** Use it to delay or track late effects such as subscriptions notification */\n callLateEffect?: typeof callSafely\n /** Use it to delay or track near effects such as API calls */\n callNearEffect?: typeof callSafely\n /** Mange multiple contexts warning */\n restrictMultipleContexts?: boolean\n}\n\nconst getRootCause = (cause: AtomCache): AtomCache => (cause.cause === null ? cause : getRootCause(cause.cause))\n\nconst isBrowser = () => typeof window === 'object' && typeof document === 'object'\n\nlet initiations = 0\n\nlet CTX: undefined | Ctx\n\nexport const createCtx = ({\n callLateEffect = callSafely,\n callNearEffect = callSafely,\n restrictMultipleContexts = isBrowser(),\n}: CtxOptions = {}): Ctx => {\n if (restrictMultipleContexts && initiations++ === 1) {\n console.warn('Reatom: multiple contexts detected, which is irrelevant in browser, you should use only one context')\n }\n\n let caches = new WeakMap<AtomProto, AtomCache>()\n let read = (proto: AtomProto): undefined | AtomCache => caches.get(proto)\n let logsListeners = new Set<Fn<[Logs, Error?]>>()\n\n let nearEffects: Array<Fn<[Ctx]>> = []\n let lateEffects: Array<Fn<[Ctx]>> = []\n\n // 'tr' is short for 'transaction'\n let inTr = false\n let trError: null | Error = null\n let trUpdates: Array<Fn<[Ctx]>> = []\n let trRollbacks: Array<Fn> = []\n let trLogs: Array<AtomCache> = []\n let trNearEffectsStart: typeof nearEffects.length = 0\n let trLateEffectsStart: typeof lateEffects.length = 0\n let effectsProcessing = false\n\n let walkNearEffects = () => {\n for (let effect of nearEffects) callNearEffect(effect, ctx)\n\n nearEffects = []\n }\n let walkLateEffects = () => {\n if (effectsProcessing) return\n effectsProcessing = true\n\n walkNearEffects()\n for (let effect of lateEffects) {\n callLateEffect(effect, ctx)\n if (nearEffects.length > 0) walkNearEffects()\n }\n\n lateEffects = []\n\n effectsProcessing = false\n }\n\n let addPatch = ({ state, proto, pubs, subs, listeners }: AtomCache, cause: AtomCache) => {\n proto.actual = false\n trLogs.push(\n (proto.patch = {\n state: state,\n proto: proto,\n cause,\n pubs: pubs,\n subs: subs,\n listeners: listeners,\n }),\n )\n return proto.patch\n }\n\n let enqueueComputers = (cache: AtomCache) => {\n for (let subProto of cache.subs) {\n let subCache = subProto.patch ?? read(subProto)!\n\n if (!subProto.patch || subProto.actual) {\n if (addPatch(subCache, cache).listeners.size === 0) {\n enqueueComputers(subCache)\n }\n }\n }\n }\n\n let disconnect = (proto: AtomProto, pubPatch: AtomCache): void => {\n if (pubPatch.subs.delete(proto)) {\n trRollbacks.push(() => pubPatch.subs.add(proto))\n\n if (!isConnected(pubPatch)) {\n if (pubPatch.proto.disconnectHooks !== null) {\n nearEffects.push(...pubPatch.proto.disconnectHooks)\n }\n\n for (let parentParent of pubPatch.pubs) {\n disconnect(pubPatch.proto, parentParent)\n }\n }\n }\n }\n\n let connect = (proto: AtomProto, pubPatch: AtomCache) => {\n if (!pubPatch.subs.has(proto)) {\n let wasConnected = isConnected(pubPatch)\n pubPatch.subs.add(proto)\n trRollbacks.push(() => pubPatch.subs.delete(proto))\n\n if (!wasConnected) {\n if (pubPatch.proto.connectHooks !== null) {\n nearEffects.push(...pubPatch.proto.connectHooks)\n }\n\n for (let parentParentPatch of (pubPatch.proto.patch ?? read(pubPatch.proto)!).pubs) {\n connect(pubPatch.proto, parentParentPatch)\n }\n }\n }\n }\n\n let actualizePubs = (patchCtx: Ctx, patch: AtomCache) => {\n let { proto, pubs } = patch\n let isDepsChanged = false\n\n if (\n pubs.length === 0 ||\n pubs.some(({ proto, state }) => !Object.is(state, (patch.cause = actualize(patchCtx, proto)).state))\n ) {\n let newPubs: typeof pubs = []\n\n patchCtx.spy = ({ __reatom: depProto }: Atom, cb?: Fn) => {\n let depPatch = actualize(patchCtx, depProto)\n let prevDepPatch = newPubs.push(depPatch) <= pubs.length ? pubs[newPubs.length - 1] : undefined\n let isDepChanged = prevDepPatch?.proto !== depPatch.proto\n isDepsChanged ||= isDepChanged\n\n let state =\n depProto.isAction && !isDepChanged ? depPatch.state.slice(prevDepPatch!.state.length) : depPatch.state\n\n if (cb && (isDepChanged || !Object.is(state, prevDepPatch!.state))) {\n if (depProto.isAction) for (const call of state) cb(call)\n else cb(state, isDepChanged ? undefined : prevDepPatch?.state)\n } else {\n return state\n }\n }\n\n patch.state = patch.proto.computer!(patchCtx as CtxSpy, patch.state)\n patch.pubs = newPubs\n\n if ((isDepsChanged || pubs.length > newPubs.length) && isConnected(patch)) {\n for (let { proto: depProto } of pubs) {\n if (newPubs.every((dep) => dep.proto !== depProto)) {\n disconnect(proto, depProto.patch ?? read(depProto)!)\n }\n }\n for (let { proto: depProto } of newPubs) {\n if (pubs.every((dep) => dep.proto !== depProto)) {\n connect(proto, depProto.patch ?? read(depProto)!)\n }\n }\n }\n\n // this changed after computer exit\n patchCtx.spy = () => throwReatomError(true, 'async spy')\n // @ts-expect-error\n patch = proto = pubs = newPubs = null\n }\n }\n\n let actualize = (ctx: Ctx, proto: AtomProto, updater?: Fn<[patchCtx: Ctx, patch: AtomCache]>): AtomCache => {\n let { patch, actual } = proto\n let updating = updater !== undefined\n\n if (!updating && actual && (patch!.pubs.length === 0 || isConnected(patch!))) return patch!\n\n let cache = patch ?? read(proto)\n let isInt = !cache\n let cause = updating ? ctx.cause : read(__root)!\n\n if (isInt) {\n cache = {\n state: proto.initState(ctx),\n proto,\n cause,\n pubs: [],\n subs: new Set(),\n listeners: new Set(),\n }\n if (updating) trLogs.push(cache)\n } else if (proto.computer === null && !updating) {\n return cache!\n }\n\n if (!patch || actual) patch = addPatch(cache!, cause)\n\n let { state } = patch\n let patchCtx: Ctx = {\n get: ctx.get,\n spy: undefined,\n schedule: ctx.schedule,\n subscribe: ctx.subscribe,\n cause: patch,\n }\n\n try {\n if (proto.computer) actualizePubs(patchCtx, patch)\n if (updating) {\n // updater's cause is a more important, than computer's cause\n patch.cause = ctx.cause\n updater!(patchCtx, patch)\n }\n proto.actual = true\n } catch (error) {\n throw (patch.error = error)\n }\n\n if (!Object.is(state, patch.state)) {\n if (patch.subs.size > 0 && (updating || patch.listeners.size > 0)) {\n enqueueComputers(patch)\n }\n\n if (proto.updateHooks) {\n let ctx = {\n get: patchCtx.get,\n spy: undefined,\n schedule: patchCtx.schedule,\n subscribe: patchCtx.subscribe,\n cause: patchCtx.cause,\n }\n proto.updateHooks.forEach((hook) => trUpdates.push(() => hook(ctx, patch!)))\n }\n }\n\n return patch\n }\n\n let ctx: Ctx = {\n get(atomOrCb) {\n throwReatomError(CTX && getRootCause(CTX.cause) !== read(__root), 'cause collision')\n\n if (isAtom(atomOrCb)) {\n let proto = atomOrCb.__reatom\n if (inTr) return actualize(this, proto).state\n let cache = read(proto)\n\n return cache !== undefined && (proto.computer === null || isConnected(cache))\n ? cache.state\n : this.get(() => actualize(this, proto).state)\n }\n\n throwReatomError(trError !== null, 'tr failed')\n\n if (inTr) return atomOrCb(read, actualize)\n\n inTr = true\n trNearEffectsStart = nearEffects.length\n trLateEffectsStart = lateEffects.length\n let start = CTX === undefined\n if (start) CTX = this\n\n try {\n var result = atomOrCb(read, actualize)\n\n for (let i = 0; i < trLogs.length; i++) {\n let { listeners, proto } = trLogs[i]!\n if (listeners.size > 0) actualize(this, proto)\n if (trUpdates.length > 0 /* TODO `&& trLogs.length === i + 1` */) {\n for (let commit of trUpdates.splice(0)) commit(this)\n }\n }\n\n if (trLogs.length) for (let log of logsListeners) log(trLogs)\n\n for (let patch of trLogs) {\n let { proto, state } = patch\n if (proto.isAction) patch.state = []\n\n if (patch === proto.patch) {\n proto.patch = null\n proto.actual = false\n\n caches.set(proto, patch)\n\n if (proto.isAction) {\n if (state.length === 0) continue\n for (let cb of patch.listeners) {\n nearEffects.push(() => cb(state))\n }\n } else {\n for (let cb of patch.listeners) {\n lateEffects.push(() => cb(read(proto)!.state))\n }\n }\n }\n }\n } catch (e: any) {\n trError = e = e instanceof Error ? e : new Error(String(e))\n for (let log of logsListeners) log(trLogs, e)\n for (let cb of trRollbacks) callSafely(cb, e)\n for (let { proto } of trLogs) {\n proto.patch = null\n proto.actual = false\n }\n\n nearEffects.length = trNearEffectsStart\n lateEffects.length = trLateEffectsStart\n\n throw e\n } finally {\n inTr = false\n trError = null\n trUpdates = []\n trRollbacks = []\n trLogs = []\n trNearEffectsStart = 0\n trLateEffectsStart = 0\n if (start) CTX = undefined\n }\n\n walkLateEffects()\n\n return result\n },\n spy: undefined,\n schedule(cb, step = 1) {\n assertFunction(cb)\n throwReatomError(!this, 'missed context')\n\n return new Promise<any>((res, rej) => {\n if (step === -1) inTr && trRollbacks.push(cb)\n else if (step === 0) inTr && trUpdates.push(() => cb(this))\n else {\n let target = step === 1 ? nearEffects : lateEffects\n target.push(() => {\n try {\n let result = cb(this)\n result instanceof Promise ? result.then(res, rej) : res(result)\n return result\n } catch (error) {\n rej(error)\n throw error\n }\n })\n inTr || walkLateEffects()\n }\n })\n },\n subscribe(atom: Atom | Fn, cb: Atom | Fn = atom) {\n assertFunction(cb)\n\n if (atom === cb) {\n logsListeners.add(cb)\n return () => logsListeners.delete(cb)\n }\n\n throwReatomError(!isAtom(atom), `target subscriber isn't an atom`)\n\n let { __reatom: proto } = atom as Atom\n\n let lastState = impossibleValue\n let listener = (state: any) => Object.is(lastState, state) || cb((lastState = state))\n\n let cache = read(proto)\n\n if (cache === undefined || !isConnected(cache)) {\n this.get(() => {\n cache = actualize(this, proto, (patchCtx, patch) => {})\n cache.listeners.add(listener)\n trRollbacks.push(() => proto.patch!.listeners.delete(listener))\n for (let pubPatch of cache.pubs) connect(proto, pubPatch)\n if (proto.connectHooks !== null) {\n nearEffects.push(...proto.connectHooks)\n }\n })\n } else {\n cache.listeners.add(listener)\n }\n\n if (lastState === impossibleValue) {\n listener((proto.patch ?? read(proto)!).state)\n }\n\n return () => {\n if (cache!.listeners.delete(listener) && !isConnected(cache!)) {\n proto.disconnectHooks && nearEffects.push(...proto.disconnectHooks)\n\n for (let pubCache of read(proto)!.pubs) {\n disconnect(proto, pubCache)\n }\n\n if (!inTr) {\n trRollbacks.length = 0\n walkLateEffects()\n }\n }\n }\n },\n cause: undefined as any,\n }\n\n ;(ctx.cause = ctx.get(() => actualize(ctx, __root))).cause = null\n\n return ctx\n}\n\nlet i = 0\n/**\n * @internal\n * @deprecated\n */\nexport let __count = (name: string) => `${name}#${++i}`\n\nfunction pipe(this: Atom, ...fns: Array<Fn>) {\n return fns.reduce((acc, fn) => fn(acc), this)\n}\nfunction onChange(this: Atom, cb: Fn) {\n const hook = (ctx: Ctx, patch: AtomCache) => cb(ctx, patch.state)\n\n ;(this.__reatom.updateHooks ??= new Set()).add(hook)\n\n return () => this.__reatom.updateHooks!.delete(hook)\n}\nfunction onCall(this: Action, cb: Fn): Unsubscribe {\n return this.onChange((ctx, state) => {\n const { params, payload } = state[state.length - 1]!\n cb(ctx, payload, params)\n })\n}\n\nexport function atom<T>(computed: (ctx: CtxSpy) => T, name?: string): Atom<T>\nexport function atom<T>(initState: T, name?: string): AtomMut<T>\nexport function atom<T>(initState: T | ((ctx: CtxSpy) => T), name = __count('_atom')): Atom<T> | AtomMut<T> {\n // TODO: it took much longer than expected in profiling\n let theAtom: any = (ctx: Ctx, update: any) =>\n ctx.get(\n (read, actualize) =>\n actualize!(ctx, theAtom.__reatom, (patchCtx: Ctx, patch: AtomCache) => {\n patch.state = typeof update === 'function' ? update(patch.state, patchCtx) : update\n }).state,\n )\n let computer = null\n\n if (typeof initState === 'function') {\n theAtom = {}\n computer = initState\n initState = undefined as T\n }\n\n theAtom.__reatom = {\n name,\n isAction: false,\n patch: null,\n initState: () => initState,\n computer,\n connectHooks: null,\n disconnectHooks: null,\n updateHooks: null,\n actual: false,\n }\n\n theAtom.pipe = pipe\n theAtom.onChange = onChange\n\n return experimental_PLUGINS.length === 0 ? theAtom : theAtom.pipe(...experimental_PLUGINS)\n}\n\nexport const action: {\n (name?: string): Action<[], void>\n\n <T>(name?: string): Action<[T], T>\n\n <Params extends any[] = any[], Res = void>(\n fn: (ctx: Ctx, ...params: Params) => Res,\n name?: string,\n ): Action<Params, Res>\n} = (fn?: string | Fn, name?: string): any => {\n if (fn === undefined || typeof fn === 'string') {\n name = fn\n fn = (ctx: Ctx, v?: any) => v\n }\n\n assertFunction(fn)\n\n let actionAtom = atom<Array<any>>([], name ?? __count('_action'))\n actionAtom.__reatom.isAction = true\n // @ts-expect-error\n actionAtom.__reatom.unstable_fn = fn\n\n return Object.assign(\n (...params: [Ctx, ...any[]]) => {\n let state = actionAtom(params[0], (state, patchCtx) => {\n params[0] = patchCtx\n return [\n ...state,\n {\n params: params.slice(1),\n // @ts-expect-error\n payload: patchCtx.cause.proto.unstable_fn(...params),\n },\n ]\n })\n return state[state.length - 1]!.payload\n },\n actionAtom,\n {\n onCall,\n },\n )\n}\n\nexport const experimental_PLUGINS: Array<(anAtom: Atom) => Atom> = []\n\n/**\n * @internal\n * @deprecated\n */\nexport const __root = atom(undefined, 'root').__reatom\n\nexport const batch = <T>(ctx: Ctx, cb: Fn<[], T>): T => ctx.get(cb)\n"],"names":["impossibleValue","Symbol","callSafely","fn","slice","call","arguments","err","setTimeout","Error","throwReatomError","condition","message","isAtom","thing","undefined","__reatom","isAction","isConnected","cache","subs","size","listeners","assertFunction","getRootCause","cause","isBrowser","window","document","CTX","initiations","createCtx","callLateEffect","callNearEffect","restrictMultipleContexts","console","warn","caches","WeakMap","read","proto","get","logsListeners","Set","nearEffects","lateEffects","inTr","trError","trUpdates","trRollbacks","trLogs","trNearEffectsStart","trLateEffectsStart","effectsProcessing","walkNearEffects","effect","ctx","walkLateEffects","length","addPatch","state","pubs","actual","push","patch","enqueueComputers","subProto","subCache","disconnect","pubPatch","delete","add","disconnectHooks","parentParent","connect","has","wasConnected","connectHooks","parentParentPatch","actualize","updater","updating","isInt","__root","initState","computer","patchCtx","spy","schedule","subscribe","actualizePubs","isDepsChanged","some","Object","is","newPubs","depProto","cb","depPatch","prevDepPatch","isDepChanged","every","dep","error","updateHooks","forEach","hook","atomOrCb","this","start","result","i","commit","splice","log","set","e","String","step","Promise","res","rej","then","atom","lastState","listener","pubCache","__count","name","pipe","reduce","acc","onChange","onCall","params","payload","theAtom","update","experimental_PLUGINS","action","v","actionAtom","unstable_fn","assign","batch"],"mappings":"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"}