@reffuse/extension-query 0.1.5 #16
@@ -1,7 +1,36 @@
|
|||||||
import type * as AsyncData from "@typed/async-data"
|
import * as AsyncData from "@typed/async-data"
|
||||||
import { Effect, type Option } from "effect"
|
import { Effect, flow, Layer, Match, Option } from "effect"
|
||||||
|
import * as QueryState from "./QueryState.js"
|
||||||
|
|
||||||
|
|
||||||
export class QueryProgress extends Effect.Tag("@reffuse/extension-query/QueryProgress")<QueryProgress, {
|
export class QueryProgress extends Effect.Tag("@reffuse/extension-query/QueryProgress")<QueryProgress, {
|
||||||
readonly set: (previous: Option.Option<AsyncData.Progress>) => Effect.Effect<void>
|
readonly get: Effect.Effect<Option.Option<AsyncData.Progress>, never, QueryState.QueryState<unknown, unknown>>
|
||||||
}>() {}
|
|
||||||
|
readonly update: (
|
||||||
|
f: (previous: Option.Option<AsyncData.Progress>) => AsyncData.Progress
|
||||||
|
) => Effect.Effect<void, never, QueryState.QueryState<unknown, unknown>>
|
||||||
|
}>() {
|
||||||
|
static readonly Live = Layer.sync(this, () => {
|
||||||
|
const queryStateTag = QueryState.makeTag()
|
||||||
|
|
||||||
|
const get = queryStateTag.pipe(
|
||||||
|
Effect.flatMap(state => state.get),
|
||||||
|
Effect.map(flow(Match.value,
|
||||||
|
Match.tag("Loading", v => v.progress),
|
||||||
|
Match.tag("Refreshing", v => v.progress),
|
||||||
|
Match.orElse(() => Option.none()),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
|
const update = (f: (previous: Option.Option<AsyncData.Progress>) => AsyncData.Progress) => get.pipe(
|
||||||
|
Effect.map(f),
|
||||||
|
Effect.flatMap(progress => queryStateTag.pipe(
|
||||||
|
Effect.flatMap(queryState => queryState.update(previous =>
|
||||||
|
AsyncData.updateProgress(previous, progress)
|
||||||
|
))
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
|
return { get, update }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
24
packages/extension-query/src/QueryState.ts
Normal file
24
packages/extension-query/src/QueryState.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import * as AsyncData from "@typed/async-data"
|
||||||
|
import { Context, Effect, Layer } from "effect"
|
||||||
|
|
||||||
|
|
||||||
|
export interface QueryState<A, E> {
|
||||||
|
readonly get: Effect.Effect<AsyncData.AsyncData<A, E>>
|
||||||
|
readonly set: (value: AsyncData.AsyncData<A, E>) => Effect.Effect<void>
|
||||||
|
readonly update: (f: (previous: AsyncData.AsyncData<A, E>) => AsyncData.AsyncData<A, E>) => Effect.Effect<void>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const makeTag = <A, E>(): Context.Tag<QueryState<A, E>, QueryState<A, E>> => Context.GenericTag("@reffuse/query-extension/QueryState")
|
||||||
|
|
||||||
|
export const layer = <A, E>(
|
||||||
|
tag: Context.Tag<QueryState<A, E>, QueryState<A, E>>,
|
||||||
|
get: Effect.Effect<AsyncData.AsyncData<A, E>>,
|
||||||
|
set: (value: AsyncData.AsyncData<A, E>) => Effect.Effect<void>,
|
||||||
|
): Layer.Layer<QueryState<A, E>> => Layer.succeed(tag, {
|
||||||
|
get,
|
||||||
|
set,
|
||||||
|
update: f => get.pipe(
|
||||||
|
Effect.map(f),
|
||||||
|
Effect.flatMap(set),
|
||||||
|
),
|
||||||
|
})
|
||||||
@@ -3,5 +3,7 @@ export * as MutationRunner from "./MutationRunner.js"
|
|||||||
export * as MutationService from "./MutationService.js"
|
export * as MutationService from "./MutationService.js"
|
||||||
export * as QueryClient from "./QueryClient.js"
|
export * as QueryClient from "./QueryClient.js"
|
||||||
export * from "./QueryExtension.js"
|
export * from "./QueryExtension.js"
|
||||||
|
export * as QueryProgress from "./QueryProgress.js"
|
||||||
export * as QueryRunner from "./QueryRunner.js"
|
export * as QueryRunner from "./QueryRunner.js"
|
||||||
export * as QueryService from "./QueryService.js"
|
export * as QueryService from "./QueryService.js"
|
||||||
|
export * as QueryState from "./QueryState.js"
|
||||||
|
|||||||
Reference in New Issue
Block a user