: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
function invalidateResolution(selectorName, args) {
type: 'INVALIDATE_RESOLUTION',
* Returns an action object used in signalling that the resolution
* @return {{ type: 'INVALIDATE_RESOLUTION_FOR_STORE' }} Action object.
function invalidateResolutionForStore() {
type: 'INVALIDATE_RESOLUTION_FOR_STORE'
* Returns an action object used in signalling that the resolution cache for a
* given selectorName should be invalidated.
* @param {string} selectorName Name of selector for which all resolvers should
* @return {{ type: 'INVALIDATE_RESOLUTION_FOR_STORE_SELECTOR', selectorName: string }} Action object.
function invalidateResolutionForStoreSelector(selectorName) {
type: 'INVALIDATE_RESOLUTION_FOR_STORE_SELECTOR',
;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/redux-store/index.js
/** @typedef {import('../types').DataRegistry} DataRegistry */
/** @typedef {import('../types').ListenerFunction} ListenerFunction */
* @typedef {import('../types').StoreDescriptor<C>} StoreDescriptor
* @template {import('../types').AnyConfig} C
* @typedef {import('../types').ReduxStoreConfig<State,Actions,Selectors>} ReduxStoreConfig
* @template {Record<string,import('../types').ActionCreator>} Actions
const trimUndefinedValues = array => {
const result = [...array];
for (let i = result.length - 1; i >= 0; i--) {
if (result[i] === undefined) {
* Creates a new object with the same keys, but with `callback()` called as
* a transformer function on each of the values.
* @param {Object} obj The object to transform.
* @param {Function} callback The function to transform each object value.
* @return {Array} Transformed object.
const mapValues = (obj, callback) => Object.fromEntries(Object.entries(obj !== null && obj !== void 0 ? obj : {}).map(([key, value]) => [key, callback(value, key)]));
// Convert non serializable types to plain objects
const devToolsReplacer = (key, state) => {
if (state instanceof Map) {
return Object.fromEntries(state);
if (state instanceof window.HTMLElement) {
* Create a cache to track whether resolvers started running or not.
* @return {Object} Resolvers Cache.
function createResolversCache() {
isRunning(selectorName, args) {
return cache[selectorName] && cache[selectorName].get(trimUndefinedValues(args));
clear(selectorName, args) {
if (cache[selectorName]) {
cache[selectorName].delete(trimUndefinedValues(args));
markAsRunning(selectorName, args) {
if (!cache[selectorName]) {
cache[selectorName] = new (equivalent_key_map_default())();
cache[selectorName].set(trimUndefinedValues(args), true);
function createBindingCache(bind) {
const cache = new WeakMap();
let boundItem = cache.get(item);
boundItem = bind(item, itemName);
cache.set(item, boundItem);
* Creates a data store descriptor for the provided Redux store configuration containing
* properties describing reducer, actions, selectors, controls and resolvers.
* import { createReduxStore } from '@wordpress/data';
* const store = createReduxStore( 'demo', {
* reducer: ( state = 'OK' ) => state,
* getValue: ( state ) => state,
* @template {Record<string,import('../types').ActionCreator>} Actions
* @param {string} key Unique namespace identifier.
* @param {ReduxStoreConfig<State,Actions,Selectors>} options Registered store options, with properties
* describing reducer, actions, selectors,
* @return {StoreDescriptor<ReduxStoreConfig<State,Actions,Selectors>>} Store Object.
function createReduxStore(key, options) {
const privateActions = {};
const privateSelectors = {};
const privateRegistrationFunctions = {
registerPrivateActions: actions => {
Object.assign(privateActions, actions);
registerPrivateSelectors: selectors => {
Object.assign(privateSelectors, selectors);
const storeDescriptor = {
instantiate: registry => {
* Stores listener functions registered with `subscribe()`.
* When functions register to listen to store changes with
* `subscribe()` they get added here. Although Redux offers
* its own `subscribe()` function directly, by wrapping the
* subscription in this store instance it's possible to
* optimize checking if the state has changed before calling
* @type {Set<ListenerFunction>}
const listeners = new Set();
const reducer = options.reducer;
return getResolveSelectors();
const store = instantiateReduxStore(key, options, registry, thunkArgs);
// Expose the private registration functions on the store
// so they can be copied to a sub registry in registry.js.
lock(store, privateRegistrationFunctions);
const resolversCache = createResolversCache();
function bindAction(action) {
return (...args) => Promise.resolve(store.dispatch(action(...args)));
...mapValues(actions_namespaceObject, bindAction),
...mapValues(options.actions, bindAction)
const boundPrivateActions = createBindingCache(bindAction);
const allActions = new Proxy(() => {}, {
const privateAction = privateActions[prop];
return privateAction ? boundPrivateActions.get(privateAction, prop) : actions[prop];
const thunkActions = new Proxy(allActions, {
apply: (target, thisArg, [action]) => store.dispatch(action)
lock(actions, allActions);
const resolvers = options.resolvers ? mapResolvers(options.resolvers) : {};
function bindSelector(selector, selectorName) {
if (selector.isRegistrySelector) {
selector.registry = registry;
const boundSelector = (...args) => {
args = normalize(selector, args);
const state = store.__unstableOriginalGetState();
// Before calling the selector, switch to the correct
if (selector.isRegistrySelector) {
selector.registry = registry;
return selector(state.root, ...args);
// Expose normalization method on the bound selector
// in order that it can be called when fullfilling
boundSelector.__unstableNormalizeArgs = selector.__unstableNormalizeArgs;
const resolver = resolvers[selectorName];
boundSelector.hasResolver = false;
return mapSelectorWithResolver(boundSelector, selectorName, resolver, store, resolversCache);
function bindMetadataSelector(metaDataSelector) {
const boundSelector = (...args) => {
const state = store.__unstableOriginalGetState();
const originalSelectorName = args && args[0];
const originalSelectorArgs = args && args[1];
const targetSelector = options?.selectors?.[originalSelectorName];
// Normalize the arguments passed to the target selector.
if (originalSelectorName && targetSelector) {
args[1] = normalize(targetSelector, originalSelectorArgs);
return metaDataSelector(state.metadata, ...args);
boundSelector.hasResolver = false;
...mapValues(selectors_namespaceObject, bindMetadataSelector),
...mapValues(options.selectors, bindSelector)
const boundPrivateSelectors = createBindingCache(bindSelector);
// Pre-bind the private selectors that have been registered by the time of
// instantiation, so that registry selectors are bound to the registry.
for (const [selectorName, selector] of Object.entries(privateSelectors)) {
boundPrivateSelectors.get(selector, selectorName);
const allSelectors = new Proxy(() => {}, {
const privateSelector = privateSelectors[prop];
return privateSelector ? boundPrivateSelectors.get(privateSelector, prop) : selectors[prop];
const thunkSelectors = new Proxy(allSelectors, {
apply: (target, thisArg, [selector]) => selector(store.__unstableOriginalGetState())
lock(selectors, allSelectors);
const resolveSelectors = mapResolveSelectors(selectors, store);
const suspendSelectors = mapSuspendSelectors(selectors, store);
const getSelectors = () => selectors;
const getActions = () => actions;
const getResolveSelectors = () => resolveSelectors;
const getSuspendSelectors = () => suspendSelectors;
// We have some modules monkey-patching the store object
// It's wrong to do so but until we refactor all of our effects to controls
// We need to keep the same "store" instance here.
store.__unstableOriginalGetState = store.getState;
store.getState = () => store.__unstableOriginalGetState().root;
// Customize subscribe behavior to call listeners only on effective change,
// not on every dispatch.
const subscribe = store && (listener => {
return () => listeners.delete(listener);
let lastState = store.__unstableOriginalGetState();
const state = store.__unstableOriginalGetState();
const hasChanged = state !== lastState;
for (const listener of listeners) {
// This can be simplified to just { subscribe, getSelectors, getActions }
// Once we remove the use function.
// Expose the private registration functions on the store
// descriptor. That's a natural choice since that's where the
// public actions and selectors are stored .
lock(storeDescriptor, privateRegistrationFunctions);
* Creates a redux store for a namespace.
* @param {string} key Unique namespace identifier.
* @param {Object} options Registered store options, with properties
* describing reducer, actions, selectors,
* @param {DataRegistry} registry Registry reference.
* @param {Object} thunkArgs Argument object for the thunk middleware.
* @return {Object} Newly created redux store.
function instantiateReduxStore(key, options, registry, thunkArgs) {
const normalizedControls = mapValues(controls, control => control.isRegistryControl ? control(registry) : control);
const middlewares = [resolvers_cache_middleware(registry, key), promise_middleware, external_wp_reduxRoutine_default()(normalizedControls), createThunkMiddleware(thunkArgs)];
const enhancers = [applyMiddleware(...middlewares)];
if (typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION__) {
enhancers.push(window.__REDUX_DEVTOOLS_EXTENSION__({
replacer: devToolsReplacer
const enhancedReducer = combine_reducers_combineReducers({
metadata: metadata_reducer,
return createStore(enhancedReducer, {
}, (0,external_wp_compose_namespaceObject.compose)(enhancers));
* Maps selectors to functions that return a resolution promise for them
* @param {Object} selectors Selectors to map.
* @param {Object} store The redux store the selectors select from.
* @return {Object} Selectors mapped to their resolution functions.
function mapResolveSelectors(selectors, store) {
return mapValues(storeSelectors, (selector, selectorName) => {
// If the selector doesn't have a resolver, just convert the return value
// (including exceptions) to a Promise, no additional extra behavior is needed.
if (!selector.hasResolver) {
return async (...args) => selector.apply(null, args);
return new Promise((resolve, reject) => {
const hasFinished = () => selectors.hasFinishedResolution(selectorName, args);
const finalize = result => {
const hasFailed = selectors.hasResolutionFailed(selectorName, args);
const error = selectors.getResolutionError(selectorName, args);
const getResult = () => selector.apply(null, args);
// Trigger the selector (to trigger the resolver)
const result = getResult();
const unsubscribe = store.subscribe(() => {
* Maps selectors to functions that throw a suspense promise if not yet resolved.
* @param {Object} selectors Selectors to map.
* @param {Object} store The redux store the selectors select from.
* @return {Object} Selectors mapped to their suspense functions.
function mapSuspendSelectors(selectors, store) {
return mapValues(selectors, (selector, selectorName) => {
// Selector without a resolver doesn't have any extra suspense behavior.
if (!selector.hasResolver) {
const result = selector.apply(null, args);
if (selectors.hasFinishedResolution(selectorName, args)) {
if (selectors.hasResolutionFailed(selectorName, args)) {
throw selectors.getResolutionError(selectorName, args);
throw new Promise(resolve => {
const unsubscribe = store.subscribe(() => {
if (selectors.hasFinishedResolution(selectorName, args)) {
* Convert resolvers to a normalized form, an object with `fulfill` method and
* optional methods like `isFulfilled`.
* @param {Object} resolvers Resolver to convert
function mapResolvers(resolvers) {
return mapValues(resolvers, resolver => {