{"version":3,"file":"transaction-context.mjs","sources":["../src/transaction-context.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\nimport { Knex } from 'knex';\n\n/**\n * After the user calls the Knex transactor’s `commit` or `rollback` (e.g. via\n * the callback object returned from `Database#transaction`, or after the\n * container’s promise has settled in Knex), a second finalisation is invalid\n * and can throw (e.g. \"Transaction query already complete\"). Knex exposes\n * `isCompleted()` for this; optional for mocks that omit it.\n */\nconst isTransactorComplete = (trx: Knex.Transaction) => {\n  const t = trx as Knex.Transaction & { isCompleted?: () => boolean };\n  return typeof t.isCompleted === 'function' && t.isCompleted();\n};\n\nexport type Callback = (...args: any[]) => Promise<any> | any;\n\nexport interface TransactionObject {\n  commit: () => Promise<void>;\n  rollback: () => Promise<void>;\n  get: () => Knex.Transaction;\n}\nexport interface Store {\n  trx: Knex.Transaction | null;\n  commitCallbacks: Callback[];\n  rollbackCallbacks: Callback[];\n}\n\nconst storage = new AsyncLocalStorage<Store>();\n\nconst transactionCtx = {\n  async run<TCallback extends Callback>(trx: Knex.Transaction, cb: TCallback) {\n    const store = storage.getStore();\n    return storage.run<ReturnType<TCallback>, void[]>(\n      {\n        trx,\n        // Fill with existing callbacks if nesting transactions\n        commitCallbacks: store?.commitCallbacks || [],\n        rollbackCallbacks: store?.rollbackCallbacks || [],\n      },\n      cb\n    );\n  },\n\n  get() {\n    const store = storage.getStore();\n    return store?.trx;\n  },\n\n  async commit(trx: Knex.Transaction) {\n    const store = storage.getStore();\n    if (isTransactorComplete(trx)) {\n      if (store?.trx) {\n        store.trx = null;\n      }\n      return;\n    }\n\n    // Clear transaction from store\n    if (store?.trx) {\n      store.trx = null;\n    }\n\n    // Commit transaction\n    await trx.commit();\n\n    if (!store?.commitCallbacks.length) {\n      return;\n    }\n\n    // Run callbacks\n    store.commitCallbacks.forEach((cb) => cb());\n    store.commitCallbacks = [];\n  },\n\n  async rollback(trx: Knex.Transaction) {\n    const store = storage.getStore();\n    if (isTransactorComplete(trx)) {\n      if (store?.trx) {\n        store.trx = null;\n      }\n      return;\n    }\n\n    // Clear transaction from store\n    if (store?.trx) {\n      store.trx = null;\n    }\n\n    // Rollback transaction\n    await trx.rollback();\n\n    if (!store?.rollbackCallbacks.length) {\n      return;\n    }\n\n    // Run callbacks\n    store.rollbackCallbacks.forEach((cb) => cb());\n    store.rollbackCallbacks = [];\n  },\n\n  onCommit(cb: Callback) {\n    const store = storage.getStore();\n    if (store?.commitCallbacks) {\n      store.commitCallbacks.push(cb);\n    }\n  },\n\n  onRollback(cb: Callback) {\n    const store = storage.getStore();\n    if (store?.rollbackCallbacks) {\n      store.rollbackCallbacks.push(cb);\n    }\n  },\n};\n\nexport { transactionCtx };\n"],"names":["isTransactorComplete","trx","t","isCompleted","storage","AsyncLocalStorage","transactionCtx","run","cb","store","getStore","commitCallbacks","rollbackCallbacks","get","commit","length","forEach","rollback","onCommit","push","onRollback"],"mappings":"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"}