@typed/fx 1.27.4 → 1.28.0

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 (191) hide show
  1. package/dist/cjs/AsyncData.js +1 -1
  2. package/dist/cjs/AsyncData.js.map +1 -1
  3. package/dist/cjs/Emitter.js +3 -3
  4. package/dist/cjs/Emitter.js.map +1 -1
  5. package/dist/cjs/Form.js +15 -15
  6. package/dist/cjs/Form.js.map +1 -1
  7. package/dist/cjs/FormEntry.js +3 -3
  8. package/dist/cjs/FormEntry.js.map +1 -1
  9. package/dist/cjs/Fx.js +11 -9
  10. package/dist/cjs/Fx.js.map +1 -1
  11. package/dist/cjs/Idle.js +8 -8
  12. package/dist/cjs/Idle.js.map +1 -1
  13. package/dist/cjs/Match.js +17 -17
  14. package/dist/cjs/Match.js.map +1 -1
  15. package/dist/cjs/Pull.js +3 -3
  16. package/dist/cjs/Pull.js.map +1 -1
  17. package/dist/cjs/Push.js +1 -1
  18. package/dist/cjs/Push.js.map +1 -1
  19. package/dist/cjs/RefArray.js +2 -2
  20. package/dist/cjs/RefArray.js.map +1 -1
  21. package/dist/cjs/RefChunk.js +1 -1
  22. package/dist/cjs/RefChunk.js.map +1 -1
  23. package/dist/cjs/RefHashMap.js +1 -1
  24. package/dist/cjs/RefHashMap.js.map +1 -1
  25. package/dist/cjs/RefHashSet.js +1 -1
  26. package/dist/cjs/RefHashSet.js.map +1 -1
  27. package/dist/cjs/RefSubject.js +150 -75
  28. package/dist/cjs/RefSubject.js.map +1 -1
  29. package/dist/cjs/Sink.js +14 -14
  30. package/dist/cjs/Sink.js.map +1 -1
  31. package/dist/cjs/Stream.js +1 -1
  32. package/dist/cjs/Stream.js.map +1 -1
  33. package/dist/cjs/Subject.js +9 -11
  34. package/dist/cjs/Subject.js.map +1 -1
  35. package/dist/cjs/Typeclass.js +1 -1
  36. package/dist/cjs/Typeclass.js.map +1 -1
  37. package/dist/cjs/Versioned.js +4 -4
  38. package/dist/cjs/Versioned.js.map +1 -1
  39. package/dist/cjs/index.js +1 -1
  40. package/dist/cjs/index.js.map +1 -1
  41. package/dist/cjs/internal/DeferredRef.js +14 -11
  42. package/dist/cjs/internal/DeferredRef.js.map +1 -1
  43. package/dist/cjs/internal/core.js +71 -42
  44. package/dist/cjs/internal/core.js.map +1 -1
  45. package/dist/cjs/internal/diff.js +1 -1
  46. package/dist/cjs/internal/diff.js.map +1 -1
  47. package/dist/cjs/internal/effect-loop-operator.js +1 -1
  48. package/dist/cjs/internal/effect-loop-operator.js.map +1 -1
  49. package/dist/cjs/internal/effect-operator.js +3 -3
  50. package/dist/cjs/internal/effect-operator.js.map +1 -1
  51. package/dist/cjs/internal/effect-producer.js +3 -3
  52. package/dist/cjs/internal/effect-producer.js.map +1 -1
  53. package/dist/cjs/internal/helpers.js +63 -42
  54. package/dist/cjs/internal/helpers.js.map +1 -1
  55. package/dist/cjs/internal/keyed.js +34 -26
  56. package/dist/cjs/internal/keyed.js.map +1 -1
  57. package/dist/cjs/internal/loop-operator.js +1 -1
  58. package/dist/cjs/internal/loop-operator.js.map +1 -1
  59. package/dist/cjs/internal/operator.js +1 -1
  60. package/dist/cjs/internal/operator.js.map +1 -1
  61. package/dist/cjs/internal/protos.js +1 -1
  62. package/dist/cjs/internal/protos.js.map +1 -1
  63. package/dist/cjs/internal/provide.js +1 -1
  64. package/dist/cjs/internal/provide.js.map +1 -1
  65. package/dist/cjs/internal/share.js +8 -13
  66. package/dist/cjs/internal/share.js.map +1 -1
  67. package/dist/cjs/internal/sync-operator.js +4 -4
  68. package/dist/cjs/internal/sync-operator.js.map +1 -1
  69. package/dist/cjs/internal/sync-producer.js +27 -23
  70. package/dist/cjs/internal/sync-producer.js.map +1 -1
  71. package/dist/cjs/internal/withKey.js +7 -7
  72. package/dist/cjs/internal/withKey.js.map +1 -1
  73. package/dist/dts/AsyncData.d.ts +2 -2
  74. package/dist/dts/AsyncData.d.ts.map +1 -1
  75. package/dist/dts/Emitter.d.ts +1 -1
  76. package/dist/dts/Emitter.d.ts.map +1 -1
  77. package/dist/dts/Fx.d.ts +39 -13
  78. package/dist/dts/Fx.d.ts.map +1 -1
  79. package/dist/dts/Idle.d.ts.map +1 -1
  80. package/dist/dts/Match.d.ts +1 -1
  81. package/dist/dts/Match.d.ts.map +1 -1
  82. package/dist/dts/Push.d.ts +4 -1
  83. package/dist/dts/Push.d.ts.map +1 -1
  84. package/dist/dts/RefArray.d.ts +1 -2
  85. package/dist/dts/RefArray.d.ts.map +1 -1
  86. package/dist/dts/RefChunk.d.ts.map +1 -1
  87. package/dist/dts/RefHashMap.d.ts +1 -1
  88. package/dist/dts/RefHashMap.d.ts.map +1 -1
  89. package/dist/dts/RefHashSet.d.ts.map +1 -1
  90. package/dist/dts/RefSubject.d.ts +64 -3
  91. package/dist/dts/RefSubject.d.ts.map +1 -1
  92. package/dist/dts/Sink.d.ts +2 -1
  93. package/dist/dts/Sink.d.ts.map +1 -1
  94. package/dist/dts/Subject.d.ts +2 -1
  95. package/dist/dts/Subject.d.ts.map +1 -1
  96. package/dist/dts/Versioned.d.ts +3 -1
  97. package/dist/dts/Versioned.d.ts.map +1 -1
  98. package/dist/dts/internal/DeferredRef.d.ts +6 -4
  99. package/dist/dts/internal/DeferredRef.d.ts.map +1 -1
  100. package/dist/dts/internal/core.d.ts +25 -12
  101. package/dist/dts/internal/core.d.ts.map +1 -1
  102. package/dist/dts/internal/diff.d.ts +1 -1
  103. package/dist/dts/internal/diff.d.ts.map +1 -1
  104. package/dist/dts/internal/effect-operator.d.ts.map +1 -1
  105. package/dist/dts/internal/helpers.d.ts +8 -6
  106. package/dist/dts/internal/helpers.d.ts.map +1 -1
  107. package/dist/dts/internal/keyed.d.ts +2 -2
  108. package/dist/dts/internal/keyed.d.ts.map +1 -1
  109. package/dist/dts/internal/loop-operator.d.ts +1 -1
  110. package/dist/dts/internal/loop-operator.d.ts.map +1 -1
  111. package/dist/dts/internal/protos.d.ts +1 -1
  112. package/dist/dts/internal/protos.d.ts.map +1 -1
  113. package/dist/dts/internal/provide.d.ts.map +1 -1
  114. package/dist/dts/internal/share.d.ts +1 -1
  115. package/dist/dts/internal/share.d.ts.map +1 -1
  116. package/dist/dts/internal/strategies.d.ts.map +1 -1
  117. package/dist/dts/internal/sync-operator.d.ts.map +1 -1
  118. package/dist/dts/internal/sync-producer.d.ts +4 -4
  119. package/dist/dts/internal/sync-producer.d.ts.map +1 -1
  120. package/dist/esm/Emitter.js +1 -1
  121. package/dist/esm/Emitter.js.map +1 -1
  122. package/dist/esm/Form.js +14 -14
  123. package/dist/esm/Form.js.map +1 -1
  124. package/dist/esm/FormEntry.js +2 -2
  125. package/dist/esm/FormEntry.js.map +1 -1
  126. package/dist/esm/Fx.js +16 -5
  127. package/dist/esm/Fx.js.map +1 -1
  128. package/dist/esm/Idle.js +7 -7
  129. package/dist/esm/Idle.js.map +1 -1
  130. package/dist/esm/Match.js +17 -17
  131. package/dist/esm/Match.js.map +1 -1
  132. package/dist/esm/Pull.js +2 -2
  133. package/dist/esm/Push.js.map +1 -1
  134. package/dist/esm/RefArray.js +1 -1
  135. package/dist/esm/RefArray.js.map +1 -1
  136. package/dist/esm/RefHashMap.js.map +1 -1
  137. package/dist/esm/RefSubject.js +140 -59
  138. package/dist/esm/RefSubject.js.map +1 -1
  139. package/dist/esm/Sink.js +13 -13
  140. package/dist/esm/Sink.js.map +1 -1
  141. package/dist/esm/Subject.js +8 -10
  142. package/dist/esm/Subject.js.map +1 -1
  143. package/dist/esm/Versioned.js +1 -1
  144. package/dist/esm/Versioned.js.map +1 -1
  145. package/dist/esm/internal/DeferredRef.js +13 -10
  146. package/dist/esm/internal/DeferredRef.js.map +1 -1
  147. package/dist/esm/internal/core.js +70 -37
  148. package/dist/esm/internal/core.js.map +1 -1
  149. package/dist/esm/internal/diff.js.map +1 -1
  150. package/dist/esm/internal/effect-operator.js +2 -2
  151. package/dist/esm/internal/effect-producer.js +1 -1
  152. package/dist/esm/internal/helpers.js +62 -39
  153. package/dist/esm/internal/helpers.js.map +1 -1
  154. package/dist/esm/internal/keyed.js +26 -17
  155. package/dist/esm/internal/keyed.js.map +1 -1
  156. package/dist/esm/internal/share.js +7 -12
  157. package/dist/esm/internal/share.js.map +1 -1
  158. package/dist/esm/internal/sync-operator.js +3 -3
  159. package/dist/esm/internal/sync-operator.js.map +1 -1
  160. package/dist/esm/internal/sync-producer.js +7 -5
  161. package/dist/esm/internal/sync-producer.js.map +1 -1
  162. package/dist/esm/internal/withKey.js +6 -6
  163. package/dist/esm/internal/withKey.js.map +1 -1
  164. package/package.json +8 -7
  165. package/src/Emitter.ts +2 -1
  166. package/src/Form.ts +22 -30
  167. package/src/FormEntry.ts +2 -2
  168. package/src/Fx.ts +54 -36
  169. package/src/Idle.ts +7 -7
  170. package/src/Match.ts +24 -26
  171. package/src/Pull.ts +2 -2
  172. package/src/Push.ts +4 -1
  173. package/src/RefArray.ts +1 -1
  174. package/src/RefHashMap.ts +1 -1
  175. package/src/RefSubject.ts +262 -98
  176. package/src/Sink.ts +15 -14
  177. package/src/Subject.ts +19 -14
  178. package/src/Versioned.ts +4 -2
  179. package/src/internal/DeferredRef.ts +21 -11
  180. package/src/internal/core.ts +92 -61
  181. package/src/internal/diff.ts +1 -1
  182. package/src/internal/effect-operator.ts +2 -2
  183. package/src/internal/effect-producer.ts +3 -3
  184. package/src/internal/helpers.ts +89 -42
  185. package/src/internal/keyed.ts +47 -42
  186. package/src/internal/loop-operator.ts +1 -1
  187. package/src/internal/protos.ts +1 -1
  188. package/src/internal/share.ts +11 -26
  189. package/src/internal/sync-operator.ts +3 -3
  190. package/src/internal/sync-producer.ts +7 -5
  191. package/src/internal/withKey.ts +6 -6
package/src/Sink.ts CHANGED
@@ -4,13 +4,14 @@
4
4
  */
5
5
 
6
6
  import * as C from "@typed/context"
7
- import type { Predicate, Tracer } from "effect"
8
7
  import * as Cause from "effect/Cause"
9
8
  import * as Clock from "effect/Clock"
10
9
  import * as Effect from "effect/Effect"
11
10
  import { dual } from "effect/Function"
12
11
  import * as Layer from "effect/Layer"
13
12
  import * as Option from "effect/Option"
13
+ import type * as Predicate from "effect/Predicate"
14
+ import type * as Tracer from "effect/Tracer"
14
15
  import { type Bounds } from "./internal/bounds.js"
15
16
 
16
17
  /**
@@ -98,10 +99,10 @@ export function withEarlyExit<A, E, R, B, R2>(
98
99
  return Effect.asyncEffect((resume: (effect: Effect.Effect<void>) => void) => {
99
100
  const earlyExit: WithEarlyExit<A, E, R> = {
100
101
  ...sink,
101
- earlyExit: Effect.sync(() => resume(Effect.unit))
102
+ earlyExit: Effect.sync(() => resume(Effect.void))
102
103
  }
103
104
 
104
- return Effect.asUnit(Effect.matchCauseEffect(f(earlyExit), {
105
+ return Effect.asVoid(Effect.matchCauseEffect(f(earlyExit), {
105
106
  onFailure: (cause) => sink.onFailure(cause),
106
107
  onSuccess: () => earlyExit.earlyExit
107
108
  }))
@@ -163,7 +164,7 @@ class FilterSink<A, E, R> implements Sink<A, E, R> {
163
164
 
164
165
  onSuccess(value: A) {
165
166
  if (this.predicate(value)) return this.sink.onSuccess(value)
166
- else return Effect.unit
167
+ else return Effect.void
167
168
  }
168
169
  }
169
170
 
@@ -190,7 +191,7 @@ class FilterMapSink<A, E, R, B> implements Sink<A, E, R> {
190
191
  onSuccess(value: A) {
191
192
  const option = this.f(value)
192
193
  if (Option.isSome(option)) return this.sink.onSuccess(option.value)
193
- else return Effect.unit
194
+ else return Effect.void
194
195
  }
195
196
  }
196
197
 
@@ -264,7 +265,7 @@ class FilterMapEffectSink<A, E, R, B, E2, R2> implements Sink<B, E2, R | R2> {
264
265
  onFailure: (cause) => this.sink.onFailure(cause),
265
266
  onSuccess: (option) => {
266
267
  if (Option.isSome(option)) return this.sink.onSuccess(option.value)
267
- else return Effect.unit
268
+ else return Effect.void
268
269
  }
269
270
  })
270
271
  }
@@ -303,7 +304,7 @@ class FilterEffectSink<A, E, R> implements Sink<A, E, R> {
303
304
  onFailure: (cause) => this.sink.onFailure(cause),
304
305
  onSuccess: (b) => {
305
306
  if (b) return this.sink.onSuccess(value)
306
- else return Effect.unit
307
+ else return Effect.void
307
308
  }
308
309
  })
309
310
  }
@@ -457,7 +458,7 @@ class FilterMapLoopSink<A, E, R, B, C> implements Sink<A, E, R> {
457
458
  const [option, acc] = this.f(this.seed, value)
458
459
  this.seed = acc
459
460
  if (Option.isSome(option)) return this.sink.onSuccess(option.value)
460
- else return Effect.unit
461
+ else return Effect.void
461
462
  }
462
463
  }
463
464
 
@@ -495,7 +496,7 @@ class FilterMapLoopCauseSink<A, E, R, B, C> implements Sink<A, E, R> {
495
496
  const [option, acc] = this.f(this.seed, cause)
496
497
  this.seed = acc
497
498
  if (Option.isSome(option)) return this.sink.onFailure(option.value)
498
- else return Effect.unit
499
+ else return Effect.void
499
500
  }
500
501
 
501
502
  onSuccess(value: A) {
@@ -588,7 +589,7 @@ class FilterMapLoopEffectSink<A, E, R, B, R2, C> implements Sink<A, E, R | R2> {
588
589
  onSuccess: ([option, acc]) => {
589
590
  this.seed = acc
590
591
  if (Option.isSome(option)) return this.sink.onSuccess(option.value)
591
- else return Effect.unit
592
+ else return Effect.void
592
593
  }
593
594
  })
594
595
  }
@@ -669,7 +670,7 @@ class FilterMapLoopCauseEffectSink<A, E, R, B, E2, R2, C> implements Sink<A, E,
669
670
  onSuccess: ([option, acc]) => {
670
671
  this.seed = acc
671
672
  if (Option.isSome(option)) return this.sink.onFailure(option.value)
672
- else return Effect.unit
673
+ else return Effect.void
673
674
  }
674
675
  })
675
676
  }
@@ -721,10 +722,10 @@ class SliceSink<A, E, R> implements Sink<A, E, R> {
721
722
  onSuccess(value: A) {
722
723
  if (this.drop > 0) {
723
724
  this.drop--
724
- return Effect.unit
725
+ return Effect.void
725
726
  }
726
727
  if (this.take-- > 0) {
727
- return Effect.tap(this.sink.onSuccess(value), () => this.take === 0 ? this.sink.earlyExit : Effect.unit)
728
+ return Effect.tap(this.sink.onSuccess(value), () => this.take === 0 ? this.sink.earlyExit : Effect.void)
728
729
  }
729
730
  return this.sink.earlyExit
730
731
  }
@@ -1019,7 +1020,7 @@ class FromTag<I, S, B, E2, R2> implements Sink<B, E2, I | R2> {
1019
1020
  */
1020
1021
  export function ignoreInterrupt<A, E, R>(sink: Sink<A, E, R>): Sink<A, E, R> {
1021
1022
  return make(
1022
- (cause) => Cause.isInterruptedOnly(cause) ? Effect.unit : sink.onFailure(cause),
1023
+ (cause) => Cause.isInterruptedOnly(cause) ? Effect.void : sink.onFailure(cause),
1023
1024
  sink.onSuccess
1024
1025
  )
1025
1026
  }
package/src/Subject.ts CHANGED
@@ -4,14 +4,16 @@
4
4
  */
5
5
 
6
6
  import * as C from "@typed/context"
7
- import type { Cause, Layer, Pipeable } from "effect"
7
+ import type * as Cause from "effect/Cause"
8
8
  import type * as Context from "effect/Context"
9
9
  import * as Effect from "effect/Effect"
10
10
  import * as ExecutionStrategy from "effect/ExecutionStrategy"
11
11
  import * as Exit from "effect/Exit"
12
12
  import { dual, identity } from "effect/Function"
13
+ import type * as Layer from "effect/Layer"
13
14
  import * as MutableRef from "effect/MutableRef"
14
15
  import * as Option from "effect/Option"
16
+ import type * as Pipeable from "effect/Pipeable"
15
17
  import { hasProperty } from "effect/Predicate"
16
18
  import * as Scope from "effect/Scope"
17
19
  import { type Fx } from "./Fx.js"
@@ -101,12 +103,7 @@ export class SubjectImpl<A, E> extends FxBase<A, E, Scope.Scope> implements Subj
101
103
  }
102
104
 
103
105
  protected interruptScopes = Effect.fiberIdWith((id) =>
104
- Effect.tap(
105
- Effect.forEach(this.sinks, ([, , scope]) => Scope.close(scope, Exit.interrupt(id)), DISCARD),
106
- () => {
107
- this.sinks.clear()
108
- }
109
- )
106
+ Effect.forEach(Array.from(this.sinks), ([, , scope]) => Scope.close(scope, Exit.interrupt(id)), DISCARD)
110
107
  )
111
108
 
112
109
  readonly interrupt = this.interruptScopes
@@ -134,7 +131,7 @@ export class SubjectImpl<A, E> extends FxBase<A, E, Scope.Scope> implements Subj
134
131
  readonly subscriberCount: Effect.Effect<number> = Effect.sync(() => this.sinks.size)
135
132
 
136
133
  protected onEvent(a: A) {
137
- if (this.sinks.size === 0) return Effect.unit
134
+ if (this.sinks.size === 0) return Effect.void
138
135
  else if (this.sinks.size === 1) {
139
136
  const [sink, ctx] = this.sinks.values().next().value
140
137
  return runSinkEvent(sink, ctx, a)
@@ -148,14 +145,14 @@ export class SubjectImpl<A, E> extends FxBase<A, E, Scope.Scope> implements Subj
148
145
  }
149
146
 
150
147
  protected onCause(cause: Cause.Cause<E>) {
151
- if (this.sinks.size === 0) return Effect.unit
148
+ if (this.sinks.size === 0) return Effect.void
152
149
  else if (this.sinks.size === 1) {
153
- const [sink, ctx] = this.sinks.values().next().value
154
- return runSinkCause(sink, ctx, cause)
150
+ const [sink, ctx, scope] = this.sinks.values().next().value
151
+ return runSinkCause(sink, ctx, scope, cause)
155
152
  } else {
156
153
  return Effect.forEach(
157
154
  this.sinks,
158
- ([sink, ctx]) => runSinkCause(sink, ctx, cause),
155
+ ([sink, ctx, scope]) => runSinkCause(sink, ctx, scope, cause),
159
156
  DISCARD
160
157
  )
161
158
  }
@@ -166,8 +163,16 @@ function runSinkEvent<A, E>(sink: Sink<A, E, any>, ctx: Context.Context<any>, a:
166
163
  return Effect.provide(Effect.catchAllCause(sink.onSuccess(a), sink.onFailure), ctx)
167
164
  }
168
165
 
169
- function runSinkCause<A, E>(sink: Sink<A, E, any>, ctx: Context.Context<any>, cause: Cause.Cause<E>) {
170
- return Effect.provide(Effect.catchAllCause(sink.onFailure(cause), () => Effect.unit), ctx)
166
+ function runSinkCause<A, E>(
167
+ sink: Sink<A, E, any>,
168
+ ctx: Context.Context<any>,
169
+ scope: Scope.CloseableScope,
170
+ cause: Cause.Cause<E>
171
+ ) {
172
+ return Effect.provide(
173
+ Effect.catchAllCause(sink.onFailure(cause), (error) => Scope.close(scope, Exit.failCause(error))),
174
+ ctx
175
+ )
171
176
  }
172
177
 
173
178
  /**
package/src/Versioned.ts CHANGED
@@ -6,12 +6,14 @@
6
6
  */
7
7
 
8
8
  import type * as Context from "@typed/context"
9
- import type { Layer, Runtime, Scope } from "effect"
10
- import { Exit } from "effect"
11
9
  import * as Effect from "effect/Effect"
10
+ import * as Exit from "effect/Exit"
12
11
  import { dual, flow } from "effect/Function"
12
+ import type * as Layer from "effect/Layer"
13
13
  import { sum } from "effect/Number"
14
14
  import * as Option from "effect/Option"
15
+ import type * as Runtime from "effect/Runtime"
16
+ import type * as Scope from "effect/Scope"
15
17
  import type { Fx } from "./Fx.js"
16
18
  import * as core from "./internal/core.js"
17
19
  import { MulticastEffect } from "./internal/helpers.js"
@@ -1,35 +1,41 @@
1
- import type { Equivalence, FiberId } from "effect"
1
+ import { MutableRef } from "effect"
2
2
  import * as Deferred from "effect/Deferred"
3
3
  import * as Effect from "effect/Effect"
4
+ import type * as Equivalence from "effect/Equivalence"
4
5
  import * as Exit from "effect/Exit"
6
+ import type * as FiberId from "effect/FiberId"
5
7
  import * as Option from "effect/Option"
6
8
  import { EffectBase } from "./protos.js"
7
9
 
8
10
  export class DeferredRef<E, A> extends EffectBase<A, E, never> {
9
11
  // Keep track of the latest value emitted by the stream
10
- public current!: Option.Option<Exit.Exit<A, E>>
11
12
  public version!: number
12
13
  public deferred!: Deferred.Deferred<A, E>
13
14
 
14
- constructor(private id: FiberId.FiberId, private eq: Equivalence.Equivalence<Exit.Exit<A, E>>) {
15
+ constructor(
16
+ private id: FiberId.FiberId,
17
+ private eq: Equivalence.Equivalence<Exit.Exit<A, E>>,
18
+ readonly current: MutableRef.MutableRef<Option.Option<Exit.Exit<A, E>>>
19
+ ) {
15
20
  super()
16
21
  this.reset()
17
22
  }
18
23
 
19
24
  toEffect() {
20
25
  return Effect.suspend(() => {
21
- if (Option.isNone(this.current)) {
26
+ const current = MutableRef.get(this.current)
27
+ if (Option.isNone(current)) {
22
28
  return Deferred.await(this.deferred)
23
29
  } else {
24
- return this.current.value
30
+ return current.value
25
31
  }
26
32
  })
27
33
  }
28
34
 
29
35
  done(exit: Exit.Exit<A, E>) {
30
- const current = this.current
36
+ const current = MutableRef.get(this.current)
31
37
 
32
- this.current = Option.some(exit)
38
+ MutableRef.set(this.current, Option.some(exit))
33
39
 
34
40
  if (Option.isSome(current) && this.eq(current.value, exit)) {
35
41
  return false
@@ -42,7 +48,7 @@ export class DeferredRef<E, A> extends EffectBase<A, E, never> {
42
48
  }
43
49
 
44
50
  reset() {
45
- this.current = Option.none()
51
+ MutableRef.set(this.current, Option.none())
46
52
  this.version = -1
47
53
 
48
54
  if (this.deferred) {
@@ -54,9 +60,13 @@ export class DeferredRef<E, A> extends EffectBase<A, E, never> {
54
60
  }
55
61
 
56
62
  export function make<E, A>(eq: Equivalence.Equivalence<Exit.Exit<A, E>>) {
57
- return Effect.map(Effect.fiberId, (id) => new DeferredRef(id, eq))
63
+ return Effect.map(Effect.fiberId, (id) => new DeferredRef(id, eq, MutableRef.make(Option.none())))
58
64
  }
59
65
 
60
- export function unsafeMake<E, A>(id: FiberId.FiberId, eq: Equivalence.Equivalence<Exit.Exit<A, E>>) {
61
- return new DeferredRef(id, eq)
66
+ export function unsafeMake<E, A>(
67
+ id: FiberId.FiberId,
68
+ eq: Equivalence.Equivalence<Exit.Exit<A, E>>,
69
+ current: MutableRef.MutableRef<Option.Option<Exit.Exit<A, E>>>
70
+ ) {
71
+ return new DeferredRef(id, eq, current)
62
72
  }
@@ -1,36 +1,36 @@
1
1
  import * as Context from "@typed/context"
2
- import {
3
- type ConfigProvider,
4
- type Duration,
5
- type Equivalence,
6
- type FiberId,
7
- type FiberRef,
8
- type HashSet,
9
- type Queue,
10
- type Request,
11
- type Runtime,
12
- type Schedule,
13
- type Scheduler,
14
- Unify
15
- } from "effect"
2
+ import { Data, Record } from "effect"
16
3
  import * as Boolean from "effect/Boolean"
17
4
  import * as Cause from "effect/Cause"
18
5
  import * as Clock from "effect/Clock"
6
+ import type * as ConfigProvider from "effect/ConfigProvider"
19
7
  import * as Deferred from "effect/Deferred"
8
+ import type * as Duration from "effect/Duration"
20
9
  import * as Effect from "effect/Effect"
21
10
  import * as Either from "effect/Either"
22
11
  import * as Equal from "effect/Equal"
12
+ import type * as Equivalence from "effect/Equivalence"
23
13
  import { boolean } from "effect/Equivalence"
24
14
  import * as ExecutionStrategy from "effect/ExecutionStrategy"
25
15
  import * as Exit from "effect/Exit"
26
16
  import * as Fiber from "effect/Fiber"
17
+ import type * as FiberId from "effect/FiberId"
18
+ import type * as FiberRef from "effect/FiberRef"
27
19
  import { constFalse, constTrue } from "effect/Function"
20
+ import type * as HashSet from "effect/HashSet"
28
21
  import * as Layer from "effect/Layer"
29
22
  import * as Option from "effect/Option"
30
23
  import * as Predicate from "effect/Predicate"
24
+ import type * as Queue from "effect/Queue"
31
25
  import * as Ref from "effect/Ref"
26
+ import type * as Request from "effect/Request"
27
+ import type * as Runtime from "effect/Runtime"
28
+ import type * as Schedule from "effect/Schedule"
29
+ import type * as Scheduler from "effect/Scheduler"
32
30
  import * as Scope from "effect/Scope"
33
31
  import * as Tracer from "effect/Tracer"
32
+ import * as Unify from "effect/Unify"
33
+ import type * as Utils from "effect/Utils"
34
34
  import type { FlattenStrategy, Fx, FxFork, MergeStrategy } from "../Fx.js"
35
35
  import * as Sink from "../Sink.js"
36
36
  import type { Bounds } from "./bounds.js"
@@ -284,7 +284,7 @@ export const observe = <A, E, R, B, E2, R2>(
284
284
  f: (a: A) => Effect.Effect<B, E2, R2>
285
285
  ): Effect.Effect<void, E | E2, R | R2> => Observe.make(fx, f)
286
286
 
287
- const constUnit = () => Effect.unit
287
+ const constUnit = () => Effect.void
288
288
 
289
289
  export const drain = <A, E, R>(fx: Fx<A, E, R>): Effect.Effect<void, E, R> => Observe.make(fx, constUnit)
290
290
 
@@ -303,7 +303,7 @@ class Observe<A, E, R, B, E2, R2> extends EffectBase<void, E | E2, R | R2> {
303
303
 
304
304
  return Effect.zipRight(
305
305
  fx.run(Sink.make(onFailure, (a) => Effect.catchAllCause(f(a), onFailure))),
306
- Effect.sync(() => resume(Effect.unit))
306
+ Effect.sync(() => resume(Effect.void))
307
307
  )
308
308
  })
309
309
  }
@@ -313,7 +313,7 @@ class Observe<A, E, R, B, E2, R2> extends EffectBase<void, E | E2, R | R2> {
313
313
  f: (a: A) => Effect.Effect<B, E2, R2>
314
314
  ): Effect.Effect<void, E | E2, R | R2> {
315
315
  if (isEmpty(fx)) {
316
- return Effect.unit
316
+ return Effect.void
317
317
  } else if (isNever(fx)) {
318
318
  return Effect.never
319
319
  } else if (isProducer(fx)) {
@@ -326,13 +326,13 @@ class Observe<A, E, R, B, E2, R2> extends EffectBase<void, E | E2, R | R2> {
326
326
  SyncProducer.effectOnce(() => SyncProducer.runEffect(fx.i0, (a) => f(op.f(a)))),
327
327
  Filter: (op) =>
328
328
  SyncProducer.effectOnce(() =>
329
- SyncProducer.runEffect(fx.i0, Unify.unify((a) => op.f(a) ? f(a) : Effect.unit))
329
+ SyncProducer.runEffect(fx.i0, Unify.unify((a) => op.f(a) ? f(a) : Effect.void))
330
330
  ),
331
331
  FilterMap: (op) =>
332
332
  SyncProducer.effectOnce(() =>
333
333
  SyncProducer.runEffect(
334
334
  fx.i0,
335
- Unify.unify((a) => Option.match(op.f(a), { onNone: () => Effect.unit, onSome: f }))
335
+ Unify.unify((a) => Option.match(op.f(a), { onNone: () => Effect.void, onSome: f }))
336
336
  )
337
337
  )
338
338
  }),
@@ -342,12 +342,12 @@ class Observe<A, E, R, B, E2, R2> extends EffectBase<void, E | E2, R | R2> {
342
342
  SyncProducer.runEffect(fx.i0, (a) => Effect.flatMap(op.f(a), f)),
343
343
  FilterMapEffect: (op) =>
344
344
  SyncProducer.runEffect(fx.i0, (a) =>
345
- Effect.flatMap(op.f(a), Unify.unify(Option.match({ onNone: () => Effect.unit, onSome: f })))),
345
+ Effect.flatMap(op.f(a), Unify.unify(Option.match({ onNone: () => Effect.void, onSome: f })))),
346
346
  FilterEffect: (op) =>
347
347
  SyncProducer.runEffect(
348
348
  fx.i0,
349
349
  Unify.unify((a) =>
350
- Effect.flatMap(op.f(a), Unify.unify((b) => b ? f(a) : Effect.unit))
350
+ Effect.flatMap(op.f(a), Unify.unify((b) => b ? f(a) : Effect.void))
351
351
  )
352
352
  ),
353
353
  TapEffect: (op) => SyncProducer.runEffect(fx.i0, (a) => Effect.flatMap(op.f(a), () => f(a)))
@@ -400,13 +400,13 @@ class Observe<A, E, R, B, E2, R2> extends EffectBase<void, E | E2, R | R2> {
400
400
  SyncProducer.effectOnce(() => EffectProducer.runEffect(fx.i0, (a) => f(op.f(a)))),
401
401
  Filter: (op) =>
402
402
  SyncProducer.effectOnce(() =>
403
- EffectProducer.runEffect(fx.i0, Unify.unify((a) => op.f(a) ? f(a) : Effect.unit))
403
+ EffectProducer.runEffect(fx.i0, Unify.unify((a) => op.f(a) ? f(a) : Effect.void))
404
404
  ),
405
405
  FilterMap: (op) =>
406
406
  SyncProducer.effectOnce(() =>
407
407
  EffectProducer.runEffect(
408
408
  fx.i0,
409
- Unify.unify((a) => Option.match(op.f(a), { onNone: () => Effect.unit, onSome: f }))
409
+ Unify.unify((a) => Option.match(op.f(a), { onNone: () => Effect.void, onSome: f }))
410
410
  )
411
411
  )
412
412
  }),
@@ -416,12 +416,12 @@ class Observe<A, E, R, B, E2, R2> extends EffectBase<void, E | E2, R | R2> {
416
416
  EffectProducer.runEffect(fx.i0, (a) => Effect.flatMap(op.f(a), f)),
417
417
  FilterMapEffect: (op) =>
418
418
  EffectProducer.runEffect(fx.i0, (a) =>
419
- Effect.flatMap(op.f(a), Unify.unify(Option.match({ onNone: () => Effect.unit, onSome: f })))),
419
+ Effect.flatMap(op.f(a), Unify.unify(Option.match({ onNone: () => Effect.void, onSome: f })))),
420
420
  FilterEffect: (op) =>
421
421
  EffectProducer.runEffect(
422
422
  fx.i0,
423
423
  Unify.unify((a) =>
424
- Effect.flatMap(op.f(a), Unify.unify((b) => b ? f(a) : Effect.unit))
424
+ Effect.flatMap(op.f(a), Unify.unify((b) => b ? f(a) : Effect.void))
425
425
  )
426
426
  ),
427
427
  TapEffect: (op) => EffectProducer.runEffect(fx.i0, (a) => Effect.flatMap(op.f(a), () => f(a)))
@@ -617,10 +617,41 @@ export function skipRepeatsWith<A, E, R>(
617
617
  })
618
618
  }
619
619
 
620
+ const toDeepEquals = (u: unknown): unknown => {
621
+ switch (typeof u) {
622
+ case "object": {
623
+ if (Predicate.isNullable(u)) {
624
+ return u
625
+ } else if (Equal.symbol in u) {
626
+ return u
627
+ } else if (Array.isArray(u)) {
628
+ return Data.tuple(u.map(toDeepEquals))
629
+ } else if (u instanceof Set) {
630
+ return Data.tuple(Array.from(u, toDeepEquals))
631
+ } else if (u instanceof Map) {
632
+ return Data.tuple(Array.from(u, ([k, v]) => Data.tuple([toDeepEquals(k), toDeepEquals(v)])))
633
+ } else {
634
+ return Data.struct(Record.map(u, toDeepEquals))
635
+ }
636
+ }
637
+ default:
638
+ return u
639
+ }
640
+ }
641
+
642
+ /**
643
+ * @internal
644
+ */
645
+ export const deepEquals = (a: unknown, b: unknown) => {
646
+ // Attempt reference equality first for performance
647
+ if (Object.is(a, b)) return true
648
+ return Equal.equals(toDeepEquals(a), toDeepEquals(b))
649
+ }
650
+
620
651
  export function skipRepeats<A, E, R>(
621
652
  fx: Fx<A, E, R>
622
653
  ): Fx<A, E, R> {
623
- return skipRepeatsWith(fx, Equal.equals)
654
+ return skipRepeatsWith(fx, deepEquals)
624
655
  }
625
656
 
626
657
  class ProducerEffectTransformer<A, E, R, B, E2, R2> extends FxBase<B, E | E2, R | R2> {
@@ -644,7 +675,7 @@ export function isProducerEffectTransformer<A, E, R>(
644
675
 
645
676
  class Empty extends FxBase<never, never, never> {
646
677
  run<R2>(): Effect.Effect<unknown, never, R2> {
647
- return Effect.unit
678
+ return Effect.void
648
679
  }
649
680
  }
650
681
 
@@ -983,22 +1014,25 @@ class FromFxEffect<
983
1014
  }
984
1015
  }
985
1016
 
986
- export function gen<Y extends Effect.EffectGen<any, any, any>, FX extends Fx<any, any, any>>(
1017
+ export function gen<Y extends Utils.YieldWrap<Effect.Effect<any, any, any>>, FX extends Fx<any, any, any>>(
987
1018
  f: (_: Effect.Adapter) => Generator<Y, FX, any>
988
1019
  ): Fx<
989
1020
  Fx.Success<FX>,
990
- Effect.Effect.Error<Y["value"]> | Fx.Error<FX>,
991
- Effect.Effect.Context<Y["value"]> | Fx.Context<FX>
1021
+ YieldWrapError<Y> | Fx.Error<FX>,
1022
+ YieldWrapContext<Y> | Fx.Context<FX>
992
1023
  > {
993
1024
  return fromFxEffect(Effect.gen(f))
994
1025
  }
995
1026
 
996
- export function genScoped<Y extends Effect.EffectGen<any, any, any>, FX extends Fx<any, any, any>>(
1027
+ type YieldWrapError<T> = T extends Utils.YieldWrap<Effect.Effect<infer _, infer E, any>> ? E : never
1028
+ type YieldWrapContext<T> = T extends Utils.YieldWrap<Effect.Effect<any, any, infer R>> ? R : never
1029
+
1030
+ export function genScoped<Y extends Utils.YieldWrap<Effect.Effect<any, any, any>>, FX extends Fx<any, any, any>>(
997
1031
  f: (_: Effect.Adapter) => Generator<Y, FX, any>
998
1032
  ): Fx<
999
1033
  Fx.Success<FX>,
1000
- Effect.Effect.Error<Y["value"]> | Fx.Error<FX>,
1001
- Exclude<Effect.Effect.Context<Y["value"]> | Fx.Context<FX>, Scope.Scope>
1034
+ YieldWrapError<Y> | Fx.Error<FX>,
1035
+ Exclude<YieldWrapContext<Y> | Fx.Context<FX>, Scope.Scope>
1002
1036
  > {
1003
1037
  return scoped(fromFxEffect(Effect.gen(f)))
1004
1038
  }
@@ -1102,7 +1136,7 @@ class OrElse<
1102
1136
  run<R3>(sink: Sink.Sink<A | B, E | E2, R3>): Effect.Effect<unknown, never, R | R2 | R3> {
1103
1137
  return Effect.catchAll(
1104
1138
  Effect.asyncEffect<unknown, E, never, never, never, R | R2 | R3>((resume) =>
1105
- Effect.asUnit(Effect.zipRight(
1139
+ Effect.asVoid(Effect.zipRight(
1106
1140
  this.i0.run(
1107
1141
  Sink.make(
1108
1142
  (cause) =>
@@ -1113,7 +1147,7 @@ class OrElse<
1113
1147
  sink.onSuccess
1114
1148
  )
1115
1149
  ),
1116
- Effect.sync(() => resume(Effect.unit))
1150
+ Effect.sync(() => resume(Effect.void))
1117
1151
  ))
1118
1152
  ),
1119
1153
  (error: E) => this.i1(error).run(sink)
@@ -1264,16 +1298,16 @@ function runOrdered<
1264
1298
  sink: Sink.Sink<any, any, R2>,
1265
1299
  concurrency: number | "unbounded"
1266
1300
  ): Effect.Effect<unknown, never, R2 | Fx.Context<FX[number]>> {
1267
- return Effect.suspend(
1268
- () => {
1269
- const buffers = withBuffers(fx.length, sink)
1301
+ return Effect.fiberIdWith(
1302
+ (id) => {
1303
+ const buffers = withBuffers(fx.length, sink, id)
1270
1304
  return Effect.forEach(
1271
1305
  fx,
1272
1306
  (fx, i) =>
1273
1307
  Effect.flatMap(
1274
1308
  fx.run(
1275
1309
  Sink.make(
1276
- (cause) => Cause.isInterruptedOnly(cause) ? Effect.unit : sink.onFailure(cause),
1310
+ (cause) => Cause.isInterruptedOnly(cause) ? buffers.onEnd(i) : sink.onFailure(cause),
1277
1311
  (a) => buffers.onSuccess(i, a)
1278
1312
  )
1279
1313
  ),
@@ -1529,7 +1563,7 @@ class During<A, E, R, B, E2, R2, E3, R3> extends FxBase<A, E | E2 | E3, R | R2 |
1529
1563
  this.i0.run(
1530
1564
  Sink.make(
1531
1565
  onFailure,
1532
- (a) => taking ? s.onSuccess(a) : Effect.unit
1566
+ (a) => taking ? s.onSuccess(a) : Effect.void
1533
1567
  )
1534
1568
  )
1535
1569
  )
@@ -1654,7 +1688,7 @@ export function withMaxOpsBeforeYield<A, E, R>(
1654
1688
 
1655
1689
  export function withParentSpan<A, E, R>(
1656
1690
  fx: Fx<A, E, R>,
1657
- parentSpan: Tracer.ParentSpan
1691
+ parentSpan: Tracer.AnySpan
1658
1692
  ): Fx<A, E, R> {
1659
1693
  return middleware(fx, (effect) => Effect.withParentSpan(effect, parentSpan))
1660
1694
  }
@@ -2479,10 +2513,10 @@ class FromAsyncIterable<A> extends FxBase<A, never, never> {
2479
2513
  const iterator = this.i0[Symbol.asyncIterator]()
2480
2514
  const loop = (result: IteratorResult<A>): Effect.Effect<unknown, never, R> =>
2481
2515
  result.done
2482
- ? Effect.sync(() => cb(Effect.unit))
2516
+ ? Effect.sync(() => cb(Effect.void))
2483
2517
  : Effect.zipRight(sink.onSuccess(result.value), Effect.flatMap(Effect.promise(() => iterator.next()), loop))
2484
2518
 
2485
- return Effect.asUnit(Effect.flatMap(
2519
+ return Effect.asVoid(Effect.flatMap(
2486
2520
  Effect.promise(() => iterator.next()),
2487
2521
  loop
2488
2522
  ))
@@ -2492,7 +2526,7 @@ class FromAsyncIterable<A> extends FxBase<A, never, never> {
2492
2526
 
2493
2527
  export function findFirst<A, E, R>(fx: Fx<A, E, R>, predicate: Predicate.Predicate<A>): Effect.Effect<A, E, R> {
2494
2528
  return Effect.asyncEffect((cb) =>
2495
- observe(fx, (a) => predicate(a) ? Effect.sync(() => cb(Effect.succeed(a))) : Effect.unit)
2529
+ observe(fx, (a) => predicate(a) ? Effect.sync(() => cb(Effect.succeed(a))) : Effect.void)
2496
2530
  )
2497
2531
  }
2498
2532
 
@@ -2544,13 +2578,13 @@ class MergeRace<A, E, R, B, E2, R2> extends FxBase<A | B, E | E2, R | R2> {
2544
2578
 
2545
2579
  run<R3>(sink: Sink.Sink<A | B, E | E2, R3>): Effect.Effect<unknown, never, R | R2 | R3> {
2546
2580
  return Effect.gen(this, function*(_) {
2547
- const fiber1 = yield* _(Effect.fork(this.i0.run(Sink.make(
2581
+ const fiber1 = yield* Effect.fork(this.i0.run(Sink.make(
2548
2582
  sink.onFailure,
2549
2583
  (a) => Effect.flatMap(sink.onSuccess(a), () => Fiber.interrupt(fiber2))
2550
- ))))
2551
- const fiber2 = yield* _(Effect.fork(this.i1.run(sink)))
2584
+ )))
2585
+ const fiber2 = yield* Effect.fork(this.i1.run(sink))
2552
2586
 
2553
- return yield* _(Fiber.joinAll([fiber1, fiber2]))
2587
+ return yield* Fiber.joinAll([fiber1, fiber2])
2554
2588
  })
2555
2589
  }
2556
2590
  }
@@ -2585,22 +2619,22 @@ class RaceAll<const FX extends ReadonlyArray<Fx<any, any, any>>> extends FxBase<
2585
2619
  sink: Sink.Sink<Fx.Success<FX[number]>, Fx.Error<FX[number]>, R2>
2586
2620
  ): Effect.Effect<unknown, never, Fx.Context<FX[number]> | R2> {
2587
2621
  return Effect.gen(this, function*(_) {
2588
- const winner = yield* _(Deferred.make<Fiber.RuntimeFiber<unknown>>())
2622
+ const winner = yield* Deferred.make<Fiber.RuntimeFiber<unknown>>()
2589
2623
  const fibers: Array<Fiber.RuntimeFiber<unknown>> = []
2590
2624
 
2591
2625
  for (const fx of this.i0) {
2592
- const fiber: Fiber.RuntimeFiber<unknown> = yield* _(Effect.fork(fx.run(Sink.make(
2626
+ const fiber: Fiber.RuntimeFiber<unknown> = yield* Effect.fork(fx.run(Sink.make(
2593
2627
  sink.onFailure,
2594
2628
  (a) => Effect.flatMap(Deferred.succeed(winner, fiber), () => sink.onSuccess(a))
2595
- ))))
2629
+ )))
2596
2630
  fibers.push(fiber)
2597
2631
  }
2598
2632
 
2599
- const winningFiber = yield* _(Deferred.await(winner))
2633
+ const winningFiber = yield* Deferred.await(winner)
2600
2634
 
2601
- yield* _(Fiber.interruptAll(fibers.filter((x) => x !== winningFiber)))
2635
+ yield* Fiber.interruptAll(fibers.filter((x) => x !== winningFiber))
2602
2636
 
2603
- return yield* _(Fiber.join(winningFiber))
2637
+ return yield* Fiber.join(winningFiber)
2604
2638
  })
2605
2639
  }
2606
2640
  }
@@ -2644,7 +2678,7 @@ class Snapshot<A, E, R, B, E2, R2, C> extends FxBase<C, E | E2, R | R2> {
2644
2678
  Effect.flatMap(
2645
2679
  Ref.get(ref),
2646
2680
  Option.match({
2647
- onNone: () => Effect.unit,
2681
+ onNone: () => Effect.void,
2648
2682
  onSome: (b) => sink.onSuccess(this.i2(a, b))
2649
2683
  })
2650
2684
  )
@@ -2688,7 +2722,7 @@ class SnapshotEffect<A, E, R, B, E2, R2, C, E3, R3> extends FxBase<C, E | E2 | E
2688
2722
  Effect.flatMap(
2689
2723
  Ref.get(ref),
2690
2724
  Option.match({
2691
- onNone: () => Effect.unit,
2725
+ onNone: () => Effect.void,
2692
2726
  onSome: (b) => Effect.matchCauseEffect(this.i2(a, b), sink)
2693
2727
  })
2694
2728
  )))
@@ -2720,11 +2754,8 @@ export function when<B, E, R, C>(
2720
2754
  readonly onTrue: B
2721
2755
  readonly onFalse: C
2722
2756
  }
2723
- ): Fx<B | C, E, R | Scope.Scope> {
2724
- return if_(bool, {
2725
- onTrue: succeed(options.onTrue),
2726
- onFalse: succeed(options.onFalse)
2727
- })
2757
+ ): Fx<B | C, E, R> {
2758
+ return map(skipRepeatsWith(bool, boolean), (b) => (b ? options.onTrue : options.onFalse))
2728
2759
  }
2729
2760
 
2730
2761
  export function mapBoth<A, E, R, B, C>(
@@ -1,5 +1,5 @@
1
- import type { Equivalence } from "effect"
2
1
  import * as Equal from "effect/Equal"
2
+ import type * as Equivalence from "effect/Equivalence"
3
3
  import { identity } from "effect/Function"
4
4
 
5
5
  export type DiffResult<A, B> = ReadonlyArray<Diff<A, B>>