import * as Effect from "effect/Effect"; import * as PubSub from "effect/PubSub"; import * as Semaphore from "effect/Semaphore"; import * as Stream from "effect/Stream"; export interface SnapshotSubscription { readonly latest: A; readonly changes: Stream.Stream; } export const subscribeBeforeSnapshot = Effect.fn("subscribeBeforeSnapshot")(function* ( changes: PubSub.PubSub, snapshot: Effect.Effect, mutex: Semaphore.Semaphore, ) { return yield* mutex.withPermits(1)( Effect.gen(function* () { const latest = yield* snapshot; const subscription = yield* PubSub.subscribe(changes); return { latest, changes: Stream.fromSubscription(subscription), } satisfies SnapshotSubscription; }), ); }); export const subscribeBeforeSnapshotWithoutMutex = Effect.fn("subscribeBeforeSnapshotWithoutMutex")( function* (changes: PubSub.PubSub, snapshot: Effect.Effect) { const subscription = yield* PubSub.subscribe(changes); const latest = yield* snapshot; return { latest, changes: Stream.fromSubscription(subscription), } satisfies SnapshotSubscription; }, );