@efesto-cloud/prisma-unit-of-work
v1.0.0
Published
Prisma-backed IUnitOfWork for efesto-cloud
Readme
@efesto-cloud/prisma-unit-of-work
Prisma implementation of IUnitOfWork. Wraps a Prisma-like client and exposes the current client (root or transactional tx) for repositories to use inside runWithTransaction.
The client is typed structurally via PrismaLikeClient — the package has no direct dependency on @prisma/client, so any object with a compatible $transaction method works (the real PrismaClient being the usual case).
Installation
pnpm add @efesto-cloud/prisma-unit-of-work @efesto-cloud/unit-of-work
# plus your Prisma client, typically:
pnpm add @prisma/clientQuick Start
import { PrismaClient } from "@prisma/client";
import PrismaUnitOfWork from "@efesto-cloud/prisma-unit-of-work/PrismaUnitOfWork";
const prisma = new PrismaClient();
const uow = new PrismaUnitOfWork(prisma);
await uow.runWithTransaction(async () => {
await uow.client.user.update({ where: { id }, data: { … } });
});API
interface PrismaLikeClient<TTx = object> {
$transaction<T>(fn: (tx: TTx) => Promise<T>): Promise<T>;
}
type PrismaTxOf<TClient> = Omit<TClient, "$connect" | "$disconnect" | "$on" | "$transaction" | "$use" | "$extends">;
interface IPrismaUnitOfWork<
TClient extends PrismaLikeClient<PrismaTxOf<TClient>> = PrismaLikeClient,
> extends IUnitOfWork {
readonly client: TClient | PrismaTxOf<TClient>; // transactional tx inside runWithTransaction, else root
}client— always use this from repositories. Outside a transaction it's the root client; insiderunWithTransactionit's the Prismatxpassed to$transaction's callback (typed asPrismaTxOf<TClient>, i.e. the client minus the management methods).runWithTransaction(fn)— inherited fromIUnitOfWork. Wrapsfninprisma.$transaction. If a transaction is already running (nested call), it reuses the outer one and just invokesfn.PrismaLikeClient/PrismaTxOfare re-exported so you can type custom clients (e.g. extended Prisma clients) precisely.
Notes
- Prisma manages the transaction lifecycle; no explicit session open/close is needed.
- Nesting is safe: inner
runWithTransactioncalls run within the outer transaction without opening a new one, so they commit/rollback atomically with the outermost call. - Repositories should always go through
uow.client— using the rootPrismaClientdirectly opts that operation out of the transaction.
