@@ -8,7 +8,7 @@ import * as Effect from "./Effect.js"
88import * as Exit from "./Exit.js"
99import * as Fiber from "./Fiber.js"
1010import * as FiberId from "./FiberId.js"
11- import { constFalse , dual } from "./Function.js"
11+ import { constFalse , constVoid , dual } from "./Function.js"
1212import * as HashSet from "./HashSet.js"
1313import * as Inspectable from "./Inspectable.js"
1414import * as Iterable from "./Iterable.js"
@@ -438,49 +438,35 @@ export const run: {
438438 } | undefined
439439 ) : Effect . Effect < Fiber . RuntimeFiber < XA , XE > , never , R >
440440} = function ( ) {
441+ const self = arguments [ 0 ]
441442 if ( Effect . isEffect ( arguments [ 2 ] ) ) {
442- const self = arguments [ 0 ] as FiberMap < any >
443- const key = arguments [ 1 ]
444- const effect = arguments [ 2 ] as Effect . Effect < any , any , any >
445- const options = arguments [ 3 ] as {
446- readonly onlyIfMissing ?: boolean
447- readonly propagateInterruption ?: boolean | undefined
448- } | undefined
449- return Effect . suspend ( ( ) => {
450- if ( self . state . _tag === "Closed" ) {
451- return Effect . interrupt
452- } else if ( options ?. onlyIfMissing === true && unsafeHas ( self , key ) ) {
453- return Effect . sync ( constInterruptedFiber )
454- }
455- return Effect . uninterruptibleMask ( ( restore ) =>
456- Effect . tap (
457- restore ( Effect . forkDaemon ( effect ) ) ,
458- ( fiber ) => set ( self , key , fiber , options )
459- )
460- )
461- } ) as any
443+ return runImpl ( self , arguments [ 1 ] , arguments [ 2 ] , arguments [ 3 ] ) as any
462444 }
463- const self = arguments [ 0 ] as FiberMap < any >
464445 const key = arguments [ 1 ]
465- const options = arguments [ 2 ] as {
446+ const options = arguments [ 2 ]
447+ return ( effect : Effect . Effect < any , any , any > ) => runImpl ( self , key , effect , options )
448+ }
449+
450+ const runImpl = < K , A , E , R , XE extends E , XA extends A > (
451+ self : FiberMap < K , A , E > ,
452+ key : K ,
453+ effect : Effect . Effect < XA , XE , R > ,
454+ options ?: {
466455 readonly onlyIfMissing ?: boolean
467456 readonly propagateInterruption ?: boolean | undefined
468- } | undefined
469- return ( effect : Effect . Effect < any , any , any > ) =>
470- Effect . suspend ( ( ) => {
471- if ( self . state . _tag === "Closed" ) {
472- return Effect . interrupt
473- } else if ( options ?. onlyIfMissing === true && unsafeHas ( self , key ) ) {
474- return Effect . sync ( constInterruptedFiber )
475- }
476- return Effect . uninterruptibleMask ( ( restore ) =>
477- Effect . tap (
478- restore ( Effect . forkDaemon ( effect ) ) ,
479- ( fiber ) => set ( self , key , fiber , options )
480- )
481- )
482- } )
483- }
457+ }
458+ ) =>
459+ Effect . fiberIdWith ( ( fiberId ) => {
460+ if ( self . state . _tag === "Closed" ) {
461+ return Effect . interrupt
462+ } else if ( options ?. onlyIfMissing === true && unsafeHas ( self , key ) ) {
463+ return Effect . sync ( constInterruptedFiber )
464+ }
465+ return Effect . tap (
466+ Effect . forkDaemon ( effect ) ,
467+ ( fiber ) => unsafeSet ( self , key , fiber , { ...options , interruptAs : fiberId } )
468+ )
469+ } )
484470
485471/**
486472 * Capture a Runtime and use it to fork Effect's, adding the forked fibers to the FiberMap.
@@ -581,3 +567,16 @@ export const size = <K, A, E>(self: FiberMap<K, A, E>): Effect.Effect<number> =>
581567 */
582568export const join = < K , A , E > ( self : FiberMap < K , A , E > ) : Effect . Effect < void , E > =>
583569 Deferred . await ( self . deferred as Deferred . Deferred < void , E > )
570+
571+ /**
572+ * Wait for the FiberMap to be empty.
573+ *
574+ * @since 3.13.0
575+ * @categories combinators
576+ */
577+ export const awaitEmpty = < K , A , E > ( self : FiberMap < K , A , E > ) : Effect . Effect < void , E > =>
578+ Effect . whileLoop ( {
579+ while : ( ) => self . state . _tag === "Open" && MutableHashMap . size ( self . state . backing ) > 0 ,
580+ body : ( ) => Fiber . await ( Iterable . unsafeHead ( self ) [ 1 ] ) ,
581+ step : constVoid
582+ } )
0 commit comments