UNPKG

react-cache-promise

Version:

react-cache-promise

96 lines (93 loc) 3.02 kB
import * as React from 'react'; const promiseCache = new Map(); const reverseCache = new Map(); function createCache(arg, promise) { let subscriptionCache = { subscribe, state: null, active: true, }; promise.then(fulfilledValue => { if (subscriptionCache.active) { subscriptionCache.state = { status: "fulfilled", value: fulfilledValue }; if (subscriptionCache.listeners) { Object.values(subscriptionCache.listeners).forEach(cb => { React.startTransition(() => cb(fulfilledValue)); }); } } }, (error) => { if (subscriptionCache.active) { subscriptionCache.state = { status: "rejected", reason: error }; if (subscriptionCache.listeners) { Object.values(subscriptionCache.listeners).forEach(cb => { React.startTransition(() => cb(error)); }); } } }); function subscribe(cb) { if (!subscriptionCache.index) { subscriptionCache.index = 0; } if (!subscriptionCache.listeners) { subscriptionCache.listeners = []; } let id = ++subscriptionCache.index; subscriptionCache.listeners[id] = cb; return () => { delete subscriptionCache.listeners[id]; }; } return subscriptionCache; } function patchQuery(fn, getCacheArg) { function modified(...args) { let arg = getCacheArg.apply(null, args); let cachedPromise = promiseCache.get(arg); if (cachedPromise) { return cachedPromise; } let promise = fn.apply(null, args); promiseCache.set(arg, promise); reverseCache.set(promise, createCache(arg, promise)); return promise; } return modified; } function usePromise(promise) { let subscription = reverseCache.get(promise); let state = subscription.state; if (state === null) { throw promise; } if (state.status === "rejected") { throw state.reason; } let rerender = React.useState()[1]; React.useEffect(() => subscription.subscribe(rerender), [subscription]); return state.value; } function evict(arg) { let promise = promiseCache.get(arg); if (!promise) { return; } let subscription = reverseCache.get(promise); if (!subscription) { return; } let returnValue = promiseCache.delete(arg) && reverseCache.delete(promise); subscription.active = false; subscription.state = null; let listeners = subscription.listeners; if (listeners) { let newObject = {}; Object.values(listeners).forEach(cb => { React.startTransition(() => cb(newObject)); }); } return returnValue; } export { evict, patchQuery, usePromise }; //# sourceMappingURL=index.js.map