@beignet/core
Version:
Core framework primitives for Beignet
101 lines • 3.45 kB
JavaScript
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