@virtualstate/examples
Version:
56 lines • 1.84 kB
JavaScript
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