@@ -566,97 +566,6 @@ function tryGetCachedValue<TKey extends OnyxKey>(key: TKey): OnyxValue<OnyxKey>
566566 return val ;
567567}
568568
569- /**
570- * Marks items that existed in previousCollection but not in preservedCollection as null.
571- * This ensures subscribers are properly notified about item removals.
572- * @param preservedCollection - The collection to mark removed items in (mutated in place)
573- * @param previousCollection - The previous collection state to compare against
574- */
575- function markRemovedItemsAsNull ( preservedCollection : OnyxInputKeyValueMapping , previousCollection : OnyxCollection < KeyValueMapping [ OnyxKey ] > ) {
576- if ( ! previousCollection ) {
577- return preservedCollection ;
578- }
579-
580- const mutablePreservedCollection = { ...preservedCollection } ;
581- Object . keys ( previousCollection ) . forEach ( ( key ) => {
582- if ( key in preservedCollection ) {
583- return ;
584- }
585-
586- mutablePreservedCollection [ key ] = null ;
587- } ) ;
588-
589- return mutablePreservedCollection ;
590- }
591-
592- /**
593- * Utility function to preserve object references for unchanged items in collection operations.
594- * Compares new values with cached values using deep equality and preserves references when data is identical.
595- * @param keyValuePairs - Array of key-value pairs to process
596- * @param previousCollection - Optional previous collection state. If provided, removed items will be included as null
597- * @returns The preserved collection with unchanged references maintained and removed items marked as null
598- */
599- function preserveCollectionReferences ( keyValuePairs : StorageKeyValuePair [ ] , previousCollection ?: OnyxCollection < KeyValueMapping [ OnyxKey ] > ) : OnyxInputKeyValueMapping {
600- const preservedCollection : OnyxInputKeyValueMapping = { } ;
601-
602- keyValuePairs . forEach ( ( [ key , value ] ) => {
603- const cachedValue = cache . get ( key , false ) ;
604-
605- // If no cached value exists, we need to add the new value (skip expensive deep equality check)
606- // Use deep equality check to preserve references for unchanged items
607- if ( cachedValue !== undefined && deepEqual ( value , cachedValue ) ) {
608- // Keep the existing reference
609- preservedCollection [ key ] = cachedValue ;
610- } else {
611- // Update cache only for changed items
612- cache . set ( key , value ) ;
613- preservedCollection [ key ] = value ;
614- }
615- } ) ;
616-
617- if ( previousCollection ) {
618- return markRemovedItemsAsNull ( preservedCollection , previousCollection ) ;
619- }
620-
621- return preservedCollection ;
622- }
623-
624- /**
625- * Utility function for merge operations that preserves references after cache merge has been performed.
626- * Compares merged values with original cached values and preserves references when data is unchanged.
627- * @param collection - Collection of merged data
628- * @param originalCachedValues - Original cached values before merge
629- * @param previousCollection - Optional previous collection state. If provided, removed items will be included as null
630- * @returns The preserved collection with unchanged references maintained and removed items marked as null
631- */
632- function preserveCollectionReferencesAfterMerge (
633- collection : Record < string , OnyxValue < OnyxKey > > ,
634- originalCachedValues : Record < string , OnyxValue < OnyxKey > > ,
635- previousCollection ?: Record < string , OnyxValue < OnyxKey > > ,
636- ) : Record < string , OnyxValue < OnyxKey > > {
637- const preservedCollection : Record < string , OnyxValue < OnyxKey > > = { } ;
638-
639- Object . keys ( collection ) . forEach ( ( key ) => {
640- const newMergedValue = cache . get ( key , false ) ;
641- const originalValue = originalCachedValues [ key ] ;
642-
643- // Use deep equality check to preserve references for unchanged items
644- if ( originalValue !== undefined && deepEqual ( newMergedValue , originalValue ) ) {
645- // Keep the existing reference and update cache
646- preservedCollection [ key ] = originalValue ;
647- cache . set ( key , originalValue ) ;
648- } else {
649- preservedCollection [ key ] = newMergedValue ;
650- }
651- } ) ;
652-
653- if ( previousCollection ) {
654- return markRemovedItemsAsNull ( preservedCollection , previousCollection ) ;
655- }
656-
657- return preservedCollection ;
658- }
659-
660569function getCachedCollection < TKey extends CollectionKeyBase > ( collectionKey : TKey , collectionMemberKeys ?: string [ ] ) : NonNullable < OnyxCollection < KeyValueMapping [ TKey ] > > {
661570 // Use optimized collection data retrieval when cache is populated
662571 const collectionData = cache . getCollectionData ( collectionKey ) ;
@@ -1544,10 +1453,9 @@ function setCollectionWithRetry<TKey extends CollectionKeyBase>({collectionKey,
15441453 const keyValuePairs = OnyxUtils . prepareKeyValuePairsForStorage ( mutableCollection , true , undefined , true ) ;
15451454 const previousCollection = OnyxUtils . getCachedCollection ( collectionKey ) ;
15461455
1547- // Preserve references for unchanged items and include removed items as null in setCollection
1548- const preservedCollection = preserveCollectionReferences ( keyValuePairs , previousCollection ) ;
1456+ keyValuePairs . forEach ( ( [ key , value ] ) => cache . set ( key , value ) ) ;
15491457
1550- const updatePromise = OnyxUtils . scheduleNotifyCollectionSubscribers ( collectionKey , preservedCollection , previousCollection ) ;
1458+ const updatePromise = OnyxUtils . scheduleNotifyCollectionSubscribers ( collectionKey , mutableCollection , previousCollection ) ;
15511459
15521460 return Storage . multiSet ( keyValuePairs )
15531461 . catch ( ( error ) => OnyxUtils . retryOperation ( error , setCollectionWithRetry , { collectionKey, collection} , retryAttempt ) )
@@ -1608,9 +1516,6 @@ function mergeCollectionWithPatches<TKey extends CollectionKeyBase>(
16081516
16091517 return getAllKeys ( )
16101518 . then ( ( persistedKeys ) => {
1611- // Capture keys that will be removed (before calling remove())
1612- const keysToRemove = resultCollectionKeys . filter ( ( key ) => resultCollection [ key ] === null && persistedKeys . has ( key ) ) ;
1613-
16141519 // Split to keys that exist in storage and keys that don't
16151520 const keys = resultCollectionKeys . filter ( ( key ) => {
16161521 if ( resultCollection [ key ] === null ) {
@@ -1622,8 +1527,6 @@ function mergeCollectionWithPatches<TKey extends CollectionKeyBase>(
16221527
16231528 const existingKeys = keys . filter ( ( key ) => persistedKeys . has ( key ) ) ;
16241529
1625- // Get previous values for both existing keys and keys that will be removed
1626- const allAffectedKeys = [ ...existingKeys , ...keysToRemove ] ;
16271530 const cachedCollectionForExistingKeys = getCachedCollection ( collectionKey , existingKeys ) ;
16281531
16291532 const existingKeyCollection = existingKeys . reduce ( ( obj : OnyxInputKeyValueMapping , key ) => {
@@ -1660,8 +1563,7 @@ function mergeCollectionWithPatches<TKey extends CollectionKeyBase>(
16601563
16611564 // We need to get the previously existing values so we can compare the new ones
16621565 // against them, to avoid unnecessary subscriber updates.
1663- // Include keys that will be removed so subscribers are notified about removals
1664- const previousCollectionPromise = Promise . all ( allAffectedKeys . map ( ( key ) => get ( key ) . then ( ( value ) => [ key , value ] ) ) ) . then ( Object . fromEntries ) ;
1566+ const previousCollectionPromise = Promise . all ( existingKeys . map ( ( key ) => get ( key ) . then ( ( value ) => [ key , value ] ) ) ) . then ( Object . fromEntries ) ;
16651567
16661568 // New keys will be added via multiSet while existing keys will be updated using multiMerge
16671569 // This is because setting a key that doesn't exist yet with multiMerge will throw errors
@@ -1679,20 +1581,8 @@ function mergeCollectionWithPatches<TKey extends CollectionKeyBase>(
16791581 // Prefill cache if necessary by calling get() on any existing keys and then merge original data to cache
16801582 // and update all subscribers
16811583 const promiseUpdate = previousCollectionPromise . then ( ( previousCollection ) => {
1682- // Capture the original cached values before merging
1683- const originalCachedValues : Record < string , OnyxValue < OnyxKey > > = { } ;
1684- Object . keys ( finalMergedCollection ) . forEach ( ( key ) => {
1685- originalCachedValues [ key ] = cache . get ( key , false ) ;
1686- } ) ;
1687-
1688- // Then merge all the data into cache as normal
1689-
16901584 cache . merge ( finalMergedCollection ) ;
1691-
1692- // Finally, preserve references for items that didn't actually change and include removed items as null
1693- const preservedCollection = preserveCollectionReferencesAfterMerge ( finalMergedCollection , originalCachedValues , previousCollection ) ;
1694-
1695- return scheduleNotifyCollectionSubscribers ( collectionKey , preservedCollection , previousCollection ) ;
1585+ return scheduleNotifyCollectionSubscribers ( collectionKey , finalMergedCollection , previousCollection ) ;
16961586 } ) ;
16971587
16981588 return Promise . all ( promises )
@@ -1756,10 +1646,9 @@ function partialSetCollection<TKey extends CollectionKeyBase>({collectionKey, co
17561646 const previousCollection = getCachedCollection ( collectionKey , existingKeys ) ;
17571647 const keyValuePairs = prepareKeyValuePairsForStorage ( mutableCollection , true , undefined , true ) ;
17581648
1759- // Preserve references for unchanged items and include removed items as null in partialSetCollection
1760- const preservedCollection = preserveCollectionReferences ( keyValuePairs , previousCollection ) ;
1649+ keyValuePairs . forEach ( ( [ key , value ] ) => cache . set ( key , value ) ) ;
17611650
1762- const updatePromise = scheduleNotifyCollectionSubscribers ( collectionKey , preservedCollection , previousCollection ) ;
1651+ const updatePromise = scheduleNotifyCollectionSubscribers ( collectionKey , mutableCollection , previousCollection ) ;
17631652
17641653 return Storage . multiSet ( keyValuePairs )
17651654 . catch ( ( error ) => retryOperation ( error , partialSetCollection , { collectionKey, collection} , retryAttempt ) )
0 commit comments