This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
import { Cause, Context, Effect, identity, Layer, PubSub, Stream } from "effect"
|
import { Cause, Effect, identity, PubSub, Stream } from "effect"
|
||||||
import type { Mutable } from "effect/Types"
|
|
||||||
|
|
||||||
|
|
||||||
export interface QueryErrorHandler<FallbackA, HandledE> {
|
export interface QueryErrorHandler<FallbackA, HandledE> {
|
||||||
@@ -11,55 +10,34 @@ export type Fallback<T> = T extends QueryErrorHandler<infer A, any> ? A : never
|
|||||||
export type Error<T> = T extends QueryErrorHandler<any, infer E> ? E : never
|
export type Error<T> = T extends QueryErrorHandler<any, infer E> ? E : never
|
||||||
|
|
||||||
|
|
||||||
export interface ServiceResult<
|
export const make = <HandledE = never>() => (
|
||||||
Self,
|
<FallbackA>(
|
||||||
Id extends string,
|
|
||||||
FallbackA,
|
|
||||||
HandledE,
|
|
||||||
> extends Context.TagClass<
|
|
||||||
Self,
|
|
||||||
Id,
|
|
||||||
QueryErrorHandler<FallbackA, HandledE>
|
|
||||||
> {
|
|
||||||
readonly Default: Layer.Layer<Self>
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Service = <Self, HandledE = never>() => (
|
|
||||||
<const Id extends string, FallbackA>(
|
|
||||||
id: Id,
|
|
||||||
f: (
|
f: (
|
||||||
self: Effect.Effect<never, HandledE>,
|
self: Effect.Effect<never, HandledE>,
|
||||||
failure: (failure: HandledE) => Effect.Effect<never>,
|
failure: (failure: HandledE) => Effect.Effect<never>,
|
||||||
defect: (defect: unknown) => Effect.Effect<never>,
|
defect: (defect: unknown) => Effect.Effect<never>,
|
||||||
) => Effect.Effect<FallbackA>,
|
) => Effect.Effect<FallbackA>
|
||||||
): ServiceResult<Self, Id, FallbackA, HandledE> => {
|
): Effect.Effect<QueryErrorHandler<FallbackA, HandledE>> => Effect.gen(function*() {
|
||||||
const TagClass = Context.Tag(id)() as ServiceResult<Self, Id, FallbackA, HandledE>
|
const pubsub = yield* PubSub.unbounded<Cause.Cause<HandledE>>()
|
||||||
|
const errors = Stream.fromPubSub(pubsub)
|
||||||
|
|
||||||
(TagClass as Mutable<typeof TagClass>).Default = Layer.effect(TagClass, Effect.gen(function*() {
|
const handle = <A, E, R>(
|
||||||
const pubsub = yield* PubSub.unbounded<Cause.Cause<HandledE>>()
|
self: Effect.Effect<A, E, R>
|
||||||
const errors = Stream.fromPubSub(pubsub)
|
): Effect.Effect<A | FallbackA, Exclude<E, HandledE>, R> => f(
|
||||||
|
self as unknown as Effect.Effect<never, HandledE, never>,
|
||||||
|
(failure: HandledE) => PubSub.publish(pubsub, Cause.fail(failure)).pipe(
|
||||||
|
Effect.andThen(Effect.failCause(Cause.empty))
|
||||||
|
),
|
||||||
|
(defect: unknown) => PubSub.publish(pubsub, Cause.die(defect)).pipe(
|
||||||
|
Effect.andThen(Effect.failCause(Cause.empty))
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
const handle = <A, E, R>(
|
return { errors, handle }
|
||||||
self: Effect.Effect<A, E, R>
|
})
|
||||||
): Effect.Effect<A | FallbackA, Exclude<E, HandledE>, R> => f(
|
|
||||||
self as unknown as Effect.Effect<never, HandledE, never>,
|
|
||||||
(failure: HandledE) => PubSub.publish(pubsub, Cause.fail(failure)).pipe(
|
|
||||||
Effect.andThen(Effect.failCause(Cause.empty))
|
|
||||||
),
|
|
||||||
(defect: unknown) => PubSub.publish(pubsub, Cause.die(defect)).pipe(
|
|
||||||
Effect.andThen(Effect.failCause(Cause.empty))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
return { errors, handle }
|
|
||||||
}))
|
|
||||||
|
|
||||||
return TagClass
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
export class DefaultQueryErrorHandler extends Service<DefaultQueryErrorHandler>()(
|
export class DefaultQueryErrorHandler extends Effect.Service<DefaultQueryErrorHandler>()("@reffuse/extension-query/DefaultQueryErrorHandler", {
|
||||||
"@reffuse/extension-query/DefaultQueryErrorHandler",
|
effect: make<never>()(identity)
|
||||||
identity,
|
}) {}
|
||||||
) {}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user