QueryClient work
All checks were successful
Lint / lint (push) Successful in 42s

This commit is contained in:
Julien Valverdé
2025-12-16 09:19:52 +01:00
parent edf06b5f99
commit f09c6e3a1c
3 changed files with 19 additions and 9 deletions

View File

@@ -1,4 +1,5 @@
import { type Cause, type Context, Effect, Fiber, identity, Option, Pipeable, Predicate, type Scope, Stream, type Subscribable, SubscriptionRef } from "effect" import { type Cause, type Context, Effect, Fiber, identity, Option, Pipeable, Predicate, type Scope, Stream, type Subscribable, SubscriptionRef } from "effect"
import type * as QueryClient from "./QueryClient.js"
import * as Result from "./Result.js" import * as Result from "./Result.js"
@@ -9,7 +10,7 @@ export interface Query<in out K extends Query.AnyKey, in out A, in out E = never
extends Pipeable.Pipeable { extends Pipeable.Pipeable {
readonly [QueryTypeId]: QueryTypeId readonly [QueryTypeId]: QueryTypeId
readonly context: Context.Context<Scope.Scope | R> readonly context: Context.Context<Scope.Scope | QueryClient.QueryClient | R>
readonly key: Stream.Stream<K> readonly key: Stream.Stream<K>
readonly f: (key: K) => Effect.Effect<A, E, R> readonly f: (key: K) => Effect.Effect<A, E, R>
readonly initialProgress: P readonly initialProgress: P
@@ -35,7 +36,7 @@ extends Pipeable.Class() implements Query<K, A, E, R, P> {
readonly [QueryTypeId]: QueryTypeId = QueryTypeId readonly [QueryTypeId]: QueryTypeId = QueryTypeId
constructor( constructor(
readonly context: Context.Context<Scope.Scope | NoInfer<R>>, readonly context: Context.Context<Scope.Scope | QueryClient.QueryClient | R>,
readonly key: Stream.Stream<K>, readonly key: Stream.Stream<K>,
readonly f: (key: K) => Effect.Effect<A, E, R>, readonly f: (key: K) => Effect.Effect<A, E, R>,
readonly initialProgress: P, readonly initialProgress: P,
@@ -155,10 +156,10 @@ export const make = Effect.fnUntraced(function* <K extends Query.AnyKey, A, E =
): Effect.fn.Return< ): Effect.fn.Return<
Query<K, A, E, Result.forkEffect.OutputContext<A, E, R, P>, P>, Query<K, A, E, Result.forkEffect.OutputContext<A, E, R, P>, P>,
never, never,
Scope.Scope | Result.forkEffect.OutputContext<A, E, R, P> Scope.Scope | QueryClient.QueryClient | Result.forkEffect.OutputContext<A, E, R, P>
> { > {
return new QueryImpl( return new QueryImpl(
yield* Effect.context<Scope.Scope | Result.forkEffect.OutputContext<A, E, R, P>>(), yield* Effect.context<Scope.Scope | QueryClient.QueryClient | Result.forkEffect.OutputContext<A, E, R, P>>(),
options.key, options.key,
options.f as any, options.f as any,
options.initialProgress as P, options.initialProgress as P,
@@ -176,7 +177,7 @@ export const service = <K extends Query.AnyKey, A, E = never, R = never, P = nev
): Effect.Effect< ): Effect.Effect<
Query<K, A, E, Result.forkEffect.OutputContext<A, E, R, P>, P>, Query<K, A, E, Result.forkEffect.OutputContext<A, E, R, P>, P>,
never, never,
Scope.Scope | Result.forkEffect.OutputContext<A, E, R, P> Scope.Scope | QueryClient.QueryClient | Result.forkEffect.OutputContext<A, E, R, P>
> => Effect.tap( > => Effect.tap(
make(options), make(options),
query => Effect.forkScoped(run(query)), query => Effect.forkScoped(run(query)),

View File

@@ -63,15 +63,18 @@ export class QueryClientCacheKey
extends Pipeable.Class() extends Pipeable.Class()
implements Pipeable.Pipeable, Equal.Equal { implements Pipeable.Pipeable, Equal.Equal {
readonly [QueryClientCacheKeyTypeId]: QueryClientCacheKeyTypeId = QueryClientCacheKeyTypeId readonly [QueryClientCacheKeyTypeId]: QueryClientCacheKeyTypeId = QueryClientCacheKeyTypeId
constructor(readonly key: Query.Query.AnyKey) { constructor(
readonly key: Query.Query.AnyKey,
readonly f: (key: Query.Query.AnyKey) => Effect.Effect<unknown, unknown, unknown>,
) {
super() super()
} }
[Equal.symbol](that: Equal.Equal) { [Equal.symbol](that: Equal.Equal) {
return isQueryClientCacheKey(that) && Equivalence.array(Equal.equivalence())(this.key, that.key) return isQueryClientCacheKey(that) && Equivalence.array(Equal.equivalence())(this.key, that.key) && Equivalence.strict()(this.f, that.f)
} }
[Hash.symbol]() { [Hash.symbol]() {
return Hash.array(this.key) return Hash.combine(Hash.hash(this.f))(Hash.array(this.key))
} }
} }

View File

@@ -3,6 +3,7 @@ import { Effect, Layer, ManagedRuntime, Predicate, Runtime, Scope } from "effect
import * as React from "react" import * as React from "react"
import * as Component from "./Component.js" import * as Component from "./Component.js"
import * as ErrorObserver from "./ErrorObserver.js" import * as ErrorObserver from "./ErrorObserver.js"
import * as QueryClient from "./QueryClient.js"
export const TypeId: unique symbol = Symbol.for("@effect-fc/ReactRuntime/ReactRuntime") export const TypeId: unique symbol = Symbol.for("@effect-fc/ReactRuntime/ReactRuntime")
@@ -17,9 +18,14 @@ export interface ReactRuntime<R, ER> {
const ReactRuntimeProto = Object.freeze({ [TypeId]: TypeId } as const) const ReactRuntimeProto = Object.freeze({ [TypeId]: TypeId } as const)
export const Prelude: Layer.Layer<Component.ScopeMap | ErrorObserver.ErrorObserver> = Layer.mergeAll( export const Prelude: Layer.Layer<
| Component.ScopeMap
| ErrorObserver.ErrorObserver
| QueryClient.QueryClient
> = Layer.mergeAll(
Component.ScopeMap.Default, Component.ScopeMap.Default,
ErrorObserver.layer, ErrorObserver.layer,
QueryClient.QueryClient.Default,
) )