effect 3.12.11 → 3.13.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 (204) hide show
  1. package/README.md +38 -49
  2. package/dist/cjs/Channel.js.map +1 -1
  3. package/dist/cjs/DateTime.js +17 -1
  4. package/dist/cjs/DateTime.js.map +1 -1
  5. package/dist/cjs/Differ.js.map +1 -1
  6. package/dist/cjs/Duration.js +128 -1
  7. package/dist/cjs/Duration.js.map +1 -1
  8. package/dist/cjs/Effect.js +175 -37
  9. package/dist/cjs/Effect.js.map +1 -1
  10. package/dist/cjs/Either.js +2 -1
  11. package/dist/cjs/Either.js.map +1 -1
  12. package/dist/cjs/FiberHandle.js +54 -21
  13. package/dist/cjs/FiberHandle.js.map +1 -1
  14. package/dist/cjs/FiberMap.js +51 -24
  15. package/dist/cjs/FiberMap.js.map +1 -1
  16. package/dist/cjs/FiberSet.js +50 -17
  17. package/dist/cjs/FiberSet.js.map +1 -1
  18. package/dist/cjs/HashMap.js +19 -1
  19. package/dist/cjs/HashMap.js.map +1 -1
  20. package/dist/cjs/HashSet.js +9 -1
  21. package/dist/cjs/HashSet.js.map +1 -1
  22. package/dist/cjs/Layer.js +21 -1
  23. package/dist/cjs/Layer.js.map +1 -1
  24. package/dist/cjs/Match.js +659 -38
  25. package/dist/cjs/Match.js.map +1 -1
  26. package/dist/cjs/RcMap.js +11 -1
  27. package/dist/cjs/RcMap.js.map +1 -1
  28. package/dist/cjs/Reloadable.js.map +1 -1
  29. package/dist/cjs/STM.js.map +1 -1
  30. package/dist/cjs/Schedule.js +1074 -309
  31. package/dist/cjs/Schedule.js.map +1 -1
  32. package/dist/cjs/Schema.js +73 -1
  33. package/dist/cjs/Schema.js.map +1 -1
  34. package/dist/cjs/Stream.js.map +1 -1
  35. package/dist/cjs/internal/channel.js.map +1 -1
  36. package/dist/cjs/internal/core-effect.js.map +1 -1
  37. package/dist/cjs/internal/core.js +27 -3
  38. package/dist/cjs/internal/core.js.map +1 -1
  39. package/dist/cjs/internal/dateTime.js +4 -1
  40. package/dist/cjs/internal/dateTime.js.map +1 -1
  41. package/dist/cjs/internal/differ.js +4 -0
  42. package/dist/cjs/internal/differ.js.map +1 -1
  43. package/dist/cjs/internal/effect/circular.js +3 -2
  44. package/dist/cjs/internal/effect/circular.js.map +1 -1
  45. package/dist/cjs/internal/fiberRuntime.js +21 -7
  46. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  47. package/dist/cjs/internal/hashMap.js +10 -1
  48. package/dist/cjs/internal/hashMap.js.map +1 -1
  49. package/dist/cjs/internal/keyedPool.js +1 -1
  50. package/dist/cjs/internal/keyedPool.js.map +1 -1
  51. package/dist/cjs/internal/layer.js.map +1 -1
  52. package/dist/cjs/internal/rcMap.js +86 -56
  53. package/dist/cjs/internal/rcMap.js.map +1 -1
  54. package/dist/cjs/internal/reloadable.js.map +1 -1
  55. package/dist/cjs/internal/schedule.js.map +1 -1
  56. package/dist/cjs/internal/sink.js.map +1 -1
  57. package/dist/cjs/internal/stm/stm.js.map +1 -1
  58. package/dist/cjs/internal/stream.js.map +1 -1
  59. package/dist/cjs/internal/version.js +1 -1
  60. package/dist/cjs/internal/version.js.map +1 -1
  61. package/dist/dts/Channel.d.ts +4 -4
  62. package/dist/dts/Channel.d.ts.map +1 -1
  63. package/dist/dts/DateTime.d.ts +16 -0
  64. package/dist/dts/DateTime.d.ts.map +1 -1
  65. package/dist/dts/Differ.d.ts +2 -1
  66. package/dist/dts/Differ.d.ts.map +1 -1
  67. package/dist/dts/Duration.d.ts +64 -0
  68. package/dist/dts/Duration.d.ts.map +1 -1
  69. package/dist/dts/Effect.d.ts +402 -30
  70. package/dist/dts/Effect.d.ts.map +1 -1
  71. package/dist/dts/Either.d.ts +7 -0
  72. package/dist/dts/Either.d.ts.map +1 -1
  73. package/dist/dts/FiberHandle.d.ts +26 -0
  74. package/dist/dts/FiberHandle.d.ts.map +1 -1
  75. package/dist/dts/FiberMap.d.ts +26 -0
  76. package/dist/dts/FiberMap.d.ts.map +1 -1
  77. package/dist/dts/FiberSet.d.ts +25 -0
  78. package/dist/dts/FiberSet.d.ts.map +1 -1
  79. package/dist/dts/HashMap.d.ts +38 -0
  80. package/dist/dts/HashMap.d.ts.map +1 -1
  81. package/dist/dts/HashSet.d.ts +7 -0
  82. package/dist/dts/HashSet.d.ts.map +1 -1
  83. package/dist/dts/Layer.d.ts +32 -13
  84. package/dist/dts/Layer.d.ts.map +1 -1
  85. package/dist/dts/Match.d.ts +731 -48
  86. package/dist/dts/Match.d.ts.map +1 -1
  87. package/dist/dts/RcMap.d.ts +32 -0
  88. package/dist/dts/RcMap.d.ts.map +1 -1
  89. package/dist/dts/Reloadable.d.ts +13 -13
  90. package/dist/dts/Reloadable.d.ts.map +1 -1
  91. package/dist/dts/STM.d.ts +4 -4
  92. package/dist/dts/STM.d.ts.map +1 -1
  93. package/dist/dts/Schedule.d.ts +2294 -633
  94. package/dist/dts/Schedule.d.ts.map +1 -1
  95. package/dist/dts/Schema.d.ts +40 -4
  96. package/dist/dts/Schema.d.ts.map +1 -1
  97. package/dist/dts/Stream.d.ts +8 -8
  98. package/dist/dts/Stream.d.ts.map +1 -1
  99. package/dist/dts/Trie.d.ts +7 -7
  100. package/dist/dts/Trie.d.ts.map +1 -1
  101. package/dist/dts/index.d.ts +25 -0
  102. package/dist/dts/index.d.ts.map +1 -1
  103. package/dist/dts/internal/stm/stm.d.ts +2 -2
  104. package/dist/dts/internal/stm/stm.d.ts.map +1 -1
  105. package/dist/esm/Channel.js.map +1 -1
  106. package/dist/esm/DateTime.js +16 -0
  107. package/dist/esm/DateTime.js.map +1 -1
  108. package/dist/esm/Differ.js.map +1 -1
  109. package/dist/esm/Duration.js +124 -0
  110. package/dist/esm/Duration.js.map +1 -1
  111. package/dist/esm/Effect.js +170 -32
  112. package/dist/esm/Effect.js.map +1 -1
  113. package/dist/esm/Either.js +7 -0
  114. package/dist/esm/Either.js.map +1 -1
  115. package/dist/esm/FiberHandle.js +48 -18
  116. package/dist/esm/FiberHandle.js.map +1 -1
  117. package/dist/esm/FiberMap.js +46 -22
  118. package/dist/esm/FiberMap.js.map +1 -1
  119. package/dist/esm/FiberSet.js +45 -15
  120. package/dist/esm/FiberSet.js.map +1 -1
  121. package/dist/esm/HashMap.js +17 -0
  122. package/dist/esm/HashMap.js.map +1 -1
  123. package/dist/esm/HashSet.js +7 -0
  124. package/dist/esm/HashSet.js.map +1 -1
  125. package/dist/esm/Layer.js +20 -0
  126. package/dist/esm/Layer.js.map +1 -1
  127. package/dist/esm/Match.js +665 -40
  128. package/dist/esm/Match.js.map +1 -1
  129. package/dist/esm/RcMap.js +10 -0
  130. package/dist/esm/RcMap.js.map +1 -1
  131. package/dist/esm/Reloadable.js.map +1 -1
  132. package/dist/esm/STM.js.map +1 -1
  133. package/dist/esm/Schedule.js +1074 -309
  134. package/dist/esm/Schedule.js.map +1 -1
  135. package/dist/esm/Schema.js +71 -0
  136. package/dist/esm/Schema.js.map +1 -1
  137. package/dist/esm/Stream.js.map +1 -1
  138. package/dist/esm/index.js +25 -0
  139. package/dist/esm/index.js.map +1 -1
  140. package/dist/esm/internal/channel.js.map +1 -1
  141. package/dist/esm/internal/core-effect.js.map +1 -1
  142. package/dist/esm/internal/core.js +23 -0
  143. package/dist/esm/internal/core.js.map +1 -1
  144. package/dist/esm/internal/dateTime.js +2 -0
  145. package/dist/esm/internal/dateTime.js.map +1 -1
  146. package/dist/esm/internal/differ.js +4 -0
  147. package/dist/esm/internal/differ.js.map +1 -1
  148. package/dist/esm/internal/effect/circular.js +3 -2
  149. package/dist/esm/internal/effect/circular.js.map +1 -1
  150. package/dist/esm/internal/fiberRuntime.js +18 -5
  151. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  152. package/dist/esm/internal/hashMap.js +9 -0
  153. package/dist/esm/internal/hashMap.js.map +1 -1
  154. package/dist/esm/internal/keyedPool.js +1 -1
  155. package/dist/esm/internal/keyedPool.js.map +1 -1
  156. package/dist/esm/internal/layer.js.map +1 -1
  157. package/dist/esm/internal/rcMap.js +85 -55
  158. package/dist/esm/internal/rcMap.js.map +1 -1
  159. package/dist/esm/internal/reloadable.js.map +1 -1
  160. package/dist/esm/internal/schedule.js.map +1 -1
  161. package/dist/esm/internal/sink.js.map +1 -1
  162. package/dist/esm/internal/stm/stm.js.map +1 -1
  163. package/dist/esm/internal/stream.js.map +1 -1
  164. package/dist/esm/internal/version.js +1 -1
  165. package/dist/esm/internal/version.js.map +1 -1
  166. package/package.json +2 -1
  167. package/src/Channel.ts +14 -17
  168. package/src/DateTime.ts +17 -8
  169. package/src/Differ.ts +2 -1
  170. package/src/Duration.ts +147 -0
  171. package/src/Effect.ts +528 -140
  172. package/src/Either.ts +9 -0
  173. package/src/FiberHandle.ts +95 -35
  174. package/src/FiberMap.ts +104 -39
  175. package/src/FiberSet.ts +93 -24
  176. package/src/HashMap.ts +40 -0
  177. package/src/HashSet.ts +8 -0
  178. package/src/Layer.ts +94 -40
  179. package/src/Match.ts +733 -49
  180. package/src/RcMap.ts +34 -0
  181. package/src/Reloadable.ts +17 -27
  182. package/src/STM.ts +10 -17
  183. package/src/Schedule.ts +2325 -653
  184. package/src/Schema.ts +81 -4
  185. package/src/Stream.ts +26 -33
  186. package/src/Trie.ts +7 -7
  187. package/src/index.ts +25 -0
  188. package/src/internal/channel.ts +37 -39
  189. package/src/internal/core-effect.ts +84 -84
  190. package/src/internal/core.ts +80 -0
  191. package/src/internal/dateTime.ts +3 -0
  192. package/src/internal/differ.ts +4 -0
  193. package/src/internal/effect/circular.ts +3 -2
  194. package/src/internal/fiberRuntime.ts +31 -6
  195. package/src/internal/hashMap.ts +16 -0
  196. package/src/internal/keyedPool.ts +1 -1
  197. package/src/internal/layer.ts +52 -52
  198. package/src/internal/rcMap.ts +131 -89
  199. package/src/internal/reloadable.ts +25 -28
  200. package/src/internal/schedule.ts +29 -23
  201. package/src/internal/sink.ts +16 -15
  202. package/src/internal/stm/stm.ts +54 -46
  203. package/src/internal/stream.ts +100 -100
  204. package/src/internal/version.ts +1 -1
package/src/Either.ts CHANGED
@@ -118,6 +118,15 @@ export declare namespace Either {
118
118
  */
119
119
  export const right: <R>(right: R) => Either<R> = either.right
120
120
 
121
+ const void_: Either<void> = right(void 0)
122
+ export {
123
+ /**
124
+ * @category constructors
125
+ * @since 3.13.0
126
+ */
127
+ void_ as void
128
+ }
129
+
121
130
  /**
122
131
  * Constructs a new `Either` holding a `Left` value. This usually represents a failure, due to the right-bias of this
123
132
  * structure.
@@ -143,6 +143,25 @@ export const makeRuntime = <R, E = unknown, A = unknown>(): Effect.Effect<
143
143
  (self) => runtime(self)<R>()
144
144
  )
145
145
 
146
+ /**
147
+ * Create an Effect run function that is backed by a FiberHandle.
148
+ *
149
+ * @since 3.13.0
150
+ * @categories constructors
151
+ */
152
+ export const makeRuntimePromise = <R = never, A = unknown, E = unknown>(): Effect.Effect<
153
+ <XE extends E, XA extends A>(
154
+ effect: Effect.Effect<XA, XE, R>,
155
+ options?: Runtime.RunForkOptions | undefined
156
+ ) => Promise<XA>,
157
+ never,
158
+ Scope.Scope | R
159
+ > =>
160
+ Effect.flatMap(
161
+ make<A, E>(),
162
+ (self) => runtimePromise(self)<R>()
163
+ )
164
+
146
165
  const internalFiberIdId = -1
147
166
  const internalFiberId = FiberId.make(internalFiberIdId, 0)
148
167
  const isInternalInterruption = Cause.reduceWithContext(undefined, {
@@ -381,44 +400,31 @@ export const run: {
381
400
  } = function() {
382
401
  const self = arguments[0] as FiberHandle
383
402
  if (Effect.isEffect(arguments[1])) {
384
- const effect = arguments[1]
385
- const options = arguments[2] as {
386
- readonly onlyIfMissing?: boolean
387
- readonly propagateInterruption?: boolean | undefined
388
- } | undefined
389
- return Effect.suspend(() => {
390
- if (self.state._tag === "Closed") {
391
- return Effect.interrupt
392
- } else if (self.state.fiber !== undefined && options?.onlyIfMissing === true) {
393
- return Effect.sync(constInterruptedFiber)
394
- }
395
- return Effect.uninterruptibleMask((restore) =>
396
- Effect.tap(
397
- restore(Effect.forkDaemon(effect)),
398
- (fiber) => set(self, fiber, options)
399
- )
400
- )
401
- }) as any
403
+ return runImpl(self, arguments[1], arguments[2]) as any
402
404
  }
403
- const options = arguments[1] as {
405
+ const options = arguments[1]
406
+ return (effect: Effect.Effect<unknown, unknown, any>) => runImpl(self, effect, options)
407
+ }
408
+
409
+ const runImpl = <A, E, R, XE extends E, XA extends A>(
410
+ self: FiberHandle<A, E>,
411
+ effect: Effect.Effect<XA, XE, R>,
412
+ options?: {
404
413
  readonly onlyIfMissing?: boolean
405
414
  readonly propagateInterruption?: boolean | undefined
406
- } | undefined
407
- return (effect: Effect.Effect<unknown, unknown, any>) =>
408
- Effect.suspend(() => {
409
- if (self.state._tag === "Closed") {
410
- return Effect.interrupt
411
- } else if (self.state.fiber !== undefined && options?.onlyIfMissing === true) {
412
- return Effect.sync(constInterruptedFiber)
413
- }
414
- return Effect.uninterruptibleMask((restore) =>
415
- Effect.tap(
416
- restore(Effect.forkDaemon(effect)),
417
- (fiber) => set(self, fiber, options)
418
- )
419
- )
420
- })
421
- }
415
+ }
416
+ ): Effect.Effect<Fiber.RuntimeFiber<XA, XE>, never, R> =>
417
+ Effect.fiberIdWith((fiberId) => {
418
+ if (self.state._tag === "Closed") {
419
+ return Effect.interrupt
420
+ } else if (self.state.fiber !== undefined && options?.onlyIfMissing === true) {
421
+ return Effect.sync(constInterruptedFiber)
422
+ }
423
+ return Effect.tap(
424
+ Effect.forkDaemon(effect),
425
+ (fiber) => unsafeSet(self, fiber, { ...options, interruptAs: fiberId })
426
+ )
427
+ })
422
428
 
423
429
  /**
424
430
  * Capture a Runtime and use it to fork Effect's, adding the forked fibers to the FiberHandle.
@@ -491,6 +497,46 @@ export const runtime: <A, E>(
491
497
  }
492
498
  )
493
499
 
500
+ /**
501
+ * Capture a Runtime and use it to fork Effect's, adding the forked fibers to the FiberHandle.
502
+ *
503
+ * The returned run function will return Promise's that will resolve when the
504
+ * fiber completes.
505
+ *
506
+ * @since 3.13.0
507
+ * @categories combinators
508
+ */
509
+ export const runtimePromise = <A, E>(self: FiberHandle<A, E>): <R = never>() => Effect.Effect<
510
+ <XE extends E, XA extends A>(
511
+ effect: Effect.Effect<XA, XE, R>,
512
+ options?:
513
+ | Runtime.RunForkOptions & { readonly propagateInterruption?: boolean | undefined }
514
+ | undefined
515
+ ) => Promise<XA>,
516
+ never,
517
+ R
518
+ > =>
519
+ <R>() =>
520
+ Effect.map(
521
+ runtime(self)<R>(),
522
+ (runFork) =>
523
+ <XE extends E, XA extends A>(
524
+ effect: Effect.Effect<XA, XE, R>,
525
+ options?:
526
+ | Runtime.RunForkOptions & { readonly propagateInterruption?: boolean | undefined }
527
+ | undefined
528
+ ): Promise<XA> =>
529
+ new Promise((resolve, reject) =>
530
+ runFork(effect, options).addObserver((exit) => {
531
+ if (Exit.isSuccess(exit)) {
532
+ resolve(exit.value)
533
+ } else {
534
+ reject(Cause.squash(exit.cause))
535
+ }
536
+ })
537
+ )
538
+ )
539
+
494
540
  /**
495
541
  * If any of the Fiber's in the handle terminate with a failure,
496
542
  * the returned Effect will terminate with the first failure that occurred.
@@ -512,3 +558,17 @@ export const runtime: <A, E>(
512
558
  */
513
559
  export const join = <A, E>(self: FiberHandle<A, E>): Effect.Effect<void, E> =>
514
560
  Deferred.await(self.deferred as Deferred.Deferred<void, E>)
561
+
562
+ /**
563
+ * Wait for the fiber in the FiberHandle to complete.
564
+ *
565
+ * @since 3.13.0
566
+ * @categories combinators
567
+ */
568
+ export const awaitEmpty = <A, E>(self: FiberHandle<A, E>): Effect.Effect<void, E> =>
569
+ Effect.suspend(() => {
570
+ if (self.state._tag === "Closed" || self.state.fiber === undefined) {
571
+ return Effect.void
572
+ }
573
+ return Fiber.await(self.state.fiber)
574
+ })
package/src/FiberMap.ts CHANGED
@@ -8,7 +8,7 @@ import * as Effect from "./Effect.js"
8
8
  import * as Exit from "./Exit.js"
9
9
  import * as Fiber from "./Fiber.js"
10
10
  import * as FiberId from "./FiberId.js"
11
- import { constFalse, dual } from "./Function.js"
11
+ import { constFalse, constVoid, dual } from "./Function.js"
12
12
  import * as HashSet from "./HashSet.js"
13
13
  import * as Inspectable from "./Inspectable.js"
14
14
  import * as Iterable from "./Iterable.js"
@@ -158,6 +158,30 @@ export const makeRuntime = <R, K, E = unknown, A = unknown>(): Effect.Effect<
158
158
  (self) => runtime(self)<R>()
159
159
  )
160
160
 
161
+ /**
162
+ * Create an Effect run function that is backed by a FiberMap.
163
+ *
164
+ * @since 3.13.0
165
+ * @categories constructors
166
+ */
167
+ export const makeRuntimePromise = <R, K, A = unknown, E = unknown>(): Effect.Effect<
168
+ <XE extends E, XA extends A>(
169
+ key: K,
170
+ effect: Effect.Effect<XA, XE, R>,
171
+ options?:
172
+ | Runtime.RunForkOptions & {
173
+ readonly onlyIfMissing?: boolean | undefined
174
+ }
175
+ | undefined
176
+ ) => Promise<XA>,
177
+ never,
178
+ Scope.Scope | R
179
+ > =>
180
+ Effect.flatMap(
181
+ make<K, A, E>(),
182
+ (self) => runtimePromise(self)<R>()
183
+ )
184
+
161
185
  const internalFiberIdId = -1
162
186
  const internalFiberId = FiberId.make(internalFiberIdId, 0)
163
187
  const isInternalInterruption = Cause.reduceWithContext(undefined, {
@@ -561,49 +585,35 @@ export const run: {
561
585
  } | undefined
562
586
  ): Effect.Effect<Fiber.RuntimeFiber<XA, XE>, never, R>
563
587
  } = function() {
588
+ const self = arguments[0]
564
589
  if (Effect.isEffect(arguments[2])) {
565
- const self = arguments[0] as FiberMap<any>
566
- const key = arguments[1]
567
- const effect = arguments[2] as Effect.Effect<any, any, any>
568
- const options = arguments[3] as {
569
- readonly onlyIfMissing?: boolean
570
- readonly propagateInterruption?: boolean | undefined
571
- } | undefined
572
- return Effect.suspend(() => {
573
- if (self.state._tag === "Closed") {
574
- return Effect.interrupt
575
- } else if (options?.onlyIfMissing === true && unsafeHas(self, key)) {
576
- return Effect.sync(constInterruptedFiber)
577
- }
578
- return Effect.uninterruptibleMask((restore) =>
579
- Effect.tap(
580
- restore(Effect.forkDaemon(effect)),
581
- (fiber) => set(self, key, fiber, options)
582
- )
583
- )
584
- }) as any
590
+ return runImpl(self, arguments[1], arguments[2], arguments[3]) as any
585
591
  }
586
- const self = arguments[0] as FiberMap<any>
587
592
  const key = arguments[1]
588
- const options = arguments[2] as {
593
+ const options = arguments[2]
594
+ return (effect: Effect.Effect<any, any, any>) => runImpl(self, key, effect, options)
595
+ }
596
+
597
+ const runImpl = <K, A, E, R, XE extends E, XA extends A>(
598
+ self: FiberMap<K, A, E>,
599
+ key: K,
600
+ effect: Effect.Effect<XA, XE, R>,
601
+ options?: {
589
602
  readonly onlyIfMissing?: boolean
590
603
  readonly propagateInterruption?: boolean | undefined
591
- } | undefined
592
- return (effect: Effect.Effect<any, any, any>) =>
593
- Effect.suspend(() => {
594
- if (self.state._tag === "Closed") {
595
- return Effect.interrupt
596
- } else if (options?.onlyIfMissing === true && unsafeHas(self, key)) {
597
- return Effect.sync(constInterruptedFiber)
598
- }
599
- return Effect.uninterruptibleMask((restore) =>
600
- Effect.tap(
601
- restore(Effect.forkDaemon(effect)),
602
- (fiber) => set(self, key, fiber, options)
603
- )
604
- )
605
- })
606
- }
604
+ }
605
+ ) =>
606
+ Effect.fiberIdWith((fiberId) => {
607
+ if (self.state._tag === "Closed") {
608
+ return Effect.interrupt
609
+ } else if (options?.onlyIfMissing === true && unsafeHas(self, key)) {
610
+ return Effect.sync(constInterruptedFiber)
611
+ }
612
+ return Effect.tap(
613
+ Effect.forkDaemon(effect),
614
+ (fiber) => unsafeSet(self, key, fiber, { ...options, interruptAs: fiberId })
615
+ )
616
+ })
607
617
 
608
618
  /**
609
619
  * Capture a Runtime and use it to fork Effect's, adding the forked fibers to the FiberMap.
@@ -676,6 +686,48 @@ export const runtime: <K, A, E>(
676
686
  }
677
687
  )
678
688
 
689
+ /**
690
+ * Capture a Runtime and use it to fork Effect's, adding the forked fibers to the FiberMap.
691
+ *
692
+ * @since 3.13.0
693
+ * @categories combinators
694
+ */
695
+ export const runtimePromise = <K, A, E>(self: FiberMap<K, A, E>): <R = never>() => Effect.Effect<
696
+ <XE extends E, XA extends A>(
697
+ key: K,
698
+ effect: Effect.Effect<XA, XE, R>,
699
+ options?:
700
+ | Runtime.RunForkOptions & {
701
+ readonly onlyIfMissing?: boolean | undefined
702
+ readonly propagateInterruption?: boolean | undefined
703
+ }
704
+ | undefined
705
+ ) => Promise<XA>,
706
+ never,
707
+ R
708
+ > =>
709
+ <R>() =>
710
+ Effect.map(
711
+ runtime(self)<R>(),
712
+ (runFork) =>
713
+ <XE extends E, XA extends A>(
714
+ key: K,
715
+ effect: Effect.Effect<XA, XE, R>,
716
+ options?:
717
+ | Runtime.RunForkOptions & { readonly propagateInterruption?: boolean | undefined }
718
+ | undefined
719
+ ): Promise<XA> =>
720
+ new Promise((resolve, reject) =>
721
+ runFork(key, effect, options).addObserver((exit) => {
722
+ if (Exit.isSuccess(exit)) {
723
+ resolve(exit.value)
724
+ } else {
725
+ reject(Cause.squash(exit.cause))
726
+ }
727
+ })
728
+ )
729
+ )
730
+
679
731
  /**
680
732
  * @since 2.0.0
681
733
  * @categories combinators
@@ -704,3 +756,16 @@ export const size = <K, A, E>(self: FiberMap<K, A, E>): Effect.Effect<number> =>
704
756
  */
705
757
  export const join = <K, A, E>(self: FiberMap<K, A, E>): Effect.Effect<void, E> =>
706
758
  Deferred.await(self.deferred as Deferred.Deferred<void, E>)
759
+
760
+ /**
761
+ * Wait for the FiberMap to be empty.
762
+ *
763
+ * @since 3.13.0
764
+ * @categories combinators
765
+ */
766
+ export const awaitEmpty = <K, A, E>(self: FiberMap<K, A, E>): Effect.Effect<void, E> =>
767
+ Effect.whileLoop({
768
+ while: () => self.state._tag === "Open" && MutableHashMap.size(self.state.backing) > 0,
769
+ body: () => Fiber.await(Iterable.unsafeHead(self)[1]),
770
+ step: constVoid
771
+ })
package/src/FiberSet.ts CHANGED
@@ -7,7 +7,7 @@ import * as Effect from "./Effect.js"
7
7
  import * as Exit from "./Exit.js"
8
8
  import * as Fiber from "./Fiber.js"
9
9
  import * as FiberId from "./FiberId.js"
10
- import { constFalse, dual } from "./Function.js"
10
+ import { constFalse, constVoid, dual } from "./Function.js"
11
11
  import * as HashSet from "./HashSet.js"
12
12
  import * as Inspectable from "./Inspectable.js"
13
13
  import * as Iterable from "./Iterable.js"
@@ -146,6 +146,25 @@ export const makeRuntime = <R = never, A = unknown, E = unknown>(): Effect.Effec
146
146
  (self) => runtime(self)<R>()
147
147
  )
148
148
 
149
+ /**
150
+ * Create an Effect run function that is backed by a FiberSet.
151
+ *
152
+ * @since 3.13.0
153
+ * @categories constructors
154
+ */
155
+ export const makeRuntimePromise = <R = never, A = unknown, E = unknown>(): Effect.Effect<
156
+ <XE extends E, XA extends A>(
157
+ effect: Effect.Effect<XA, XE, R>,
158
+ options?: Runtime.RunForkOptions | undefined
159
+ ) => Promise<XA>,
160
+ never,
161
+ Scope.Scope | R
162
+ > =>
163
+ Effect.flatMap(
164
+ make<A, E>(),
165
+ (self) => runtimePromise(self)<R>()
166
+ )
167
+
149
168
  const internalFiberIdId = -1
150
169
  const internalFiberId = FiberId.make(internalFiberIdId, 0)
151
170
  const isInternalInterruption = Cause.reduceWithContext(undefined, {
@@ -329,34 +348,32 @@ export const run: {
329
348
  } = function() {
330
349
  const self = arguments[0] as FiberSet<any, any>
331
350
  if (!Effect.isEffect(arguments[1])) {
332
- const options = arguments[1] as { readonly propagateInterruption?: boolean | undefined } | undefined
333
- return (effect: Effect.Effect<any, any, any>) =>
334
- Effect.suspend(() => {
335
- if (self.state._tag === "Closed") {
336
- return Effect.interrupt
337
- }
338
- return Effect.uninterruptibleMask((restore) =>
339
- Effect.tap(
340
- restore(Effect.forkDaemon(effect)),
341
- (fiber) => add(self, fiber, options)
342
- )
343
- )
344
- })
351
+ const options = arguments[1]
352
+ return (effect: Effect.Effect<any, any, any>) => runImpl(self, effect, options)
353
+ }
354
+ return runImpl(self, arguments[1], arguments[2]) as any
355
+ }
356
+
357
+ const runImpl = <A, E, R, XE extends E, XA extends A>(
358
+ self: FiberSet<A, E>,
359
+ effect: Effect.Effect<XA, XE, R>,
360
+ options?: {
361
+ readonly propagateInterruption?: boolean | undefined
345
362
  }
346
- const effect = arguments[1]
347
- const options = arguments[2] as { readonly propagateInterruption?: boolean | undefined } | undefined
348
- return Effect.suspend(() => {
363
+ ): Effect.Effect<Fiber.RuntimeFiber<XA, XE>, never, R> =>
364
+ Effect.fiberIdWith((fiberId) => {
349
365
  if (self.state._tag === "Closed") {
350
366
  return Effect.interrupt
351
367
  }
352
- return Effect.uninterruptibleMask((restore) =>
353
- Effect.tap(
354
- restore(Effect.forkDaemon(effect)),
355
- (fiber) => add(self, fiber, options)
356
- )
368
+ return Effect.tap(
369
+ Effect.forkDaemon(effect),
370
+ (fiber) =>
371
+ unsafeAdd(self, fiber, {
372
+ ...options,
373
+ interruptAs: fiberId
374
+ })
357
375
  )
358
- }) as any
359
- }
376
+ })
360
377
 
361
378
  /**
362
379
  * Capture a Runtime and use it to fork Effect's, adding the forked fibers to the FiberSet.
@@ -415,6 +432,45 @@ export const runtime: <A, E>(
415
432
  }
416
433
  )
417
434
 
435
+ /**
436
+ * Capture a Runtime and use it to fork Effect's, adding the forked fibers to the FiberSet.
437
+ *
438
+ * The returned run function will return Promise's.
439
+ *
440
+ * @since 3.13.0
441
+ * @categories combinators
442
+ */
443
+ export const runtimePromise = <A, E>(self: FiberSet<A, E>): <R = never>() => Effect.Effect<
444
+ <XE extends E, XA extends A>(
445
+ effect: Effect.Effect<XA, XE, R>,
446
+ options?:
447
+ | Runtime.RunForkOptions & { readonly propagateInterruption?: boolean | undefined }
448
+ | undefined
449
+ ) => Promise<XA>,
450
+ never,
451
+ R
452
+ > =>
453
+ <R>() =>
454
+ Effect.map(
455
+ runtime(self)<R>(),
456
+ (runFork) =>
457
+ <XE extends E, XA extends A>(
458
+ effect: Effect.Effect<XA, XE, R>,
459
+ options?:
460
+ | Runtime.RunForkOptions & { readonly propagateInterruption?: boolean | undefined }
461
+ | undefined
462
+ ): Promise<XA> =>
463
+ new Promise((resolve, reject) =>
464
+ runFork(effect, options).addObserver((exit) => {
465
+ if (Exit.isSuccess(exit)) {
466
+ resolve(exit.value)
467
+ } else {
468
+ reject(Cause.squash(exit.cause))
469
+ }
470
+ })
471
+ )
472
+ )
473
+
418
474
  /**
419
475
  * @since 2.0.0
420
476
  * @categories combinators
@@ -443,3 +499,16 @@ export const size = <A, E>(self: FiberSet<A, E>): Effect.Effect<number> =>
443
499
  */
444
500
  export const join = <A, E>(self: FiberSet<A, E>): Effect.Effect<void, E> =>
445
501
  Deferred.await(self.deferred as Deferred.Deferred<void, E>)
502
+
503
+ /**
504
+ * Wait until the fiber set is empty.
505
+ *
506
+ * @since 3.13.0
507
+ * @categories combinators
508
+ */
509
+ export const awaitEmpty = <A, E>(self: FiberSet<A, E>): Effect.Effect<void> =>
510
+ Effect.whileLoop({
511
+ while: () => self.state._tag === "Open" && self.state.backing.size > 0,
512
+ body: () => Fiber.await(Iterable.unsafeHead(self)),
513
+ step: constVoid
514
+ })
package/src/HashMap.ts CHANGED
@@ -315,6 +315,14 @@ export const keySet: <K, V>(self: HashMap<K, V>) => HashSet<K> = keySet_.keySet
315
315
  */
316
316
  export const values: <K, V>(self: HashMap<K, V>) => IterableIterator<V> = HM.values
317
317
 
318
+ /**
319
+ * Returns an `Array` of the values within the `HashMap`.
320
+ *
321
+ * @since 3.13.0
322
+ * @category getters
323
+ */
324
+ export const toValues = <K, V>(self: HashMap<K, V>): Array<V> => Array.from(values(self))
325
+
318
326
  /**
319
327
  * Returns an `IterableIterator` of the entries within the `HashMap`.
320
328
  *
@@ -742,3 +750,35 @@ export const findFirst: {
742
750
  */
743
751
  <K, A>(self: HashMap<K, A>, predicate: (a: A, k: K) => boolean): Option<[K, A]>
744
752
  } = HM.findFirst
753
+
754
+ /**
755
+ * Checks if any entry in a hashmap meets a specific condition.
756
+ *
757
+ * @param self - The hashmap to check.
758
+ * @param predicate - The condition to test entries (value, key).
759
+ *
760
+ * @since 3.13.0
761
+ * @category elements
762
+ */
763
+ export const some: {
764
+ /**
765
+ * Checks if any entry in a hashmap meets a specific condition.
766
+ *
767
+ * @param self - The hashmap to check.
768
+ * @param predicate - The condition to test entries (value, key).
769
+ *
770
+ * @since 3.13.0
771
+ * @category elements
772
+ */
773
+ <K, A>(predicate: (a: NoInfer<A>, k: K) => boolean): (self: HashMap<K, A>) => boolean
774
+ /**
775
+ * Checks if any entry in a hashmap meets a specific condition.
776
+ *
777
+ * @param self - The hashmap to check.
778
+ * @param predicate - The condition to test entries (value, key).
779
+ *
780
+ * @since 3.13.0
781
+ * @category elements
782
+ */
783
+ <K, A>(self: HashMap<K, A>, predicate: (a: A, k: K) => boolean): boolean
784
+ } = HM.some
package/src/HashSet.ts CHANGED
@@ -189,6 +189,14 @@ export const isSubset: {
189
189
  */
190
190
  export const values: <A>(self: HashSet<A>) => IterableIterator<A> = HS.values
191
191
 
192
+ /**
193
+ * Returns an `Array` of the values within the `HashSet`.
194
+ *
195
+ * @since 3.13.0
196
+ * @category getters
197
+ */
198
+ export const toValues = <A>(self: HashSet<A>): Array<A> => Array.from(values(self))
199
+
192
200
  /**
193
201
  * Calculates the number of values in the `HashSet`.
194
202
  *