import { EmitArg, EventBus, EventBusEmit } from '@/modules/shared/services/eventBus' import { Knex } from 'knex' export const commandFactory = ) => ReturnType>({ db, eventBus, operationFactory }: { db: Knex eventBus?: EventBus operationFactory: (arg: { db: Knex; trx: Knex; emit: EventBusEmit }) => TOperation }) => async (...args: Parameters): Promise>> => { const events: EmitArg[] = [] const emit: EventBusEmit = async ({ eventName, payload }) => { events.push({ eventName, payload }) } const trx = await db.transaction() try { const result = await operationFactory({ db, trx, emit })(...args) await trx.commit() if (eventBus) { for (const event of events) { await eventBus.emit(event) } } return result as Awaited> } catch (err) { trx.rollback() throw err } }