UNPKG

jotai-effect

Version:
109 lines 4.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.withAtomEffect = withAtomEffect; const internals_1 = require("jotai/vanilla/internals"); const atomEffect_1 = require("./atomEffect.js"); const env_1 = require("./env.js"); function withAtomEffect(targetAtom, effect) { const proto = Object.getPrototypeOf(targetAtom); const desc = Object.getOwnPropertyDescriptors(targetAtom); let depth = 0; desc.read.value = function read(get, options) { try { ++depth; // handles case when withAtomEffect is nested const context = depth === 1 ? targetAtom : this; return targetAtom.read.call(context, get, options); } finally { --depth; } }; if (isWritableAtom(targetAtom)) { desc.write.value = function write(get, set, ...args) { try { ++depth; const context = depth === 1 ? targetAtom : this; return targetAtom.write.call(context, get, set, ...args); } finally { --depth; } }; } const targetWithEffect = Object.create(proto, desc); targetWithEffect.unstable_onInit = (store) => { const buildingBlocks = (0, internals_1.INTERNAL_getBuildingBlocksRev2)(store); const invalidatedAtoms = buildingBlocks[2]; const storeHooks = (0, internals_1.INTERNAL_initializeStoreHooksRev2)(buildingBlocks[6]); const ensureAtomState = buildingBlocks[11]; const flushCallbacks = buildingBlocks[12]; const readAtomState = buildingBlocks[14]; const mountDependencies = buildingBlocks[17]; const mountAtom = buildingBlocks[18]; const unmountAtom = buildingBlocks[19]; let inProgress = false; let isSubscribed = false; const effectAtom = (0, atomEffect_1.atomEffect)((get, set) => { if (inProgress) { return; } isSubscribed = false; const getter = (a) => { if (a === targetWithEffect) { isSubscribed = true; return get.peek(a); } return get(a); }; getter.peek = get.peek; const setter = (a, ...args) => { if (a === targetWithEffect) { inProgress = true; return set(a, ...args); } return set(a, ...args); }; setter.recurse = (...args) => { inProgress = false; return set.recurse(...args); }; return targetWithEffect.effect.call(targetAtom, getter, setter); }); if ((0, env_1.isDev)()) { Object.defineProperty(effectAtom, 'debugLabel', { get: () => { var _a; return `${(_a = targetWithEffect.debugLabel) !== null && _a !== void 0 ? _a : 'atom'}:effect`; }, }); effectAtom.debugPrivate = true; } const effectAtomState = ensureAtomState(store, effectAtom); const targetWithEffectAtomState = ensureAtomState(store, targetWithEffect); storeHooks.c.add(targetWithEffect, function atomChanged() { if (isSubscribed) { invalidatedAtoms.set(effectAtom, effectAtomState.n); effectAtomState.d.set(targetWithEffect, targetWithEffectAtomState.n - 1); readAtomState(store, effectAtom); mountDependencies(store, effectAtom); invalidatedAtoms.delete(effectAtom); effectAtomState.d.delete(targetWithEffect); } }); storeHooks.m.add(targetWithEffect, function mountEffect() { mountAtom(store, effectAtom); flushCallbacks(store); }); storeHooks.u.add(targetWithEffect, function unmountEffect() { unmountAtom(store, effectAtom); flushCallbacks(store); }); storeHooks.f.add(function flushEffect() { inProgress = false; }); }; targetWithEffect.effect = effect; return targetWithEffect; } function isWritableAtom(atom) { return 'write' in atom && typeof atom.write === 'function'; } //# sourceMappingURL=withAtomEffect.js.map