Adapting Prisma's Transaction API to Effect TypeScript

Hi! I'm using Prisma ORM in my project, and trying to adapt its callback/promise-y transaction API:
const result = await prisma.transaction(async (tx) => {
  // do something with the transaction
  const result = await tx.someTable.select(/* blah */);
  // do anything else
  return result;
});


I've currently come up with this, but I'm wondering if there's a better way to do it

Working solution in the playground, with some more comments and context: https://effect.website/play#ff4d35749a68

The main parts here:
// Some example callback-y API. Could use promises, but doesn't in this example for mild simplicity
const sampleCallbackApi = <A>(input: number, callback: (evenNumber: number) => A): A => {
  if (input % 2 !== 0) {
    throw new Error(`${input} is not even`)
  }

  return callback(input)
}

const effectApi02 = <A, E>(
  input: number,
  handleEvenNumber: (evenNumber: number) => Effect.Effect<A, E, never>
): Effect.Effect<A, E | Error, never> =>
  Effect.gen(function*() {
    const exit = yield* Effect.promise(() =>
      sampleCallbackApi(input, async (evenNumber) => Effect.runPromiseExit(handleEvenNumber(evenNumber)))
    )

    return yield* exitToEffect(exit)
  })

function exitToEffect<A, E>(
  exit: Exit.Exit<A, E>
): Effect.Effect<A, E, never> {
  return Effect.gen(function*() {
    return yield* exit.pipe(
      Exit.match({
        onSuccess: (value) => Effect.succeed(value),
        onFailure: (cause) => {
          // Surface our "expected" errors
          if (Cause.isFailType(cause)) {
            return Effect.fail(cause.error)
          }
          return Effect.die(cause)
        }
      })
    )
  })
}
Was this page helpful?