diff --git a/packages/effect-fc/src/Form.ts b/packages/effect-fc/src/Form.ts index 295bdd2..a52e322 100644 --- a/packages/effect-fc/src/Form.ts +++ b/packages/effect-fc/src/Form.ts @@ -295,7 +295,7 @@ export namespace useInput { readonly debounce?: Duration.DurationInput } - export interface Result { + export interface Success { readonly value: T readonly setValue: React.Dispatch> } @@ -304,7 +304,7 @@ export namespace useInput { export const useInput = Effect.fnUntraced(function* ( field: FormField, options?: useInput.Options, -): Effect.fn.Return, Cause.NoSuchElementException, Scope.Scope> { +): Effect.fn.Return, Cause.NoSuchElementException, Scope.Scope> { const internalValueRef = yield* Component.useOnChange(() => Effect.tap( Effect.andThen(field.encodedValue, SubscriptionRef.make), internalValueRef => Effect.forkScoped(Effect.all([ @@ -336,7 +336,7 @@ export namespace useOptionalInput { readonly defaultValue: T } - export interface Result extends useInput.Result { + export interface Success extends useInput.Success { readonly enabled: boolean readonly setEnabled: React.Dispatch> } @@ -345,7 +345,7 @@ export namespace useOptionalInput { export const useOptionalInput = Effect.fnUntraced(function* ( field: FormField>, options: useOptionalInput.Options, -): Effect.fn.Return, Cause.NoSuchElementException, Scope.Scope> { +): Effect.fn.Return, Cause.NoSuchElementException, Scope.Scope> { const [enabledRef, internalValueRef] = yield* Component.useOnChange(() => Effect.tap( Effect.andThen( field.encodedValue, diff --git a/packages/effect-fc/src/Mutation.ts b/packages/effect-fc/src/Mutation.ts index 7e026a0..0eaccdd 100644 --- a/packages/effect-fc/src/Mutation.ts +++ b/packages/effect-fc/src/Mutation.ts @@ -5,7 +5,7 @@ import * as Result from "./Result.js" export const MutationTypeId: unique symbol = Symbol.for("@effect-fc/Mutation/Mutation") export type MutationTypeId = typeof MutationTypeId -export interface Mutation +export interface Mutation extends Pipeable.Pipeable { readonly [MutationTypeId]: MutationTypeId @@ -21,7 +21,11 @@ extends Pipeable.Pipeable { mutateSubscribable(key: K): Effect.Effect>> } -export class MutationImpl +export declare namespace Mutation { + export type AnyKey = readonly any[] +} + +export class MutationImpl extends Pipeable.Class() implements Mutation { readonly [MutationTypeId]: MutationTypeId = MutationTypeId @@ -95,16 +99,16 @@ extends Pipeable.Class() implements Mutation { } } -export const isMutation = (u: unknown): u is Mutation => Predicate.hasProperty(u, MutationTypeId) +export const isMutation = (u: unknown): u is Mutation => Predicate.hasProperty(u, MutationTypeId) export declare namespace make { - export interface Options { + export interface Options { readonly f: (key: K) => Effect.Effect>> readonly initialProgress?: P } } -export const make = Effect.fnUntraced(function* ( +export const make = Effect.fnUntraced(function* ( options: make.Options ): Effect.fn.Return< Mutation, P>, diff --git a/packages/effect-fc/src/Query.ts b/packages/effect-fc/src/Query.ts index 93c4e96..9d51efa 100644 --- a/packages/effect-fc/src/Query.ts +++ b/packages/effect-fc/src/Query.ts @@ -5,7 +5,7 @@ import * as Result from "./Result.js" export const QueryTypeId: unique symbol = Symbol.for("@effect-fc/Query/Query") export type QueryTypeId = typeof QueryTypeId -export interface Query +export interface Query extends Pipeable.Pipeable { readonly [QueryTypeId]: QueryTypeId @@ -26,7 +26,11 @@ extends Pipeable.Pipeable { readonly refreshSubscribable: Effect.Effect>, Cause.NoSuchElementException> } -export class QueryImpl +export declare namespace Query { + export type AnyKey = readonly any[] +} + +export class QueryImpl extends Pipeable.Class() implements Query { readonly [QueryTypeId]: QueryTypeId = QueryTypeId @@ -136,17 +140,17 @@ extends Pipeable.Class() implements Query { } } -export const isQuery = (u: unknown): u is Query => Predicate.hasProperty(u, QueryTypeId) +export const isQuery = (u: unknown): u is Query => Predicate.hasProperty(u, QueryTypeId) export declare namespace make { - export interface Options { + export interface Options { readonly key: Stream.Stream readonly f: (key: NoInfer) => Effect.Effect>> readonly initialProgress?: P } } -export const make = Effect.fnUntraced(function* ( +export const make = Effect.fnUntraced(function* ( options: make.Options ): Effect.fn.Return< Query, P>, @@ -167,7 +171,7 @@ export const make = Effect.fnUntraced(function* ( +export const service = ( options: make.Options ): Effect.Effect< Query, P>, @@ -178,7 +182,7 @@ export const service = Effect.forkScoped(run(query)), ) -export const run = ( +export const run = ( self: Query ): Effect.Effect => { const _self = self as QueryImpl diff --git a/packages/effect-fc/src/QueryClient.ts b/packages/effect-fc/src/QueryClient.ts new file mode 100644 index 0000000..3191348 --- /dev/null +++ b/packages/effect-fc/src/QueryClient.ts @@ -0,0 +1,25 @@ +import { type HashMap, Pipeable, Predicate, type Subscribable, type SubscriptionRef } 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 + + readonly cache: Subscribable.Subscribable>> +} + +export class QueryClientImpl extends Pipeable.Class() implements QueryClient { + readonly [QueryClientTypeId]: QueryClientTypeId = QueryClientTypeId + + constructor( + readonly cache: SubscriptionRef.SubscriptionRef>> + ) { + super() + } +} + +export const isQueryClient = (u: unknown): u is QueryClient => Predicate.hasProperty(u, QueryClientTypeId) diff --git a/packages/effect-fc/src/index.ts b/packages/effect-fc/src/index.ts index 2167ff9..b5fe27e 100644 --- a/packages/effect-fc/src/index.ts +++ b/packages/effect-fc/src/index.ts @@ -7,6 +7,7 @@ export * as Mutation from "./Mutation.js" export * as PropertyPath from "./PropertyPath.js" export * as PubSub from "./PubSub.js" export * as Query from "./Query.js" +export * as QueryClient from "./QueryClient.js" export * as ReactRuntime from "./ReactRuntime.js" export * as Result from "./Result.js" export * as SetStateAction from "./SetStateAction.js"