effect 3.10.19 → 3.11.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 (167) hide show
  1. package/dist/cjs/BigDecimal.js +125 -24
  2. package/dist/cjs/BigDecimal.js.map +1 -1
  3. package/dist/cjs/Channel.js +44 -4
  4. package/dist/cjs/Channel.js.map +1 -1
  5. package/dist/cjs/Config.js +8 -1
  6. package/dist/cjs/Config.js.map +1 -1
  7. package/dist/cjs/Context.js +26 -1
  8. package/dist/cjs/Context.js.map +1 -1
  9. package/dist/cjs/Cron.js +75 -67
  10. package/dist/cjs/Cron.js.map +1 -1
  11. package/dist/cjs/DateTime.js +114 -664
  12. package/dist/cjs/DateTime.js.map +1 -1
  13. package/dist/cjs/Effect.js +82 -4
  14. package/dist/cjs/Effect.js.map +1 -1
  15. package/dist/cjs/Inspectable.js +8 -4
  16. package/dist/cjs/Inspectable.js.map +1 -1
  17. package/dist/cjs/JSONSchema.js.map +1 -1
  18. package/dist/cjs/Micro.js +1099 -1072
  19. package/dist/cjs/Micro.js.map +1 -1
  20. package/dist/cjs/STM.js.map +1 -1
  21. package/dist/cjs/Schema.js +57 -8
  22. package/dist/cjs/Schema.js.map +1 -1
  23. package/dist/cjs/Sink.js +9 -1
  24. package/dist/cjs/Sink.js.map +1 -1
  25. package/dist/cjs/Stream.js +25 -7
  26. package/dist/cjs/Stream.js.map +1 -1
  27. package/dist/cjs/Utils.js +7 -1
  28. package/dist/cjs/Utils.js.map +1 -1
  29. package/dist/cjs/internal/channel/channelExecutor.js +5 -9
  30. package/dist/cjs/internal/channel/channelExecutor.js.map +1 -1
  31. package/dist/cjs/internal/channel.js +156 -130
  32. package/dist/cjs/internal/channel.js.map +1 -1
  33. package/dist/cjs/internal/config.js +13 -4
  34. package/dist/cjs/internal/config.js.map +1 -1
  35. package/dist/cjs/internal/context.js +46 -3
  36. package/dist/cjs/internal/context.js.map +1 -1
  37. package/dist/cjs/internal/dateTime.js +747 -0
  38. package/dist/cjs/internal/dateTime.js.map +1 -0
  39. package/dist/cjs/internal/fiberRuntime.js +34 -11
  40. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  41. package/dist/cjs/internal/groupBy.js +9 -3
  42. package/dist/cjs/internal/groupBy.js.map +1 -1
  43. package/dist/cjs/internal/layer.js +1 -1
  44. package/dist/cjs/internal/layer.js.map +1 -1
  45. package/dist/cjs/internal/mailbox.js +1 -1
  46. package/dist/cjs/internal/mailbox.js.map +1 -1
  47. package/dist/cjs/internal/sink.js +25 -21
  48. package/dist/cjs/internal/sink.js.map +1 -1
  49. package/dist/cjs/internal/stream.js +70 -71
  50. package/dist/cjs/internal/stream.js.map +1 -1
  51. package/dist/cjs/internal/version.js +1 -1
  52. package/dist/cjs/internal/version.js.map +1 -1
  53. package/dist/dts/BigDecimal.d.ts +56 -1
  54. package/dist/dts/BigDecimal.d.ts.map +1 -1
  55. package/dist/dts/Channel.d.ts +66 -5
  56. package/dist/dts/Channel.d.ts.map +1 -1
  57. package/dist/dts/Config.d.ts +23 -1
  58. package/dist/dts/Config.d.ts.map +1 -1
  59. package/dist/dts/Context.d.ts +111 -0
  60. package/dist/dts/Context.d.ts.map +1 -1
  61. package/dist/dts/Cron.d.ts +15 -6
  62. package/dist/dts/Cron.d.ts.map +1 -1
  63. package/dist/dts/DateTime.d.ts +40 -49
  64. package/dist/dts/DateTime.d.ts.map +1 -1
  65. package/dist/dts/Effect.d.ts +88 -1
  66. package/dist/dts/Effect.d.ts.map +1 -1
  67. package/dist/dts/Inspectable.d.ts.map +1 -1
  68. package/dist/dts/JSONSchema.d.ts +1 -0
  69. package/dist/dts/JSONSchema.d.ts.map +1 -1
  70. package/dist/dts/Micro.d.ts +875 -872
  71. package/dist/dts/Micro.d.ts.map +1 -1
  72. package/dist/dts/STM.d.ts +2 -0
  73. package/dist/dts/STM.d.ts.map +1 -1
  74. package/dist/dts/Schema.d.ts +32 -0
  75. package/dist/dts/Schema.d.ts.map +1 -1
  76. package/dist/dts/Sink.d.ts +8 -0
  77. package/dist/dts/Sink.d.ts.map +1 -1
  78. package/dist/dts/Stream.d.ts +50 -32
  79. package/dist/dts/Stream.d.ts.map +1 -1
  80. package/dist/dts/Utils.d.ts +4 -0
  81. package/dist/dts/Utils.d.ts.map +1 -1
  82. package/dist/dts/internal/context.d.ts +1 -1
  83. package/dist/dts/internal/context.d.ts.map +1 -1
  84. package/dist/dts/internal/dateTime.d.ts +2 -0
  85. package/dist/dts/internal/dateTime.d.ts.map +1 -0
  86. package/dist/dts/internal/fiberRuntime.d.ts.map +1 -1
  87. package/dist/dts/internal/stream.d.ts.map +1 -1
  88. package/dist/esm/BigDecimal.js +119 -20
  89. package/dist/esm/BigDecimal.js.map +1 -1
  90. package/dist/esm/Channel.js +42 -2
  91. package/dist/esm/Channel.js.map +1 -1
  92. package/dist/esm/Config.js +7 -0
  93. package/dist/esm/Config.js.map +1 -1
  94. package/dist/esm/Context.js +25 -0
  95. package/dist/esm/Context.js.map +1 -1
  96. package/dist/esm/Cron.js +75 -67
  97. package/dist/esm/Cron.js.map +1 -1
  98. package/dist/esm/DateTime.js +112 -627
  99. package/dist/esm/DateTime.js.map +1 -1
  100. package/dist/esm/Effect.js +77 -0
  101. package/dist/esm/Effect.js.map +1 -1
  102. package/dist/esm/Inspectable.js +8 -4
  103. package/dist/esm/Inspectable.js.map +1 -1
  104. package/dist/esm/JSONSchema.js.map +1 -1
  105. package/dist/esm/Micro.js +1077 -1047
  106. package/dist/esm/Micro.js.map +1 -1
  107. package/dist/esm/STM.js.map +1 -1
  108. package/dist/esm/Schema.js +54 -0
  109. package/dist/esm/Schema.js.map +1 -1
  110. package/dist/esm/Sink.js +8 -0
  111. package/dist/esm/Sink.js.map +1 -1
  112. package/dist/esm/Stream.js +23 -5
  113. package/dist/esm/Stream.js.map +1 -1
  114. package/dist/esm/Utils.js +5 -0
  115. package/dist/esm/Utils.js.map +1 -1
  116. package/dist/esm/internal/channel/channelExecutor.js +5 -7
  117. package/dist/esm/internal/channel/channelExecutor.js.map +1 -1
  118. package/dist/esm/internal/channel.js +152 -129
  119. package/dist/esm/internal/channel.js.map +1 -1
  120. package/dist/esm/internal/config.js +11 -3
  121. package/dist/esm/internal/config.js.map +1 -1
  122. package/dist/esm/internal/context.js +42 -2
  123. package/dist/esm/internal/context.js.map +1 -1
  124. package/dist/esm/internal/dateTime.js +704 -0
  125. package/dist/esm/internal/dateTime.js.map +1 -0
  126. package/dist/esm/internal/fiberRuntime.js +31 -9
  127. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  128. package/dist/esm/internal/groupBy.js +9 -3
  129. package/dist/esm/internal/groupBy.js.map +1 -1
  130. package/dist/esm/internal/layer.js +1 -1
  131. package/dist/esm/internal/layer.js.map +1 -1
  132. package/dist/esm/internal/mailbox.js +1 -1
  133. package/dist/esm/internal/mailbox.js.map +1 -1
  134. package/dist/esm/internal/sink.js +23 -20
  135. package/dist/esm/internal/sink.js.map +1 -1
  136. package/dist/esm/internal/stream.js +66 -69
  137. package/dist/esm/internal/stream.js.map +1 -1
  138. package/dist/esm/internal/version.js +1 -1
  139. package/dist/esm/internal/version.js.map +1 -1
  140. package/package.json +1 -1
  141. package/src/BigDecimal.ts +131 -21
  142. package/src/Channel.ts +81 -5
  143. package/src/Config.ts +24 -1
  144. package/src/Context.ts +119 -0
  145. package/src/Cron.ts +85 -68
  146. package/src/DateTime.ts +155 -757
  147. package/src/Effect.ts +340 -1
  148. package/src/Inspectable.ts +11 -7
  149. package/src/JSONSchema.ts +1 -0
  150. package/src/Micro.ts +2005 -1757
  151. package/src/STM.ts +2 -0
  152. package/src/Schema.ts +60 -0
  153. package/src/Sink.ts +11 -0
  154. package/src/Stream.ts +55 -44
  155. package/src/Utils.ts +8 -0
  156. package/src/internal/channel/channelExecutor.ts +37 -33
  157. package/src/internal/channel.ts +504 -467
  158. package/src/internal/config.ts +18 -6
  159. package/src/internal/context.ts +56 -4
  160. package/src/internal/dateTime.ts +1126 -0
  161. package/src/internal/fiberRuntime.ts +35 -16
  162. package/src/internal/groupBy.ts +13 -22
  163. package/src/internal/layer.ts +5 -8
  164. package/src/internal/mailbox.ts +6 -4
  165. package/src/internal/sink.ts +55 -35
  166. package/src/internal/stream.ts +299 -299
  167. package/src/internal/version.ts +1 -1
@@ -910,87 +910,66 @@ export const mapOutEffectPar = dual<
910
910
  f: (o: OutElem) => Effect.Effect<OutElem1, OutErr1, Env1>,
911
911
  n: number
912
912
  ): Channel.Channel<OutElem1, InElem, OutErr | OutErr1, InErr, OutDone, InDone, Env | Env1> =>
913
- pipe(
914
- Effect.gen(function*($) {
915
- const queue = yield* $(
916
- Effect.acquireRelease(
917
- Queue.bounded<Effect.Effect<Either.Either<OutElem1, OutDone>, OutErr | OutErr1, Env1>>(n),
918
- (queue) => Queue.shutdown(queue)
919
- )
920
- )
921
- const errorSignal = yield* $(Deferred.make<never, OutErr1>())
922
- const withPermits = n === Number.POSITIVE_INFINITY ?
923
- ((_: number) => identity) :
924
- (yield* $(Effect.makeSemaphore(n))).withPermits
925
- const pull = yield* $(toPull(self))
926
- yield* $(
927
- Effect.matchCauseEffect(pull, {
928
- onFailure: (cause) => Queue.offer(queue, Effect.failCause(cause)),
929
- onSuccess: (either) =>
930
- Either.match(
931
- either,
932
- {
933
- onLeft: (outDone) => {
934
- const lock = withPermits(n)
935
- return Effect.zipRight(
936
- Effect.interruptible(lock(Effect.void)),
937
- Effect.asVoid(Queue.offer(
938
- queue,
939
- Effect.succeed(Either.left(outDone))
940
- ))
941
- )
942
- },
943
- onRight: (outElem) =>
944
- Effect.gen(function*($) {
945
- const deferred = yield* $(Deferred.make<OutElem1, OutErr1>())
946
- const latch = yield* $(Deferred.make<void>())
947
- yield* $(Effect.asVoid(Queue.offer(
948
- queue,
949
- Effect.map(Deferred.await(deferred), Either.right)
950
- )))
951
- yield* $(
952
- Deferred.succeed(latch, void 0),
953
- Effect.zipRight(
954
- pipe(
955
- Effect.uninterruptibleMask((restore) =>
956
- pipe(
957
- Effect.exit(restore(Deferred.await(errorSignal))),
958
- Effect.raceFirst(Effect.exit(restore(f(outElem)))),
959
- // TODO: remove
960
- Effect.flatMap((exit) => Effect.suspend(() => exit))
961
- )
962
- ),
963
- Effect.tapErrorCause((cause) => Deferred.failCause(errorSignal, cause)),
964
- Effect.intoDeferred(deferred)
913
+ unwrapScopedWith(
914
+ (scope) =>
915
+ Effect.gen(function*() {
916
+ const input = yield* singleProducerAsyncInput.make<InErr, InElem, InDone>()
917
+ const queueReader = fromInput(input)
918
+ const queue = yield* Queue.bounded<Effect.Effect<Either.Either<OutElem1, OutDone>, OutErr | OutErr1, Env1>>(n)
919
+ yield* Scope.addFinalizer(scope, Queue.shutdown(queue))
920
+ const errorSignal = yield* Deferred.make<never, OutErr1>()
921
+ const withPermits = n === Number.POSITIVE_INFINITY ?
922
+ ((_: number) => identity) :
923
+ (yield* Effect.makeSemaphore(n)).withPermits
924
+ const pull = yield* queueReader.pipe(core.pipeTo(self), toPullIn(scope))
925
+ yield* pull.pipe(
926
+ Effect.matchCauseEffect({
927
+ onFailure: (cause) => Queue.offer(queue, Effect.failCause(cause)),
928
+ onSuccess: Either.match({
929
+ onLeft: (outDone) =>
930
+ Effect.zipRight(
931
+ Effect.interruptible(withPermits(n)(Effect.void)),
932
+ Effect.asVoid(Queue.offer(queue, Effect.succeed(Either.left(outDone))))
933
+ ),
934
+ onRight: (outElem) =>
935
+ Effect.gen(function*() {
936
+ const deferred = yield* Deferred.make<OutElem1, OutErr1>()
937
+ const latch = yield* Deferred.make<void>()
938
+ yield* Queue.offer(queue, Effect.map(Deferred.await(deferred), Either.right))
939
+ yield* Deferred.succeed(latch, void 0).pipe(
940
+ Effect.zipRight(
941
+ Effect.uninterruptibleMask((restore) =>
942
+ Effect.exit(restore(Deferred.await(errorSignal))).pipe(
943
+ Effect.raceFirst(Effect.exit(restore(f(outElem)))),
944
+ Effect.flatMap(identity)
965
945
  )
966
- ),
967
- withPermits(1),
968
- Effect.forkScoped
969
- )
970
- yield* $(Deferred.await(latch))
971
- })
972
- }
973
- )
974
- }),
975
- Effect.forever,
976
- Effect.interruptible,
977
- Effect.forkScoped
978
- )
979
- return queue
980
- }),
981
- Effect.map((queue) => {
982
- const consumer: Channel.Channel<OutElem1, unknown, OutErr | OutErr1, unknown, OutDone, unknown, Env1> = unwrap(
983
- Effect.matchCause(Effect.flatten(Queue.take(queue)), {
984
- onFailure: core.failCause,
985
- onSuccess: Either.match({
986
- onLeft: core.succeedNow,
987
- onRight: (outElem) => core.flatMap(core.write(outElem), () => consumer)
946
+ ).pipe(
947
+ Effect.tapErrorCause((cause) => Deferred.failCause(errorSignal, cause)),
948
+ Effect.intoDeferred(deferred)
949
+ )
950
+ ),
951
+ withPermits(1),
952
+ Effect.forkIn(scope)
953
+ )
954
+ yield* Deferred.await(latch)
955
+ })
956
+ })
957
+ }),
958
+ Effect.forever,
959
+ Effect.interruptible,
960
+ Effect.forkIn(scope)
961
+ )
962
+ const consumer: Channel.Channel<OutElem1, unknown, OutErr | OutErr1, unknown, OutDone, unknown, Env1> = unwrap(
963
+ Effect.matchCause(Effect.flatten(Queue.take(queue)), {
964
+ onFailure: core.failCause,
965
+ onSuccess: Either.match({
966
+ onLeft: core.succeedNow,
967
+ onRight: (outElem) => core.flatMap(core.write(outElem), () => consumer)
968
+ })
988
969
  })
989
- })
990
- )
991
- return consumer
992
- }),
993
- unwrapScoped
970
+ )
971
+ return core.embedInput(consumer, input)
972
+ })
994
973
  ))
995
974
 
996
975
  /** @internal */
@@ -1134,180 +1113,168 @@ export const mergeAllWith = (
1134
1113
  InDone & InDone1,
1135
1114
  Env | Env1
1136
1115
  > =>
1137
- pipe(
1138
- Effect.gen(function*($) {
1139
- const concurrencyN = concurrency === "unbounded" ? Number.MAX_SAFE_INTEGER : concurrency
1140
- const input = yield* $(singleProducerAsyncInput.make<
1141
- InErr & InErr1,
1142
- InElem & InElem1,
1143
- InDone & InDone1
1144
- >())
1145
- const queueReader = fromInput(input)
1146
- const queue = yield* $(
1147
- Effect.acquireRelease(
1148
- Queue.bounded<Effect.Effect<Either.Either<OutElem, OutDone>, OutErr | OutErr1, Env>>(bufferSize),
1149
- (queue) => Queue.shutdown(queue)
1150
- )
1151
- )
1152
- const cancelers = yield* $(
1153
- Effect.acquireRelease(
1154
- Queue.unbounded<Deferred.Deferred<void>>(),
1155
- (queue) => Queue.shutdown(queue)
1116
+ unwrapScopedWith(
1117
+ (scope) =>
1118
+ Effect.gen(function*() {
1119
+ const concurrencyN = concurrency === "unbounded" ? Number.MAX_SAFE_INTEGER : concurrency
1120
+ const input = yield* singleProducerAsyncInput.make<
1121
+ InErr & InErr1,
1122
+ InElem & InElem1,
1123
+ InDone & InDone1
1124
+ >()
1125
+ const queueReader = fromInput(input)
1126
+ const queue = yield* Queue.bounded<Effect.Effect<Either.Either<OutElem, OutDone>, OutErr | OutErr1, Env>>(
1127
+ bufferSize
1156
1128
  )
1157
- )
1158
- const lastDone = yield* $(Ref.make<Option.Option<OutDone>>(Option.none()))
1159
- const errorSignal = yield* $(Deferred.make<void>())
1160
- const withPermits = (yield* $(Effect.makeSemaphore(concurrencyN)))
1161
- .withPermits
1162
- const pull = yield* $(toPull(channels))
1163
- const evaluatePull = (
1164
- pull: Effect.Effect<Either.Either<OutElem, OutDone>, OutErr | OutErr1, Env | Env1>
1165
- ) =>
1166
- pipe(
1167
- Effect.flatMap(
1168
- pull,
1169
- Either.match({
1129
+ yield* Scope.addFinalizer(scope, Queue.shutdown(queue))
1130
+ const cancelers = yield* Queue.unbounded<Deferred.Deferred<void>>()
1131
+ yield* Scope.addFinalizer(scope, Queue.shutdown(cancelers))
1132
+ const lastDone = yield* Ref.make<Option.Option<OutDone>>(Option.none())
1133
+ const errorSignal = yield* Deferred.make<void>()
1134
+ const withPermits = (yield* Effect.makeSemaphore(concurrencyN)).withPermits
1135
+ const pull = yield* toPullIn(core.pipeTo(queueReader, channels), scope)
1136
+
1137
+ function evaluatePull(
1138
+ pull: Effect.Effect<
1139
+ Either.Either<OutElem, OutDone>,
1140
+ OutErr | OutErr1,
1141
+ Env | Env1
1142
+ >
1143
+ ) {
1144
+ return pull.pipe(
1145
+ Effect.flatMap(Either.match({
1170
1146
  onLeft: (done) => Effect.succeed(Option.some(done)),
1171
1147
  onRight: (outElem) =>
1172
1148
  Effect.as(
1173
1149
  Queue.offer(queue, Effect.succeed(Either.right(outElem))),
1174
1150
  Option.none()
1175
1151
  )
1176
- })
1177
- ),
1178
- Effect.repeat({ until: (_): _ is Option.Some<OutDone> => Option.isSome(_) }),
1179
- Effect.flatMap((outDone) =>
1180
- Ref.update(
1181
- lastDone,
1182
- Option.match({
1183
- onNone: () => Option.some(outDone.value),
1184
- onSome: (lastDone) => Option.some(f(lastDone, outDone.value))
1185
- })
1186
- )
1187
- ),
1188
- Effect.catchAllCause((cause) =>
1189
- Cause.isInterrupted(cause) ?
1190
- Effect.failCause(cause) :
1191
- pipe(
1192
- Queue.offer(queue, Effect.failCause(cause)),
1193
- Effect.zipRight(Deferred.succeed(errorSignal, void 0)),
1194
- Effect.asVoid
1152
+ })),
1153
+ Effect.repeat({ until: (_): _ is Option.Some<OutDone> => Option.isSome(_) }),
1154
+ Effect.flatMap((outDone) =>
1155
+ Ref.update(
1156
+ lastDone,
1157
+ Option.match({
1158
+ onNone: () => Option.some(outDone.value),
1159
+ onSome: (lastDone) => Option.some(f(lastDone, outDone.value))
1160
+ })
1195
1161
  )
1196
- )
1197
- )
1198
- yield* $(
1199
- Effect.matchCauseEffect(pull, {
1200
- onFailure: (cause) =>
1201
- pipe(
1202
- Queue.offer(queue, Effect.failCause(cause)),
1203
- Effect.zipRight(Effect.succeed(false))
1204
1162
  ),
1205
- onSuccess: Either.match({
1206
- onLeft: (outDone) =>
1207
- Effect.raceWith(
1208
- Effect.interruptible(Deferred.await(errorSignal)),
1209
- Effect.interruptible(withPermits(concurrencyN)(Effect.void)),
1210
- {
1211
- onSelfDone: (_, permitAcquisition) => Effect.as(Fiber.interrupt(permitAcquisition), false),
1212
- onOtherDone: (_, failureAwait) =>
1213
- Effect.zipRight(
1214
- Fiber.interrupt(failureAwait),
1215
- pipe(
1216
- Ref.get(lastDone),
1217
- Effect.flatMap(Option.match({
1218
- onNone: () => Queue.offer(queue, Effect.succeed(Either.left(outDone))),
1219
- onSome: (lastDone) => Queue.offer(queue, Effect.succeed(Either.left(f(lastDone, outDone))))
1220
- })),
1221
- Effect.as(false)
1222
- )
1223
- )
1224
- }
1163
+ Effect.catchAllCause((cause) =>
1164
+ Cause.isInterrupted(cause)
1165
+ ? Effect.failCause(cause)
1166
+ : Queue.offer(queue, Effect.failCause(cause)).pipe(
1167
+ Effect.zipRight(Deferred.succeed(errorSignal, void 0)),
1168
+ Effect.asVoid
1169
+ )
1170
+ )
1171
+ )
1172
+ }
1173
+
1174
+ yield* pull.pipe(
1175
+ Effect.matchCauseEffect({
1176
+ onFailure: (cause) =>
1177
+ Queue.offer(queue, Effect.failCause(cause)).pipe(
1178
+ Effect.zipRight(Effect.succeed(false))
1225
1179
  ),
1226
- onRight: (channel) =>
1227
- _mergeStrategy.match(mergeStrategy, {
1228
- onBackPressure: () =>
1229
- Effect.gen(function*($) {
1230
- const latch = yield* $(Deferred.make<void>())
1231
- const raceEffects: Effect.Effect<void, OutErr | OutErr1, Env | Env1> = pipe(
1232
- queueReader,
1233
- core.pipeTo(channel),
1234
- toPull,
1235
- Effect.flatMap((pull) =>
1236
- Effect.race(
1237
- evaluatePull(pull),
1238
- Effect.interruptible(Deferred.await(errorSignal))
1180
+ onSuccess: Either.match({
1181
+ onLeft: (outDone) =>
1182
+ Effect.raceWith(
1183
+ Effect.interruptible(Deferred.await(errorSignal)),
1184
+ Effect.interruptible(withPermits(concurrencyN)(Effect.void)),
1185
+ {
1186
+ onSelfDone: (_, permitAcquisition) => Effect.as(Fiber.interrupt(permitAcquisition), false),
1187
+ onOtherDone: (_, failureAwait) =>
1188
+ Effect.zipRight(
1189
+ Fiber.interrupt(failureAwait),
1190
+ Ref.get(lastDone).pipe(
1191
+ Effect.flatMap(Option.match({
1192
+ onNone: () => Queue.offer(queue, Effect.succeed(Either.left(outDone))),
1193
+ onSome: (lastDone) => Queue.offer(queue, Effect.succeed(Either.left(f(lastDone, outDone))))
1194
+ })),
1195
+ Effect.as(false)
1239
1196
  )
1240
- ),
1241
- Effect.scoped
1242
- )
1243
- yield* $(
1244
- Deferred.succeed(latch, void 0),
1245
- Effect.zipRight(raceEffects),
1246
- withPermits(1),
1247
- Effect.forkScoped
1248
- )
1249
- yield* $(Deferred.await(latch))
1250
- const errored = yield* $(Deferred.isDone(errorSignal))
1251
- return !errored
1252
- }),
1253
- onBufferSliding: () =>
1254
- Effect.gen(function*($) {
1255
- const canceler = yield* $(Deferred.make<void>())
1256
- const latch = yield* $(Deferred.make<void>())
1257
- const size = yield* $(Queue.size(cancelers))
1258
- yield* $(
1259
- Queue.take(cancelers),
1260
- Effect.flatMap((_) => Deferred.succeed(_, void 0)),
1261
- Effect.when(() => size >= concurrencyN)
1262
- )
1263
- yield* $(Queue.offer(cancelers, canceler))
1264
- const raceEffects: Effect.Effect<void, OutErr | OutErr1, Env | Env1> = pipe(
1265
- queueReader,
1266
- core.pipeTo(channel),
1267
- toPull,
1268
- Effect.flatMap((pull) =>
1269
- pipe(
1270
- evaluatePull(pull),
1271
- Effect.race(Effect.interruptible(Deferred.await(errorSignal))),
1272
- Effect.race(Effect.interruptible(Deferred.await(canceler)))
1197
+ )
1198
+ }
1199
+ ),
1200
+ onRight: (channel) =>
1201
+ _mergeStrategy.match(mergeStrategy, {
1202
+ onBackPressure: () =>
1203
+ Effect.gen(function*() {
1204
+ const latch = yield* Deferred.make<void>()
1205
+ const raceEffects = Effect.scopedWith((scope) =>
1206
+ toPullIn(core.pipeTo(queueReader, channel), scope).pipe(
1207
+ Effect.flatMap((pull) =>
1208
+ Effect.race(
1209
+ Effect.exit(evaluatePull(pull)),
1210
+ Effect.exit(Effect.interruptible(Deferred.await(errorSignal)))
1211
+ )
1212
+ ),
1213
+ Effect.flatMap(identity)
1273
1214
  )
1274
- ),
1275
- Effect.scoped
1276
- )
1277
- yield* $(
1278
- Deferred.succeed(latch, void 0),
1279
- Effect.zipRight(raceEffects),
1280
- withPermits(1),
1281
- Effect.forkScoped
1282
- )
1283
- yield* $(Deferred.await(latch))
1284
- const errored = yield* $(Deferred.isDone(errorSignal))
1285
- return !errored
1286
- })
1215
+ )
1216
+ yield* Deferred.succeed(latch, void 0).pipe(
1217
+ Effect.zipRight(raceEffects),
1218
+ withPermits(1),
1219
+ Effect.forkIn(scope)
1220
+ )
1221
+ yield* Deferred.await(latch)
1222
+ const errored = yield* Deferred.isDone(errorSignal)
1223
+ return !errored
1224
+ }),
1225
+ onBufferSliding: () =>
1226
+ Effect.gen(function*() {
1227
+ const canceler = yield* Deferred.make<void>()
1228
+ const latch = yield* Deferred.make<void>()
1229
+ const size = yield* Queue.size(cancelers)
1230
+ yield* Queue.take(cancelers).pipe(
1231
+ Effect.flatMap((canceler) => Deferred.succeed(canceler, void 0)),
1232
+ Effect.when(() => size >= concurrencyN)
1233
+ )
1234
+ yield* Queue.offer(cancelers, canceler)
1235
+ const raceEffects = Effect.scopedWith((scope) =>
1236
+ toPullIn(core.pipeTo(queueReader, channel), scope).pipe(
1237
+ Effect.flatMap((pull) =>
1238
+ Effect.exit(evaluatePull(pull)).pipe(
1239
+ Effect.race(Effect.exit(Effect.interruptible(Deferred.await(errorSignal)))),
1240
+ Effect.race(Effect.exit(Effect.interruptible(Deferred.await(canceler))))
1241
+ )
1242
+ ),
1243
+ Effect.flatMap(identity)
1244
+ )
1245
+ )
1246
+ yield* Deferred.succeed(latch, void 0).pipe(
1247
+ Effect.zipRight(raceEffects),
1248
+ withPermits(1),
1249
+ Effect.forkIn(scope)
1250
+ )
1251
+ yield* Deferred.await(latch)
1252
+ const errored = yield* Deferred.isDone(errorSignal)
1253
+ return !errored
1254
+ })
1255
+ })
1256
+ })
1257
+ }),
1258
+ Effect.repeat({ while: (_) => _ }),
1259
+ Effect.forkIn(scope)
1260
+ )
1261
+
1262
+ const consumer: Channel.Channel<OutElem, unknown, OutErr | OutErr1, unknown, OutDone, unknown, Env | Env1> =
1263
+ pipe(
1264
+ Queue.take(queue),
1265
+ Effect.flatten,
1266
+ Effect.matchCause({
1267
+ onFailure: core.failCause,
1268
+ onSuccess: Either.match({
1269
+ onLeft: core.succeedNow,
1270
+ onRight: (outElem) => core.flatMap(core.write(outElem), () => consumer)
1287
1271
  })
1288
- })
1289
- }),
1290
- Effect.repeat({ while: (_) => _ }),
1291
- Effect.forkScoped
1292
- )
1293
- return [queue, input] as const
1294
- }),
1295
- Effect.map(([queue, input]) => {
1296
- const consumer: Channel.Channel<OutElem, unknown, OutErr | OutErr1, unknown, OutDone, unknown, Env | Env1> = pipe(
1297
- Queue.take(queue),
1298
- Effect.flatten,
1299
- Effect.matchCause({
1300
- onFailure: core.failCause,
1301
- onSuccess: Either.match({
1302
- onLeft: core.succeedNow,
1303
- onRight: (outElem) => core.flatMap(core.write(outElem), () => consumer)
1304
- })
1305
- }),
1306
- unwrap
1307
- )
1308
- return core.embedInput(consumer, input)
1309
- }),
1310
- unwrapScoped
1272
+ }),
1273
+ unwrap
1274
+ )
1275
+
1276
+ return core.embedInput(consumer, input)
1277
+ })
1311
1278
  )
1312
1279
 
1313
1280
  /** @internal */
@@ -1596,132 +1563,76 @@ export const mergeWith = dual<
1596
1563
  OutDone2 | OutDone3,
1597
1564
  InDone & InDone1,
1598
1565
  Env1 | Env
1599
- > =>
1600
- unwrapScoped(
1601
- Effect.flatMap(
1602
- singleProducerAsyncInput.make<
1566
+ > => {
1567
+ function merge(scope: Scope.Scope) {
1568
+ return Effect.gen(function*() {
1569
+ type State = MergeState.MergeState<
1570
+ Env | Env1,
1571
+ OutErr,
1572
+ OutErr1,
1573
+ OutErr2 | OutErr3,
1574
+ OutElem | OutElem1,
1575
+ OutDone,
1576
+ OutDone1,
1577
+ OutDone2 | OutDone3
1578
+ >
1579
+
1580
+ const input = yield* singleProducerAsyncInput.make<
1603
1581
  InErr & InErr1,
1604
1582
  InElem & InElem1,
1605
1583
  InDone & InDone1
1606
- >(),
1607
- (input) => {
1608
- const queueReader = fromInput(input)
1609
- return Effect.map(
1610
- Effect.all([
1611
- toPull(core.pipeTo(queueReader, self)),
1612
- toPull(core.pipeTo(queueReader, options.other)),
1613
- Effect.scope
1614
- ]),
1615
- ([pullL, pullR, scope]) => {
1616
- type State = MergeState.MergeState<
1584
+ >()
1585
+ const queueReader = fromInput(input)
1586
+ const pullL = yield* toPullIn(core.pipeTo(queueReader, self), scope)
1587
+ const pullR = yield* toPullIn(core.pipeTo(queueReader, options.other), scope)
1588
+
1589
+ function handleSide<Err, Done, Err2, Done2>(
1590
+ exit: Exit.Exit<Either.Either<OutElem | OutElem1, Done>, Err>,
1591
+ fiber: Fiber.Fiber<Either.Either<OutElem | OutElem1, Done2>, Err2>,
1592
+ pull: Effect.Effect<Either.Either<OutElem | OutElem1, Done>, Err, Env | Env1>
1593
+ ) {
1594
+ return (
1595
+ done: (
1596
+ ex: Exit.Exit<Done, Err>
1597
+ ) => MergeDecision.MergeDecision<
1598
+ Env | Env1,
1599
+ Err2,
1600
+ Done2,
1601
+ OutErr2 | OutErr3,
1602
+ OutDone2 | OutDone3
1603
+ >,
1604
+ both: (
1605
+ f1: Fiber.Fiber<Either.Either<OutElem | OutElem1, Done>, Err>,
1606
+ f2: Fiber.Fiber<Either.Either<OutElem | OutElem1, Done2>, Err2>
1607
+ ) => State,
1608
+ single: (
1609
+ f: (
1610
+ ex: Exit.Exit<Done2, Err2>
1611
+ ) => Effect.Effect<OutDone2 | OutDone3, OutErr2 | OutErr3, Env | Env1>
1612
+ ) => State
1613
+ ): Effect.Effect<
1614
+ Channel.Channel<
1615
+ OutElem | OutElem1,
1616
+ unknown,
1617
+ OutErr2 | OutErr3,
1618
+ unknown,
1619
+ OutDone2 | OutDone3,
1620
+ unknown,
1621
+ Env | Env1
1622
+ >,
1623
+ never,
1624
+ Env | Env1
1625
+ > => {
1626
+ function onDecision(
1627
+ decision: MergeDecision.MergeDecision<
1617
1628
  Env | Env1,
1618
- OutErr,
1619
- OutErr1,
1629
+ Err2,
1630
+ Done2,
1620
1631
  OutErr2 | OutErr3,
1621
- OutElem | OutElem1,
1622
- OutDone,
1623
- OutDone1,
1624
1632
  OutDone2 | OutDone3
1625
1633
  >
1626
-
1627
- const handleSide = <Err, Done, Err2, Done2>(
1628
- exit: Exit.Exit<Either.Either<OutElem | OutElem1, Done>, Err>,
1629
- fiber: Fiber.Fiber<Either.Either<OutElem | OutElem1, Done2>, Err2>,
1630
- pull: Effect.Effect<Either.Either<OutElem | OutElem1, Done>, Err, Env | Env1>
1631
- ) =>
1632
- (
1633
- done: (
1634
- ex: Exit.Exit<Done, Err>
1635
- ) => MergeDecision.MergeDecision<
1636
- Env | Env1,
1637
- Err2,
1638
- Done2,
1639
- OutErr2 | OutErr3,
1640
- OutDone2 | OutDone3
1641
- >,
1642
- both: (
1643
- f1: Fiber.Fiber<Either.Either<OutElem | OutElem1, Done>, Err>,
1644
- f2: Fiber.Fiber<Either.Either<OutElem | OutElem1, Done2>, Err2>
1645
- ) => State,
1646
- single: (
1647
- f: (
1648
- ex: Exit.Exit<Done2, Err2>
1649
- ) => Effect.Effect<OutDone2 | OutDone3, OutErr2 | OutErr3, Env | Env1>
1650
- ) => State
1651
- ): Effect.Effect<
1652
- Channel.Channel<
1653
- OutElem | OutElem1,
1654
- unknown,
1655
- OutErr2 | OutErr3,
1656
- unknown,
1657
- OutDone2 | OutDone3,
1658
- unknown,
1659
- Env | Env1
1660
- >,
1661
- never,
1662
- Env | Env1
1663
- > => {
1664
- const onDecision = (
1665
- decision: MergeDecision.MergeDecision<
1666
- Env | Env1,
1667
- Err2,
1668
- Done2,
1669
- OutErr2 | OutErr3,
1670
- OutDone2 | OutDone3
1671
- >
1672
- ): Effect.Effect<
1673
- Channel.Channel<
1674
- OutElem | OutElem1,
1675
- unknown,
1676
- OutErr2 | OutErr3,
1677
- unknown,
1678
- OutDone2 | OutDone3,
1679
- unknown,
1680
- Env | Env1
1681
- >
1682
- > => {
1683
- const op = decision as mergeDecision.Primitive
1684
- if (op._tag === MergeDecisionOpCodes.OP_DONE) {
1685
- return Effect.succeed(
1686
- core.fromEffect(
1687
- Effect.zipRight(
1688
- Fiber.interrupt(fiber),
1689
- op.effect
1690
- )
1691
- )
1692
- )
1693
- }
1694
- return Effect.map(
1695
- Fiber.await(fiber),
1696
- Exit.match({
1697
- onFailure: (cause) => core.fromEffect(op.f(Exit.failCause(cause))),
1698
- onSuccess: Either.match({
1699
- onLeft: (done) => core.fromEffect(op.f(Exit.succeed(done))),
1700
- onRight: (elem) => zipRight(core.write(elem), go(single(op.f)))
1701
- })
1702
- })
1703
- )
1704
- }
1705
-
1706
- return Exit.match(exit, {
1707
- onFailure: (cause) => onDecision(done(Exit.failCause(cause))),
1708
- onSuccess: Either.match({
1709
- onLeft: (z) => onDecision(done(Exit.succeed(z))),
1710
- onRight: (elem) =>
1711
- Effect.succeed(
1712
- core.flatMap(core.write(elem), () =>
1713
- core.flatMap(
1714
- core.fromEffect(Effect.forkIn(Effect.interruptible(pull), scope)),
1715
- (leftFiber) => go(both(leftFiber, fiber))
1716
- ))
1717
- )
1718
- })
1719
- })
1720
- }
1721
-
1722
- const go = (
1723
- state: State
1724
- ): Channel.Channel<
1634
+ ): Effect.Effect<
1635
+ Channel.Channel<
1725
1636
  OutElem | OutElem1,
1726
1637
  unknown,
1727
1638
  OutErr2 | OutErr3,
@@ -1729,107 +1640,184 @@ export const mergeWith = dual<
1729
1640
  OutDone2 | OutDone3,
1730
1641
  unknown,
1731
1642
  Env | Env1
1732
- > => {
1733
- switch (state._tag) {
1734
- case MergeStateOpCodes.OP_BOTH_RUNNING: {
1735
- const leftJoin = Effect.interruptible(Fiber.join(state.left))
1736
- const rightJoin = Effect.interruptible(Fiber.join(state.right))
1737
- return unwrap(
1738
- Effect.raceWith(leftJoin, rightJoin, {
1739
- onSelfDone: (leftExit, rf) =>
1740
- Effect.zipRight(
1741
- Fiber.interrupt(rf),
1742
- handleSide(leftExit, state.right, pullL)(
1743
- options.onSelfDone,
1744
- mergeState.BothRunning,
1745
- (f) => mergeState.LeftDone(f)
1746
- )
1747
- ),
1748
- onOtherDone: (rightExit, lf) =>
1749
- Effect.zipRight(
1750
- Fiber.interrupt(lf),
1751
- handleSide(rightExit, state.left, pullR)(
1752
- options.onOtherDone as (
1753
- ex: Exit.Exit<OutDone1, InErr1 | OutErr1>
1754
- ) => MergeDecision.MergeDecision<
1755
- Env1 | Env,
1756
- OutErr,
1757
- OutDone,
1758
- OutErr2 | OutErr3,
1759
- OutDone2 | OutDone3
1760
- >,
1761
- (left, right) => mergeState.BothRunning(right, left),
1762
- (f) => mergeState.RightDone(f)
1763
- )
1764
- )
1765
- })
1766
- )
1767
- }
1768
- case MergeStateOpCodes.OP_LEFT_DONE: {
1769
- return unwrap(
1770
- Effect.map(
1771
- Effect.exit(pullR),
1772
- Exit.match({
1773
- onFailure: (cause) => core.fromEffect(state.f(Exit.failCause(cause))),
1774
- onSuccess: Either.match({
1775
- onLeft: (done) => core.fromEffect(state.f(Exit.succeed(done))),
1776
- onRight: (elem) =>
1777
- core.flatMap(
1778
- core.write(elem),
1779
- () => go(mergeState.LeftDone(state.f))
1780
- )
1781
- })
1782
- })
1783
- )
1784
- )
1785
- }
1786
- case MergeStateOpCodes.OP_RIGHT_DONE: {
1787
- return unwrap(
1788
- Effect.map(
1789
- Effect.exit(pullL),
1790
- Exit.match({
1791
- onFailure: (cause) => core.fromEffect(state.f(Exit.failCause(cause))),
1792
- onSuccess: Either.match({
1793
- onLeft: (done) => core.fromEffect(state.f(Exit.succeed(done))),
1794
- onRight: (elem) =>
1795
- core.flatMap(
1796
- core.write(elem),
1797
- () => go(mergeState.RightDone(state.f))
1798
- )
1799
- })
1800
- })
1801
- )
1643
+ >
1644
+ > {
1645
+ const op = decision as mergeDecision.Primitive
1646
+ if (op._tag === MergeDecisionOpCodes.OP_DONE) {
1647
+ return Effect.succeed(
1648
+ core.fromEffect(
1649
+ Effect.zipRight(
1650
+ Fiber.interrupt(fiber),
1651
+ op.effect
1802
1652
  )
1803
- }
1804
- }
1653
+ )
1654
+ )
1805
1655
  }
1656
+ return Effect.map(
1657
+ Fiber.await(fiber),
1658
+ Exit.match({
1659
+ onFailure: (cause) => core.fromEffect(op.f(Exit.failCause(cause))),
1660
+ onSuccess: Either.match({
1661
+ onLeft: (done) => core.fromEffect(op.f(Exit.succeed(done))),
1662
+ onRight: (elem) => zipRight(core.write(elem), go(single(op.f)))
1663
+ })
1664
+ })
1665
+ )
1666
+ }
1806
1667
 
1807
- return pipe(
1808
- core.fromEffect(
1809
- Effect.zipWith(
1810
- Effect.forkIn(Effect.interruptible(pullL), scope),
1811
- Effect.forkIn(Effect.interruptible(pullR), scope),
1812
- (left, right): State =>
1813
- mergeState.BothRunning<
1814
- Env | Env1,
1815
- OutErr,
1816
- OutErr1,
1817
- OutErr2 | OutErr3,
1818
- OutElem | OutElem1,
1819
- OutDone,
1820
- OutDone1,
1821
- OutDone2 | OutDone3
1822
- >(left, right)
1668
+ return Exit.match(exit, {
1669
+ onFailure: (cause) => onDecision(done(Exit.failCause(cause))),
1670
+ onSuccess: Either.match({
1671
+ onLeft: (z) => onDecision(done(Exit.succeed(z))),
1672
+ onRight: (elem) =>
1673
+ Effect.succeed(
1674
+ core.flatMap(core.write(elem), () =>
1675
+ core.flatMap(
1676
+ core.fromEffect(Effect.forkIn(Effect.interruptible(pull), scope)),
1677
+ (leftFiber) => go(both(leftFiber, fiber))
1678
+ ))
1823
1679
  )
1824
- ),
1825
- core.flatMap(go),
1826
- core.embedInput(input)
1680
+ })
1681
+ })
1682
+ }
1683
+ }
1684
+
1685
+ function go(
1686
+ state: State
1687
+ ): Channel.Channel<
1688
+ OutElem | OutElem1,
1689
+ unknown,
1690
+ OutErr2 | OutErr3,
1691
+ unknown,
1692
+ OutDone2 | OutDone3,
1693
+ unknown,
1694
+ Env | Env1
1695
+ > {
1696
+ switch (state._tag) {
1697
+ case MergeStateOpCodes.OP_BOTH_RUNNING: {
1698
+ const leftJoin = Effect.interruptible(Fiber.join(state.left))
1699
+ const rightJoin = Effect.interruptible(Fiber.join(state.right))
1700
+ return unwrap(
1701
+ Effect.raceWith(leftJoin, rightJoin, {
1702
+ onSelfDone: (leftExit, rf) =>
1703
+ Effect.zipRight(
1704
+ Fiber.interrupt(rf),
1705
+ handleSide(leftExit, state.right, pullL)(
1706
+ options.onSelfDone,
1707
+ mergeState.BothRunning,
1708
+ (f) => mergeState.LeftDone(f)
1709
+ )
1710
+ ),
1711
+ onOtherDone: (rightExit, lf) =>
1712
+ Effect.zipRight(
1713
+ Fiber.interrupt(lf),
1714
+ handleSide(rightExit, state.left, pullR)(
1715
+ options.onOtherDone as (
1716
+ ex: Exit.Exit<OutDone1, InErr1 | OutErr1>
1717
+ ) => MergeDecision.MergeDecision<
1718
+ Env1 | Env,
1719
+ OutErr,
1720
+ OutDone,
1721
+ OutErr2 | OutErr3,
1722
+ OutDone2 | OutDone3
1723
+ >,
1724
+ (left, right) => mergeState.BothRunning(right, left),
1725
+ (f) => mergeState.RightDone(f)
1726
+ )
1727
+ )
1728
+ })
1827
1729
  )
1828
1730
  }
1829
- )
1731
+ case MergeStateOpCodes.OP_LEFT_DONE: {
1732
+ return unwrap(
1733
+ Effect.map(
1734
+ Effect.exit(pullR),
1735
+ Exit.match({
1736
+ onFailure: (cause) => core.fromEffect(state.f(Exit.failCause(cause))),
1737
+ onSuccess: Either.match({
1738
+ onLeft: (done) => core.fromEffect(state.f(Exit.succeed(done))),
1739
+ onRight: (elem) =>
1740
+ core.flatMap(
1741
+ core.write(elem),
1742
+ () => go(mergeState.LeftDone(state.f))
1743
+ )
1744
+ })
1745
+ })
1746
+ )
1747
+ )
1748
+ }
1749
+ case MergeStateOpCodes.OP_RIGHT_DONE: {
1750
+ return unwrap(
1751
+ Effect.map(
1752
+ Effect.exit(pullL),
1753
+ Exit.match({
1754
+ onFailure: (cause) => core.fromEffect(state.f(Exit.failCause(cause))),
1755
+ onSuccess: Either.match({
1756
+ onLeft: (done) => core.fromEffect(state.f(Exit.succeed(done))),
1757
+ onRight: (elem) =>
1758
+ core.flatMap(
1759
+ core.write(elem),
1760
+ () => go(mergeState.RightDone(state.f))
1761
+ )
1762
+ })
1763
+ })
1764
+ )
1765
+ )
1766
+ }
1767
+ }
1830
1768
  }
1831
- )
1832
- ))
1769
+
1770
+ return core.fromEffect(
1771
+ Effect.withFiberRuntime<
1772
+ MergeState.MergeState<
1773
+ Env | Env1,
1774
+ OutErr,
1775
+ OutErr1,
1776
+ OutErr2 | OutErr3,
1777
+ OutElem | OutElem1,
1778
+ OutDone,
1779
+ OutDone1,
1780
+ OutDone2 | OutDone3
1781
+ >,
1782
+ never,
1783
+ Env | Env1
1784
+ >((parent) => {
1785
+ const inherit = Effect.withFiberRuntime<void, never, never>((state) => {
1786
+ ;(state as any).transferChildren((parent as any).scope())
1787
+ return Effect.void
1788
+ })
1789
+ const leftFiber = Effect.interruptible(pullL).pipe(
1790
+ Effect.ensuring(inherit),
1791
+ Effect.forkIn(scope)
1792
+ )
1793
+ const rightFiber = Effect.interruptible(pullR).pipe(
1794
+ Effect.ensuring(inherit),
1795
+ Effect.forkIn(scope)
1796
+ )
1797
+ return Effect.zipWith(
1798
+ leftFiber,
1799
+ rightFiber,
1800
+ (left, right): State =>
1801
+ mergeState.BothRunning<
1802
+ Env | Env1,
1803
+ OutErr,
1804
+ OutErr1,
1805
+ OutErr2 | OutErr3,
1806
+ OutElem | OutElem1,
1807
+ OutDone,
1808
+ OutDone1,
1809
+ OutDone2 | OutDone3
1810
+ >(left, right)
1811
+ )
1812
+ })
1813
+ ).pipe(
1814
+ core.flatMap(go),
1815
+ core.embedInput(input)
1816
+ )
1817
+ })
1818
+ }
1819
+ return unwrapScopedWith(merge)
1820
+ })
1833
1821
 
1834
1822
  /** @internal */
1835
1823
  export const never: Channel.Channel<never, unknown, never, unknown, never, unknown> = core.fromEffect(
@@ -2003,7 +1991,9 @@ export const provideLayer = dual<
2003
1991
  self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
2004
1992
  layer: Layer.Layer<Env, OutErr2, Env0>
2005
1993
  ): Channel.Channel<OutElem, InElem, OutErr | OutErr2, InErr, OutDone, InDone, Env0> =>
2006
- unwrapScoped(Effect.map(Layer.build(layer), (env) => core.provideContext(self, env))))
1994
+ unwrapScopedWith((scope) =>
1995
+ Effect.map(Layer.buildWithScope(layer, scope), (context) => core.provideContext(self, context))
1996
+ ))
2007
1997
 
2008
1998
  /** @internal */
2009
1999
  export const mapInputContext = dual<
@@ -2052,18 +2042,22 @@ export const repeated = <OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>(
2052
2042
  /** @internal */
2053
2043
  export const run = <OutErr, InErr, OutDone, InDone, Env>(
2054
2044
  self: Channel.Channel<never, unknown, OutErr, InErr, OutDone, InDone, Env>
2055
- ): Effect.Effect<OutDone, OutErr, Exclude<Env, Scope.Scope>> => Effect.scoped(executor.runScoped(self))
2045
+ ): Effect.Effect<OutDone, OutErr, Env> => Effect.scopedWith((scope) => executor.runIn(self, scope))
2056
2046
 
2057
2047
  /** @internal */
2058
2048
  export const runCollect = <OutElem, OutErr, InErr, OutDone, InDone, Env>(
2059
2049
  self: Channel.Channel<OutElem, unknown, OutErr, InErr, OutDone, InDone, Env>
2060
- ): Effect.Effect<[Chunk.Chunk<OutElem>, OutDone], OutErr, Exclude<Env, Scope.Scope>> =>
2061
- executor.run(core.collectElements(self))
2050
+ ): Effect.Effect<[Chunk.Chunk<OutElem>, OutDone], OutErr, Env> => run(core.collectElements(self))
2062
2051
 
2063
2052
  /** @internal */
2064
2053
  export const runDrain = <OutElem, OutErr, InErr, OutDone, InDone, Env>(
2065
2054
  self: Channel.Channel<OutElem, unknown, OutErr, InErr, OutDone, InDone, Env>
2066
- ): Effect.Effect<OutDone, OutErr, Exclude<Env, Scope.Scope>> => executor.run(drain(self))
2055
+ ): Effect.Effect<OutDone, OutErr, Env> => run(drain(self))
2056
+
2057
+ /** @internal */
2058
+ export const runScoped = <OutErr, InErr, OutDone, InDone, Env>(
2059
+ self: Channel.Channel<never, unknown, OutErr, InErr, OutDone, InDone, Env>
2060
+ ): Effect.Effect<OutDone, OutErr, Env | Scope.Scope> => Effect.scopeWith((scope) => executor.runIn(self, scope))
2067
2061
 
2068
2062
  /** @internal */
2069
2063
  export const scoped = <A, E, R>(
@@ -2082,6 +2076,12 @@ export const scoped = <A, E, R>(
2082
2076
  )
2083
2077
  )
2084
2078
 
2079
+ /** @internal */
2080
+ export const scopedWith = <A, E, R>(
2081
+ f: (scope: Scope.Scope) => Effect.Effect<A, E, R>
2082
+ ): Channel.Channel<A, unknown, E, unknown, unknown, unknown, R> =>
2083
+ unwrapScoped(Effect.map(Effect.scope, (scope) => core.flatMap(core.fromEffect(f(scope)), core.write)))
2084
+
2085
2085
  /** @internal */
2086
2086
  export const service = <T extends Context.Tag<any, any>>(
2087
2087
  tag: T
@@ -2210,16 +2210,43 @@ export const toPubSub = <Done, Err, Elem>(
2210
2210
  export const toPull = <OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>(
2211
2211
  self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>
2212
2212
  ): Effect.Effect<Effect.Effect<Either.Either<OutElem, OutDone>, OutErr, Env>, never, Env | Scope.Scope> =>
2213
- Effect.map(
2214
- Effect.acquireRelease(
2215
- Effect.sync(() => new executor.ChannelExecutor(self, void 0, identity)),
2216
- (exec, exit) => {
2217
- const finalize = exec.close(exit)
2218
- return finalize === undefined ? Effect.void : finalize
2219
- }
2213
+ Effect.flatMap(Effect.scope, (scope) => toPullIn(self, scope))
2214
+
2215
+ /** @internal */
2216
+ export const toPullIn = dual<
2217
+ (scope: Scope.Scope) => <OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>(
2218
+ self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>
2219
+ ) => Effect.Effect<Effect.Effect<Either.Either<OutElem, OutDone>, OutErr, Env>, never, Env>,
2220
+ <OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>(
2221
+ self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
2222
+ scope: Scope.Scope
2223
+ ) => Effect.Effect<Effect.Effect<Either.Either<OutElem, OutDone>, OutErr, Env>, never, Env>
2224
+ >(2, <OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>(
2225
+ self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
2226
+ scope: Scope.Scope
2227
+ ) =>
2228
+ Effect.zip(
2229
+ Effect.sync(() => new executor.ChannelExecutor(self, void 0, identity)),
2230
+ Effect.runtime<Env>()
2231
+ ).pipe(
2232
+ Effect.tap(([executor, runtime]) =>
2233
+ Scope.addFinalizerExit(scope, (exit) => {
2234
+ const finalizer = executor.close(exit)
2235
+ return finalizer !== undefined
2236
+ ? Effect.provide(finalizer, runtime)
2237
+ : Effect.void
2238
+ })
2220
2239
  ),
2221
- (exec) => Effect.suspend(() => interpretToPull(exec.run() as ChannelState.ChannelState<OutErr, Env>, exec))
2222
- )
2240
+ Effect.uninterruptible,
2241
+ Effect.map(([executor]) =>
2242
+ Effect.suspend(() =>
2243
+ interpretToPull(
2244
+ executor.run() as ChannelState.ChannelState<OutErr, Env>,
2245
+ executor
2246
+ )
2247
+ )
2248
+ )
2249
+ ))
2223
2250
 
2224
2251
  /** @internal */
2225
2252
  const interpretToPull = <Env, InErr, InElem, InDone, OutErr, OutElem, OutDone>(
@@ -2289,6 +2316,16 @@ export const unwrapScoped = <OutElem, InElem, OutErr, InErr, OutDone, InDone, En
2289
2316
  (d, _) => d
2290
2317
  )
2291
2318
 
2319
+ /** @internal */
2320
+ export const unwrapScopedWith = <OutElem, InElem, OutErr, InErr, OutDone, InDone, Env, E, R>(
2321
+ f: (scope: Scope.Scope) => Effect.Effect<Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>, E, R>
2322
+ ): Channel.Channel<OutElem, InElem, E | OutErr, InErr, OutDone, InDone, R | Env> =>
2323
+ core.concatAllWith(
2324
+ scopedWith(f),
2325
+ (d, _) => d,
2326
+ (d, _) => d
2327
+ )
2328
+
2292
2329
  /** @internal */
2293
2330
  export const updateService = dual<
2294
2331
  <T extends Context.Tag<any, any>>(