3 Commits

Author SHA1 Message Date
Julien Valverdé
66b8fd2c2e Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-12 06:37:39 +01:00
Julien Valverdé
bc81c443ab Query work
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-11 21:19:57 +01:00
Julien Valverdé
ee5dbe3766 Query work
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-11 20:39:56 +01:00
3 changed files with 53 additions and 36 deletions

View File

@@ -0,0 +1,20 @@
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,
}))
))

View File

@@ -6,6 +6,13 @@ import * as QueryRunner from "./QueryRunner.js"
import type * as QueryService from "./QueryService.js"
export interface QueryExtension<HandlerE> {
useQuery<K extends readonly unknown[], A, E, R>(
this: ReffuseHelpers.ReffuseHelpers<R>,
props: UseQueryProps<K, A, E, R>,
): UseQueryResult<K, A, Exclude<E, HandlerE>>
}
export interface UseQueryProps<K extends readonly unknown[], A, E, R> {
readonly key: Stream.Stream<K>
readonly query: (key: K) => Effect.Effect<A, E, R>

View File

@@ -54,22 +54,23 @@ export const make = <K extends readonly unknown[], A, E, R>(
}))
)
const forkFetch = interrupt.pipe(
Effect.andThen(
Ref.set(stateRef, AsyncData.loading()).pipe(
Effect.andThen(latestKeyRef),
Effect.flatMap(identity),
Effect.flatMap(key => query(key).pipe(
Effect.matchCauseEffect({
onSuccess: v => Ref.set(stateRef, AsyncData.success(v)),
onFailure: c => Ref.set(stateRef, AsyncData.failure(c)),
})
)),
const run = latestKeyRef.pipe(
Effect.flatMap(identity),
Effect.flatMap(key => query(key).pipe(
Effect.matchCauseEffect({
onSuccess: v => Ref.set(stateRef, AsyncData.success(v)),
onFailure: c => Ref.set(stateRef, AsyncData.failure(c)),
})
)),
Effect.provide(context),
Effect.fork,
)
),
Effect.provide(context),
)
const forkFetch = interrupt.pipe(
Effect.andThen(Ref.set(stateRef, AsyncData.loading()).pipe(
Effect.andThen(run),
Effect.fork,
)),
Effect.flatMap(fiber =>
Ref.set(fiberRef, Option.some(fiber)).pipe(
@@ -82,27 +83,16 @@ export const make = <K extends readonly unknown[], A, E, R>(
)
const forkRefresh = interrupt.pipe(
Effect.andThen(
Ref.update(stateRef, previous => {
if (AsyncData.isSuccess(previous) || AsyncData.isFailure(previous))
return AsyncData.refreshing(previous)
if (AsyncData.isRefreshing(previous))
return AsyncData.refreshing(previous.previous)
return AsyncData.loading()
}).pipe(
Effect.andThen(latestKeyRef),
Effect.flatMap(identity),
Effect.flatMap(key => query(key).pipe(
Effect.matchCauseEffect({
onSuccess: v => Ref.set(stateRef, AsyncData.success(v)),
onFailure: c => Ref.set(stateRef, AsyncData.failure(c)),
})
)),
Effect.provide(context),
Effect.fork,
)
),
Effect.andThen(Ref.update(stateRef, previous => {
if (AsyncData.isSuccess(previous) || AsyncData.isFailure(previous))
return AsyncData.refreshing(previous)
if (AsyncData.isRefreshing(previous))
return AsyncData.refreshing(previous.previous)
return AsyncData.loading()
}).pipe(
Effect.andThen(run),
Effect.fork,
)),
Effect.flatMap(fiber =>
Ref.set(fiberRef, Option.some(fiber)).pipe(