import * as Deferred from "effect/Deferred"; import * as Effect from "effect/Effect"; import * as SynchronizedRef from "effect/SynchronizedRef"; export interface ReplayRecorderDeferredRegistry { readonly getOrCreate: (key: string) => Effect.Effect>; readonly succeed: (key: string) => Effect.Effect; } export const makeReplayRecorderDeferredRegistry = Effect.fn("makeReplayRecorderDeferredRegistry")( function* () { const state = yield* SynchronizedRef.make(new Map>()); const getOrCreate = Effect.fn("ReplayRecorderDeferredRegistry.getOrCreate")(function* ( key: string, ) { return yield* SynchronizedRef.modifyEffect(state, (deferreds) => { const existing = deferreds.get(key); if (existing !== undefined) { return Effect.succeed([existing, deferreds] as const); } return Deferred.make().pipe( Effect.map((deferred) => { const next = new Map(deferreds); next.set(key, deferred); return [deferred, next] as const; }), ); }); }); const succeed = Effect.fn("ReplayRecorderDeferredRegistry.succeed")(function* (key: string) { const deferred = yield* getOrCreate(key); yield* Deferred.succeed(deferred, undefined); }); return { getOrCreate, succeed, } satisfies ReplayRecorderDeferredRegistry; }, );