import { type Cause, Context, Effect, Layer, Queue, Stream } from "effect" import type { Mutable } from "effect/Types" export interface ErrorHandler { readonly errors: Stream.Stream> readonly handle: (self: Effect.Effect) => Effect.Effect, R> } export type Error = T extends ErrorHandler ? E : never export interface ServiceResult extends Context.TagClass> { readonly Live: Layer.Layer } export const Service = (id: Id) => ( (): ServiceResult => { const TagClass = Context.Tag(id)() as ServiceResult (TagClass as Mutable).Live = Layer.effect(TagClass, Effect.gen(function*() { const queue = yield* Queue.unbounded>() const errors = Stream.fromQueue(queue) const handle = ( self: Effect.Effect ) => Effect.tapErrorCause(self, cause => Queue.offer(queue, cause as Cause.Cause) ) as Effect.Effect, R> return { errors, handle } })) return TagClass } ) export class DefaultErrorHandler extends Service("@reffuse/extension-query/DefaultErrorHandler")() {}