From e52a253af2c5bce19439f43f238b846b76e4cbc7 Mon Sep 17 00:00:00 2001 From: Jarda Snajdr Date: Fri, 22 Sep 2023 14:56:24 +0200 Subject: [PATCH 1/2] createResolversCacheMiddleware: remove dependency on core/data store --- .../data/src/resolvers-cache-middleware.js | 64 ++++++++----------- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/packages/data/src/resolvers-cache-middleware.js b/packages/data/src/resolvers-cache-middleware.js index 68945db2535752..10607abffc6dd5 100644 --- a/packages/data/src/resolvers-cache-middleware.js +++ b/packages/data/src/resolvers-cache-middleware.js @@ -1,53 +1,41 @@ -/** - * Internal dependencies - */ -import coreDataStore from './store'; - /** @typedef {import('./registry').WPDataRegistry} WPDataRegistry */ /** * Creates a middleware handling resolvers cache invalidation. * - * @param {WPDataRegistry} registry The registry reference for which to create - * the middleware. - * @param {string} reducerKey The namespace for which to create the - * middleware. + * @param {WPDataRegistry} registry Registry for which to create the middleware. + * @param {string} storeName Name of the store for which to create the middleware. * * @return {Function} Middleware function. */ const createResolversCacheMiddleware = - ( registry, reducerKey ) => () => ( next ) => ( action ) => { - const resolvers = registry - .select( coreDataStore ) - .getCachedResolvers( reducerKey ); - Object.entries( resolvers ).forEach( - ( [ selectorName, resolversByArgs ] ) => { - const resolver = - registry.stores?.[ reducerKey ]?.resolvers?.[ - selectorName - ]; - if ( ! resolver || ! resolver.shouldInvalidate ) { + ( registry, storeName ) => () => ( next ) => ( action ) => { + const resolvers = registry.select( storeName ).getCachedResolvers(); + const resolverEntries = Object.entries( resolvers ); + resolverEntries.forEach( ( [ selectorName, resolversByArgs ] ) => { + const resolver = + registry.stores[ storeName ]?.resolvers?.[ selectorName ]; + if ( ! resolver || ! resolver.shouldInvalidate ) { + return; + } + resolversByArgs.forEach( ( value, args ) => { + // resolversByArgs is the map Map([ args ] => boolean) storing the cache resolution status for a given selector. + // If the value is "finished" or "error" it means this resolver has finished its resolution which means we need + // to invalidate it, if it's true it means it's inflight and the invalidation is not necessary. + if ( + ( value.status !== 'finished' && + value.status !== 'error' ) || + ! resolver.shouldInvalidate( action, ...args ) + ) { return; } - resolversByArgs.forEach( ( value, args ) => { - // resolversByArgs is the map Map([ args ] => boolean) storing the cache resolution status for a given selector. - // If the value is "finished" or "error" it means this resolver has finished its resolution which means we need - // to invalidate it, if it's true it means it's inflight and the invalidation is not necessary. - if ( - ( value?.status !== 'finished' && - value?.status !== 'error' ) || - ! resolver.shouldInvalidate( action, ...args ) - ) { - return; - } - // Trigger cache invalidation - registry - .dispatch( coreDataStore ) - .invalidateResolution( reducerKey, selectorName, args ); - } ); - } - ); + // Trigger cache invalidation + registry + .dispatch( storeName ) + .invalidateResolution( selectorName, args ); + } ); + } ); return next( action ); }; From e500adaeed2e0c199fa3eb1a8d0fe7ff23bdc429 Mon Sep 17 00:00:00 2001 From: Jarda Snajdr Date: Mon, 25 Sep 2023 13:35:17 +0200 Subject: [PATCH 2/2] Work around bug in EquivalentKeyMap delete method --- packages/data/src/resolvers-cache-middleware.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/data/src/resolvers-cache-middleware.js b/packages/data/src/resolvers-cache-middleware.js index 10607abffc6dd5..13a0214a8bc930 100644 --- a/packages/data/src/resolvers-cache-middleware.js +++ b/packages/data/src/resolvers-cache-middleware.js @@ -19,14 +19,20 @@ const createResolversCacheMiddleware = return; } resolversByArgs.forEach( ( value, args ) => { + // Works around a bug in `EquivalentKeyMap` where `map.delete` merely sets an entry value + // to `undefined` and `map.forEach` then iterates also over these orphaned entries. + if ( value === undefined ) { + return; + } + // resolversByArgs is the map Map([ args ] => boolean) storing the cache resolution status for a given selector. // If the value is "finished" or "error" it means this resolver has finished its resolution which means we need // to invalidate it, if it's true it means it's inflight and the invalidation is not necessary. - if ( - ( value.status !== 'finished' && - value.status !== 'error' ) || - ! resolver.shouldInvalidate( action, ...args ) - ) { + if ( value.status !== 'finished' && value.status !== 'error' ) { + return; + } + + if ( ! resolver.shouldInvalidate( action, ...args ) ) { return; }