UNPKG

@virtualstate/examples

Version:
56 lines 1.84 kB
import { isAsyncIterable, isPromise } from "iterable"; import { queue } from "./queue.js"; export async function* performCached(caches, intermediateCacheEnabled, key, input) { const existingValue = caches.reduce((found, cache) => found ?? cache?.get(key), undefined); if (intermediateCacheEnabled && isAsyncIterable(existingValue)) { // If we have an async iterable, we can replay it return yield* existingValue; } else if (intermediateCacheEnabled && isPromise(existingValue)) { const value = await existingValue; if (isValueNotUndefined(value)) { yield value; } return; } else if (isValueNotUndefined(existingValue) && (intermediateCacheEnabled || !isPromise(existingValue))) { return yield existingValue; } const q = queue(intermediateCacheEnabled); if (intermediateCacheEnabled) { for (const cache of caches) { cache?.set(key, q); } } let value; try { for await (value of input) { yield q.value(value); } } catch (error) { if (intermediateCacheEnabled) { resetCachesIfPromise(); q.reject(error); } await Promise.reject(error); throw error; // awaiting a rejected promise above should close this stack... but for a programmers eye... } for (const cache of caches) { cache?.set(key, value); } if (intermediateCacheEnabled) { q.end(); } function resetCachesIfPromise() { for (const cache of caches) { if (cache?.get(key) === q) { cache.set(key, undefined); } } } function isValueNotUndefined(value) { return typeof value !== "undefined"; } } //# sourceMappingURL=perform-cached.js.map