@@ -44,16 +44,13 @@ let count = Signal.make(0)
4444let doubled = Computed.make(() => Signal.get(count) * 2)
4545
4646// Run a side effect (executes when dependencies change)
47- let disposer = Effect.run(() => {
47+ Effect.run(() => {
4848 Console.log(`Count: ${Int.toString(Signal.get(count))}, Doubled: ${Int.toString(Signal.get(doubled))}`)
4949 None
5050})
5151
5252// Update the signal
5353Signal.set(count, 5) // Logs: "Count: 5, Doubled: 10"
54-
55- // Clean up when done
56- disposer.dispose()
5754```
5855
5956## Usage
@@ -167,13 +164,29 @@ Effects run side effects in response to signal changes. They execute immediately
167164``` rescript
168165let count = Signal.make(0)
169166
170- let disposer = Effect.run(() => {
167+ // Fire-and-forget effect
168+ Effect.run(() => {
171169 Console.log(`Count is: ${Int.toString(Signal.get(count))}`)
172170 None
173171})
174172
175173Signal.set(count, 1) // Logs: "Count is: 1"
176- disposer.dispose()
174+ ```
175+
176+ #### Effect with Disposer
177+
178+ Use ` Effect.runWithDisposer ` when you need to manually stop the effect:
179+
180+ ``` rescript
181+ let count = Signal.make(0)
182+
183+ let disposer = Effect.runWithDisposer(() => {
184+ Console.log(`Count is: ${Int.toString(Signal.get(count))}`)
185+ None
186+ })
187+
188+ Signal.set(count, 1) // Logs: "Count is: 1"
189+ disposer.dispose() // Stop tracking
177190```
178191
179192#### Effect with Cleanup
@@ -183,7 +196,7 @@ Effects can return a cleanup function that runs before the next execution and on
183196``` rescript
184197let url = Signal.make("/api/data")
185198
186- let disposer = Effect.run (() => {
199+ let disposer = Effect.runWithDisposer (() => {
187200 let currentUrl = Signal.get(url)
188201
189202 // Start async operation
@@ -203,7 +216,7 @@ disposer.dispose() // Final cleanup
203216#### Named Effects for Debugging
204217
205218``` rescript
206- let disposer = Effect.run(
219+ Effect.run(
207220 () => {
208221 Console.log(Signal.get(count))
209222 None
@@ -221,7 +234,7 @@ let showDetails = Signal.make(false)
221234let userData = Signal.make({name: "John"})
222235let adminData = Signal.make({role: "admin"})
223236
224- let disposer = Effect.run(() => {
237+ Effect.run(() => {
225238 if Signal.get(showDetails) {
226239 Console.log(Signal.get(userData)) // Tracked
227240 } else {
@@ -243,7 +256,7 @@ let firstName = Signal.make("John")
243256let lastName = Signal.make("Doe")
244257let runCount = ref(0)
245258
246- let disposer = Effect.run(() => {
259+ Effect.run(() => {
247260 Console.log(Signal.get(firstName) ++ " " ++ Signal.get(lastName))
248261 runCount := runCount.contents + 1
249262 None
@@ -275,7 +288,7 @@ Read signal values without creating dependencies. Useful when you need a value b
275288let count = Signal.make(0)
276289let threshold = Signal.make(10)
277290
278- let disposer = Effect.run(() => {
291+ Effect.run(() => {
279292 let current = Signal.get(count)
280293 let limit = Signal.untrack(() => Signal.get(threshold))
281294
@@ -393,18 +406,26 @@ Run side effects in response to signal changes.
393406``` rescript
394407type disposer = {dispose: unit => unit}
395408
396- // Run an effect
409+ // Run a fire-and-forget effect
397410let run: (
398411 unit => option<unit => unit>,
399412 ~name: option<string>=?
413+ ) => unit
414+
415+ // Run an effect with manual disposal
416+ let runWithDisposer: (
417+ unit => option<unit => unit>,
418+ ~name: option<string>=?
400419) => disposer
401420```
402421
403422** Parameters:**
404423- ` fn ` : Effect function to execute. Can return ` None ` or ` Some(cleanupFn) `
405424- ` ~name ` : Optional name for debugging
406425
407- ** Returns:** A disposer object with a ` dispose() ` method
426+ ** ` Effect.run ` ** : Fire-and-forget effect. Returns ` unit ` .
427+
428+ ** ` Effect.runWithDisposer ` ** : Returns a disposer object with a ` dispose() ` method for manual cleanup.
408429
409430** Note:** Effects run immediately and re-run whenever tracked dependencies change. Cleanup functions run before re-execution and on disposal.
410431
@@ -428,7 +449,7 @@ let isValid = Computed.make(() => {
428449})
429450
430451// Effect for auto-save
431- let disposer = Effect.run(() => {
452+ Effect.run(() => {
432453 if Signal.get(isValid) {
433454 saveToLocalStorage(Signal.get(formData))
434455 }
@@ -443,7 +464,7 @@ let userId = Signal.make(1)
443464let userData = Signal.make(None)
444465let isLoading = Signal.make(false)
445466
446- let disposer = Effect.run(() => {
467+ Effect.run(() => {
447468 let id = Signal.get(userId)
448469
449470 Signal.set(isLoading, true)
@@ -503,7 +524,7 @@ let movePoint = (dx, dy, dz) => {
503524}
504525
505526// Effect only runs once per movePoint call
506- let disposer = Effect.run(() => {
527+ Effect.run(() => {
507528 Console.log(
508529 `Position: (${Int.toString(Signal.get(x))}, ${Int.toString(Signal.get(y))}, ${Int.toString(Signal.get(z))})`
509530 )
@@ -520,7 +541,7 @@ let config = Signal.make({theme: "dark", locale: "en"})
520541// Frequently changing data
521542let data = Signal.make([])
522543
523- let disposer = Effect.run(() => {
544+ Effect.run(() => {
524545 let items = Signal.get(data)
525546
526547 // Read config without tracking—we'll manually refresh when config changes
0 commit comments