/** * Transaction support for atomic multi-collection operations. * * `createTransaction` returns a TransactionContext with collection accessors, * commit/rollback methods, and mutation tracking. Mutations are visible * immediately within the transaction (read-own-writes) and either committed * atomically or rolled back to pre-transaction state. * * `$transaction` is a callback wrapper that auto-commits on success and * auto-rolls back on failure. */ import { Effect, PubSub, Ref } from "effect"; import { TransactionError } from "../errors/crud-errors.js"; import type { EffectCollection } from "../factories/database-effect.js"; import type { TransactionContext } from "../types/crud-types.js"; import type { ChangeEvent } from "../types/reactive-types.js"; type HasId = { readonly id: string; }; /** * Internal ref map type used for cross-collection references. */ type StateRefs = Record>>; /** * Persistence trigger interface for scheduling debounced saves. */ interface PersistenceTrigger { /** Schedule a debounced save for the given key */ readonly schedule: (key: string) => void; } /** * Callback type for building a collection with transaction-aware afterMutation. * The afterMutation adds the collection name to the mutation set instead of * scheduling a persistence write. */ type BuildCollectionForTx = (collectionName: string, addMutation: (name: string) => void) => EffectCollection; /** * Create a new transaction context. * * Parameters: * - stateRefs: The database's collection Refs (will be snapshotted and potentially restored) * - transactionLock: Single-writer lock Ref (prevents concurrent transactions) * - buildCollectionForTx: Callback to create collection accessors with transaction-aware mutations * - persistenceTrigger: Optional trigger for scheduling saves on commit * - changePubSub: Optional PubSub for reactive change notifications. When provided, * individual mutation events are suppressed during the transaction and a single * batch event is published for each mutated collection on commit. * * Returns an Effect that yields a TransactionContext. The context provides: * - Collection accessors with the same interface as db.collectionName * - commit() to finalize changes and trigger persistence * - rollback() to restore snapshots and discard changes * - isActive to check if transaction is still open * - mutatedCollections to see which collections were written to * * On failure (e.g., lock already held), returns TransactionError. */ export declare const createTransaction: >>(stateRefs: StateRefs, transactionLock: Ref.Ref, buildCollectionForTx: BuildCollectionForTx, persistenceTrigger?: PersistenceTrigger, changePubSub?: PubSub.PubSub) => Effect.Effect, TransactionError>; /** * Execute a callback within an atomic transaction context. * * All CRUD operations inside the callback operate against the live in-memory state. * On success, changes are committed and persistence is triggered. * On failure (error thrown or explicit rollback), all mutations are reverted. * * Usage: * ```ts * const result = await db.$transaction((ctx) => * Effect.gen(function* () { * const user = yield* ctx.users.create({ name: "Alice" }) * const post = yield* ctx.posts.create({ authorId: user.id, title: "Hello" }) * return { user, post } * }) * ).pipe(Effect.runPromise) * ``` * * @param stateRefs - The database's collection Refs * @param transactionLock - Single-writer lock Ref * @param buildCollectionForTx - Callback to create collection accessors * @param persistenceTrigger - Optional trigger for scheduling saves on commit * @param changePubSub - Optional PubSub for reactive change notifications * @param fn - The callback to execute within the transaction * @returns Effect that yields the callback result, with TransactionError in error channel */ export declare const $transaction: >, A, E>(stateRefs: StateRefs, transactionLock: Ref.Ref, buildCollectionForTx: BuildCollectionForTx, persistenceTrigger: PersistenceTrigger | undefined, changePubSub: PubSub.PubSub | undefined, fn: (ctx: TransactionContext) => Effect.Effect) => Effect.Effect; export {}; //# sourceMappingURL=transaction.d.ts.map