@@ -80,6 +80,7 @@ interface VersionedSnapshot<State, Error, Output> {
8080 readonly revision : number
8181 readonly snapshot : RuntimeSnapshot < State , Error , Output >
8282 readonly terminalizing : boolean
83+ readonly changes : PubSub . PubSub < Take . Take < VersionedSnapshot < State , Error , Output > > > | undefined
8384}
8485
8586export type RuntimeOutcome < State , Error = never , Output = never > =
@@ -309,9 +310,6 @@ const startInternal: <
309310 const terminalized = yield * Deferred . make < void > ( )
310311 const externalFailure = yield * Deferred . make < never , Error > ( )
311312 const done = yield * Deferred . make < Output , Error | StoppedError > ( )
312- const changes = yield * PubSub . unbounded < Take . Take < VersionedSnapshot < State , Error , Output > > > ( {
313- replay : 1
314- } )
315313 const childResourcesState = yield * SynchronizedRef . make < ChildResourcesState > ( {
316314 closed : false ,
317315 resources : undefined
@@ -634,6 +632,7 @@ const startInternal: <
634632 const current = yield * SynchronizedRef . make < VersionedSnapshot < State , Error , Output > > ( {
635633 revision : 0 ,
636634 terminalizing : false ,
635+ changes : undefined ,
637636 snapshot : {
638637 status : "active" ,
639638 state : initial
@@ -642,19 +641,24 @@ const startInternal: <
642641 const publishSnapshot = (
643642 snapshot : VersionedSnapshot < State , Error , Output >
644643 ) : Effect . Effect < VersionedSnapshot < State , Error , Output > > =>
645- PubSub . publish ( changes , [ snapshot ] as const ) . pipe ( Effect . as ( snapshot ) )
644+ snapshot . changes === undefined
645+ ? Effect . succeed ( snapshot )
646+ : PubSub . publish ( snapshot . changes , [ snapshot ] as const ) . pipe ( Effect . as ( snapshot ) )
646647
647- const completeChanges : Effect . Effect < void > = PubSub . publish ( changes , Exit . succeed < void > ( undefined ) ) . pipe (
648- Effect . asVoid
649- )
648+ const completeChanges = (
649+ snapshot : VersionedSnapshot < State , Error , Output >
650+ ) : Effect . Effect < void > =>
651+ snapshot . changes === undefined
652+ ? Effect . void
653+ : PubSub . publish ( snapshot . changes , Exit . succeed < void > ( undefined ) ) . pipe ( Effect . asVoid )
650654
651655 const completeIfTerminal = (
652656 snapshot : VersionedSnapshot < State , Error , Output >
653657 ) : Effect . Effect < VersionedSnapshot < State , Error , Output > > => {
654658 if ( snapshot . snapshot . status === "active" ) {
655659 return Effect . succeed ( snapshot )
656660 }
657- return completeChanges . pipe ( Effect . as ( snapshot ) )
661+ return completeChanges ( snapshot ) . pipe ( Effect . as ( snapshot ) )
658662 }
659663
660664 const publishIfCurrent = (
@@ -694,7 +698,8 @@ const startInternal: <
694698 const versioned = {
695699 revision : current . revision + 1 ,
696700 snapshot : next ,
697- terminalizing : false
701+ terminalizing : false ,
702+ changes : current . changes
698703 }
699704 return [ versioned , versioned ] as const
700705 }
@@ -719,7 +724,8 @@ const startInternal: <
719724 {
720725 revision : current . revision + 1 ,
721726 snapshot : f ( current . snapshot ) ,
722- terminalizing : true
727+ terminalizing : true ,
728+ changes : current . changes
723729 } ,
724730 { ...current , terminalizing : true }
725731 ]
@@ -732,7 +738,8 @@ const startInternal: <
732738 SynchronizedRef . updateAndGet ( current , ( current ) => ( {
733739 revision : current . revision + 1 ,
734740 snapshot,
735- terminalizing : true
741+ terminalizing : true ,
742+ changes : current . changes
736743 } ) ) . pipe (
737744 Effect . flatMap ( publishSnapshot ) ,
738745 Effect . flatMap ( completeIfTerminal ) ,
@@ -844,10 +851,27 @@ const startInternal: <
844851 ) . pipe ( Effect . asVoid )
845852 }
846853
847- yield * publishSnapshot ( yield * SynchronizedRef . get ( current ) )
854+ const getOrCreateChanges = SynchronizedRef . modifyEffect (
855+ current ,
856+ ( current ) => {
857+ if ( current . snapshot . status !== "active" ) {
858+ return Effect . succeed ( [ undefined , current ] as const )
859+ }
860+ if ( current . changes !== undefined ) {
861+ return Effect . succeed ( [ current . changes , current ] as const )
862+ }
863+ return PubSub . unbounded < Take . Take < VersionedSnapshot < State , Error , Output > > > ( { replay : 1 } ) . pipe (
864+ Effect . map ( ( changes ) => [ changes , { ...current , changes } ] as const )
865+ )
866+ }
867+ )
848868
849869 const changesStream : Stream . Stream < RuntimeSnapshot < State , Error , Output > > = Stream . unwrap (
850870 Effect . gen ( function * ( ) {
871+ const changes = yield * getOrCreateChanges
872+ if ( changes === undefined ) {
873+ return Stream . succeed ( ( yield * SynchronizedRef . get ( current ) ) . snapshot )
874+ }
851875 const subscription = yield * PubSub . subscribe ( changes )
852876 const captured = yield * SynchronizedRef . get ( current )
853877 if ( captured . snapshot . status !== "active" ) {
0 commit comments