export type transactionTag = Prisma.TransactionClient;
export const transactionTag =
Context.GenericTag<transactionTag>("PrismaTransaction");
export const layer = Layer.succeed(tag, prisma);
export const transactionLayer = Layer.scoped(
transactionTag,
Effect.gen(function* ($) {
const scope = yield* $(Effect.scope);
const prisma = yield* $(tag);
const txClientDeferred = yield* $(
Deferred.make<Prisma.TransactionClient>(),
);
const txCommitDeferred = yield* $(
Deferred.make<null | PrismaError | Cause.Cause<unknown>>(),
);
yield* $(
Scope.addFinalizerExit(
scope,
Exit.match({
onFailure: (err) => {
if (err._tag === "Fail") {
return Deferred.succeed(
txCommitDeferred,
PrismaError.fromUnknown(err.error),
);
} else {
return Deferred.succeed(txCommitDeferred, err);
}
},
onSuccess: () => {
return Deferred.succeed(txCommitDeferred, null);
},
}),
),
);
yield* $(
Effect.fork(
Effect.tryPromise({
try: () =>
prisma.$transaction((txClient) =>
Effect.gen(function* ($) {
yield* $(Deferred.succeed(txClientDeferred, txClient));
const res = yield* $(Deferred.await(txCommitDeferred));
if (res instanceof PrismaError) {
return yield* $(res);
}
}).pipe(Effect.runPromise),
),
catch: (_) => PrismaError.fromUnknown(_),
}),
),
);
return yield* $(Deferred.await(txClientDeferred));
}),
);
export type transactionTag = Prisma.TransactionClient;
export const transactionTag =
Context.GenericTag<transactionTag>("PrismaTransaction");
export const layer = Layer.succeed(tag, prisma);
export const transactionLayer = Layer.scoped(
transactionTag,
Effect.gen(function* ($) {
const scope = yield* $(Effect.scope);
const prisma = yield* $(tag);
const txClientDeferred = yield* $(
Deferred.make<Prisma.TransactionClient>(),
);
const txCommitDeferred = yield* $(
Deferred.make<null | PrismaError | Cause.Cause<unknown>>(),
);
yield* $(
Scope.addFinalizerExit(
scope,
Exit.match({
onFailure: (err) => {
if (err._tag === "Fail") {
return Deferred.succeed(
txCommitDeferred,
PrismaError.fromUnknown(err.error),
);
} else {
return Deferred.succeed(txCommitDeferred, err);
}
},
onSuccess: () => {
return Deferred.succeed(txCommitDeferred, null);
},
}),
),
);
yield* $(
Effect.fork(
Effect.tryPromise({
try: () =>
prisma.$transaction((txClient) =>
Effect.gen(function* ($) {
yield* $(Deferred.succeed(txClientDeferred, txClient));
const res = yield* $(Deferred.await(txCommitDeferred));
if (res instanceof PrismaError) {
return yield* $(res);
}
}).pipe(Effect.runPromise),
),
catch: (_) => PrismaError.fromUnknown(_),
}),
),
);
return yield* $(Deferred.await(txClientDeferred));
}),
);