import { err, ok, Result, ResultAsync } from "@/result/index.js";
import { PgTransactionConfig } from "drizzle-orm/pg-core";
import { createContext } from "../context/index.js";
import { DrizzlePgClient, DrizzlePgExecutor } from "./types.js";
function createPgTransactionContext<S extends Record<string, unknown>>(
db: DrizzlePgClient<S>,
schema: S,
) {
const TransactionContext = createContext<{
exec: DrizzlePgExecutor<typeof schema>;
}>();
function getDb(): DrizzlePgExecutor<typeof schema> {
return TransactionContext.use()?.exec ?? db;
}
async function createTransaction<T, E>(
cb: () => ResultAsync<T, E>,
isolationLevel: PgTransactionConfig["isolationLevel"] = "read committed",
): Promise<Result<T, E>> {
try {
const exec_ = TransactionContext.use()?.exec ?? db;
const res = await exec_.transaction(
async (exec) => {
const res = await TransactionContext.with({ exec }, cb);
if (!res.isOk()) {
throw res.error;
}
return res.value;
},
{
isolationLevel,
},
);
return ok(res);
} catch (e) {
return err(e as E);
}
}
return {
TransactionContext,
getDb,
createTransaction,
};
}
import { err, ok, Result, ResultAsync } from "@/result/index.js";
import { PgTransactionConfig } from "drizzle-orm/pg-core";
import { createContext } from "../context/index.js";
import { DrizzlePgClient, DrizzlePgExecutor } from "./types.js";
function createPgTransactionContext<S extends Record<string, unknown>>(
db: DrizzlePgClient<S>,
schema: S,
) {
const TransactionContext = createContext<{
exec: DrizzlePgExecutor<typeof schema>;
}>();
function getDb(): DrizzlePgExecutor<typeof schema> {
return TransactionContext.use()?.exec ?? db;
}
async function createTransaction<T, E>(
cb: () => ResultAsync<T, E>,
isolationLevel: PgTransactionConfig["isolationLevel"] = "read committed",
): Promise<Result<T, E>> {
try {
const exec_ = TransactionContext.use()?.exec ?? db;
const res = await exec_.transaction(
async (exec) => {
const res = await TransactionContext.with({ exec }, cb);
if (!res.isOk()) {
throw res.error;
}
return res.value;
},
{
isolationLevel,
},
);
return ok(res);
} catch (e) {
return err(e as E);
}
}
return {
TransactionContext,
getDb,
createTransaction,
};
}