UNPKG

medama

Version:

A minimalist, powerful, and dependency-free reactive state management library for TypeScript and JavaScript applications.

101 lines 3.88 kB
export const createSelectorStore = (runOverState) => { const selectorSubscriptionStore = new WeakMap(); const getSelectorRecord = (selector) => { var _a; const selectorRecord = (_a = selectorSubscriptionStore.get(selector)) !== null && _a !== void 0 ? _a : createSelectorRecord(selector, runOverState); selectorSubscriptionStore.set(selector, selectorRecord); return selectorRecord; }; const getSelectorValue = (selector) => { const { getValue } = getSelectorRecord(selector); return getValue(); }; const subscribeToStateInSelectorStore = (selector, subscription) => { let currentSelector = selector; let unsubscribeHandle = null; let currentRevealedSubscriptionJob; const evaluateAndSubscribe = (subscriptionToReveal) => { const { addSubscription, getValue } = getSelectorRecord(currentSelector); const possibleSubscriptionJob = subscriptionToReveal(getValue()); currentRevealedSubscriptionJob = typeof possibleSubscriptionJob === 'function' ? possibleSubscriptionJob : subscriptionToReveal; unsubscribeHandle = addSubscription(currentRevealedSubscriptionJob); }; evaluateAndSubscribe(subscription); const unsubscribe = () => { unsubscribeHandle === null || unsubscribeHandle === void 0 ? void 0 : unsubscribeHandle(); unsubscribeHandle = null; }; const resubscribe = (subscriptionToResubscribe) => { unsubscribe(); evaluateAndSubscribe(subscriptionToResubscribe); }; const transfer = (selectorToTransferTo) => { unsubscribe(); currentSelector = selectorToTransferTo; evaluateAndSubscribe(currentRevealedSubscriptionJob); }; return { unsubscribe, resubscribe, transfer }; }; return { getSelectorValue, subscribeToStateInSelectorStore }; }; export const createSelectorRecord = (selector, runOverState) => { const collectedKeyHandles = new Set(); const keyHandleCollector = (keyHandle) => { collectedKeyHandles.add(keyHandle); }; const unregisterTriggerHandleCallbacks = new Set(); let isRegistered = false; const registerTrigger = (isToPopulateUnregisterCallbacks = false) => { if (isRegistered) return; collectedKeyHandles.forEach((handle) => { const callback = handle(selectorTrigger); isToPopulateUnregisterCallbacks && unregisterTriggerHandleCallbacks.add(callback); }); isRegistered = true; }; const unregisterTrigger = () => { unregisterTriggerHandleCallbacks.forEach((callback) => { callback(); }); }; let memValue; let isToRecalculateValue = false; const runSelectorWithMemoization = () => { if (isToRecalculateValue) { memValue = runOverState(selector); isToRecalculateValue = false; } }; const jobs = new Set(); const selectorTrigger = () => { isToRecalculateValue = true; if (jobs.size === 0) { unregisterTrigger(); isRegistered = false; return; } runSelectorWithMemoization(); jobs.forEach((job) => { job(memValue); }); }; const addSubscription = (subscriptionJob) => { jobs.add(subscriptionJob); return () => { jobs.delete(subscriptionJob); }; }; const getValue = () => { runSelectorWithMemoization(); registerTrigger(); return memValue; }; memValue = runOverState(selector, keyHandleCollector); registerTrigger(true); return { addSubscription, getValue }; }; //# sourceMappingURL=selectorStore.js.map