repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/the-system/lazy.ts
Raw/**
* Memoize a dynamic import so concurrent callers share one evaluation.
*
* Pi loads extensions through jiti with the module cache disabled.
* Two concurrent imports of the same module can then race: the second
* caller receives a partially initialized module whose top-level awaits
* have not finished and whose imported bindings are still `undefined`.
*
* Memoize each target and serialize distinct targets, since their shared
* dependencies can also race through jiti's partially initialized cache.
* A rejected load clears the memo so the next call retries.
*/
let pending: Promise<unknown> = Promise.resolve();
export function lazy<T>(load: () => Promise<T>): () => Promise<T> {
let promise: Promise<T> | undefined;
return () =>
(promise ??= (() => {
const next = pending.then(load);
pending = next.catch(() => {});
return next.catch((error: unknown) => {
promise = undefined;
throw error;
});
})());
}