diff --git a/packages/extension-query/src/QueryExtension.ts b/packages/extension-query/src/QueryExtension.ts new file mode 100644 index 0000000..2ee4607 --- /dev/null +++ b/packages/extension-query/src/QueryExtension.ts @@ -0,0 +1,36 @@ +import * as AsyncData from "@typed/async-data" +import { Effect, Fiber, Ref, SubscriptionRef } from "effect" +import * as React from "react" +import { ReffuseExtension, type ReffuseHelpers } from "reffuse" +import * as QueryRunner from "./QueryRunner.js" + + +export interface UseQueryProps { + effect: () => Effect.Effect + readonly deps: React.DependencyList +} + +export interface UseQueryResult { + readonly state: SubscriptionRef.SubscriptionRef> + readonly refresh: Effect.Effect> +} + + +export const QueryExtension = ReffuseExtension.make(() => ({ + useQuery( + this: ReffuseHelpers.ReffuseHelpers, + props: UseQueryProps, + ): UseQueryResult { + const runner = this.useMemo(() => QueryRunner.make(props.effect()), []) + + this.useEffect(() => Effect.addFinalizer(() => runner.forkInterrupt).pipe( + Effect.andThen(Ref.set(runner.queryRef, props.effect())), + Effect.andThen(runner.forkFetch), + ), [runner, ...props.deps]) + + return React.useMemo(() => ({ + state: runner.stateRef, + refresh: runner.forkRefresh, + }), [runner]) + } +})) diff --git a/packages/extension-query/src/index.ts b/packages/extension-query/src/index.ts index 76bb022..0052524 100644 --- a/packages/extension-query/src/index.ts +++ b/packages/extension-query/src/index.ts @@ -1,39 +1,2 @@ -import * as AsyncData from "@typed/async-data" -import { Effect, Fiber, Ref, SubscriptionRef } from "effect" -import * as React from "react" -import { ReffuseExtension, type ReffuseHelpers } from "reffuse" -import * as QueryRunner from "./QueryRunner.js" - - -export interface UseQueryProps { - effect: () => Effect.Effect - readonly deps: React.DependencyList -} - -export interface UseQueryResult { - readonly state: SubscriptionRef.SubscriptionRef> - readonly refresh: Effect.Effect> -} - - -export const QueryExtension = ReffuseExtension.make(() => ({ - useQuery( - this: ReffuseHelpers.ReffuseHelpers, - props: UseQueryProps, - ): UseQueryResult { - const runner = this.useMemo(() => QueryRunner.make(props.effect()), []) - - this.useEffect(() => Effect.addFinalizer(() => runner.forkInterrupt).pipe( - Effect.andThen(Ref.set(runner.queryRef, props.effect())), - Effect.andThen(runner.forkFetch), - ), [runner, ...props.deps]) - - return React.useMemo(() => ({ - state: runner.stateRef, - refresh: runner.forkRefresh, - }), [runner]) - } -})) - - +export * from "./QueryExtension.js" export * as QueryRunner from "./QueryRunner.js"