@typed/fx 1.9.2 → 1.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/dist/catchAllCause.d.ts.map +1 -1
  2. package/dist/catchAllCause.js +7 -6
  3. package/dist/catchAllCause.js.map +1 -1
  4. package/dist/cjs/catchAllCause.d.ts.map +1 -1
  5. package/dist/cjs/catchAllCause.js +6 -5
  6. package/dist/cjs/catchAllCause.js.map +1 -1
  7. package/dist/cjs/combineAllDiscard.d.ts +3 -0
  8. package/dist/cjs/combineAllDiscard.d.ts.map +1 -0
  9. package/dist/cjs/combineAllDiscard.js +26 -0
  10. package/dist/cjs/combineAllDiscard.js.map +1 -0
  11. package/dist/cjs/data-first.d.ts +2 -0
  12. package/dist/cjs/data-first.d.ts.map +1 -1
  13. package/dist/cjs/data-first.js +2 -0
  14. package/dist/cjs/data-first.js.map +1 -1
  15. package/dist/cjs/exhaustMap.d.ts.map +1 -1
  16. package/dist/cjs/exhaustMap.js +4 -3
  17. package/dist/cjs/exhaustMap.js.map +1 -1
  18. package/dist/cjs/exhaustMapCause.d.ts.map +1 -1
  19. package/dist/cjs/exhaustMapCause.js +4 -3
  20. package/dist/cjs/exhaustMapCause.js.map +1 -1
  21. package/dist/cjs/exhaustMapLatest.d.ts.map +1 -1
  22. package/dist/cjs/exhaustMapLatest.js +5 -4
  23. package/dist/cjs/exhaustMapLatest.js.map +1 -1
  24. package/dist/cjs/exhaustMapLatestCause.d.ts.map +1 -1
  25. package/dist/cjs/exhaustMapLatestCause.js +5 -4
  26. package/dist/cjs/exhaustMapLatestCause.js.map +1 -1
  27. package/dist/cjs/flatMap.d.ts.map +1 -1
  28. package/dist/cjs/flatMap.js +9 -8
  29. package/dist/cjs/flatMap.js.map +1 -1
  30. package/dist/cjs/index.d.ts +10 -0
  31. package/dist/cjs/index.d.ts.map +1 -1
  32. package/dist/cjs/index.js +7 -3
  33. package/dist/cjs/index.js.map +1 -1
  34. package/dist/cjs/mergeAll.d.ts +1 -0
  35. package/dist/cjs/mergeAll.d.ts.map +1 -1
  36. package/dist/cjs/mergeAll.js +7 -1
  37. package/dist/cjs/mergeAll.js.map +1 -1
  38. package/dist/cjs/scoped.d.ts +4 -0
  39. package/dist/cjs/scoped.d.ts.map +1 -0
  40. package/dist/cjs/scoped.js +10 -0
  41. package/dist/cjs/scoped.js.map +1 -0
  42. package/dist/cjs/snapshotEffect.d.ts.map +1 -1
  43. package/dist/cjs/snapshotEffect.js +4 -3
  44. package/dist/cjs/snapshotEffect.js.map +1 -1
  45. package/dist/cjs/switchMap.d.ts.map +1 -1
  46. package/dist/cjs/switchMap.js +12 -8
  47. package/dist/cjs/switchMap.js.map +1 -1
  48. package/dist/cjs/switchMapCause.d.ts.map +1 -1
  49. package/dist/cjs/switchMapCause.js +4 -3
  50. package/dist/cjs/switchMapCause.js.map +1 -1
  51. package/dist/cjs/switchMatch.d.ts.map +1 -1
  52. package/dist/cjs/switchMatch.js +4 -3
  53. package/dist/cjs/switchMatch.js.map +1 -1
  54. package/dist/cjs/throttle.d.ts +1 -1
  55. package/dist/cjs/throttle.d.ts.map +1 -1
  56. package/dist/cjs/throttle.js +4 -4
  57. package/dist/cjs/throttle.js.map +1 -1
  58. package/dist/combineAllDiscard.d.ts +3 -0
  59. package/dist/combineAllDiscard.d.ts.map +1 -0
  60. package/dist/combineAllDiscard.js +22 -0
  61. package/dist/combineAllDiscard.js.map +1 -0
  62. package/dist/data-first.d.ts +2 -0
  63. package/dist/data-first.d.ts.map +1 -1
  64. package/dist/data-first.js +2 -0
  65. package/dist/data-first.js.map +1 -1
  66. package/dist/exhaustMap.d.ts.map +1 -1
  67. package/dist/exhaustMap.js +5 -4
  68. package/dist/exhaustMap.js.map +1 -1
  69. package/dist/exhaustMapCause.d.ts.map +1 -1
  70. package/dist/exhaustMapCause.js +5 -4
  71. package/dist/exhaustMapCause.js.map +1 -1
  72. package/dist/exhaustMapLatest.d.ts.map +1 -1
  73. package/dist/exhaustMapLatest.js +6 -5
  74. package/dist/exhaustMapLatest.js.map +1 -1
  75. package/dist/exhaustMapLatestCause.d.ts.map +1 -1
  76. package/dist/exhaustMapLatestCause.js +6 -5
  77. package/dist/exhaustMapLatestCause.js.map +1 -1
  78. package/dist/flatMap.d.ts.map +1 -1
  79. package/dist/flatMap.js +10 -9
  80. package/dist/flatMap.js.map +1 -1
  81. package/dist/index.d.ts +10 -0
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +4 -0
  84. package/dist/index.js.map +1 -1
  85. package/dist/mergeAll.d.ts +1 -0
  86. package/dist/mergeAll.d.ts.map +1 -1
  87. package/dist/mergeAll.js +6 -1
  88. package/dist/mergeAll.js.map +1 -1
  89. package/dist/scoped.d.ts +4 -0
  90. package/dist/scoped.d.ts.map +1 -0
  91. package/dist/scoped.js +6 -0
  92. package/dist/scoped.js.map +1 -0
  93. package/dist/snapshotEffect.d.ts.map +1 -1
  94. package/dist/snapshotEffect.js +5 -4
  95. package/dist/snapshotEffect.js.map +1 -1
  96. package/dist/switchMap.d.ts.map +1 -1
  97. package/dist/switchMap.js +13 -9
  98. package/dist/switchMap.js.map +1 -1
  99. package/dist/switchMapCause.d.ts.map +1 -1
  100. package/dist/switchMapCause.js +5 -4
  101. package/dist/switchMapCause.js.map +1 -1
  102. package/dist/switchMatch.d.ts.map +1 -1
  103. package/dist/switchMatch.js +5 -4
  104. package/dist/switchMatch.js.map +1 -1
  105. package/dist/throttle.d.ts +1 -1
  106. package/dist/throttle.d.ts.map +1 -1
  107. package/dist/throttle.js +5 -5
  108. package/dist/throttle.js.map +1 -1
  109. package/dist/tsconfig.cjs.build.tsbuildinfo +1 -1
  110. package/package.json +2 -2
  111. package/src/catchAllCause.ts +38 -43
  112. package/src/combineAllDiscard.ts +42 -0
  113. package/src/data-first.ts +2 -0
  114. package/src/exhaustMap.ts +32 -35
  115. package/src/exhaustMapCause.ts +32 -35
  116. package/src/exhaustMapLatest.ts +64 -68
  117. package/src/exhaustMapLatestCause.ts +64 -68
  118. package/src/flatMap.ts +38 -43
  119. package/src/index.ts +22 -0
  120. package/src/mergeAll.ts +10 -1
  121. package/src/scoped.ts +6 -0
  122. package/src/snapshotEffect.ts +23 -23
  123. package/src/switchMap.ts +27 -31
  124. package/src/switchMapCause.ts +29 -29
  125. package/src/switchMatch.ts +34 -35
  126. package/src/throttle.ts +32 -33
  127. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,7 +1,7 @@
1
1
  import { pipe } from '@effect/data/Function'
2
2
 
3
3
  import { Fx, Sink } from './Fx.js'
4
- import { Cause, Effect, Either, Fiber, Ref } from './externals.js'
4
+ import { Cause, Effect, Either, Fiber, Ref, Runtime } from './externals.js'
5
5
  import { failCause } from './failCause.js'
6
6
  import { fromEffect } from './fromEffect.js'
7
7
 
@@ -9,55 +9,50 @@ export function catchAllCause<R, E, A, R2, E2, B>(
9
9
  fx: Fx<R, E, A>,
10
10
  f: (cause: Cause.Cause<E>) => Fx<R2, E2, B>,
11
11
  ): Fx<R | R2, E2, A | B> {
12
- return Fx((sink) =>
13
- Effect.scoped(
14
- Effect.gen(function* ($) {
15
- const ref = yield* $(Ref.make<Set<Fiber.RuntimeFiber<never, void>>>(new Set()))
12
+ return Fx(<R3>(sink: Sink<R3, E2, A | B>) =>
13
+ Effect.gen(function* ($) {
14
+ const runFork = Runtime.runFork(yield* $(Effect.runtime<R | R2 | R3>()))
15
+ const ref = yield* $(Ref.make<Set<Fiber.RuntimeFiber<never, void>>>(new Set()))
16
16
 
17
- yield* $(
18
- fx.run(
19
- Sink(sink.event, (cause: Cause.Cause<E>) =>
20
- Effect.gen(function* ($) {
21
- const fiber = yield* $(
22
- Effect.forkScoped(
23
- f(cause).run(
24
- Sink(sink.event, (cause) =>
25
- Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
26
- ),
27
- ),
17
+ yield* $(
18
+ fx.run(
19
+ Sink(sink.event, (cause: Cause.Cause<E>) =>
20
+ Effect.gen(function* ($) {
21
+ const fiber = runFork(
22
+ f(cause).run(
23
+ Sink(sink.event, (cause) =>
24
+ Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
28
25
  ),
29
- )
26
+ ),
27
+ )
30
28
 
31
- // Add Fiber to fibers
32
- yield* $(Ref.update(ref, (fs) => fs.add(fiber)))
29
+ // Add Fiber to fibers
30
+ yield* $(Ref.update(ref, (fs) => fs.add(fiber)))
33
31
 
34
- // When the fiber ends, we need to remove it from the list of fibers
35
- yield* $(
36
- pipe(
37
- Fiber.join(fiber),
38
- Effect.flatMap(() =>
39
- Ref.update(ref, (fs) => {
40
- fs.delete(fiber)
41
- return fs
42
- }),
43
- ),
44
- // but don't allow this to be blocking
45
- Effect.forkScoped,
46
- ),
47
- )
48
- }),
49
- ),
32
+ // When the fiber ends, we need to remove it from the list of fibers
33
+ pipe(
34
+ Fiber.join(fiber),
35
+ Effect.ensuring(
36
+ Ref.update(ref, (fs) => {
37
+ fs.delete(fiber)
38
+ return fs
39
+ }),
40
+ ),
41
+ // but don't allow this to be blocking
42
+ runFork,
43
+ )
44
+ }),
50
45
  ),
51
- )
46
+ ),
47
+ )
52
48
 
53
- // Wait for the last fibers to finish
54
- const fibers = yield* $(Ref.get(ref))
49
+ // Wait for the last fibers to finish
50
+ const fibers = yield* $(Ref.get(ref))
55
51
 
56
- if (fibers.size > 0) {
57
- yield* $(Fiber.joinAll(fibers))
58
- }
59
- }),
60
- ),
52
+ if (fibers.size > 0) {
53
+ yield* $(Fiber.joinAll(fibers))
54
+ }
55
+ }),
61
56
  )
62
57
  }
63
58
 
@@ -0,0 +1,42 @@
1
+ import { Fx, Sink } from './Fx.js'
2
+ import { Effect } from './externals.js'
3
+ import { map } from './map.js'
4
+ import { succeed } from './succeed.js'
5
+
6
+ export function combineAllDiscard<FX extends ReadonlyArray<Fx<any, any, any>>>(
7
+ ...fx: FX
8
+ ): Fx<Fx.ResourcesOf<FX[number]>, Fx.ErrorsOf<FX[number]>, void> {
9
+ if (fx.length === 0) {
10
+ return succeed([]) as any
11
+ }
12
+
13
+ if (fx.length === 1) {
14
+ return map(fx[0], (x) => [x]) as any
15
+ }
16
+
17
+ return Fx((sink) =>
18
+ Effect.gen(function* ($) {
19
+ const length = fx.length
20
+ const values = new Map<number, any>()
21
+
22
+ const emitIfReady = Effect.suspend(() =>
23
+ values.size === length ? sink.event() : Effect.unit(),
24
+ )
25
+
26
+ yield* $(
27
+ Effect.forEachParWithIndex(fx, (f, i) =>
28
+ f.run(
29
+ Sink(
30
+ () =>
31
+ Effect.suspend(() => {
32
+ values.set(i, null)
33
+ return emitIfReady
34
+ }),
35
+ sink.error,
36
+ ),
37
+ ),
38
+ ),
39
+ )
40
+ }),
41
+ )
42
+ }
package/src/data-first.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './at.js'
2
2
  export * from './catchAllCause.js'
3
3
  export * from './combineAll.js'
4
+ export * from './combineAllDiscard.js'
4
5
  export * from './continueWith.js'
5
6
  export * from './debounce.js'
6
7
  export * from './delay.js'
@@ -32,6 +33,7 @@ export * from './provide.js'
32
33
  export * from './reduce.js'
33
34
  export * from './RefSubject.js'
34
35
  export * from './scan.js'
36
+ export * from './scoped.js'
35
37
  export * from './skipRepeats.js'
36
38
  export * from './skipWhile.js'
37
39
  export * from './slice.js'
package/src/exhaustMap.ts CHANGED
@@ -1,55 +1,52 @@
1
1
  import { pipe } from '@effect/data/Function'
2
2
 
3
3
  import { Fx, Sink } from './Fx.js'
4
- import { Cause, Effect, Fiber, Ref } from './externals.js'
4
+ import { Cause, Effect, Fiber, Ref, Runtime } from './externals.js'
5
5
  import { fromEffect } from './fromEffect.js'
6
6
 
7
7
  export function exhaustMap<R, E, A, R2, E2, B>(
8
8
  fx: Fx<R, E, A>,
9
9
  f: (a: A) => Fx<R2, E2, B>,
10
10
  ): Fx<R | R2, E | E2, B> {
11
- return Fx((sink) =>
12
- Effect.scoped(
13
- Effect.gen(function* ($) {
14
- const ref = yield* $(Ref.make<Fiber.RuntimeFiber<never, void> | void>(void 0))
15
- const reset = Ref.set(ref, void 0)
11
+ return Fx(<R3>(sink: Sink<R3, E | E2, B>) =>
12
+ Effect.gen(function* ($) {
13
+ const runFork = Runtime.runFork(yield* $(Effect.runtime<R | R2 | R3>()))
14
+ const ref = yield* $(Ref.make<Fiber.RuntimeFiber<never, void> | void>(void 0))
15
+ const reset = Ref.set(ref, void 0)
16
16
 
17
- const exhaustMapEvent = (a: A) =>
18
- Effect.gen(function* ($) {
19
- const currentFiber = yield* $(Ref.get(ref))
17
+ const exhaustMapEvent = (a: A) =>
18
+ Effect.gen(function* ($) {
19
+ const currentFiber = yield* $(Ref.get(ref))
20
20
 
21
- if (currentFiber) {
22
- return
23
- }
21
+ if (currentFiber) {
22
+ return
23
+ }
24
24
 
25
- const fiber = yield* $(
26
- pipe(
27
- f(a).run(
28
- Sink(sink.event, (cause) =>
29
- Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
30
- ),
31
- ),
32
- Effect.zipLeft(reset),
33
- Effect.catchAllCause((cause) =>
34
- Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
35
- ),
36
- Effect.forkScoped,
25
+ const fiber = pipe(
26
+ f(a).run(
27
+ Sink(sink.event, (cause) =>
28
+ Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
37
29
  ),
38
- )
30
+ ),
31
+ Effect.zipLeft(reset),
32
+ Effect.catchAllCause((cause) =>
33
+ Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
34
+ ),
35
+ runFork,
36
+ )
39
37
 
40
- yield* $(Ref.set(ref, fiber))
41
- })
38
+ yield* $(Ref.set(ref, fiber))
39
+ })
42
40
 
43
- yield* $(fx.run(Sink(exhaustMapEvent, sink.error)))
41
+ yield* $(fx.run(Sink(exhaustMapEvent, sink.error)))
44
42
 
45
- // Wait for the last fiber to finish
46
- const fiber = yield* $(Ref.get(ref))
43
+ // Wait for the last fiber to finish
44
+ const fiber = yield* $(Ref.get(ref))
47
45
 
48
- if (fiber) {
49
- yield* $(Fiber.join(fiber))
50
- }
51
- }),
52
- ),
46
+ if (fiber) {
47
+ yield* $(Fiber.join(fiber))
48
+ }
49
+ }),
53
50
  )
54
51
  }
55
52
 
@@ -1,7 +1,7 @@
1
1
  import { pipe } from '@effect/data/Function'
2
2
 
3
3
  import { Fx, Sink } from './Fx.js'
4
- import { Cause, Effect, Either, Fiber, Ref } from './externals.js'
4
+ import { Cause, Effect, Either, Fiber, Ref, Runtime } from './externals.js'
5
5
  import { failCause } from './failCause.js'
6
6
  import { fromEffect } from './fromEffect.js'
7
7
 
@@ -9,48 +9,45 @@ export function exhaustMapCause<R, E, A, R2, E2, B>(
9
9
  fx: Fx<R, E, A>,
10
10
  f: (cause: Cause.Cause<E>) => Fx<R2, E2, B>,
11
11
  ): Fx<R | R2, E2, A | B> {
12
- return Fx((sink) =>
13
- Effect.scoped(
14
- Effect.gen(function* ($) {
15
- const ref = yield* $(Ref.make<Fiber.RuntimeFiber<never, void> | void>(void 0))
16
- const reset = Ref.set(ref, void 0)
12
+ return Fx(<R3>(sink: Sink<R3, E2, A | B>) =>
13
+ Effect.gen(function* ($) {
14
+ const runFork = Runtime.runFork(yield* $(Effect.runtime<R | R2 | R3>()))
15
+ const ref = yield* $(Ref.make<Fiber.RuntimeFiber<never, void> | void>(void 0))
16
+ const reset = Ref.set(ref, void 0)
17
17
 
18
- const exhaustMapError = (cause: Cause.Cause<E>) =>
19
- Effect.gen(function* ($) {
20
- const currentFiber = yield* $(Ref.get(ref))
18
+ const exhaustMapError = (cause: Cause.Cause<E>) =>
19
+ Effect.gen(function* ($) {
20
+ const currentFiber = yield* $(Ref.get(ref))
21
21
 
22
- if (currentFiber) {
23
- return
24
- }
22
+ if (currentFiber) {
23
+ return
24
+ }
25
25
 
26
- const fiber = yield* $(
27
- pipe(
28
- f(cause).run(
29
- Sink(sink.event, (cause) =>
30
- Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
31
- ),
32
- ),
33
- Effect.zipLeft(reset),
34
- Effect.catchAllCause((cause) =>
35
- Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
36
- ),
37
- Effect.forkScoped,
26
+ const fiber = pipe(
27
+ f(cause).run(
28
+ Sink(sink.event, (cause) =>
29
+ Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
38
30
  ),
39
- )
31
+ ),
32
+ Effect.zipLeft(reset),
33
+ Effect.catchAllCause((cause) =>
34
+ Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
35
+ ),
36
+ runFork,
37
+ )
40
38
 
41
- yield* $(Ref.set(ref, fiber))
42
- })
39
+ yield* $(Ref.set(ref, fiber))
40
+ })
43
41
 
44
- yield* $(fx.run(Sink(sink.event, exhaustMapError)))
42
+ yield* $(fx.run(Sink(sink.event, exhaustMapError)))
45
43
 
46
- // Wait for the last fiber to finish
47
- const fiber = yield* $(Ref.get(ref))
44
+ // Wait for the last fiber to finish
45
+ const fiber = yield* $(Ref.get(ref))
48
46
 
49
- if (fiber) {
50
- yield* $(Fiber.join(fiber))
51
- }
52
- }),
53
- ),
47
+ if (fiber) {
48
+ yield* $(Fiber.join(fiber))
49
+ }
50
+ }),
54
51
  )
55
52
  }
56
53
 
@@ -1,9 +1,8 @@
1
1
  import { pipe } from '@effect/data/Function'
2
2
  import * as Option from '@effect/data/Option'
3
- import type { Scope } from '@effect/io/Scope'
4
3
 
5
4
  import { Fx, Sink } from './Fx.js'
6
- import { Cause, Effect, Fiber, Ref } from './externals.js'
5
+ import { Cause, Effect, Fiber, Ref, Runtime } from './externals.js'
7
6
  import { fromEffect } from './fromEffect.js'
8
7
 
9
8
  export function exhaustMapLatest<R, E, A, R2, E2, B>(
@@ -11,77 +10,74 @@ export function exhaustMapLatest<R, E, A, R2, E2, B>(
11
10
  f: (a: A) => Fx<R2, E2, B>,
12
11
  ): Fx<R | R2, E | E2, B> {
13
12
  return Fx(<R3>(sink: Sink<R3, E | E2, B>) =>
14
- Effect.scoped(
15
- Effect.gen(function* ($) {
16
- const ref = yield* $(Ref.make<Fiber.RuntimeFiber<never, void> | void>(void 0))
17
- const nextValue = yield* $(Ref.make<Option.Option<A>>(Option.none()))
18
- const reset = Ref.set(ref, void 0)
19
-
20
- // Wait for the current fiber to finish
21
- const awaitNext = Effect.gen(function* ($) {
22
- // Wait for the last fiber to finish
23
- const fiber = yield* $(Ref.get(ref))
24
-
25
- if (fiber) {
26
- // Wait for the fiber to end to check to see if we need to run another
27
- yield* $(Fiber.join(fiber))
28
- }
29
- })
30
-
31
- // Run the next value that's be saved for replay if it exists
32
- const runNext: Effect.Effect<R2 | R3 | Scope, never, void> = Effect.gen(function* ($) {
33
- const next = yield* $(Ref.get(nextValue))
34
-
35
- if (Option.isSome(next)) {
36
- // Clear the next A to be replayed
37
- yield* $(Ref.set(nextValue, Option.none()))
38
-
39
- // Replay the next A
40
- yield* $(exhaustMapLatestEvent(next.value))
41
-
42
- // Ensure we don't close the scope until the last fiber completes
43
- yield* $(awaitNext)
13
+ Effect.gen(function* ($) {
14
+ const runFork = Runtime.runFork(yield* $(Effect.runtime<R | R2 | R3>()))
15
+ const ref = yield* $(Ref.make<Fiber.RuntimeFiber<never, void> | void>(void 0))
16
+ const nextValue = yield* $(Ref.make<Option.Option<A>>(Option.none()))
17
+ const reset = Ref.set(ref, void 0)
18
+
19
+ // Wait for the current fiber to finish
20
+ const awaitNext = Effect.gen(function* ($) {
21
+ // Wait for the last fiber to finish
22
+ const fiber = yield* $(Ref.get(ref))
23
+
24
+ if (fiber) {
25
+ // Wait for the fiber to end to check to see if we need to run another
26
+ yield* $(Fiber.join(fiber))
27
+ }
28
+ })
29
+
30
+ // Run the next value that's be saved for replay if it exists
31
+ const runNext: Effect.Effect<R2 | R3, never, void> = Effect.gen(function* ($) {
32
+ const next = yield* $(Ref.get(nextValue))
33
+
34
+ if (Option.isSome(next)) {
35
+ // Clear the next A to be replayed
36
+ yield* $(Ref.set(nextValue, Option.none()))
37
+
38
+ // Replay the next A
39
+ yield* $(exhaustMapLatestEvent(next.value))
40
+
41
+ // Ensure we don't close the scope until the last fiber completes
42
+ yield* $(awaitNext)
43
+ }
44
+ })
45
+
46
+ const exhaustMapLatestEvent = (a: A) =>
47
+ Effect.gen(function* ($) {
48
+ const currentFiber = yield* $(Ref.get(ref))
49
+
50
+ // Always allow the current fiber to continue
51
+ if (currentFiber) {
52
+ // Track the latest A to be replayed layer
53
+ return yield* $(Ref.set(nextValue, Option.some(a)))
44
54
  }
45
- })
46
55
 
47
- const exhaustMapLatestEvent = (a: A) =>
48
- Effect.gen(function* ($) {
49
- const currentFiber = yield* $(Ref.get(ref))
50
-
51
- // Always allow the current fiber to continue
52
- if (currentFiber) {
53
- // Track the latest A to be replayed layer
54
- return yield* $(Ref.set(nextValue, Option.some(a)))
55
- }
56
-
57
- // Run our Fx with the current value
58
- const fiber = yield* $(
59
- pipe(
60
- f(a).run(
61
- Sink(sink.event, (cause) =>
62
- Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
63
- ),
64
- ),
65
- // Clear the current fiber when finished
66
- Effect.zipRight(reset),
67
- // See if there's another value to replay
68
- Effect.zipRight(runNext),
69
- Effect.catchAllCause((cause) =>
70
- Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
71
- ),
72
- Effect.forkScoped,
56
+ // Run our Fx with the current value
57
+ const fiber = pipe(
58
+ f(a).run(
59
+ Sink(sink.event, (cause) =>
60
+ Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
73
61
  ),
74
- )
75
-
76
- yield* $(Ref.set(ref, fiber))
77
- })
62
+ ),
63
+ // Clear the current fiber when finished
64
+ Effect.zipRight(reset),
65
+ // See if there's another value to replay
66
+ Effect.zipRight(runNext),
67
+ Effect.catchAllCause((cause) =>
68
+ Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
69
+ ),
70
+ runFork,
71
+ )
72
+
73
+ yield* $(Ref.set(ref, fiber))
74
+ })
78
75
 
79
- yield* $(fx.run(Sink(exhaustMapLatestEvent, sink.error)))
76
+ yield* $(fx.run(Sink(exhaustMapLatestEvent, sink.error)))
80
77
 
81
- // Wait for the last fiber to finish
82
- yield* $(awaitNext)
83
- }),
84
- ),
78
+ // Wait for the last fiber to finish
79
+ yield* $(awaitNext)
80
+ }),
85
81
  )
86
82
  }
87
83
 
@@ -1,9 +1,8 @@
1
1
  import { pipe } from '@effect/data/Function'
2
2
  import * as Option from '@effect/data/Option'
3
- import type { Scope } from '@effect/io/Scope'
4
3
 
5
4
  import { Fx, Sink } from './Fx.js'
6
- import { Cause, Effect, Either, Fiber, Ref } from './externals.js'
5
+ import { Cause, Effect, Either, Fiber, Ref, Runtime } from './externals.js'
7
6
  import { failCause } from './failCause.js'
8
7
  import { fromEffect } from './fromEffect.js'
9
8
 
@@ -12,77 +11,74 @@ export function exhaustMapLatestCause<R, E, A, R2, E2, B>(
12
11
  f: (cause: Cause.Cause<E>) => Fx<R2, E2, B>,
13
12
  ): Fx<R | R2, E2, A | B> {
14
13
  return Fx(<R3>(sink: Sink<R3, E2, A | B>) =>
15
- Effect.scoped(
16
- Effect.gen(function* ($) {
17
- const ref = yield* $(Ref.make<Fiber.RuntimeFiber<never, void> | void>(void 0))
18
- const nextValue = yield* $(Ref.make<Option.Option<Cause.Cause<E>>>(Option.none()))
19
- const reset = Ref.set(ref, void 0)
20
-
21
- // Wait for the current fiber to finish
22
- const awaitNext = Effect.gen(function* ($) {
23
- // Wait for the last fiber to finish
24
- const fiber = yield* $(Ref.get(ref))
25
-
26
- if (fiber) {
27
- // Wait for the fiber to end to check to see if we need to run another
28
- yield* $(Fiber.join(fiber))
29
- }
30
- })
31
-
32
- // Run the next value that's be saved for replay if it exists
33
- const runNext: Effect.Effect<R2 | R3 | Scope, never, void> = Effect.gen(function* ($) {
34
- const next = yield* $(Ref.get(nextValue))
35
-
36
- if (Option.isSome(next)) {
37
- // Clear the next A to be replayed
38
- yield* $(Ref.set(nextValue, Option.none()))
39
-
40
- // Replay the next A
41
- yield* $(exhaustMapLatestError(next.value))
42
-
43
- // Ensure we don't close the scope until the last fiber completes
44
- yield* $(awaitNext)
14
+ Effect.gen(function* ($) {
15
+ const runFork = Runtime.runFork(yield* $(Effect.runtime<R | R2 | R3>()))
16
+ const ref = yield* $(Ref.make<Fiber.RuntimeFiber<never, void> | void>(void 0))
17
+ const nextValue = yield* $(Ref.make<Option.Option<Cause.Cause<E>>>(Option.none()))
18
+ const reset = Ref.set(ref, void 0)
19
+
20
+ // Wait for the current fiber to finish
21
+ const awaitNext = Effect.gen(function* ($) {
22
+ // Wait for the last fiber to finish
23
+ const fiber = yield* $(Ref.get(ref))
24
+
25
+ if (fiber) {
26
+ // Wait for the fiber to end to check to see if we need to run another
27
+ yield* $(Fiber.join(fiber))
28
+ }
29
+ })
30
+
31
+ // Run the next value that's be saved for replay if it exists
32
+ const runNext: Effect.Effect<R2 | R3, never, void> = Effect.gen(function* ($) {
33
+ const next = yield* $(Ref.get(nextValue))
34
+
35
+ if (Option.isSome(next)) {
36
+ // Clear the next A to be replayed
37
+ yield* $(Ref.set(nextValue, Option.none()))
38
+
39
+ // Replay the next A
40
+ yield* $(exhaustMapLatestError(next.value))
41
+
42
+ // Ensure we don't close the scope until the last fiber completes
43
+ yield* $(awaitNext)
44
+ }
45
+ })
46
+
47
+ const exhaustMapLatestError = (cause: Cause.Cause<E>) =>
48
+ Effect.gen(function* ($) {
49
+ const currentFiber = yield* $(Ref.get(ref))
50
+
51
+ // Always allow the current fiber to continue
52
+ if (currentFiber) {
53
+ // Track the latest A to be replayed layer
54
+ return yield* $(Ref.set(nextValue, Option.some(cause)))
45
55
  }
46
- })
47
56
 
48
- const exhaustMapLatestError = (cause: Cause.Cause<E>) =>
49
- Effect.gen(function* ($) {
50
- const currentFiber = yield* $(Ref.get(ref))
51
-
52
- // Always allow the current fiber to continue
53
- if (currentFiber) {
54
- // Track the latest A to be replayed layer
55
- return yield* $(Ref.set(nextValue, Option.some(cause)))
56
- }
57
-
58
- // Run our Fx with the current value
59
- const fiber = yield* $(
60
- pipe(
61
- f(cause).run(
62
- Sink(sink.event, (cause) =>
63
- Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
64
- ),
65
- ),
66
- // Clear the current fiber when finished
67
- Effect.zipRight(reset),
68
- // See if there's another value to replay
69
- Effect.zipRight(runNext),
70
- Effect.catchAllCause((cause) =>
71
- Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
72
- ),
73
- Effect.forkScoped,
57
+ // Run our Fx with the current value
58
+ const fiber = pipe(
59
+ f(cause).run(
60
+ Sink(sink.event, (cause) =>
61
+ Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
74
62
  ),
75
- )
76
-
77
- yield* $(Ref.set(ref, fiber))
78
- })
63
+ ),
64
+ // Clear the current fiber when finished
65
+ Effect.zipRight(reset),
66
+ // See if there's another value to replay
67
+ Effect.zipRight(runNext),
68
+ Effect.catchAllCause((cause) =>
69
+ Cause.isInterruptedOnly(cause) ? Effect.unit() : sink.error(cause),
70
+ ),
71
+ runFork,
72
+ )
73
+
74
+ yield* $(Ref.set(ref, fiber))
75
+ })
79
76
 
80
- yield* $(fx.run(Sink(sink.event, exhaustMapLatestError)))
77
+ yield* $(fx.run(Sink(sink.event, exhaustMapLatestError)))
81
78
 
82
- // Wait for the last fiber to finish
83
- yield* $(awaitNext)
84
- }),
85
- ),
79
+ // Wait for the last fiber to finish
80
+ yield* $(awaitNext)
81
+ }),
86
82
  )
87
83
  }
88
84