diff --git a/packages/effect-fc/src/Query.ts b/packages/effect-fc/src/Query.ts index 5d29457..361c1de 100644 --- a/packages/effect-fc/src/Query.ts +++ b/packages/effect-fc/src/Query.ts @@ -1,4 +1,4 @@ -import { type Cause, type Context, DateTime, type Duration, Effect, Exit, Fiber, HashMap, identity, Option, Pipeable, Predicate, type Scope, Stream, Subscribable, SubscriptionRef } from "effect" +import { type Cause, type Context, DateTime, type Duration, Effect, Equivalence, Exit, Fiber, HashMap, identity, Option, Pipeable, Predicate, type Scope, Stream, Subscribable, SubscriptionRef } from "effect" import * as QueryClient from "./QueryClient.js" import * as Result from "./Result.js" @@ -25,10 +25,11 @@ extends Pipeable.Pipeable { readonly run: Effect.Effect fetch(key: K): Effect.Effect> fetchSubscribable(key: K): Effect.Effect>, never, Scope.Scope> - readonly refetch: Effect.Effect, Cause.NoSuchElementException> - readonly refetchSubscribable: Effect.Effect>, Cause.NoSuchElementException, Scope.Scope> readonly refresh: Effect.Effect, Cause.NoSuchElementException> readonly refreshSubscribable: Effect.Effect>, Cause.NoSuchElementException, Scope.Scope> + + readonly invalidateCache: Effect.Effect + invalidateCacheEntry(key: K): Effect.Effect } export declare namespace Query { @@ -114,42 +115,6 @@ extends Pipeable.Class() implements Query { ) } - get refetch(): Effect.Effect, Cause.NoSuchElementException> { - return this.interrupt.pipe( - Effect.andThen(Effect.Do), - Effect.bind("latestKey", () => Effect.andThen(this.latestKey, identity)), - Effect.bind("latestFinalResult", () => this.latestFinalResult), - Effect.andThen(({ latestKey, latestFinalResult }) => Effect.provide( - this.startCached(latestKey, Option.isSome(latestFinalResult) - ? Result.willFetch(latestFinalResult.value) as Result.Final - : Result.initial() - ), - this.context, - )), - Effect.andThen(sub => this.watch(sub)), - ) - } - - get refetchSubscribable(): Effect.Effect< - Subscribable.Subscribable>, - Cause.NoSuchElementException, - Scope.Scope - > { - return this.interrupt.pipe( - Effect.andThen(Effect.Do), - Effect.bind("latestKey", () => Effect.andThen(this.latestKey, identity)), - Effect.bind("latestFinalResult", () => this.latestFinalResult), - Effect.andThen(({ latestKey, latestFinalResult }) => Effect.provide( - this.startCached(latestKey, Option.isSome(latestFinalResult) - ? Result.willFetch(latestFinalResult.value) as Result.Final - : Result.initial() - ), - this.context, - )), - Effect.tap(sub => Effect.forkScoped(this.watch(sub))), - ) - } - get refresh(): Effect.Effect, Cause.NoSuchElementException> { return this.interrupt.pipe( Effect.andThen(Effect.Do), @@ -218,10 +183,10 @@ extends Pipeable.Class() implements Query { > { return Result.unsafeForkEffect( Effect.onExit(this.f(key), exit => Effect.andThen( + SubscriptionRef.set(this.fiber, Option.none()), Exit.isSuccess(exit) ? this.updateCacheEntry(key, Result.fromExit(exit)) : Effect.void, - SubscriptionRef.set(this.fiber, Option.none()), )), { initial, @@ -275,13 +240,23 @@ extends Pipeable.Class() implements Query { ) } - removeCacheEntry(key: K): Effect.Effect { - return Effect.andThen( - QueryClient.QueryClient, - client => SubscriptionRef.update( + get invalidateCache(): Effect.Effect { + return QueryClient.QueryClient.pipe( + Effect.andThen(client => SubscriptionRef.update( + client.cache, + HashMap.filter((_, key) => !Equivalence.strict()(key.f, this.f)), + )), + Effect.provide(this.context), + ) + } + + invalidateCacheEntry(key: K): Effect.Effect { + return QueryClient.QueryClient.pipe( + Effect.andThen(client => SubscriptionRef.update( client.cache, HashMap.remove(this.makeCacheKey(key)), - ), + )), + Effect.provide(this.context), ) } } diff --git a/packages/example/src/routes/query.tsx b/packages/example/src/routes/query.tsx index b579bd2..d7ad441 100644 --- a/packages/example/src/routes/query.tsx +++ b/packages/example/src/routes/query.tsx @@ -28,7 +28,7 @@ const ResultView = Component.makeUntraced("Result")(function*() { Effect.andThen(response => response.json), Effect.andThen(Schema.decodeUnknown(Post)), ), - staleTime: "10 seconds", + staleTime: "1 minutes", }) const mutation = yield* Mutation.make({ @@ -87,6 +87,7 @@ const ResultView = Component.makeUntraced("Result")(function*() { +