@@ -237,7 +237,13 @@ function merge<TKey extends OnyxKey>(key: TKey, changes: OnyxMergeInput<TKey>):
237237
238238 try {
239239 const validChanges = mergeQueue [ key ] . filter ( ( change ) => {
240- const { isCompatible, existingValueType, newValueType} = utils . checkCompatibilityWithExistingValue ( change , existingValue ) ;
240+ const { isCompatible, existingValueType, newValueType, isEmptyArrayCoercion} = utils . checkCompatibilityWithExistingValue ( change , existingValue ) ;
241+ if ( isEmptyArrayCoercion ) {
242+ // Merging an object into an empty array isn't semantically correct, but we allow it
243+ // in case we accidentally encoded an empty object as an empty array in PHP. If you're
244+ // looking at a bugbot from this message, we're probably missing that key in OnyxKeys::KEYS_REQUIRING_EMPTY_OBJECT
245+ Logger . logAlert ( `[ENSURE_BUGBOT] Onyx merge called on key "${ key } " whose existing value is an empty array. Will coerce to object.` ) ;
246+ }
241247 if ( ! isCompatible ) {
242248 Logger . logAlert ( logMessages . incompatibleUpdateAlert ( key , 'merge' , existingValueType , newValueType ) ) ;
243249 }
@@ -260,8 +266,9 @@ function merge<TKey extends OnyxKey>(key: TKey, changes: OnyxMergeInput<TKey>):
260266 return Promise . resolve ( ) ;
261267 }
262268
263- return OnyxMerge . applyMerge ( key , existingValue , validChanges ) . then ( ( { mergedValue} ) => {
269+ return OnyxMerge . applyMerge ( key , existingValue , validChanges ) . then ( ( { mergedValue, updatePromise } ) => {
264270 OnyxUtils . sendActionToDevTools ( OnyxUtils . METHOD . MERGE , key , changes , mergedValue ) ;
271+ return updatePromise ;
265272 } ) ;
266273 } catch ( error ) {
267274 Logger . logAlert ( `An error occurred while applying merge for key: ${ key } , Error: ${ error } ` ) ;
@@ -373,6 +380,16 @@ function clear(keysToPreserve: OnyxKey[] = []): Promise<void> {
373380 keysToBeClearedFromStorage . push ( key ) ;
374381 }
375382
383+ const updatePromises : Array < Promise < void > > = [ ] ;
384+
385+ // Notify the subscribers for each key/value group so they can receive the new values
386+ for ( const [ key , value ] of Object . entries ( keyValuesToResetIndividually ) ) {
387+ updatePromises . push ( OnyxUtils . scheduleSubscriberUpdate ( key , value ) ) ;
388+ }
389+ for ( const [ key , value ] of Object . entries ( keyValuesToResetAsCollection ) ) {
390+ updatePromises . push ( OnyxUtils . scheduleNotifyCollectionSubscribers ( key , value . newValues , value . oldValues ) ) ;
391+ }
392+
376393 // Exclude RAM-only keys to prevent them from being saved to storage
377394 const defaultKeyValuePairs = Object . entries (
378395 Object . keys ( defaultKeyStates )
@@ -391,14 +408,7 @@ function clear(keysToPreserve: OnyxKey[] = []): Promise<void> {
391408 . then ( ( ) => Storage . multiSet ( defaultKeyValuePairs ) )
392409 . then ( ( ) => {
393410 DevTools . clearState ( keysToPreserve ) ;
394-
395- // Notify the subscribers for each key/value group so they can receive the new values
396- for ( const [ key , value ] of Object . entries ( keyValuesToResetIndividually ) ) {
397- OnyxUtils . keyChanged ( key , value ) ;
398- }
399- for ( const [ key , value ] of Object . entries ( keyValuesToResetAsCollection ) ) {
400- OnyxUtils . keysChanged ( key , value . newValues , value . oldValues ) ;
401- }
411+ return Promise . all ( updatePromises ) ;
402412 } ) ;
403413 } )
404414 . then ( ( ) => undefined ) ;
0 commit comments