0.1.8 #11
26
packages/extension-query/src/ErrorHandler.ts
Normal file
26
packages/extension-query/src/ErrorHandler.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { type Cause, type Context, Effect, Layer, Queue, Stream } from "effect"
|
||||||
|
|
||||||
|
|
||||||
|
export interface ErrorHandler<E> {
|
||||||
|
readonly errors: Stream.Stream<Cause.Cause<E>>
|
||||||
|
handle<A, SelfE, R>(self: Effect.Effect<A, SelfE | E, R>): Effect.Effect<A, SelfE, R>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Tag = <const Id extends string>(id: Id) => <
|
||||||
|
Self, E = never,
|
||||||
|
>() => Effect.Tag(id)<Self, ErrorHandler<E>>()
|
||||||
|
|
||||||
|
export const layer = <Self, Id extends string, E>(
|
||||||
|
tag: Context.TagClass<Self, Id, ErrorHandler<E>>
|
||||||
|
): Layer.Layer<Self> => Layer.effect(tag, Effect.gen(function*() {
|
||||||
|
const queue = yield* Queue.unbounded<Cause.Cause<E>>()
|
||||||
|
const errors = Stream.fromQueue(queue)
|
||||||
|
|
||||||
|
const handle = <A, SelfE, R>(
|
||||||
|
self: Effect.Effect<A, SelfE | E, R>
|
||||||
|
) => Effect.tapErrorCause(self, cause =>
|
||||||
|
Queue.offer(queue, cause as Cause.Cause<E>)
|
||||||
|
) as Effect.Effect<A, SelfE, R>
|
||||||
|
|
||||||
|
return { errors, handle }
|
||||||
|
}))
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import { type Context, Effect, Layer, Queue, Stream } from "effect"
|
|
||||||
|
|
||||||
|
|
||||||
export interface FailureHandler<E> {
|
|
||||||
readonly failures: Stream.Stream<E>
|
|
||||||
readonly queue: Queue.Queue<E>
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Tag = <const Id extends string>(id: Id) => <
|
|
||||||
Self, E = never,
|
|
||||||
>() => Effect.Tag(id)<Self, FailureHandler<E>>()
|
|
||||||
|
|
||||||
export const layer = <Self, Id extends string, E>(
|
|
||||||
tag: Context.TagClass<Self, Id, FailureHandler<E>>
|
|
||||||
): Layer.Layer<Self> => Layer.effect(tag, Queue.unbounded<E>().pipe(
|
|
||||||
Effect.map(queue => ({
|
|
||||||
failures: Stream.fromQueue(queue),
|
|
||||||
queue,
|
|
||||||
}))
|
|
||||||
))
|
|
||||||
@@ -1,20 +1,19 @@
|
|||||||
import { Context, Effect, Layer } from "effect"
|
import { Context, Effect, Layer } from "effect"
|
||||||
|
import * as ErrorHandler from "./ErrorHandler.js"
|
||||||
|
|
||||||
|
|
||||||
interface MyService<T> {
|
export interface QueryClient<EH, HandledE> {
|
||||||
readonly value: T
|
readonly ErrorHandler: Context.Tag<EH, ErrorHandler.ErrorHandler<HandledE>>
|
||||||
}
|
}
|
||||||
|
|
||||||
const MyServiceAnyTag = Context.GenericTag<MyService<any>>("MyService")
|
|
||||||
const MyServiceStringTag = Context.GenericTag<MyService<string>>("MyService")
|
|
||||||
|
|
||||||
declare const MyServiceAnyLayer: Layer.Layer<Context.Tag.Service<typeof MyServiceAnyTag>>
|
export interface LayerProps<EH, HandledE> {
|
||||||
declare const MyServiceStringLayer: Layer.Layer<Context.Tag.Service<typeof MyServiceStringTag>>
|
readonly ErrorHandler?: Context.Tag<EH, ErrorHandler.ErrorHandler<HandledE>>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const layer = <EH = never, HandledE = never>(
|
||||||
const prg = Effect.gen(function*() {
|
props: LayerProps<EH, HandledE>
|
||||||
yield* MyServiceAnyTag
|
): Layer.Layer<QueryClient<EH, HandledE>> =>
|
||||||
yield* MyServiceStringTag
|
Layer.effect(Context.GenericTag<QueryClient<EH, HandledE>>("@reffuse/extension-query/QueryClient"), Effect.succeed({
|
||||||
}).pipe(
|
ErrorHandler: props.ErrorHandler
|
||||||
Effect.provide(MyServiceStringLayer)
|
}))
|
||||||
)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user