diff --git a/packages/effect-fc/src/Query.ts b/packages/effect-fc/src/Query.ts index 9d81175..edc5062 100644 --- a/packages/effect-fc/src/Query.ts +++ b/packages/effect-fc/src/Query.ts @@ -1,4 +1,4 @@ -import { type Cause, type Context, type Duration, Effect, Fiber, identity, Option, Pipeable, Predicate, type Scope, Stream, type Subscribable, SubscriptionRef } from "effect" +import { type Cause, type Context, DateTime, type Duration, Effect, Fiber, HashMap, identity, Option, Pipeable, Predicate, type Scope, Stream, type Subscribable, SubscriptionRef } from "effect" import * as QueryClient from "./QueryClient.js" import * as Result from "./Result.js" @@ -143,6 +143,31 @@ extends Pipeable.Class() implements Query { ), ) as Effect.Effect> } + + getCacheEntry( + key: K + ): Effect.Effect, never, QueryClient.QueryClient> { + return QueryClient.QueryClient.pipe( + Effect.andThen(client => client.cache), + Effect.map(HashMap.get(new QueryClient.QueryClientCacheKey(key, this.f as (key: Query.AnyKey) => Effect.Effect))), + ) + } + + updateCacheEntry( + key: K, + result: Result.Success, + ): Effect.Effect { + return Effect.Do.pipe( + Effect.bind("client", () => QueryClient.QueryClient), + Effect.bind("now", () => DateTime.now), + Effect.let("entry", ({ now }) => new QueryClient.QueryClientCacheEntry(result, now)), + Effect.tap(({ client, entry }) => SubscriptionRef.update( + client.cache, + HashMap.set(new QueryClient.QueryClientCacheKey(key, this.f as (key: Query.AnyKey) => Effect.Effect), entry), + )), + Effect.map(({ entry }) => entry), + ) + } } export const isQuery = (u: unknown): u is Query => Predicate.hasProperty(u, QueryTypeId) diff --git a/packages/effect-fc/src/QueryClient.ts b/packages/effect-fc/src/QueryClient.ts index 5862865..31a4910 100644 --- a/packages/effect-fc/src/QueryClient.ts +++ b/packages/effect-fc/src/QueryClient.ts @@ -97,7 +97,7 @@ implements Pipeable.Pipeable { readonly [QueryClientCacheEntryTypeId]: QueryClientCacheEntryTypeId = QueryClientCacheEntryTypeId constructor( - readonly result: Result.Final, + readonly result: Result.Success, readonly createdAt: DateTime.DateTime, ) { super() diff --git a/packages/effect-fc/src/Result.ts b/packages/effect-fc/src/Result.ts index d0ea148..f676f93 100644 --- a/packages/effect-fc/src/Result.ts +++ b/packages/effect-fc/src/Result.ts @@ -4,19 +4,20 @@ import { Cause, Context, Data, Effect, Equal, Exit, type Fiber, Hash, Layer, Mat export const ResultTypeId: unique symbol = Symbol.for("@effect-fc/Result/Result") export type ResultTypeId = typeof ResultTypeId -export type Result = ResultState & (ResultState | Optimistic) -type ResultState = ( +export type Result = ( | Initial | Running

| Final -) +// biome-ignore lint/complexity/noBannedTypes: relevant here +) & ({} | Optimistic) export type Final = ( - & FinalState - & (FinalState | Refreshing

) - & (FinalState | Optimistic) + & (Success | Failure) + // biome-ignore lint/complexity/noBannedTypes: relevant here + & ({} | Refreshing

) + // biome-ignore lint/complexity/noBannedTypes: relevant here + & ({} | Optimistic) ) -type FinalState = Success | Failure export namespace Result { export interface Prototype extends Pipeable.Pipeable, Equal.Equal {