(db: FumaDb, options: MakeFumaClientOptions = {})
| 149 | }; |
| 150 | |
| 151 | export const makeFumaClient = (db: FumaDb, options: MakeFumaClientOptions = {}): IFumaClient => { |
| 152 | const use: IFumaClient["use"] = (label, fn) => |
| 153 | Effect.flatMap(Effect.service(activeFumaDbRef), (active) => |
| 154 | fumaEffect(label, () => fn(makeSafeFumaQuery(active ?? db, options))), |
| 155 | ).pipe(Effect.withSpan(`fumadb.${label}`)); |
| 156 | |
| 157 | const transaction = <A, E>(effect: Effect.Effect<A, E>): Effect.Effect<A, E | StorageFailure> => |
| 158 | Effect.flatMap(Effect.service(activeFumaDbRef), (active) => { |
| 159 | if (active) return effect as Effect.Effect<unknown, unknown>; |
| 160 | |
| 161 | return Effect.tryPromise({ |
| 162 | try: () => |
| 163 | db.transaction(async (transactionDb) => { |
| 164 | const exit = await Effect.runPromiseExit( |
| 165 | effect.pipe(Effect.provideService(activeFumaDbRef, transactionDb)), |
| 166 | ); |
| 167 | if (Exit.isSuccess(exit)) return exit.value; |
| 168 | |
| 169 | const failure = exit.cause.reasons.find(Cause.isFailReason); |
| 170 | // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: FumaDB transactions roll back when the callback rejects |
| 171 | if (failure) throw new TransactionEffectFailure(failure.error); |
| 172 | // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: FumaDB transactions roll back when the callback rejects |
| 173 | throw new TransactionEffectDefect(exit.cause); |
| 174 | }), |
| 175 | catch: (cause): E | StorageFailure => { |
| 176 | if (cause instanceof TransactionEffectFailure) return cause.error as E; |
| 177 | if (cause instanceof TransactionEffectDefect) { |
| 178 | return fumaFailureFromCause("transaction", cause.cause); |
| 179 | } |
| 180 | return fumaFailureFromCause("transaction", cause); |
| 181 | }, |
| 182 | }); |
| 183 | }).pipe(Effect.withSpan("fumadb.transaction")) as Effect.Effect<A, E | StorageFailure>; |
| 184 | |
| 185 | return { use, transaction }; |
| 186 | }; |
| 187 | |
| 188 | export class FumaClient extends Context.Service<FumaClient, IFumaClient>()("executor/FumaClient") { |
| 189 | static layer = (db: FumaDb) => Layer.succeed(this)(makeFumaClient(db)); |
no outgoing calls
no test coverage detected