UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

101 lines 3.45 kB
import { parseEventPayload, } from "../events/index.js"; /** * Create a simple Unit of Work implementation for tests, in-memory adapters, * and infrastructure that already handles transactions elsewhere. * * This helper does not create database transactions. It gives applications the * same UOW shape everywhere and runs commit/rollback hooks around the callback. * * @param txPortsOrFactory - Transaction-scoped ports or a factory that creates * them per transaction call. * @param options - Optional commit and rollback hooks. * @returns A Unit of Work port with no durable transaction semantics. */ export function createNoopUnitOfWork(txPortsOrFactory, options = {}) { const createTxPorts = typeof txPortsOrFactory === "function" ? txPortsOrFactory : () => txPortsOrFactory; return { async transaction(work) { const tx = createTxPorts(); let result; try { result = await work(tx); } catch (error) { try { await options.afterRollback?.(error, tx); } catch { // Preserve the application error that caused the rollback path. } throw error; } await options.afterCommit?.(tx); return result; }, }; } /** * Decorate a Unit of Work with an isolated post-commit observer. * * The observer runs only after the wrapped transaction resolves. Its failure * cannot turn a committed operation into an apparent transaction failure. * Use the observer to schedule best-effort follow-up work; durable side * effects still belong inside the transaction through an outbox. */ export function createObservedUnitOfWork(options) { return { async transaction(work) { const result = await options.unitOfWork.transaction(work); try { await options.afterCommit(); } catch (error) { try { await options.onObserverError?.(error); } catch { // Preserve the successful transaction result when reporting fails. } } return result; }, }; } /** * Create a recorder that buffers domain events until the caller flushes them. * * Unit of Work adapters commonly flush this recorder from an `afterCommit` * hook so events are not published when the work rolls back. * * @returns A buffered domain event recorder for tests or Unit of Work adapters. */ export function createDomainEventRecorder() { const records = []; return { record(event, payload, options) { records.push({ event, eventName: event.name, payload, ...(options ? { options } : {}), }); }, entries() { return records; }, clear() { records.length = 0; }, async flush(eventBus) { while (records.length > 0) { const record = records[0]; await parseEventPayload(record.event, record.payload); await eventBus.publish(record.event, record.payload, record.options); records.shift(); } }, }; } //# sourceMappingURL=unit-of-work.js.map