UNPKG

@tanstack/store

Version:

Framework agnostic type-safe store w/ reactive framework adapters

223 lines (222 loc) 6.3 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const alien = require("./alien.cjs"); function toObserver(nextHandler, errorHandler, completionHandler) { const isObserver = typeof nextHandler === "object"; const self = isObserver ? nextHandler : void 0; return { next: (isObserver ? nextHandler.next : nextHandler)?.bind(self), error: (isObserver ? nextHandler.error : errorHandler)?.bind(self), complete: (isObserver ? nextHandler.complete : completionHandler)?.bind( self ) }; } const queuedEffects = []; let cycle = 0; const { link, unlink, propagate, checkDirty, shallowPropagate } = alien.createReactiveSystem({ update(atom) { return atom._update(); }, // eslint-disable-next-line no-shadow notify(effect2) { queuedEffects[queuedEffectsLength++] = effect2; effect2.flags &= ~alien.ReactiveFlags.Watching; }, unwatched(atom) { if (atom.depsTail !== void 0) { atom.depsTail = void 0; atom.flags = alien.ReactiveFlags.Mutable | alien.ReactiveFlags.Dirty; purgeDeps(atom); } } }); let notifyIndex = 0; let queuedEffectsLength = 0; let activeSub; function purgeDeps(sub) { const depsTail = sub.depsTail; let dep = depsTail !== void 0 ? depsTail.nextDep : sub.deps; while (dep !== void 0) { dep = unlink(dep, sub); } } function flush() { if (alien.getBatchDepth() > 0) { return; } while (notifyIndex < queuedEffectsLength) { const effect2 = queuedEffects[notifyIndex]; queuedEffects[notifyIndex++] = void 0; effect2.notify(); } notifyIndex = 0; queuedEffectsLength = 0; } function createAsyncAtom(getValue, options) { const ref = {}; const atom = createAtom(() => { getValue().then( (data) => { const internalAtom = ref.current; if (internalAtom._update({ status: "done", data })) { const subs = internalAtom.subs; if (subs !== void 0) { propagate(subs); shallowPropagate(subs); flush(); } } }, (error) => { const internalAtom = ref.current; if (internalAtom._update({ status: "error", error })) { const subs = internalAtom.subs; if (subs !== void 0) { propagate(subs); shallowPropagate(subs); flush(); } } } ); return { status: "pending" }; }, options); ref.current = atom; return atom; } function createAtom(valueOrFn, options) { const isComputed = typeof valueOrFn === "function"; const getter = valueOrFn; const atom = { _snapshot: isComputed ? void 0 : valueOrFn, subs: void 0, subsTail: void 0, deps: void 0, depsTail: void 0, flags: isComputed ? alien.ReactiveFlags.None : alien.ReactiveFlags.Mutable, get() { if (activeSub !== void 0) { link(atom, activeSub, cycle); } return atom._snapshot; }, subscribe(observerOrFn) { const obs = toObserver(observerOrFn); const observed = { current: false }; const e = effect(() => { atom.get(); if (!observed.current) { observed.current = true; } else { obs.next?.(atom._snapshot); } }); return { unsubscribe: () => { e.stop(); } }; }, _update(getValue) { const prevSub = activeSub; const compare = options?.compare ?? Object.is; activeSub = atom; ++cycle; atom.depsTail = void 0; if (isComputed) { atom.flags = alien.ReactiveFlags.Mutable | alien.ReactiveFlags.RecursedCheck; } try { const oldValue = atom._snapshot; const newValue = typeof getValue === "function" ? getValue(oldValue) : getValue === void 0 && isComputed ? getter(oldValue) : getValue; if (oldValue === void 0 || !compare(oldValue, newValue)) { atom._snapshot = newValue; return true; } return false; } finally { activeSub = prevSub; if (isComputed) { atom.flags &= ~alien.ReactiveFlags.RecursedCheck; } purgeDeps(atom); } } }; if (isComputed) { atom.flags = alien.ReactiveFlags.Mutable | alien.ReactiveFlags.Dirty; atom.get = function() { const flags = atom.flags; if (flags & alien.ReactiveFlags.Dirty || flags & alien.ReactiveFlags.Pending && checkDirty(atom.deps, atom)) { if (atom._update()) { const subs = atom.subs; if (subs !== void 0) { shallowPropagate(subs); } } } else if (flags & alien.ReactiveFlags.Pending) { atom.flags = flags & ~alien.ReactiveFlags.Pending; } if (activeSub !== void 0) { link(atom, activeSub, cycle); } return atom._snapshot; }; } else { atom.set = function(valueOrFn2) { if (atom._update(valueOrFn2)) { const subs = atom.subs; if (subs !== void 0) { propagate(subs); shallowPropagate(subs); flush(); } } }; } return atom; } function effect(fn) { const run = () => { const prevSub = activeSub; activeSub = effectObj; ++cycle; effectObj.depsTail = void 0; effectObj.flags = alien.ReactiveFlags.Watching | alien.ReactiveFlags.RecursedCheck; try { return fn(); } finally { activeSub = prevSub; effectObj.flags &= ~alien.ReactiveFlags.RecursedCheck; purgeDeps(effectObj); } }; const effectObj = { deps: void 0, depsTail: void 0, subs: void 0, subsTail: void 0, flags: alien.ReactiveFlags.Watching | alien.ReactiveFlags.RecursedCheck, notify() { const flags = this.flags; if (flags & alien.ReactiveFlags.Dirty || flags & alien.ReactiveFlags.Pending && checkDirty(this.deps, this)) { run(); } else { this.flags = alien.ReactiveFlags.Watching; } }, stop() { this.flags = alien.ReactiveFlags.None; this.depsTail = void 0; purgeDeps(this); } }; run(); return effectObj; } exports.createAsyncAtom = createAsyncAtom; exports.createAtom = createAtom; exports.flush = flush; exports.toObserver = toObserver; //# sourceMappingURL=atom.cjs.map