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;
},
);