This commit is contained in:
@@ -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<void>
|
||||
fetch(key: K): Effect.Effect<Result.Final<A, E, P>>
|
||||
fetchSubscribable(key: K): Effect.Effect<Subscribable.Subscribable<Result.Result<A, E, P>>, never, Scope.Scope>
|
||||
readonly refetch: Effect.Effect<Result.Final<A, E, P>, Cause.NoSuchElementException>
|
||||
readonly refetchSubscribable: Effect.Effect<Subscribable.Subscribable<Result.Result<A, E, P>>, Cause.NoSuchElementException, Scope.Scope>
|
||||
readonly refresh: Effect.Effect<Result.Final<A, E, P>, Cause.NoSuchElementException>
|
||||
readonly refreshSubscribable: Effect.Effect<Subscribable.Subscribable<Result.Result<A, E, P>>, Cause.NoSuchElementException, Scope.Scope>
|
||||
|
||||
readonly invalidateCache: Effect.Effect<void>
|
||||
invalidateCacheEntry(key: K): Effect.Effect<void>
|
||||
}
|
||||
|
||||
export declare namespace Query {
|
||||
@@ -114,42 +115,6 @@ extends Pipeable.Class() implements Query<K, A, E, R, P> {
|
||||
)
|
||||
}
|
||||
|
||||
get refetch(): Effect.Effect<Result.Final<A, E, P>, 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<A, E, P>
|
||||
: Result.initial()
|
||||
),
|
||||
this.context,
|
||||
)),
|
||||
Effect.andThen(sub => this.watch(sub)),
|
||||
)
|
||||
}
|
||||
|
||||
get refetchSubscribable(): Effect.Effect<
|
||||
Subscribable.Subscribable<Result.Result<A, E, P>>,
|
||||
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<A, E, P>
|
||||
: Result.initial()
|
||||
),
|
||||
this.context,
|
||||
)),
|
||||
Effect.tap(sub => Effect.forkScoped(this.watch(sub))),
|
||||
)
|
||||
}
|
||||
|
||||
get refresh(): Effect.Effect<Result.Final<A, E, P>, Cause.NoSuchElementException> {
|
||||
return this.interrupt.pipe(
|
||||
Effect.andThen(Effect.Do),
|
||||
@@ -218,10 +183,10 @@ extends Pipeable.Class() implements Query<K, A, E, R, P> {
|
||||
> {
|
||||
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<K, A, E, R, P> {
|
||||
)
|
||||
}
|
||||
|
||||
removeCacheEntry(key: K): Effect.Effect<void, never, QueryClient.QueryClient> {
|
||||
return Effect.andThen(
|
||||
QueryClient.QueryClient,
|
||||
client => SubscriptionRef.update(
|
||||
get invalidateCache(): Effect.Effect<void> {
|
||||
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<void> {
|
||||
return QueryClient.QueryClient.pipe(
|
||||
Effect.andThen(client => SubscriptionRef.update(
|
||||
client.cache,
|
||||
HashMap.remove(this.makeCacheKey(key)),
|
||||
),
|
||||
)),
|
||||
Effect.provide(this.context),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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*() {
|
||||
<Flex direction="row" justify="center" align="center" gap="1">
|
||||
<Button onClick={() => runPromise(query.refresh)}>Refresh</Button>
|
||||
<Button onClick={() => runPromise(query.refetch)}>Refetch</Button>
|
||||
<Button onClick={() => runPromise(query.invalidateCache)}>Invalidate cache</Button>
|
||||
</Flex>
|
||||
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user