Skip to content
Source
Sign inSign up

replayRecorderDeferredRegistry.ts

43 lines1.4 KB

1import * as Deferred from "effect/Deferred";
2import * as Effect from "effect/Effect";
3import * as SynchronizedRef from "effect/SynchronizedRef";
4​
5export interface ReplayRecorderDeferredRegistry {
6 readonly getOrCreate: (key: string) => Effect.Effect<Deferred.Deferred<void>>;
7 readonly succeed: (key: string) => Effect.Effect<void>;
8}
9​
10export const makeReplayRecorderDeferredRegistry = Effect.fn("makeReplayRecorderDeferredRegistry")(
11 function* () {
12 const state = yield* SynchronizedRef.make(new Map<string, Deferred.Deferred<void>>());
13​
14 const getOrCreate = Effect.fn("ReplayRecorderDeferredRegistry.getOrCreate")(function* (
15 key: string,
16 ) {
17 return yield* SynchronizedRef.modifyEffect(state, (deferreds) => {
18 const existing = deferreds.get(key);
19 if (existing !== undefined) {
20 return Effect.succeed([existing, deferreds] as const);
21 }
22​
23 return Deferred.make<void>().pipe(
24 Effect.map((deferred) => {
25 const next = new Map(deferreds);
26 next.set(key, deferred);
27 return [deferred, next] as const;
28 }),
29 );
30 });
31 });
32​
33 const succeed = Effect.fn("ReplayRecorderDeferredRegistry.succeed")(function* (key: string) {
34 const deferred = yield* getOrCreate(key);
35 yield* Deferred.succeed(deferred, undefined);
36 });
37​
38 return {
39 getOrCreate,
40 succeed,
41 } satisfies ReplayRecorderDeferredRegistry;
42 },
43);