@@ -127,11 +127,11 @@ export default class CardStoreWithGarbageCollection implements CardStore {
127127 // importantly these properties are not tracked so that we are able
128128 // to deserialize an instance without glimmer rendering the inner workings of
129129 // the deserialization process.
130- #nonTrackedCards = new Map < string , StoredInstance > ( ) ;
131- #nonTrackedCardErrors = new Map < string , CardErrorJSONAPI > ( ) ;
130+ #nonTrackedInstances = new Map < string , StoredInstance > ( ) ;
131+ #nonTrackedInstanceErrors = new Map < string , CardErrorJSONAPI > ( ) ;
132132
133133 #cards = new TrackedMap < string , StoredInstance > ( ) ;
134- #cardErrors = new TrackedMap < string , CardErrorJSONAPI > ( ) ;
134+ #instanceErrors = new TrackedMap < string , CardErrorJSONAPI > ( ) ;
135135 #gcCandidates: Set < LocalId > = new Set ( ) ;
136136 #referenceCount: ReferenceCount ;
137137 #idResolver = new IDResolver ( ) ;
@@ -299,9 +299,9 @@ export default class CardStoreWithGarbageCollection implements CardStore {
299299
300300 reset ( ) {
301301 this . #cards. clear ( ) ;
302- this . #clearEphemeralErrors( this . #cardErrors ) ;
303- this . #nonTrackedCards . clear ( ) ;
304- this . #clearEphemeralErrors( this . #nonTrackedCardErrors ) ;
302+ this . #clearEphemeralErrors( this . #instanceErrors ) ;
303+ this . #nonTrackedInstances . clear ( ) ;
304+ this . #clearEphemeralErrors( this . #nonTrackedInstanceErrors ) ;
305305 this . #gcCandidates. clear ( ) ;
306306 this . #cardDocsInFlight. clear ( ) ;
307307 this . #fileMetaDocsInFlight. clear ( ) ;
@@ -334,20 +334,26 @@ export default class CardStoreWithGarbageCollection implements CardStore {
334334 sweep ( api : typeof CardAPI ) {
335335 let dependencyGraph = this . makeDependencyGraph ( api ) ;
336336 let reachable = new Set < string > ( ) ;
337- let visited = new WeakSet < CardDef > ( ) ;
337+ let visited = new WeakSet < StoredInstance > ( ) ;
338338 let rootLocalIds : string [ ] = [ ] ;
339339
340340 for ( let instance of this . #cards. values ( ) ) {
341- if ( ! instance || ! isCardInstance ( instance ) ) {
341+ if ( ! instance || visited . has ( instance ) ) {
342342 continue ;
343343 }
344- if ( visited . has ( instance ) ) {
344+ visited . add ( instance ) ;
345+ if ( isCardInstance ( instance ) ) {
346+ let localId = instance [ localIdSymbol ] ;
347+ if ( this . hasReferences ( localId ) ) {
348+ rootLocalIds . push ( localId ) ;
349+ }
345350 continue ;
346351 }
347- visited . add ( instance ) ;
348- let localId = instance [ localIdSymbol ] ;
349- if ( this . hasReferences ( localId ) ) {
350- rootLocalIds . push ( localId ) ;
352+ if ( isFileDefInstance ( instance ) ) {
353+ let fileId = instance . id ;
354+ if ( fileId && this . hasReferences ( fileId ) ) {
355+ reachable . add ( fileId ) ;
356+ }
351357 }
352358 }
353359
@@ -367,49 +373,57 @@ export default class CardStoreWithGarbageCollection implements CardStore {
367373 }
368374 }
369375
370- visited = new WeakSet < CardDef > ( ) ;
376+ visited = new WeakSet < StoredInstance > ( ) ;
371377 for ( let instance of this . #cards. values ( ) ) {
372- if ( ! instance || ! isCardInstance ( instance ) ) {
373- continue ;
374- }
375- if ( visited . has ( instance ) ) {
378+ if ( ! instance || visited . has ( instance ) ) {
376379 continue ;
377380 }
378381 visited . add ( instance ) ;
379- let localId = instance [ localIdSymbol ] ;
380- if ( ! reachable . has ( localId ) ) {
381- if ( this . #gcCandidates. has ( localId ) ) {
382+ let gcId : string | undefined ;
383+ let extraDeleteIds : string [ ] = [ ] ;
384+ if ( isCardInstance ( instance ) ) {
385+ gcId = instance [ localIdSymbol ] ;
386+ if ( instance . id ) {
387+ extraDeleteIds . push ( instance . id ) ;
388+ }
389+ } else if ( isFileDefInstance ( instance ) ) {
390+ gcId = instance . id ;
391+ }
392+ if ( ! gcId ) {
393+ continue ; // we should alwyays have a gcId by this point, but this helps TypeScript know that
394+ }
395+ if ( ! reachable . has ( gcId ) ) {
396+ if ( this . #gcCandidates. has ( gcId ) ) {
382397 destroy ( instance ) ;
383- // brand the instance to make it easier for debugging
384398 ( instance as unknown as any ) [
385399 Symbol . for ( '__instance_detached_from_store' )
386400 ] = true ;
387- this . delete ( localId ) ;
388- if ( instance . id ) {
389- this . delete ( instance . id ) ;
401+ this . delete ( gcId ) ;
402+ for ( let id of extraDeleteIds ) {
403+ this . delete ( id ) ;
390404 }
391405 } else {
392- this . #gcCandidates. add ( localId ) ;
406+ this . #gcCandidates. add ( gcId ) ;
393407 }
394408 } else {
395- this . #gcCandidates. delete ( localId ) ;
409+ this . #gcCandidates. delete ( gcId ) ;
396410 }
397411 }
398412 }
399413
400414 makeTracked ( remoteId : string ) {
401415 remoteId = remoteId . replace ( / \. j s o n $ / , '' ) ;
402- let instance = this . #nonTrackedCards . get ( remoteId ) ;
416+ let instance = this . #nonTrackedInstances . get ( remoteId ) ;
403417 if ( instance ) {
404418 this . setItem ( remoteId , instance ) ;
405419 }
406- this . #nonTrackedCards . delete ( remoteId ) ;
420+ this . #nonTrackedInstances . delete ( remoteId ) ;
407421
408- let error = this . #nonTrackedCardErrors . get ( remoteId ) ;
422+ let error = this . #nonTrackedInstanceErrors . get ( remoteId ) ;
409423 if ( error ) {
410424 this . addInstanceOrError ( remoteId , error ) ;
411425 }
412- this . #nonTrackedCardErrors . delete ( remoteId ) ;
426+ this . #nonTrackedInstanceErrors . delete ( remoteId ) ;
413427 }
414428
415429 consumersOf ( api : typeof CardAPI , instance : CardDef ) {
@@ -431,9 +445,9 @@ export default class CardStoreWithGarbageCollection implements CardStore {
431445 private deleteFromAll ( id : string ) {
432446 id = id . replace ( / \. j s o n $ / , '' ) ;
433447 this . #cards. delete ( id ) ;
434- this . #cardErrors . delete ( id ) ;
435- this . #nonTrackedCards . delete ( id ) ;
436- this . #nonTrackedCardErrors . delete ( id ) ;
448+ this . #instanceErrors . delete ( id ) ;
449+ this . #nonTrackedInstances . delete ( id ) ;
450+ this . #nonTrackedInstanceErrors . delete ( id ) ;
437451 }
438452
439453 private getItem ( type : 'instance' , id : string ) : StoredInstance | undefined ;
@@ -465,9 +479,11 @@ export default class CardStoreWithGarbageCollection implements CardStore {
465479 item : StoredInstance | CardErrorJSONAPI | undefined ;
466480 localId : string | undefined ;
467481 } {
468- let bucket = type === 'instance' ? this . #cards : this . #cardErrors ;
482+ let bucket = type === 'instance' ? this . #cards : this . #instanceErrors ;
469483 let silentBucket =
470- type === 'instance' ? this . #nonTrackedCards : this . #nonTrackedCardErrors;
484+ type === 'instance'
485+ ? this . #nonTrackedInstances
486+ : this . #nonTrackedInstanceErrors;
471487 let localId = isLocalId ( localOrRemoteId ) ? localOrRemoteId : undefined ;
472488 let remoteId = ! isLocalId ( localOrRemoteId ) ? localOrRemoteId : undefined ;
473489 let item : StoredInstance | CardErrorJSONAPI | undefined ;
@@ -505,10 +521,10 @@ export default class CardStoreWithGarbageCollection implements CardStore {
505521 notTracked ?: true ,
506522 ) {
507523 id = id . replace ( / \. j s o n $ / , '' ) ;
508- let cardBucket = notTracked ? this . #nonTrackedCards : this . #cards;
524+ let cardBucket = notTracked ? this . #nonTrackedInstances : this . #cards;
509525 let errorBucket = notTracked
510- ? this . #nonTrackedCardErrors
511- : this . #cardErrors ;
526+ ? this . #nonTrackedInstanceErrors
527+ : this . #instanceErrors ;
512528 if ( ! isLocalId ( id ) && isCardInstance ( item ) ) {
513529 this . #idResolver. addIdPair ( item [ localIdSymbol ] , id ) ;
514530 } else if ( ! isLocalId ( id ) ) {
@@ -569,10 +585,18 @@ export default class CardStoreWithGarbageCollection implements CardStore {
569585 }
570586 }
571587
572- private hasReferences ( localId : string ) : boolean {
573- let referenceCount = this . #referenceCount. get ( localId ) ?? 0 ;
574- for ( let remoteId of this . #idResolver. getRemoteIds ( localId ) ) {
575- referenceCount += this . #referenceCount. get ( remoteId ) ?? 0 ;
588+ private hasReferences ( id : string ) : boolean {
589+ let idsToCheck = new Set < string > ( [ id ] ) ;
590+ let localId = isLocalId ( id ) ? id : this . #idResolver. getLocalId ( id ) ;
591+ if ( localId ) {
592+ idsToCheck . add ( localId ) ;
593+ for ( let remoteId of this . #idResolver. getRemoteIds ( localId ) ) {
594+ idsToCheck . add ( remoteId ) ;
595+ }
596+ }
597+ let referenceCount = 0 ;
598+ for ( let refId of idsToCheck ) {
599+ referenceCount += this . #referenceCount. get ( refId ) ?? 0 ;
576600 }
577601 return referenceCount > 0 ;
578602 }
0 commit comments