Skip to content

Commit f70c207

Browse files
tim-smartdatner
authored andcommitted
manage useResultCallback fiber within useEffect
1 parent 8723653 commit f70c207

File tree

2 files changed

+26
-45
lines changed

2 files changed

+26
-45
lines changed

.changeset/strange-bottles-walk.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"effect-react": patch
3+
---
4+
5+
manage useResultCallback fiber within useEffect

src/hooks/useResultCallback.ts

Lines changed: 21 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
1+
import * as Option from "@effect/data/Option"
12
import * as Effect from "@effect/io/Effect"
2-
import * as Exit from "@effect/io/Exit"
33
import * as Fiber from "@effect/io/Fiber"
4-
import * as Ref from "@effect/io/Ref"
54
import * as Runtime from "@effect/io/Runtime"
65
import * as Stream from "@effect/stream/Stream"
76
import type { ResultBag } from "effect-react/hooks/useResultBag"
87
import { updateNext, useResultBag } from "effect-react/hooks/useResultBag"
98
import type { RuntimeContext } from "effect-react/internal/runtimeContext"
109
import * as Result from "effect-react/Result"
11-
import { useCallback, useContext, useEffect, useRef, useState } from "react"
12-
13-
type FiberState<E> = { readonly _tag: "Idle" } | {
14-
readonly _tag: "Running"
15-
readonly fiber: Fiber.RuntimeFiber<E, void>
16-
readonly interruptingRef: Ref.Ref<boolean>
17-
}
10+
import { useCallback, useContext, useEffect, useState } from "react"
1811

1912
export type UseResultCallback<R> = <Args extends Array<any>, R0 extends R, E, A>(
2013
callback: (...args: Args) => Effect.Effect<R0, E, A>
@@ -32,57 +25,40 @@ export const makeUseResultCallback: <R>(
3225
const [trackRef, resultBag] = useResultBag(result)
3326
trackRef.current.currentStatus = result._tag
3427

35-
const fiberState = useRef<FiberState<E>>({ _tag: "Idle" })
36-
useEffect(() =>
37-
() => {
38-
if (fiberState.current._tag === "Running") {
39-
Effect.runSync(Ref.set(fiberState.current.interruptingRef, true))
40-
Effect.runFork(Fiber.interruptFork(fiberState.current.fiber))
41-
}
42-
}, [])
43-
4428
const runtime = useContext(runtimeContext)
45-
const run = useCallback((...args: Args) => {
46-
if (fiberState.current._tag === "Running") {
47-
Effect.runSync(Ref.set(fiberState.current.interruptingRef, true))
48-
Effect.runFork(Fiber.interruptFork(fiberState.current.fiber))
29+
const [currentArgs, setCurrentArgs] = useState<Option.Option<Args>>(Option.none())
30+
useEffect(() => {
31+
if (Option.isNone(currentArgs)) {
32+
return
4933
}
5034

51-
trackRef.current.invocationCount++
52-
53-
const interruptingRef = Ref.unsafeMake(false)
35+
let interrupting = false
5436
const maybeSetResult = (result: Result.Result<E, A> | ((_: Result.Result<E, A>) => Result.Result<E, A>)) =>
55-
Effect.flatMap(
56-
Ref.get(interruptingRef),
57-
(interrupting) =>
58-
interrupting ? Effect.unit : Effect.sync(() => {
59-
setResult(result)
60-
})
61-
)
37+
Effect.sync(() => {
38+
if (!interrupting) {
39+
setResult(result)
40+
}
41+
})
6242

6343
const fiber = Stream.suspend(() => {
6444
setResult((prev) => updateNext(Result.waiting(prev), trackRef))
65-
return f(...args)
45+
return f(...currentArgs.value)
6646
}).pipe(
6747
Stream.tap((value) => maybeSetResult(updateNext(Result.success(value), trackRef))),
6848
Stream.tapErrorCause((cause) => maybeSetResult(updateNext(Result.failCause(cause), trackRef))),
6949
Stream.runDrain,
70-
Effect.onExit((exit) =>
71-
Exit.isInterrupted(exit)
72-
? Effect.unit
73-
: Effect.sync(() => {
74-
fiberState.current = { _tag: "Idle" }
75-
})
76-
),
7750
Runtime.runFork(runtime)
7851
)
7952

80-
fiberState.current = {
81-
_tag: "Running",
82-
fiber,
83-
interruptingRef
53+
return () => {
54+
interrupting = true
55+
Effect.runFork(Fiber.interruptFork(fiber))
8456
}
85-
}, [f])
57+
}, [currentArgs])
58+
59+
const run = useCallback((...args: Args) => {
60+
setCurrentArgs(Option.some(args))
61+
}, [])
8662

8763
return [resultBag, run] as const
8864
}

0 commit comments

Comments
 (0)