@@ -95,8 +95,25 @@ const dependantSignalsCleanupRegistry = new SafeFinalizationRegistry((signalWeak
9595 }
9696 } ) ;
9797} ) ;
98+
9899const gcPersistentSignals = new SafeSet ( ) ;
99100
101+ const finalizer = new SafeFinalizationRegistry ( ( { sourceSignalRef, composedSignalRef } ) => {
102+ // TODO: remove ref from source signal
103+ // TODO: remove composed signal from gcPersistentSignals
104+ const composedSignal = composedSignalRef . deref ( ) ;
105+ if ( composedSignal !== undefined ) {
106+ composedSignal [ kSourceSignals ] . delete ( sourceSignalRef ) ;
107+ gcPersistentSignals . delete ( composedSignal ) ;
108+ }
109+
110+ // TODO: remove ref from dependant signal
111+ const sourceSignal = sourceSignalRef . deref ( ) ;
112+ if ( sourceSignal !== undefined ) {
113+ sourceSignal [ kDependantSignals ] . delete ( composedSignalRef ) ;
114+ }
115+ } ) ;
116+
100117const kAborted = Symbol ( 'kAborted' ) ;
101118const kReason = Symbol ( 'kReason' ) ;
102119const kCloneData = Symbol ( 'kCloneData' ) ;
@@ -258,6 +275,9 @@ class AbortSignal extends EventTarget {
258275 resultSignal [ kSourceSignals ] . add ( signalWeakRef ) ;
259276 signal [ kDependantSignals ] . add ( resultSignalWeakRef ) ;
260277 dependantSignalsCleanupRegistry . register ( resultSignal , signalWeakRef ) ;
278+ // when the source signal - coming from the controller - is gced, we need to remove it from the dependant
279+ // signals of the composite signal
280+ finalizer . register ( signal , { sourceSignalRef : signalWeakRef , composedSignalRef : resultSignalWeakRef } ) ;
261281 } else if ( ! signal [ kSourceSignals ] ) {
262282 continue ;
263283 } else {
@@ -293,6 +313,7 @@ class AbortSignal extends EventTarget {
293313 // listener, then we don't want it to be gc'd while the listener
294314 // is attached and the timer still hasn't fired. So, we retain a
295315 // strong ref that is held for as long as the listener is registered.
316+
296317 gcPersistentSignals . add ( this ) ;
297318 }
298319 }
@@ -434,6 +455,7 @@ class AbortController {
434455 */
435456 get signal ( ) {
436457 this . #signal ??= new AbortSignal ( kDontThrowSymbol ) ;
458+
437459 return this . #signal;
438460 }
439461
0 commit comments