0.2.2 #31
@@ -121,7 +121,7 @@ extends Pipeable.Class() implements Form<A, I, R, MA, ME, MR, MP> {
|
||||
|
||||
export const isForm = (u: unknown): u is Form<unknown, unknown, unknown, unknown, unknown, unknown> => Predicate.hasProperty(u, FormTypeId)
|
||||
|
||||
export namespace make {
|
||||
export declare namespace make {
|
||||
export interface Options<in out A, in out I = A, in out R = never, in out MA = void, in out ME = never, in out MR = never, in out MP = never>
|
||||
extends Mutation.make.Options<
|
||||
readonly [value: NoInfer<A>, form: Form<NoInfer<A>, NoInfer<I>, NoInfer<R>, unknown, unknown, unknown>],
|
||||
@@ -203,7 +203,7 @@ export const run = <A, I, R, MA, ME, MR, MP>(
|
||||
))
|
||||
}
|
||||
|
||||
export namespace service {
|
||||
export declare namespace service {
|
||||
export interface Options<in out A, in out I = A, in out R = never, in out MA = void, in out ME = never, in out MR = never, in out MP = never>
|
||||
extends make.Options<A, I, R, MA, ME, MR, MP> {}
|
||||
}
|
||||
|
||||
@@ -1,43 +1,97 @@
|
||||
import { Equal, Equivalence, Hash, type HashMap, Pipeable, Predicate, type Ref } from "effect"
|
||||
import { type DateTime, type Duration, Effect, Equal, Equivalence, Hash, HashMap, Pipeable, Predicate, Ref, type Scope } from "effect"
|
||||
import type * as Query from "./Query.js"
|
||||
import type * as Result from "./Result.js"
|
||||
|
||||
|
||||
export const QueryClientTypeId: unique symbol = Symbol.for("@effect-fc/QueryClient/QueryClient")
|
||||
export type QueryClientTypeId = typeof QueryClientTypeId
|
||||
|
||||
export interface QueryClient extends Pipeable.Pipeable {
|
||||
readonly [QueryClientTypeId]: QueryClientTypeId
|
||||
export const QueryClientServiceTypeId: unique symbol = Symbol.for("@effect-fc/QueryClient/QueryClientServiceTypeId")
|
||||
export type QueryClientServiceTypeId = typeof QueryClientServiceTypeId
|
||||
|
||||
export interface QueryClientService extends Pipeable.Pipeable {
|
||||
readonly [QueryClientServiceTypeId]: QueryClientServiceTypeId
|
||||
readonly cache: Ref.Ref<HashMap.HashMap<Query.Query.AnyKey, Result.Final<unknown, unknown, unknown>>>
|
||||
readonly defaultTtl: Duration.DurationInput
|
||||
}
|
||||
|
||||
export class QueryClientImpl extends Pipeable.Class() implements QueryClient {
|
||||
readonly [QueryClientTypeId]: QueryClientTypeId = QueryClientTypeId
|
||||
export class QueryClient extends Effect.Service<QueryClient>()("@effect-fc/QueryClient/QueryClient", {
|
||||
scoped: Effect.suspend(() => service())
|
||||
}) {}
|
||||
|
||||
export class QueryClientServiceImpl extends Pipeable.Class() implements QueryClientService {
|
||||
readonly [QueryClientServiceTypeId]: QueryClientServiceTypeId = QueryClientServiceTypeId
|
||||
|
||||
constructor(
|
||||
readonly cache: Ref.Ref<HashMap.HashMap<Query.Query.AnyKey, Result.Final<unknown, unknown, unknown>>>
|
||||
readonly cache: Ref.Ref<HashMap.HashMap<Query.Query.AnyKey, Result.Final<unknown, unknown, unknown>>>,
|
||||
readonly defaultTtl: Duration.DurationInput,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
}
|
||||
|
||||
export const isQueryClient = (u: unknown): u is QueryClient => Predicate.hasProperty(u, QueryClientTypeId)
|
||||
export const isQueryClientService = (u: unknown): u is QueryClientService => Predicate.hasProperty(u, QueryClientServiceTypeId)
|
||||
|
||||
export declare namespace make {
|
||||
export interface Options {
|
||||
readonly defaultTtl?: Duration.DurationInput
|
||||
}
|
||||
}
|
||||
|
||||
export const make = Effect.fnUntraced(function* (options: make.Options = {}): Effect.fn.Return<QueryClientService> {
|
||||
return new QueryClientServiceImpl(
|
||||
yield* Ref.make(HashMap.empty<Query.Query.AnyKey, Result.Final<unknown, unknown, unknown>>()),
|
||||
options.defaultTtl ?? "5 minutes",
|
||||
)
|
||||
})
|
||||
|
||||
export const run = (_self: QueryClientService): Effect.Effect<void> => Effect.void
|
||||
|
||||
export declare namespace service {
|
||||
export interface Options extends make.Options {}
|
||||
}
|
||||
|
||||
export const service = (options?: service.Options): Effect.Effect<QueryClientService, never, Scope.Scope> => Effect.tap(
|
||||
make(options),
|
||||
client => Effect.forkScoped(run(client)),
|
||||
)
|
||||
|
||||
|
||||
const QueryClientCacheKeyTypeId: unique symbol = Symbol.for("@effect-fc/QueryClient/QueryClientCacheKey")
|
||||
type QueryClientCacheKeyTypeId = typeof QueryClientCacheKeyTypeId
|
||||
export const QueryClientCacheKeyTypeId: unique symbol = Symbol.for("@effect-fc/QueryClient/QueryClientCacheKey")
|
||||
export type QueryClientCacheKeyTypeId = typeof QueryClientCacheKeyTypeId
|
||||
|
||||
class QueryClientCacheKey implements Equal.Equal {
|
||||
export class QueryClientCacheKey implements Equal.Equal {
|
||||
readonly [QueryClientCacheKeyTypeId]: QueryClientCacheKeyTypeId = QueryClientCacheKeyTypeId
|
||||
constructor(readonly key: Query.Query.AnyKey) {}
|
||||
|
||||
[Equal.symbol](that: Equal.Equal) {
|
||||
return isQueryClientKey(that) && Equivalence.array(Equal.equivalence())(this.key, that.key)
|
||||
return isQueryClientCacheKey(that) && Equivalence.array(Equal.equivalence())(this.key, that.key)
|
||||
}
|
||||
[Hash.symbol]() {
|
||||
return Hash.array(this.key)
|
||||
}
|
||||
}
|
||||
|
||||
const isQueryClientKey = (u: unknown): u is QueryClientCacheKey => Predicate.hasProperty(u, QueryClientCacheKeyTypeId)
|
||||
export const isQueryClientCacheKey = (u: unknown): u is QueryClientCacheKey => Predicate.hasProperty(u, QueryClientCacheKeyTypeId)
|
||||
|
||||
|
||||
export const QueryClientCacheEntryTypeId: unique symbol = Symbol.for("@effect-fc/QueryClient/QueryClientCacheEntry")
|
||||
export type QueryClientCacheEntryTypeId = typeof QueryClientCacheEntryTypeId
|
||||
|
||||
export interface QueryClientCacheEntry extends Pipeable.Pipeable {
|
||||
readonly [QueryClientCacheEntryTypeId]: QueryClientCacheEntryTypeId
|
||||
readonly at: DateTime.DateTime
|
||||
readonly ttl: Duration.DurationInput
|
||||
readonly result: Result.Final<unknown, unknown, unknown>
|
||||
}
|
||||
|
||||
export class QueryClientCacheEntryImpl extends Pipeable.Class() implements QueryClientCacheEntry {
|
||||
readonly [QueryClientCacheEntryTypeId]: QueryClientCacheEntryTypeId = QueryClientCacheEntryTypeId
|
||||
|
||||
constructor(
|
||||
readonly at: DateTime.DateTime,
|
||||
readonly ttl: Duration.DurationInput,
|
||||
readonly result: Result.Final<unknown, unknown, unknown>,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
}
|
||||
|
||||
export const isQueryClientCacheEntry = (u: unknown): u is QueryClientCacheEntry => Predicate.hasProperty(u, QueryClientCacheEntryTypeId)
|
||||
|
||||
Reference in New Issue
Block a user