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 QueryClient from "./QueryClient.js"
|
||||||
import * as Result from "./Result.js"
|
import * as Result from "./Result.js"
|
||||||
|
|
||||||
@@ -25,10 +25,11 @@ extends Pipeable.Pipeable {
|
|||||||
readonly run: Effect.Effect<void>
|
readonly run: Effect.Effect<void>
|
||||||
fetch(key: K): Effect.Effect<Result.Final<A, E, P>>
|
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>
|
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 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 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 {
|
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> {
|
get refresh(): Effect.Effect<Result.Final<A, E, P>, Cause.NoSuchElementException> {
|
||||||
return this.interrupt.pipe(
|
return this.interrupt.pipe(
|
||||||
Effect.andThen(Effect.Do),
|
Effect.andThen(Effect.Do),
|
||||||
@@ -218,10 +183,10 @@ extends Pipeable.Class() implements Query<K, A, E, R, P> {
|
|||||||
> {
|
> {
|
||||||
return Result.unsafeForkEffect(
|
return Result.unsafeForkEffect(
|
||||||
Effect.onExit(this.f(key), exit => Effect.andThen(
|
Effect.onExit(this.f(key), exit => Effect.andThen(
|
||||||
|
SubscriptionRef.set(this.fiber, Option.none()),
|
||||||
Exit.isSuccess(exit)
|
Exit.isSuccess(exit)
|
||||||
? this.updateCacheEntry(key, Result.fromExit(exit))
|
? this.updateCacheEntry(key, Result.fromExit(exit))
|
||||||
: Effect.void,
|
: Effect.void,
|
||||||
SubscriptionRef.set(this.fiber, Option.none()),
|
|
||||||
)),
|
)),
|
||||||
{
|
{
|
||||||
initial,
|
initial,
|
||||||
@@ -275,13 +240,23 @@ extends Pipeable.Class() implements Query<K, A, E, R, P> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
removeCacheEntry(key: K): Effect.Effect<void, never, QueryClient.QueryClient> {
|
get invalidateCache(): Effect.Effect<void> {
|
||||||
return Effect.andThen(
|
return QueryClient.QueryClient.pipe(
|
||||||
QueryClient.QueryClient,
|
Effect.andThen(client => SubscriptionRef.update(
|
||||||
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,
|
client.cache,
|
||||||
HashMap.remove(this.makeCacheKey(key)),
|
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(response => response.json),
|
||||||
Effect.andThen(Schema.decodeUnknown(Post)),
|
Effect.andThen(Schema.decodeUnknown(Post)),
|
||||||
),
|
),
|
||||||
staleTime: "10 seconds",
|
staleTime: "1 minutes",
|
||||||
})
|
})
|
||||||
|
|
||||||
const mutation = yield* Mutation.make({
|
const mutation = yield* Mutation.make({
|
||||||
@@ -87,6 +87,7 @@ const ResultView = Component.makeUntraced("Result")(function*() {
|
|||||||
<Flex direction="row" justify="center" align="center" gap="1">
|
<Flex direction="row" justify="center" align="center" gap="1">
|
||||||
<Button onClick={() => runPromise(query.refresh)}>Refresh</Button>
|
<Button onClick={() => runPromise(query.refresh)}>Refresh</Button>
|
||||||
<Button onClick={() => runPromise(query.refetch)}>Refetch</Button>
|
<Button onClick={() => runPromise(query.refetch)}>Refetch</Button>
|
||||||
|
<Button onClick={() => runPromise(query.invalidateCache)}>Invalidate cache</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in New Issue
Block a user