jotai
Version:
👻 Primitive and flexible state management for React
45 lines (44 loc) • 1.92 kB
JavaScript
import { INTERNAL_getBuildingBlocksRev4 as INTERNAL_getBuildingBlocks, INTERNAL_KEY_registerAbortHandler as KEY_registerAbortHandler, } from '../vanilla/internals.js';
export const isPromiseLike = (x) => typeof x?.then === 'function';
const continuablePromiseMap = new WeakMap();
export const createContinuablePromise = (store, promise, getValue) => {
const buildingBlocks = INTERNAL_getBuildingBlocks(store);
const registerAbortHandler = buildingBlocks[KEY_registerAbortHandler];
let continuablePromise = continuablePromiseMap.get(promise);
if (!continuablePromise) {
continuablePromise = new Promise((resolve, reject) => {
let curr = promise;
const onFulfilled = (me) => (v) => {
if (curr === me) {
resolve(v);
}
};
const onRejected = (me) => (e) => {
if (curr === me) {
reject(e);
}
};
const onAbort = () => {
try {
const nextValue = getValue();
if (isPromiseLike(nextValue)) {
continuablePromiseMap.set(nextValue, continuablePromise);
curr = nextValue;
nextValue.then(onFulfilled(nextValue), onRejected(nextValue));
registerAbortHandler(buildingBlocks, store, nextValue, onAbort);
}
else {
resolve(nextValue);
}
}
catch (e) {
reject(e);
}
};
promise.then(onFulfilled(promise), onRejected(promise));
registerAbortHandler(buildingBlocks, store, promise, onAbort);
});
continuablePromiseMap.set(promise, continuablePromise);
}
return continuablePromise;
};