@tanstack/store 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/atom.cjs CHANGED
@@ -121,9 +121,13 @@ function createAtom(valueOrFn, options) {
121
121
  _update(getValue) {
122
122
  const prevSub = activeSub;
123
123
  const compare = options?.compare ?? Object.is;
124
- activeSub = atom;
125
- ++cycle;
126
- atom.depsTail = void 0;
124
+ if (isComputed) {
125
+ activeSub = atom;
126
+ ++cycle;
127
+ atom.depsTail = void 0;
128
+ } else if (getValue === void 0) {
129
+ return false;
130
+ }
127
131
  if (isComputed) {
128
132
  atom.flags = alien.ReactiveFlags.Mutable | alien.ReactiveFlags.RecursedCheck;
129
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"atom.cjs","sources":["../../src/atom.ts"],"sourcesContent":["import { ReactiveFlags, createReactiveSystem, getBatchDepth } from './alien'\n\nimport type { ReactiveNode } from './alien'\nimport type {\n Atom,\n AtomOptions,\n Observer,\n ReadonlyAtom,\n Subscription,\n} from './types'\n\nexport function toObserver<T>(\n nextHandler?: Observer<T> | ((value: T) => void),\n errorHandler?: (error: any) => void,\n completionHandler?: () => void,\n): Observer<T> {\n const isObserver = typeof nextHandler === 'object'\n const self = isObserver ? nextHandler : undefined\n\n return {\n next: (isObserver ? nextHandler.next : nextHandler)?.bind(self),\n error: (isObserver ? nextHandler.error : errorHandler)?.bind(self),\n complete: (isObserver ? nextHandler.complete : completionHandler)?.bind(\n self,\n ),\n }\n}\n\ninterface InternalAtom<T> extends ReactiveNode {\n _snapshot: T\n _update: (getValue?: T | ((snapshot: T) => T)) => boolean\n get: () => T\n subscribe: (observerOrFn: Observer<T> | ((value: T) => void)) => Subscription\n}\n\nconst queuedEffects: Array<Effect | undefined> = []\nlet cycle = 0\nconst { link, unlink, propagate, checkDirty, shallowPropagate } =\n createReactiveSystem({\n update(atom: InternalAtom<any>): boolean {\n return atom._update()\n },\n // eslint-disable-next-line no-shadow\n notify(effect: Effect): void {\n queuedEffects[queuedEffectsLength++] = effect\n effect.flags &= ~ReactiveFlags.Watching\n },\n unwatched(atom: InternalAtom<any>): void {\n if (atom.depsTail !== undefined) {\n atom.depsTail = undefined\n atom.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty\n purgeDeps(atom)\n }\n },\n })\n\nlet notifyIndex = 0\nlet queuedEffectsLength = 0\nlet activeSub: ReactiveNode | undefined\n\nfunction purgeDeps(sub: ReactiveNode) {\n const depsTail = sub.depsTail\n let dep = depsTail !== undefined ? depsTail.nextDep : sub.deps\n while (dep !== undefined) {\n dep = unlink(dep, sub)\n }\n}\n\nexport function flush(): void {\n if (getBatchDepth() > 0) {\n return\n }\n while (notifyIndex < queuedEffectsLength) {\n // eslint-disable-next-line no-shadow\n const effect = queuedEffects[notifyIndex]!\n queuedEffects[notifyIndex++] = undefined\n effect.notify()\n }\n notifyIndex = 0\n queuedEffectsLength = 0\n}\n\ntype AsyncAtomState<TData, TError = unknown> =\n | { status: 'pending' }\n | { status: 'done'; data: TData }\n | { status: 'error'; error: TError }\n\nexport function createAsyncAtom<T>(\n getValue: () => Promise<T>,\n options?: AtomOptions<AsyncAtomState<T>>,\n): ReadonlyAtom<AsyncAtomState<T>> {\n const ref: { current?: InternalAtom<AsyncAtomState<T>> } = {}\n const atom = createAtom<AsyncAtomState<T>>(() => {\n getValue().then(\n (data) => {\n const internalAtom = ref.current!\n if (internalAtom._update({ status: 'done', data })) {\n const subs = internalAtom.subs\n if (subs !== undefined) {\n propagate(subs)\n shallowPropagate(subs)\n flush()\n }\n }\n },\n (error) => {\n const internalAtom = ref.current!\n if (internalAtom._update({ status: 'error', error })) {\n const subs = internalAtom.subs\n if (subs !== undefined) {\n propagate(subs)\n shallowPropagate(subs)\n flush()\n }\n }\n },\n )\n\n return { status: 'pending' }\n }, options)\n ref.current = atom as unknown as InternalAtom<AsyncAtomState<T>>\n\n return atom\n}\n\nexport function createAtom<T>(\n getValue: (prev?: NoInfer<T>) => T,\n options?: AtomOptions<T>,\n): ReadonlyAtom<T>\nexport function createAtom<T>(\n initialValue: T,\n options?: AtomOptions<T>,\n): Atom<T>\nexport function createAtom<T>(\n valueOrFn: T | ((prev?: T) => T),\n options?: AtomOptions<T>,\n): Atom<T> | ReadonlyAtom<T> {\n const isComputed = typeof valueOrFn === 'function'\n const getter = valueOrFn as (prev?: T) => T\n\n // Create plain object atom\n const atom: InternalAtom<T> = {\n _snapshot: isComputed ? undefined! : valueOrFn,\n\n subs: undefined,\n subsTail: undefined,\n deps: undefined,\n depsTail: undefined,\n flags: isComputed ? ReactiveFlags.None : ReactiveFlags.Mutable,\n\n get(): T {\n if (activeSub !== undefined) {\n link(atom, activeSub, cycle)\n }\n return atom._snapshot\n },\n\n subscribe(observerOrFn: Observer<T> | ((value: T) => void)) {\n const obs = toObserver(observerOrFn)\n const observed = { current: false }\n const e = effect(() => {\n atom.get()\n if (!observed.current) {\n observed.current = true\n } else {\n obs.next?.(atom._snapshot)\n }\n })\n\n return {\n unsubscribe: () => {\n e.stop()\n },\n }\n },\n _update(getValue?: T | ((snapshot: T) => T)): boolean {\n const prevSub = activeSub\n const compare = options?.compare ?? Object.is\n activeSub = atom\n ++cycle\n atom.depsTail = undefined\n if (isComputed) {\n atom.flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck\n }\n try {\n const oldValue = atom._snapshot\n const newValue =\n typeof getValue === 'function'\n ? (getValue as (snapshot: T) => T)(oldValue)\n : getValue === undefined && isComputed\n ? getter(oldValue)\n : getValue!\n if (oldValue === undefined || !compare(oldValue, newValue)) {\n atom._snapshot = newValue\n return true\n }\n return false\n } finally {\n activeSub = prevSub\n if (isComputed) {\n atom.flags &= ~ReactiveFlags.RecursedCheck\n }\n purgeDeps(atom)\n }\n },\n }\n\n if (isComputed) {\n atom.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty\n atom.get = function (): T {\n const flags = atom.flags\n if (\n flags & ReactiveFlags.Dirty ||\n (flags & ReactiveFlags.Pending && checkDirty(atom.deps!, atom))\n ) {\n if (atom._update()) {\n const subs = atom.subs\n if (subs !== undefined) {\n shallowPropagate(subs)\n }\n }\n } else if (flags & ReactiveFlags.Pending) {\n atom.flags = flags & ~ReactiveFlags.Pending\n }\n if (activeSub !== undefined) {\n link(atom, activeSub, cycle)\n }\n return atom._snapshot\n }\n } else {\n ;(atom as unknown as Atom<T>).set = function (\n // eslint-disable-next-line no-shadow\n valueOrFn: T | ((prev: T) => T),\n ): void {\n if (atom._update(valueOrFn)) {\n const subs = atom.subs\n if (subs !== undefined) {\n propagate(subs)\n shallowPropagate(subs)\n flush()\n }\n }\n }\n }\n\n return atom as unknown as Atom<T> | ReadonlyAtom<T>\n}\n\ninterface Effect extends ReactiveNode {\n notify: () => void\n stop: () => void\n}\n\nfunction effect<T>(fn: () => T): Effect {\n const run = (): T => {\n const prevSub = activeSub\n activeSub = effectObj\n ++cycle\n effectObj.depsTail = undefined\n effectObj.flags = ReactiveFlags.Watching | ReactiveFlags.RecursedCheck\n try {\n return fn()\n } finally {\n activeSub = prevSub\n effectObj.flags &= ~ReactiveFlags.RecursedCheck\n purgeDeps(effectObj)\n }\n }\n const effectObj: Effect = {\n deps: undefined,\n depsTail: undefined,\n subs: undefined,\n subsTail: undefined,\n flags: ReactiveFlags.Watching | ReactiveFlags.RecursedCheck,\n\n notify(): void {\n const flags = this.flags\n if (\n flags & ReactiveFlags.Dirty ||\n (flags & ReactiveFlags.Pending && checkDirty(this.deps!, this))\n ) {\n run()\n } else {\n this.flags = ReactiveFlags.Watching\n }\n },\n\n stop(): void {\n this.flags = ReactiveFlags.None\n this.depsTail = undefined\n purgeDeps(this)\n },\n }\n\n run()\n\n return effectObj\n}\n"],"names":["createReactiveSystem","effect","ReactiveFlags","getBatchDepth","valueOrFn"],"mappings":"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"}
1
+ {"version":3,"file":"atom.cjs","sources":["../../src/atom.ts"],"sourcesContent":["import { ReactiveFlags, createReactiveSystem, getBatchDepth } from './alien'\n\nimport type { ReactiveNode } from './alien'\nimport type {\n Atom,\n AtomOptions,\n Observer,\n ReadonlyAtom,\n Subscription,\n} from './types'\n\nexport function toObserver<T>(\n nextHandler?: Observer<T> | ((value: T) => void),\n errorHandler?: (error: any) => void,\n completionHandler?: () => void,\n): Observer<T> {\n const isObserver = typeof nextHandler === 'object'\n const self = isObserver ? nextHandler : undefined\n\n return {\n next: (isObserver ? nextHandler.next : nextHandler)?.bind(self),\n error: (isObserver ? nextHandler.error : errorHandler)?.bind(self),\n complete: (isObserver ? nextHandler.complete : completionHandler)?.bind(\n self,\n ),\n }\n}\n\ninterface InternalAtom<T> extends ReactiveNode {\n _snapshot: T\n _update: (getValue?: T | ((snapshot: T) => T)) => boolean\n get: () => T\n subscribe: (observerOrFn: Observer<T> | ((value: T) => void)) => Subscription\n}\n\nconst queuedEffects: Array<Effect | undefined> = []\nlet cycle = 0\nconst { link, unlink, propagate, checkDirty, shallowPropagate } =\n createReactiveSystem({\n update(atom: InternalAtom<any>): boolean {\n return atom._update()\n },\n // eslint-disable-next-line no-shadow\n notify(effect: Effect): void {\n queuedEffects[queuedEffectsLength++] = effect\n effect.flags &= ~ReactiveFlags.Watching\n },\n unwatched(atom: InternalAtom<any>): void {\n if (atom.depsTail !== undefined) {\n atom.depsTail = undefined\n atom.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty\n purgeDeps(atom)\n }\n },\n })\n\nlet notifyIndex = 0\nlet queuedEffectsLength = 0\nlet activeSub: ReactiveNode | undefined\n\nfunction purgeDeps(sub: ReactiveNode) {\n const depsTail = sub.depsTail\n let dep = depsTail !== undefined ? depsTail.nextDep : sub.deps\n while (dep !== undefined) {\n dep = unlink(dep, sub)\n }\n}\n\nexport function flush(): void {\n if (getBatchDepth() > 0) {\n return\n }\n while (notifyIndex < queuedEffectsLength) {\n // eslint-disable-next-line no-shadow\n const effect = queuedEffects[notifyIndex]!\n queuedEffects[notifyIndex++] = undefined\n effect.notify()\n }\n notifyIndex = 0\n queuedEffectsLength = 0\n}\n\ntype AsyncAtomState<TData, TError = unknown> =\n | { status: 'pending' }\n | { status: 'done'; data: TData }\n | { status: 'error'; error: TError }\n\nexport function createAsyncAtom<T>(\n getValue: () => Promise<T>,\n options?: AtomOptions<AsyncAtomState<T>>,\n): ReadonlyAtom<AsyncAtomState<T>> {\n const ref: { current?: InternalAtom<AsyncAtomState<T>> } = {}\n const atom = createAtom<AsyncAtomState<T>>(() => {\n getValue().then(\n (data) => {\n const internalAtom = ref.current!\n if (internalAtom._update({ status: 'done', data })) {\n const subs = internalAtom.subs\n if (subs !== undefined) {\n propagate(subs)\n shallowPropagate(subs)\n flush()\n }\n }\n },\n (error) => {\n const internalAtom = ref.current!\n if (internalAtom._update({ status: 'error', error })) {\n const subs = internalAtom.subs\n if (subs !== undefined) {\n propagate(subs)\n shallowPropagate(subs)\n flush()\n }\n }\n },\n )\n\n return { status: 'pending' }\n }, options)\n ref.current = atom as unknown as InternalAtom<AsyncAtomState<T>>\n\n return atom\n}\n\nexport function createAtom<T>(\n getValue: (prev?: NoInfer<T>) => T,\n options?: AtomOptions<T>,\n): ReadonlyAtom<T>\nexport function createAtom<T>(\n initialValue: T,\n options?: AtomOptions<T>,\n): Atom<T>\nexport function createAtom<T>(\n valueOrFn: T | ((prev?: T) => T),\n options?: AtomOptions<T>,\n): Atom<T> | ReadonlyAtom<T> {\n const isComputed = typeof valueOrFn === 'function'\n const getter = valueOrFn as (prev?: T) => T\n\n // Create plain object atom\n const atom: InternalAtom<T> = {\n _snapshot: isComputed ? undefined! : valueOrFn,\n\n subs: undefined,\n subsTail: undefined,\n deps: undefined,\n depsTail: undefined,\n flags: isComputed ? ReactiveFlags.None : ReactiveFlags.Mutable,\n\n get(): T {\n if (activeSub !== undefined) {\n link(atom, activeSub, cycle)\n }\n return atom._snapshot\n },\n\n subscribe(observerOrFn: Observer<T> | ((value: T) => void)) {\n const obs = toObserver(observerOrFn)\n const observed = { current: false }\n const e = effect(() => {\n atom.get()\n if (!observed.current) {\n observed.current = true\n } else {\n obs.next?.(atom._snapshot)\n }\n })\n\n return {\n unsubscribe: () => {\n e.stop()\n },\n }\n },\n _update(getValue?: T | ((snapshot: T) => T)): boolean {\n const prevSub = activeSub\n const compare = options?.compare ?? Object.is\n if (isComputed) {\n activeSub = atom\n ++cycle\n atom.depsTail = undefined\n } else if (getValue === undefined) {\n // Mutable atoms can be marked dirty by the reactive graph, but they should\n // never be recomputed without an explicit value/updater.\n return false\n }\n if (isComputed) {\n atom.flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck\n }\n try {\n const oldValue = atom._snapshot\n const newValue =\n typeof getValue === 'function'\n ? (getValue as (snapshot: T) => T)(oldValue)\n : getValue === undefined && isComputed\n ? getter(oldValue)\n : getValue!\n if (oldValue === undefined || !compare(oldValue, newValue)) {\n atom._snapshot = newValue\n return true\n }\n return false\n } finally {\n activeSub = prevSub\n if (isComputed) {\n atom.flags &= ~ReactiveFlags.RecursedCheck\n }\n purgeDeps(atom)\n }\n },\n }\n\n if (isComputed) {\n atom.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty\n atom.get = function (): T {\n const flags = atom.flags\n if (\n flags & ReactiveFlags.Dirty ||\n (flags & ReactiveFlags.Pending && checkDirty(atom.deps!, atom))\n ) {\n if (atom._update()) {\n const subs = atom.subs\n if (subs !== undefined) {\n shallowPropagate(subs)\n }\n }\n } else if (flags & ReactiveFlags.Pending) {\n atom.flags = flags & ~ReactiveFlags.Pending\n }\n if (activeSub !== undefined) {\n link(atom, activeSub, cycle)\n }\n return atom._snapshot\n }\n } else {\n ;(atom as unknown as Atom<T>).set = function (\n // eslint-disable-next-line no-shadow\n valueOrFn: T | ((prev: T) => T),\n ): void {\n if (atom._update(valueOrFn)) {\n const subs = atom.subs\n if (subs !== undefined) {\n propagate(subs)\n shallowPropagate(subs)\n flush()\n }\n }\n }\n }\n\n return atom as unknown as Atom<T> | ReadonlyAtom<T>\n}\n\ninterface Effect extends ReactiveNode {\n notify: () => void\n stop: () => void\n}\n\nfunction effect<T>(fn: () => T): Effect {\n const run = (): T => {\n const prevSub = activeSub\n activeSub = effectObj\n ++cycle\n effectObj.depsTail = undefined\n effectObj.flags = ReactiveFlags.Watching | ReactiveFlags.RecursedCheck\n try {\n return fn()\n } finally {\n activeSub = prevSub\n effectObj.flags &= ~ReactiveFlags.RecursedCheck\n purgeDeps(effectObj)\n }\n }\n const effectObj: Effect = {\n deps: undefined,\n depsTail: undefined,\n subs: undefined,\n subsTail: undefined,\n flags: ReactiveFlags.Watching | ReactiveFlags.RecursedCheck,\n\n notify(): void {\n const flags = this.flags\n if (\n flags & ReactiveFlags.Dirty ||\n (flags & ReactiveFlags.Pending && checkDirty(this.deps!, this))\n ) {\n run()\n } else {\n this.flags = ReactiveFlags.Watching\n }\n },\n\n stop(): void {\n this.flags = ReactiveFlags.None\n this.depsTail = undefined\n purgeDeps(this)\n },\n }\n\n run()\n\n return effectObj\n}\n"],"names":["createReactiveSystem","effect","ReactiveFlags","getBatchDepth","valueOrFn"],"mappings":"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"}
package/dist/esm/atom.js CHANGED
@@ -119,9 +119,13 @@ function createAtom(valueOrFn, options) {
119
119
  _update(getValue) {
120
120
  const prevSub = activeSub;
121
121
  const compare = options?.compare ?? Object.is;
122
- activeSub = atom;
123
- ++cycle;
124
- atom.depsTail = void 0;
122
+ if (isComputed) {
123
+ activeSub = atom;
124
+ ++cycle;
125
+ atom.depsTail = void 0;
126
+ } else if (getValue === void 0) {
127
+ return false;
128
+ }
125
129
  if (isComputed) {
126
130
  atom.flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck;
127
131
  }
@@ -1 +1 @@
1
- {"version":3,"file":"atom.js","sources":["../../src/atom.ts"],"sourcesContent":["import { ReactiveFlags, createReactiveSystem, getBatchDepth } from './alien'\n\nimport type { ReactiveNode } from './alien'\nimport type {\n Atom,\n AtomOptions,\n Observer,\n ReadonlyAtom,\n Subscription,\n} from './types'\n\nexport function toObserver<T>(\n nextHandler?: Observer<T> | ((value: T) => void),\n errorHandler?: (error: any) => void,\n completionHandler?: () => void,\n): Observer<T> {\n const isObserver = typeof nextHandler === 'object'\n const self = isObserver ? nextHandler : undefined\n\n return {\n next: (isObserver ? nextHandler.next : nextHandler)?.bind(self),\n error: (isObserver ? nextHandler.error : errorHandler)?.bind(self),\n complete: (isObserver ? nextHandler.complete : completionHandler)?.bind(\n self,\n ),\n }\n}\n\ninterface InternalAtom<T> extends ReactiveNode {\n _snapshot: T\n _update: (getValue?: T | ((snapshot: T) => T)) => boolean\n get: () => T\n subscribe: (observerOrFn: Observer<T> | ((value: T) => void)) => Subscription\n}\n\nconst queuedEffects: Array<Effect | undefined> = []\nlet cycle = 0\nconst { link, unlink, propagate, checkDirty, shallowPropagate } =\n createReactiveSystem({\n update(atom: InternalAtom<any>): boolean {\n return atom._update()\n },\n // eslint-disable-next-line no-shadow\n notify(effect: Effect): void {\n queuedEffects[queuedEffectsLength++] = effect\n effect.flags &= ~ReactiveFlags.Watching\n },\n unwatched(atom: InternalAtom<any>): void {\n if (atom.depsTail !== undefined) {\n atom.depsTail = undefined\n atom.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty\n purgeDeps(atom)\n }\n },\n })\n\nlet notifyIndex = 0\nlet queuedEffectsLength = 0\nlet activeSub: ReactiveNode | undefined\n\nfunction purgeDeps(sub: ReactiveNode) {\n const depsTail = sub.depsTail\n let dep = depsTail !== undefined ? depsTail.nextDep : sub.deps\n while (dep !== undefined) {\n dep = unlink(dep, sub)\n }\n}\n\nexport function flush(): void {\n if (getBatchDepth() > 0) {\n return\n }\n while (notifyIndex < queuedEffectsLength) {\n // eslint-disable-next-line no-shadow\n const effect = queuedEffects[notifyIndex]!\n queuedEffects[notifyIndex++] = undefined\n effect.notify()\n }\n notifyIndex = 0\n queuedEffectsLength = 0\n}\n\ntype AsyncAtomState<TData, TError = unknown> =\n | { status: 'pending' }\n | { status: 'done'; data: TData }\n | { status: 'error'; error: TError }\n\nexport function createAsyncAtom<T>(\n getValue: () => Promise<T>,\n options?: AtomOptions<AsyncAtomState<T>>,\n): ReadonlyAtom<AsyncAtomState<T>> {\n const ref: { current?: InternalAtom<AsyncAtomState<T>> } = {}\n const atom = createAtom<AsyncAtomState<T>>(() => {\n getValue().then(\n (data) => {\n const internalAtom = ref.current!\n if (internalAtom._update({ status: 'done', data })) {\n const subs = internalAtom.subs\n if (subs !== undefined) {\n propagate(subs)\n shallowPropagate(subs)\n flush()\n }\n }\n },\n (error) => {\n const internalAtom = ref.current!\n if (internalAtom._update({ status: 'error', error })) {\n const subs = internalAtom.subs\n if (subs !== undefined) {\n propagate(subs)\n shallowPropagate(subs)\n flush()\n }\n }\n },\n )\n\n return { status: 'pending' }\n }, options)\n ref.current = atom as unknown as InternalAtom<AsyncAtomState<T>>\n\n return atom\n}\n\nexport function createAtom<T>(\n getValue: (prev?: NoInfer<T>) => T,\n options?: AtomOptions<T>,\n): ReadonlyAtom<T>\nexport function createAtom<T>(\n initialValue: T,\n options?: AtomOptions<T>,\n): Atom<T>\nexport function createAtom<T>(\n valueOrFn: T | ((prev?: T) => T),\n options?: AtomOptions<T>,\n): Atom<T> | ReadonlyAtom<T> {\n const isComputed = typeof valueOrFn === 'function'\n const getter = valueOrFn as (prev?: T) => T\n\n // Create plain object atom\n const atom: InternalAtom<T> = {\n _snapshot: isComputed ? undefined! : valueOrFn,\n\n subs: undefined,\n subsTail: undefined,\n deps: undefined,\n depsTail: undefined,\n flags: isComputed ? ReactiveFlags.None : ReactiveFlags.Mutable,\n\n get(): T {\n if (activeSub !== undefined) {\n link(atom, activeSub, cycle)\n }\n return atom._snapshot\n },\n\n subscribe(observerOrFn: Observer<T> | ((value: T) => void)) {\n const obs = toObserver(observerOrFn)\n const observed = { current: false }\n const e = effect(() => {\n atom.get()\n if (!observed.current) {\n observed.current = true\n } else {\n obs.next?.(atom._snapshot)\n }\n })\n\n return {\n unsubscribe: () => {\n e.stop()\n },\n }\n },\n _update(getValue?: T | ((snapshot: T) => T)): boolean {\n const prevSub = activeSub\n const compare = options?.compare ?? Object.is\n activeSub = atom\n ++cycle\n atom.depsTail = undefined\n if (isComputed) {\n atom.flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck\n }\n try {\n const oldValue = atom._snapshot\n const newValue =\n typeof getValue === 'function'\n ? (getValue as (snapshot: T) => T)(oldValue)\n : getValue === undefined && isComputed\n ? getter(oldValue)\n : getValue!\n if (oldValue === undefined || !compare(oldValue, newValue)) {\n atom._snapshot = newValue\n return true\n }\n return false\n } finally {\n activeSub = prevSub\n if (isComputed) {\n atom.flags &= ~ReactiveFlags.RecursedCheck\n }\n purgeDeps(atom)\n }\n },\n }\n\n if (isComputed) {\n atom.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty\n atom.get = function (): T {\n const flags = atom.flags\n if (\n flags & ReactiveFlags.Dirty ||\n (flags & ReactiveFlags.Pending && checkDirty(atom.deps!, atom))\n ) {\n if (atom._update()) {\n const subs = atom.subs\n if (subs !== undefined) {\n shallowPropagate(subs)\n }\n }\n } else if (flags & ReactiveFlags.Pending) {\n atom.flags = flags & ~ReactiveFlags.Pending\n }\n if (activeSub !== undefined) {\n link(atom, activeSub, cycle)\n }\n return atom._snapshot\n }\n } else {\n ;(atom as unknown as Atom<T>).set = function (\n // eslint-disable-next-line no-shadow\n valueOrFn: T | ((prev: T) => T),\n ): void {\n if (atom._update(valueOrFn)) {\n const subs = atom.subs\n if (subs !== undefined) {\n propagate(subs)\n shallowPropagate(subs)\n flush()\n }\n }\n }\n }\n\n return atom as unknown as Atom<T> | ReadonlyAtom<T>\n}\n\ninterface Effect extends ReactiveNode {\n notify: () => void\n stop: () => void\n}\n\nfunction effect<T>(fn: () => T): Effect {\n const run = (): T => {\n const prevSub = activeSub\n activeSub = effectObj\n ++cycle\n effectObj.depsTail = undefined\n effectObj.flags = ReactiveFlags.Watching | ReactiveFlags.RecursedCheck\n try {\n return fn()\n } finally {\n activeSub = prevSub\n effectObj.flags &= ~ReactiveFlags.RecursedCheck\n purgeDeps(effectObj)\n }\n }\n const effectObj: Effect = {\n deps: undefined,\n depsTail: undefined,\n subs: undefined,\n subsTail: undefined,\n flags: ReactiveFlags.Watching | ReactiveFlags.RecursedCheck,\n\n notify(): void {\n const flags = this.flags\n if (\n flags & ReactiveFlags.Dirty ||\n (flags & ReactiveFlags.Pending && checkDirty(this.deps!, this))\n ) {\n run()\n } else {\n this.flags = ReactiveFlags.Watching\n }\n },\n\n stop(): void {\n this.flags = ReactiveFlags.None\n this.depsTail = undefined\n purgeDeps(this)\n },\n }\n\n run()\n\n return effectObj\n}\n"],"names":["effect","valueOrFn"],"mappings":"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"}
1
+ {"version":3,"file":"atom.js","sources":["../../src/atom.ts"],"sourcesContent":["import { ReactiveFlags, createReactiveSystem, getBatchDepth } from './alien'\n\nimport type { ReactiveNode } from './alien'\nimport type {\n Atom,\n AtomOptions,\n Observer,\n ReadonlyAtom,\n Subscription,\n} from './types'\n\nexport function toObserver<T>(\n nextHandler?: Observer<T> | ((value: T) => void),\n errorHandler?: (error: any) => void,\n completionHandler?: () => void,\n): Observer<T> {\n const isObserver = typeof nextHandler === 'object'\n const self = isObserver ? nextHandler : undefined\n\n return {\n next: (isObserver ? nextHandler.next : nextHandler)?.bind(self),\n error: (isObserver ? nextHandler.error : errorHandler)?.bind(self),\n complete: (isObserver ? nextHandler.complete : completionHandler)?.bind(\n self,\n ),\n }\n}\n\ninterface InternalAtom<T> extends ReactiveNode {\n _snapshot: T\n _update: (getValue?: T | ((snapshot: T) => T)) => boolean\n get: () => T\n subscribe: (observerOrFn: Observer<T> | ((value: T) => void)) => Subscription\n}\n\nconst queuedEffects: Array<Effect | undefined> = []\nlet cycle = 0\nconst { link, unlink, propagate, checkDirty, shallowPropagate } =\n createReactiveSystem({\n update(atom: InternalAtom<any>): boolean {\n return atom._update()\n },\n // eslint-disable-next-line no-shadow\n notify(effect: Effect): void {\n queuedEffects[queuedEffectsLength++] = effect\n effect.flags &= ~ReactiveFlags.Watching\n },\n unwatched(atom: InternalAtom<any>): void {\n if (atom.depsTail !== undefined) {\n atom.depsTail = undefined\n atom.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty\n purgeDeps(atom)\n }\n },\n })\n\nlet notifyIndex = 0\nlet queuedEffectsLength = 0\nlet activeSub: ReactiveNode | undefined\n\nfunction purgeDeps(sub: ReactiveNode) {\n const depsTail = sub.depsTail\n let dep = depsTail !== undefined ? depsTail.nextDep : sub.deps\n while (dep !== undefined) {\n dep = unlink(dep, sub)\n }\n}\n\nexport function flush(): void {\n if (getBatchDepth() > 0) {\n return\n }\n while (notifyIndex < queuedEffectsLength) {\n // eslint-disable-next-line no-shadow\n const effect = queuedEffects[notifyIndex]!\n queuedEffects[notifyIndex++] = undefined\n effect.notify()\n }\n notifyIndex = 0\n queuedEffectsLength = 0\n}\n\ntype AsyncAtomState<TData, TError = unknown> =\n | { status: 'pending' }\n | { status: 'done'; data: TData }\n | { status: 'error'; error: TError }\n\nexport function createAsyncAtom<T>(\n getValue: () => Promise<T>,\n options?: AtomOptions<AsyncAtomState<T>>,\n): ReadonlyAtom<AsyncAtomState<T>> {\n const ref: { current?: InternalAtom<AsyncAtomState<T>> } = {}\n const atom = createAtom<AsyncAtomState<T>>(() => {\n getValue().then(\n (data) => {\n const internalAtom = ref.current!\n if (internalAtom._update({ status: 'done', data })) {\n const subs = internalAtom.subs\n if (subs !== undefined) {\n propagate(subs)\n shallowPropagate(subs)\n flush()\n }\n }\n },\n (error) => {\n const internalAtom = ref.current!\n if (internalAtom._update({ status: 'error', error })) {\n const subs = internalAtom.subs\n if (subs !== undefined) {\n propagate(subs)\n shallowPropagate(subs)\n flush()\n }\n }\n },\n )\n\n return { status: 'pending' }\n }, options)\n ref.current = atom as unknown as InternalAtom<AsyncAtomState<T>>\n\n return atom\n}\n\nexport function createAtom<T>(\n getValue: (prev?: NoInfer<T>) => T,\n options?: AtomOptions<T>,\n): ReadonlyAtom<T>\nexport function createAtom<T>(\n initialValue: T,\n options?: AtomOptions<T>,\n): Atom<T>\nexport function createAtom<T>(\n valueOrFn: T | ((prev?: T) => T),\n options?: AtomOptions<T>,\n): Atom<T> | ReadonlyAtom<T> {\n const isComputed = typeof valueOrFn === 'function'\n const getter = valueOrFn as (prev?: T) => T\n\n // Create plain object atom\n const atom: InternalAtom<T> = {\n _snapshot: isComputed ? undefined! : valueOrFn,\n\n subs: undefined,\n subsTail: undefined,\n deps: undefined,\n depsTail: undefined,\n flags: isComputed ? ReactiveFlags.None : ReactiveFlags.Mutable,\n\n get(): T {\n if (activeSub !== undefined) {\n link(atom, activeSub, cycle)\n }\n return atom._snapshot\n },\n\n subscribe(observerOrFn: Observer<T> | ((value: T) => void)) {\n const obs = toObserver(observerOrFn)\n const observed = { current: false }\n const e = effect(() => {\n atom.get()\n if (!observed.current) {\n observed.current = true\n } else {\n obs.next?.(atom._snapshot)\n }\n })\n\n return {\n unsubscribe: () => {\n e.stop()\n },\n }\n },\n _update(getValue?: T | ((snapshot: T) => T)): boolean {\n const prevSub = activeSub\n const compare = options?.compare ?? Object.is\n if (isComputed) {\n activeSub = atom\n ++cycle\n atom.depsTail = undefined\n } else if (getValue === undefined) {\n // Mutable atoms can be marked dirty by the reactive graph, but they should\n // never be recomputed without an explicit value/updater.\n return false\n }\n if (isComputed) {\n atom.flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck\n }\n try {\n const oldValue = atom._snapshot\n const newValue =\n typeof getValue === 'function'\n ? (getValue as (snapshot: T) => T)(oldValue)\n : getValue === undefined && isComputed\n ? getter(oldValue)\n : getValue!\n if (oldValue === undefined || !compare(oldValue, newValue)) {\n atom._snapshot = newValue\n return true\n }\n return false\n } finally {\n activeSub = prevSub\n if (isComputed) {\n atom.flags &= ~ReactiveFlags.RecursedCheck\n }\n purgeDeps(atom)\n }\n },\n }\n\n if (isComputed) {\n atom.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty\n atom.get = function (): T {\n const flags = atom.flags\n if (\n flags & ReactiveFlags.Dirty ||\n (flags & ReactiveFlags.Pending && checkDirty(atom.deps!, atom))\n ) {\n if (atom._update()) {\n const subs = atom.subs\n if (subs !== undefined) {\n shallowPropagate(subs)\n }\n }\n } else if (flags & ReactiveFlags.Pending) {\n atom.flags = flags & ~ReactiveFlags.Pending\n }\n if (activeSub !== undefined) {\n link(atom, activeSub, cycle)\n }\n return atom._snapshot\n }\n } else {\n ;(atom as unknown as Atom<T>).set = function (\n // eslint-disable-next-line no-shadow\n valueOrFn: T | ((prev: T) => T),\n ): void {\n if (atom._update(valueOrFn)) {\n const subs = atom.subs\n if (subs !== undefined) {\n propagate(subs)\n shallowPropagate(subs)\n flush()\n }\n }\n }\n }\n\n return atom as unknown as Atom<T> | ReadonlyAtom<T>\n}\n\ninterface Effect extends ReactiveNode {\n notify: () => void\n stop: () => void\n}\n\nfunction effect<T>(fn: () => T): Effect {\n const run = (): T => {\n const prevSub = activeSub\n activeSub = effectObj\n ++cycle\n effectObj.depsTail = undefined\n effectObj.flags = ReactiveFlags.Watching | ReactiveFlags.RecursedCheck\n try {\n return fn()\n } finally {\n activeSub = prevSub\n effectObj.flags &= ~ReactiveFlags.RecursedCheck\n purgeDeps(effectObj)\n }\n }\n const effectObj: Effect = {\n deps: undefined,\n depsTail: undefined,\n subs: undefined,\n subsTail: undefined,\n flags: ReactiveFlags.Watching | ReactiveFlags.RecursedCheck,\n\n notify(): void {\n const flags = this.flags\n if (\n flags & ReactiveFlags.Dirty ||\n (flags & ReactiveFlags.Pending && checkDirty(this.deps!, this))\n ) {\n run()\n } else {\n this.flags = ReactiveFlags.Watching\n }\n },\n\n stop(): void {\n this.flags = ReactiveFlags.None\n this.depsTail = undefined\n purgeDeps(this)\n },\n }\n\n run()\n\n return effectObj\n}\n"],"names":["effect","valueOrFn"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/store",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "description": "Framework agnostic type-safe store w/ reactive framework adapters",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
package/src/atom.ts CHANGED
@@ -176,9 +176,15 @@ export function createAtom<T>(
176
176
  _update(getValue?: T | ((snapshot: T) => T)): boolean {
177
177
  const prevSub = activeSub
178
178
  const compare = options?.compare ?? Object.is
179
- activeSub = atom
180
- ++cycle
181
- atom.depsTail = undefined
179
+ if (isComputed) {
180
+ activeSub = atom
181
+ ++cycle
182
+ atom.depsTail = undefined
183
+ } else if (getValue === undefined) {
184
+ // Mutable atoms can be marked dirty by the reactive graph, but they should
185
+ // never be recomputed without an explicit value/updater.
186
+ return false
187
+ }
182
188
  if (isComputed) {
183
189
  atom.flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck
184
190
  }