diff --git a/packages/effect-fc-next/src/Query.ts b/packages/effect-fc-next/src/Query.ts index 9b5007b..e9a155b 100644 --- a/packages/effect-fc-next/src/Query.ts +++ b/packages/effect-fc-next/src/Query.ts @@ -53,7 +53,7 @@ extends Pipeable.Class implements Query { constructor( readonly context: Context.Context, - readonly key: Lens.Lens, + readonly key: Subscribable.Subscribable, readonly keyEquivalence: Equivalence.Equivalence, readonly f: (key: K) => Effect.Effect, @@ -71,15 +71,23 @@ extends Pipeable.Class implements Query { get run(): Effect.Effect { return Effect.all([ - Stream.runFoldEffect( + Stream.runForEach( this.key.changes, - () => Option.none(), - (previous, key) => Effect.as( - Option.isSome(previous) && this.keyEquivalence(key, previous.value) - ? this.refreshSubscribable - : this.fetchSubscribable(key), - Option.some(key), - ), + key => Effect.gen({ self: this }, function*() { + yield* this.interrupt + const latestFinalState = yield* Lens.get(this.latestFinalState) + + const state = yield* this.startCached( + Option.isSome(latestFinalState) && this.keyEquivalence(key, latestFinalState.value.key) + ? latestFinalState.value + : { + key, + result: AsyncResult.initial(false), + } + ) + + yield* Effect.forkScoped(this.watch(state)) + }), ), Effect.promise(() => import("@effect/platform-browser")).pipe( @@ -109,8 +117,6 @@ extends Pipeable.Class implements Query { fetch(key: K): Effect.Effect, Cause.NoSuchElementError> { return Effect.gen({ self: this }, function*() { yield* this.interrupt - yield* Lens.set(this.key, key) - const state = yield* this.startCached({ key, result: AsyncResult.initial(false), @@ -127,8 +133,6 @@ extends Pipeable.Class implements Query { > { return Effect.gen({ self: this }, function*() { yield* this.interrupt - yield* Lens.set(this.key, key) - const state = yield* this.startCached({ key, result: AsyncResult.initial(false), @@ -144,14 +148,14 @@ extends Pipeable.Class implements Query { get refresh(): Effect.Effect, Cause.NoSuchElementError> { return Effect.gen({ self: this }, function*() { yield* this.interrupt - const latestKey = yield* Lens.get(this.key) + const latestState = yield* Lens.get(this.state) const latestFinalState = yield* Lens.get(this.latestFinalState) const state = yield* this.startCached( - Option.isSome(latestFinalState) && this.keyEquivalence(latestKey, latestFinalState.value.key) + Option.isSome(latestFinalState) && this.keyEquivalence(latestState.key, latestFinalState.value.key) ? latestFinalState.value : { - key: latestKey, + key: latestState.key, result: AsyncResult.initial(false), } ) @@ -168,14 +172,14 @@ extends Pipeable.Class implements Query { > { return Effect.gen({ self: this }, function*() { yield* this.interrupt - const latestKey = yield* Lens.get(this.key) + const latestState = yield* Lens.get(this.state) const latestFinalState = yield* Lens.get(this.latestFinalState) const state = yield* this.startCached( - Option.isSome(latestFinalState) && this.keyEquivalence(latestKey, latestFinalState.value.key) + Option.isSome(latestFinalState) && this.keyEquivalence(latestState.key, latestFinalState.value.key) ? latestFinalState.value : { - key: latestKey, + key: latestState.key, result: AsyncResult.initial(false), } ) @@ -363,7 +367,7 @@ extends Pipeable.Class implements Query { export declare namespace make { export interface Options { - readonly key: Lens.Lens, + readonly key: Subscribable.Subscribable, readonly keyEquivalence?: Equivalence.Equivalence, readonly f: (key: K) => Effect.Effect @@ -392,7 +396,7 @@ export const make = Effect.fnUntraced(function* ( Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())), Lens.fromSubscriptionRef(yield* SubscriptionRef.make>({ - key: yield* Lens.get(options.key), + key: yield* options.key.get, result: AsyncResult.initial(false), })), Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())),