Files
veridian/server/lib/auth-transaction.ts
T
2026-10-15 10:22:06 -05:00

31 lines
1.3 KiB
TypeScript

import { AsyncLocalStorage } from "node:async_hooks";
import { db } from "./db";
export type Transaction = Parameters<Parameters<typeof db.transaction>[0]>[0];
const storage = new AsyncLocalStorage<Transaction>();
/** The transaction opened by authTransaction() around the running code, if any. */
export const currentTransaction = (): Transaction | undefined => storage.getStore();
// What the one auth instance is given as its database. Every access goes to
// the transaction opened by authTransaction() around the running code, or to
// the pool when there is none, so no second auth instance is needed to make
// Better Auth write on a transaction's connection.
export const authDatabase = new Proxy(db, {
get(_target, property) {
const target = storage.getStore() ?? db;
const value = Reflect.get(target, property, target);
return typeof value === "function" ? value.bind(target) : value;
},
});
/**
* Runs the callback in a transaction that everything the auth instance does
* inside it joins: its endpoints, its hooks and its internal adapter all
* commit or roll back together with the callback's own writes.
*/
export const authTransaction = <T>(callback: (tx: Transaction) => Promise<T>): Promise<T> =>
db.transaction(tx => storage.run(tx, () => callback(tx)));