From f99d18b8463fd26f7014d2d4e8c2f23754a04977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Thu, 6 Mar 2025 03:15:43 +0100 Subject: [PATCH] Cleanup fix --- packages/example/src/routes/query.tsx | 12 +++++- .../extension-query/src/QueryExtension.ts | 14 +++++-- packages/extension-query/src/QueryRunner.ts | 42 ++++++++++++------- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/packages/example/src/routes/query.tsx b/packages/example/src/routes/query.tsx index 07387ac..79b51a9 100644 --- a/packages/example/src/routes/query.tsx +++ b/packages/example/src/routes/query.tsx @@ -21,13 +21,23 @@ function RouteComponent() { const query = R.useQuery({ query: () => Console.log(`Querying ${ count } IDs...`).pipe( - // Effect.andThen(Effect.sleep("500 millis")), + Effect.andThen(Effect.sleep("500 millis")), Effect.andThen(HttpClient.get(`https://www.uuidtools.com/api/generate/v4/count/${ count }`)), HttpClient.withTracerPropagation(false), Effect.flatMap(res => res.json), Effect.flatMap(Schema.decodeUnknown(Result)), Effect.scoped, ), + // query: () => Console.log(`Creating ${ count } IDs...`).pipe( + // Effect.andThen(Effect.sleep("500 millis")), + // Effect.andThen(pipe( + // Array.range(1, count), + // Array.map(() => makeUuid4), + // Effect.all, + // )), + // Effect.flatMap(Schema.decode(Result)), + // Effect.provide(GetRandomValues.CryptoRandom), + // ), key: ["uuid4", count], }) diff --git a/packages/extension-query/src/QueryExtension.ts b/packages/extension-query/src/QueryExtension.ts index 8ad003f..1aa807d 100644 --- a/packages/extension-query/src/QueryExtension.ts +++ b/packages/extension-query/src/QueryExtension.ts @@ -21,14 +21,20 @@ export const QueryExtension = ReffuseExtension.make(() => ({ this: ReffuseHelpers.ReffuseHelpers, props: UseQueryProps, ): UseQueryResult { + const runSync = this.useRunSync() + const runner = this.useMemo(() => QueryRunner.make({ query: props.query() }), []) - this.useEffect(() => Effect.addFinalizer(() => runner.forkInterrupt).pipe( - Effect.andThen(Ref.set(runner.queryRef, props.query())), - Effect.andThen(runner.forkFetch), - ), [runner, ...props.key]) + React.useEffect(() => { + Ref.set(runner.queryRef, props.query()).pipe( + Effect.andThen(runner.forkFetch), + runSync, + ) + + return () => { runSync(runner.forkInterrupt) } + }, [runner, ...props.key]) this.useFork(() => runner.refreshOnWindowFocus, [runner]) diff --git a/packages/extension-query/src/QueryRunner.ts b/packages/extension-query/src/QueryRunner.ts index 2a75a70..e5857bf 100644 --- a/packages/extension-query/src/QueryRunner.ts +++ b/packages/extension-query/src/QueryRunner.ts @@ -31,17 +31,28 @@ export const make = ( const interrupt = fiberRef.pipe( Effect.flatMap(Option.match({ - onSome: Fiber.interrupt, + onSome: fiber => Ref.set(fiberRef, Option.none()).pipe( + Effect.andThen(Fiber.interrupt(fiber)) + ), onNone: () => Effect.void, })) ) - const forkInterrupt = Effect.forkDaemon(interrupt) + const forkInterrupt = fiberRef.pipe( + Effect.flatMap(Option.match({ + onSome: fiber => Ref.set(fiberRef, Option.none()).pipe( + Effect.andThen(Fiber.interrupt(fiber).pipe( + Effect.asVoid, + Effect.forkDaemon, + )) + ), + onNone: () => Effect.forkDaemon(Effect.void), + })) + ) const forkFetch = interrupt.pipe( Effect.andThen( - Effect.addFinalizer(() => Ref.set(fiberRef, Option.none())).pipe( - Effect.andThen(Ref.set(stateRef, AsyncData.loading())), + Ref.set(stateRef, AsyncData.loading()).pipe( Effect.andThen(queryRef.pipe(Effect.flatMap(identity))), Effect.matchCauseEffect({ onSuccess: v => Ref.set(stateRef, AsyncData.success(v)), @@ -49,14 +60,14 @@ export const make = ( }), Effect.provide(context), - Effect.scoped, Effect.fork, ) ), Effect.flatMap(fiber => Ref.set(fiberRef, Option.some(fiber)).pipe( - Effect.andThen(Fiber.join(fiber)) + Effect.andThen(Fiber.join(fiber)), + Effect.andThen(Ref.set(fiberRef, Option.none())), ) ), @@ -65,14 +76,13 @@ export const make = ( const forkRefresh = interrupt.pipe( Effect.andThen( - Effect.addFinalizer(() => Ref.set(fiberRef, Option.none())).pipe( - Effect.andThen(Ref.update(stateRef, previous => { - if (AsyncData.isSuccess(previous) || AsyncData.isFailure(previous)) - return AsyncData.refreshing(previous) - if (AsyncData.isRefreshing(previous)) - return AsyncData.refreshing(previous.previous) - return AsyncData.loading() - })), + Ref.update(stateRef, previous => { + if (AsyncData.isSuccess(previous) || AsyncData.isFailure(previous)) + return AsyncData.refreshing(previous) + if (AsyncData.isRefreshing(previous)) + return AsyncData.refreshing(previous.previous) + return AsyncData.loading() + }).pipe( Effect.andThen(queryRef.pipe(Effect.flatMap(identity))), Effect.matchCauseEffect({ onSuccess: v => Ref.set(stateRef, AsyncData.success(v)), @@ -80,14 +90,14 @@ export const make = ( }), Effect.provide(context), - Effect.scoped, Effect.fork, ) ), Effect.flatMap(fiber => Ref.set(fiberRef, Option.some(fiber)).pipe( - Effect.andThen(Fiber.join(fiber)) + Effect.andThen(Fiber.join(fiber)), + Effect.andThen(Ref.set(fiberRef, Option.none())), ) ),