export type Cleanup = () => void | PromiseLike; export interface Provider { readonly load: (ctx: Ctx) => Promise; readonly values: WeakMap>; } export function provider(load: (ctx: Ctx) => Promise): Provider { return { load, values: new WeakMap() }; } /** A run-scoped, lazy provider cache with last-created-first-disposed cleanup. */ export class Ctx { private readonly cleanups: Cleanup[] = []; use(source: Provider): Promise { const existing = source.values.get(this); if (existing) return existing; const value = source.load(this); source.values.set(this, value); return value; } onDispose(cleanup: Cleanup): void { this.cleanups.push(cleanup); } async dispose(): Promise { for (const cleanup of this.cleanups.reverse()) { try { await cleanup(); } catch (error) { console.error("cleanup failed:", error); } } this.cleanups.length = 0; } }