diff -r 7b1b88e27a20 -r 48c4eec2b7e6 wp/wp-includes/js/dist/data.js --- a/wp/wp-includes/js/dist/data.js Thu Sep 29 08:06:27 2022 +0200 +++ b/wp/wp-includes/js/dist/data.js Fri Sep 05 18:40:08 2025 +0200 @@ -1,10 +1,150 @@ -/******/ (function() { // webpackBootstrap +/******/ (() => { // webpackBootstrap +/******/ "use strict"; /******/ var __webpack_modules__ = ({ -/***/ 2167: -/***/ (function(module) { - -"use strict"; +/***/ 66: +/***/ ((module) => { + + + +var isMergeableObject = function isMergeableObject(value) { + return isNonNullObject(value) + && !isSpecial(value) +}; + +function isNonNullObject(value) { + return !!value && typeof value === 'object' +} + +function isSpecial(value) { + var stringValue = Object.prototype.toString.call(value); + + return stringValue === '[object RegExp]' + || stringValue === '[object Date]' + || isReactElement(value) +} + +// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25 +var canUseSymbol = typeof Symbol === 'function' && Symbol.for; +var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7; + +function isReactElement(value) { + return value.$$typeof === REACT_ELEMENT_TYPE +} + +function emptyTarget(val) { + return Array.isArray(val) ? [] : {} +} + +function cloneUnlessOtherwiseSpecified(value, options) { + return (options.clone !== false && options.isMergeableObject(value)) + ? deepmerge(emptyTarget(value), value, options) + : value +} + +function defaultArrayMerge(target, source, options) { + return target.concat(source).map(function(element) { + return cloneUnlessOtherwiseSpecified(element, options) + }) +} + +function getMergeFunction(key, options) { + if (!options.customMerge) { + return deepmerge + } + var customMerge = options.customMerge(key); + return typeof customMerge === 'function' ? customMerge : deepmerge +} + +function getEnumerableOwnPropertySymbols(target) { + return Object.getOwnPropertySymbols + ? Object.getOwnPropertySymbols(target).filter(function(symbol) { + return Object.propertyIsEnumerable.call(target, symbol) + }) + : [] +} + +function getKeys(target) { + return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target)) +} + +function propertyIsOnObject(object, property) { + try { + return property in object + } catch(_) { + return false + } +} + +// Protects from prototype poisoning and unexpected merging up the prototype chain. +function propertyIsUnsafe(target, key) { + return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet, + && !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain, + && Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable. +} + +function mergeObject(target, source, options) { + var destination = {}; + if (options.isMergeableObject(target)) { + getKeys(target).forEach(function(key) { + destination[key] = cloneUnlessOtherwiseSpecified(target[key], options); + }); + } + getKeys(source).forEach(function(key) { + if (propertyIsUnsafe(target, key)) { + return + } + + if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) { + destination[key] = getMergeFunction(key, options)(target[key], source[key], options); + } else { + destination[key] = cloneUnlessOtherwiseSpecified(source[key], options); + } + }); + return destination +} + +function deepmerge(target, source, options) { + options = options || {}; + options.arrayMerge = options.arrayMerge || defaultArrayMerge; + options.isMergeableObject = options.isMergeableObject || isMergeableObject; + // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge() + // implementations can use it. The caller may not replace it. + options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified; + + var sourceIsArray = Array.isArray(source); + var targetIsArray = Array.isArray(target); + var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray; + + if (!sourceAndTargetTypesMatch) { + return cloneUnlessOtherwiseSpecified(source, options) + } else if (sourceIsArray) { + return options.arrayMerge(target, source, options) + } else { + return mergeObject(target, source, options) + } +} + +deepmerge.all = function deepmergeAll(array, options) { + if (!Array.isArray(array)) { + throw new Error('first argument should be an array') + } + + return array.reduce(function(prev, next) { + return deepmerge(prev, next, options) + }, {}) +}; + +var deepmerge_1 = deepmerge; + +module.exports = deepmerge_1; + + +/***/ }), + +/***/ 3249: +/***/ ((module) => { + function _typeof(obj) { @@ -314,65 +454,6 @@ module.exports = EquivalentKeyMap; -/***/ }), - -/***/ 9125: -/***/ (function(module) { - -function combineReducers( reducers ) { - var keys = Object.keys( reducers ), - getNextState; - - getNextState = ( function() { - var fn, i, key; - - fn = 'return {'; - for ( i = 0; i < keys.length; i++ ) { - // Rely on Quoted escaping of JSON.stringify with guarantee that - // each member of Object.keys is a string. - // - // "If Type(value) is String, then return the result of calling the - // abstract operation Quote with argument value. [...] The abstract - // operation Quote(value) wraps a String value in double quotes and - // escapes characters within it." - // - // https://www.ecma-international.org/ecma-262/5.1/#sec-15.12.3 - key = JSON.stringify( keys[ i ] ); - - fn += key + ':r[' + key + '](s[' + key + '],a),'; - } - fn += '}'; - - return new Function( 'r,s,a', fn ); - } )(); - - return function combinedReducer( state, action ) { - var nextState, i, key; - - // Assumed changed if initial state. - if ( state === undefined ) { - return getNextState( reducers, {}, action ); - } - - nextState = getNextState( reducers, state, action ); - - // Determine whether state has changed. - i = keys.length; - while ( i-- ) { - key = keys[ i ]; - if ( state[ key ] !== nextState[ key ] ) { - // Return immediately if a changed value is encountered. - return nextState; - } - } - - return state; - }; -} - -module.exports = combineReducers; - - /***/ }) /******/ }); @@ -403,127 +484,157 @@ /******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ -/******/ !function() { +/******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { +/******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? -/******/ function() { return module['default']; } : -/******/ function() { return module; }; +/******/ () => (module['default']) : +/******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; -/******/ }(); +/******/ })(); /******/ /******/ /* webpack/runtime/define property getters */ -/******/ !function() { +/******/ (() => { /******/ // define getter functions for harmony exports -/******/ __webpack_require__.d = function(exports, definition) { +/******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; -/******/ }(); +/******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ -/******/ !function() { -/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } -/******/ }(); +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ -/******/ !function() { +/******/ (() => { /******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { +/******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; -/******/ }(); +/******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; -// This entry need to be wrapped in an IIFE because it need to be in strict mode. -!function() { -"use strict"; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, { - "AsyncModeProvider": function() { return /* reexport */ async_mode_provider_context; }, - "RegistryConsumer": function() { return /* reexport */ RegistryConsumer; }, - "RegistryProvider": function() { return /* reexport */ context; }, - "combineReducers": function() { return /* reexport */ (turbo_combine_reducers_default()); }, - "controls": function() { return /* reexport */ controls; }, - "createReduxStore": function() { return /* reexport */ createReduxStore; }, - "createRegistry": function() { return /* reexport */ createRegistry; }, - "createRegistryControl": function() { return /* reexport */ createRegistryControl; }, - "createRegistrySelector": function() { return /* reexport */ createRegistrySelector; }, - "dispatch": function() { return /* binding */ build_module_dispatch; }, - "plugins": function() { return /* reexport */ plugins_namespaceObject; }, - "register": function() { return /* binding */ register; }, - "registerGenericStore": function() { return /* binding */ registerGenericStore; }, - "registerStore": function() { return /* binding */ registerStore; }, - "resolveSelect": function() { return /* binding */ build_module_resolveSelect; }, - "select": function() { return /* binding */ build_module_select; }, - "subscribe": function() { return /* binding */ subscribe; }, - "use": function() { return /* binding */ use; }, - "useDispatch": function() { return /* reexport */ use_dispatch; }, - "useRegistry": function() { return /* reexport */ useRegistry; }, - "useSelect": function() { return /* reexport */ useSelect; }, - "withDispatch": function() { return /* reexport */ with_dispatch; }, - "withRegistry": function() { return /* reexport */ with_registry; }, - "withSelect": function() { return /* reexport */ with_select; } + AsyncModeProvider: () => (/* reexport */ async_mode_provider_context), + RegistryConsumer: () => (/* reexport */ RegistryConsumer), + RegistryProvider: () => (/* reexport */ context), + combineReducers: () => (/* binding */ build_module_combineReducers), + controls: () => (/* reexport */ controls), + createReduxStore: () => (/* reexport */ createReduxStore), + createRegistry: () => (/* reexport */ createRegistry), + createRegistryControl: () => (/* reexport */ createRegistryControl), + createRegistrySelector: () => (/* reexport */ createRegistrySelector), + createSelector: () => (/* reexport */ rememo), + dispatch: () => (/* reexport */ dispatch_dispatch), + plugins: () => (/* reexport */ plugins_namespaceObject), + register: () => (/* binding */ register), + registerGenericStore: () => (/* binding */ registerGenericStore), + registerStore: () => (/* binding */ registerStore), + resolveSelect: () => (/* binding */ build_module_resolveSelect), + select: () => (/* reexport */ select_select), + subscribe: () => (/* binding */ subscribe), + suspendSelect: () => (/* binding */ suspendSelect), + use: () => (/* binding */ use), + useDispatch: () => (/* reexport */ use_dispatch), + useRegistry: () => (/* reexport */ useRegistry), + useSelect: () => (/* reexport */ useSelect), + useSuspenseSelect: () => (/* reexport */ useSuspenseSelect), + withDispatch: () => (/* reexport */ with_dispatch), + withRegistry: () => (/* reexport */ with_registry), + withSelect: () => (/* reexport */ with_select) }); // NAMESPACE OBJECT: ./node_modules/@wordpress/data/build-module/redux-store/metadata/selectors.js var selectors_namespaceObject = {}; __webpack_require__.r(selectors_namespaceObject); __webpack_require__.d(selectors_namespaceObject, { - "getCachedResolvers": function() { return getCachedResolvers; }, - "getIsResolving": function() { return getIsResolving; }, - "getResolutionError": function() { return getResolutionError; }, - "getResolutionState": function() { return getResolutionState; }, - "hasFinishedResolution": function() { return hasFinishedResolution; }, - "hasResolutionFailed": function() { return hasResolutionFailed; }, - "hasStartedResolution": function() { return hasStartedResolution; }, - "isResolving": function() { return isResolving; } + countSelectorsByStatus: () => (countSelectorsByStatus), + getCachedResolvers: () => (getCachedResolvers), + getIsResolving: () => (getIsResolving), + getResolutionError: () => (getResolutionError), + getResolutionState: () => (getResolutionState), + hasFinishedResolution: () => (hasFinishedResolution), + hasResolutionFailed: () => (hasResolutionFailed), + hasResolvingSelectors: () => (hasResolvingSelectors), + hasStartedResolution: () => (hasStartedResolution), + isResolving: () => (isResolving) }); // NAMESPACE OBJECT: ./node_modules/@wordpress/data/build-module/redux-store/metadata/actions.js var actions_namespaceObject = {}; __webpack_require__.r(actions_namespaceObject); __webpack_require__.d(actions_namespaceObject, { - "failResolution": function() { return failResolution; }, - "failResolutions": function() { return failResolutions; }, - "finishResolution": function() { return finishResolution; }, - "finishResolutions": function() { return finishResolutions; }, - "invalidateResolution": function() { return invalidateResolution; }, - "invalidateResolutionForStore": function() { return invalidateResolutionForStore; }, - "invalidateResolutionForStoreSelector": function() { return invalidateResolutionForStoreSelector; }, - "startResolution": function() { return startResolution; }, - "startResolutions": function() { return startResolutions; } + failResolution: () => (failResolution), + failResolutions: () => (failResolutions), + finishResolution: () => (finishResolution), + finishResolutions: () => (finishResolutions), + invalidateResolution: () => (invalidateResolution), + invalidateResolutionForStore: () => (invalidateResolutionForStore), + invalidateResolutionForStoreSelector: () => (invalidateResolutionForStoreSelector), + startResolution: () => (startResolution), + startResolutions: () => (startResolutions) }); // NAMESPACE OBJECT: ./node_modules/@wordpress/data/build-module/plugins/index.js var plugins_namespaceObject = {}; __webpack_require__.r(plugins_namespaceObject); __webpack_require__.d(plugins_namespaceObject, { - "persistence": function() { return persistence; } + persistence: () => (persistence) }); -// EXTERNAL MODULE: ./node_modules/turbo-combine-reducers/index.js -var turbo_combine_reducers = __webpack_require__(9125); -var turbo_combine_reducers_default = /*#__PURE__*/__webpack_require__.n(turbo_combine_reducers); -;// CONCATENATED MODULE: external "lodash" -var external_lodash_namespaceObject = window["lodash"]; ;// CONCATENATED MODULE: external ["wp","deprecated"] -var external_wp_deprecated_namespaceObject = window["wp"]["deprecated"]; +const external_wp_deprecated_namespaceObject = window["wp"]["deprecated"]; var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject); +;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/typeof.js +function _typeof(o) { + "@babel/helpers - typeof"; + + return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { + return typeof o; + } : function (o) { + return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; + }, _typeof(o); +} +;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toPrimitive.js + +function _toPrimitive(input, hint) { + if (_typeof(input) !== "object" || input === null) return input; + var prim = input[Symbol.toPrimitive]; + if (prim !== undefined) { + var res = prim.call(input, hint || "default"); + if (_typeof(res) !== "object") return res; + throw new TypeError("@@toPrimitive must return a primitive value."); + } + return (hint === "string" ? String : Number)(input); +} +;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toPropertyKey.js + + +function _toPropertyKey(arg) { + var key = _toPrimitive(arg, "string"); + return _typeof(key) === "symbol" ? key : String(key); +} ;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/defineProperty.js + function _defineProperty(obj, key, value) { + key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, @@ -534,36 +645,30 @@ } else { obj[key] = value; } - return obj; } ;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/objectSpread2.js - -function ownKeys(object, enumerableOnly) { - var keys = Object.keys(object); - +function ownKeys(e, r) { + var t = Object.keys(e); if (Object.getOwnPropertySymbols) { - var symbols = Object.getOwnPropertySymbols(object); - enumerableOnly && (symbols = symbols.filter(function (sym) { - return Object.getOwnPropertyDescriptor(object, sym).enumerable; - })), keys.push.apply(keys, symbols); + var o = Object.getOwnPropertySymbols(e); + r && (o = o.filter(function (r) { + return Object.getOwnPropertyDescriptor(e, r).enumerable; + })), t.push.apply(t, o); } - - return keys; + return t; } - -function _objectSpread2(target) { - for (var i = 1; i < arguments.length; i++) { - var source = null != arguments[i] ? arguments[i] : {}; - i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { - _defineProperty(target, key, source[key]); - }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { - Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); +function _objectSpread2(e) { + for (var r = 1; r < arguments.length; r++) { + var t = null != arguments[r] ? arguments[r] : {}; + r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { + _defineProperty(e, r, t[r]); + }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { + Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } - - return target; + return e; } ;// CONCATENATED MODULE: ./node_modules/redux/es/redux.js @@ -1256,23 +1361,33 @@ }; } -/* - * This is a dummy function to check if the function name has been altered by minification. - * If the function has been minified and NODE_ENV !== 'production', warn the user. - */ - -function isCrushed() {} - -if (false) {} - // EXTERNAL MODULE: ./node_modules/equivalent-key-map/equivalent-key-map.js -var equivalent_key_map = __webpack_require__(2167); +var equivalent_key_map = __webpack_require__(3249); var equivalent_key_map_default = /*#__PURE__*/__webpack_require__.n(equivalent_key_map); ;// CONCATENATED MODULE: external ["wp","reduxRoutine"] -var external_wp_reduxRoutine_namespaceObject = window["wp"]["reduxRoutine"]; +const external_wp_reduxRoutine_namespaceObject = window["wp"]["reduxRoutine"]; var external_wp_reduxRoutine_default = /*#__PURE__*/__webpack_require__.n(external_wp_reduxRoutine_namespaceObject); +;// CONCATENATED MODULE: external ["wp","compose"] +const external_wp_compose_namespaceObject = window["wp"]["compose"]; +;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/redux-store/combine-reducers.js +function combine_reducers_combineReducers(reducers) { + const keys = Object.keys(reducers); + return function combinedReducer(state = {}, action) { + const nextState = {}; + let hasChanged = false; + for (const key of keys) { + const reducer = reducers[key]; + const prevStateForKey = state[key]; + const nextStateForKey = reducer(prevStateForKey, action); + nextState[key] = nextStateForKey; + hasChanged = hasChanged || nextStateForKey !== prevStateForKey; + } + return hasChanged ? nextState : state; + }; +} + ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/factory.js /** * Creates a selector function that takes additional curried argument with the @@ -1289,15 +1404,18 @@ * * @example * ```js + * import { store as coreStore } from '@wordpress/core-data'; + * import { store as editorStore } from '@wordpress/editor'; + * * const getCurrentPostId = createRegistrySelector( ( select ) => ( state ) => { - * return select( 'core/editor' ).getCurrentPostId(); + * return select( editorStore ).getCurrentPostId(); * } ); * * const getPostEdits = createRegistrySelector( ( select ) => ( state ) => { * // calling another registry selector just like any other function * const postType = getCurrentPostType( state ); * const postId = getCurrentPostId( state ); - * return select( 'core' ).getEntityRecordEdits( 'postType', postType, postId ); + * return select( coreStore ).getEntityRecordEdits( 'postType', postType, postId ); * } ); * ``` * @@ -1312,24 +1430,34 @@ * @return {Function} Registry selector that can be registered with a store. */ function createRegistrySelector(registrySelector) { + const selectorsByRegistry = new WeakMap(); // Create a selector function that is bound to the registry referenced by `selector.registry` // and that has the same API as a regular selector. Binding it in such a way makes it // possible to call the selector directly from another selector. - const selector = function () { - return registrySelector(selector.registry.select)(...arguments); + const wrappedSelector = (...args) => { + let selector = selectorsByRegistry.get(wrappedSelector.registry); + // We want to make sure the cache persists even when new registry + // instances are created. For example patterns create their own editors + // with their own core/block-editor stores, so we should keep track of + // the cache for each registry instance. + if (!selector) { + selector = registrySelector(wrappedSelector.registry.select); + selectorsByRegistry.set(wrappedSelector.registry, selector); + } + return selector(...args); }; + /** * Flag indicating that the selector is a registry selector that needs the correct registry - * reference to be assigned to `selecto.registry` to make it work correctly. + * reference to be assigned to `selector.registry` to make it work correctly. * be mapped as a registry selector. * * @type {boolean} */ - - - selector.isRegistrySelector = true; - return selector; + wrappedSelector.isRegistrySelector = true; + return wrappedSelector; } + /** * Creates a control function that takes additional curried argument with the `registry` object. * While a regular control has signature @@ -1350,7 +1478,6 @@ * * @return {Function} Registry control that can be registered with a store. */ - function createRegistryControl(registryControl) { registryControl.isRegistryControl = true; return registryControl; @@ -1358,10 +1485,6 @@ ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/controls.js /** - * External dependencies - */ - -/** * Internal dependencies */ @@ -1371,6 +1494,10 @@ const SELECT = '@@data/SELECT'; const RESOLVE_SELECT = '@@data/RESOLVE_SELECT'; const DISPATCH = '@@data/DISPATCH'; +function isObject(object) { + return object !== null && typeof object === 'object'; +} + /** * Dispatches a control action for triggering a synchronous registry select. * @@ -1394,19 +1521,15 @@ * * @return {Object} The control descriptor. */ - -function controls_select(storeNameOrDescriptor, selectorName) { - for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { - args[_key - 2] = arguments[_key]; - } - +function controls_select(storeNameOrDescriptor, selectorName, ...args) { return { type: SELECT, - storeKey: (0,external_lodash_namespaceObject.isObject)(storeNameOrDescriptor) ? storeNameOrDescriptor.name : storeNameOrDescriptor, + storeKey: isObject(storeNameOrDescriptor) ? storeNameOrDescriptor.name : storeNameOrDescriptor, selectorName, args }; } + /** * Dispatches a control action for triggering and resolving a registry select. * @@ -1431,20 +1554,15 @@ * * @return {Object} The control descriptor. */ - - -function resolveSelect(storeNameOrDescriptor, selectorName) { - for (var _len2 = arguments.length, args = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { - args[_key2 - 2] = arguments[_key2]; - } - +function resolveSelect(storeNameOrDescriptor, selectorName, ...args) { return { type: RESOLVE_SELECT, - storeKey: (0,external_lodash_namespaceObject.isObject)(storeNameOrDescriptor) ? storeNameOrDescriptor.name : storeNameOrDescriptor, + storeKey: isObject(storeNameOrDescriptor) ? storeNameOrDescriptor.name : storeNameOrDescriptor, selectorName, args }; } + /** * Dispatches a control action for triggering a registry dispatch. * @@ -1458,61 +1576,59 @@ * * // Action generator using dispatch * export function* myAction() { - * yield controls.dispatch( 'core/edit-post', 'togglePublishSidebar' ); + * yield controls.dispatch( 'core/editor', 'togglePublishSidebar' ); * // do some other things. * } * ``` * * @return {Object} The control descriptor. */ - - -function dispatch(storeNameOrDescriptor, actionName) { - for (var _len3 = arguments.length, args = new Array(_len3 > 2 ? _len3 - 2 : 0), _key3 = 2; _key3 < _len3; _key3++) { - args[_key3 - 2] = arguments[_key3]; - } - +function dispatch(storeNameOrDescriptor, actionName, ...args) { return { type: DISPATCH, - storeKey: (0,external_lodash_namespaceObject.isObject)(storeNameOrDescriptor) ? storeNameOrDescriptor.name : storeNameOrDescriptor, + storeKey: isObject(storeNameOrDescriptor) ? storeNameOrDescriptor.name : storeNameOrDescriptor, actionName, args }; } - const controls = { select: controls_select, resolveSelect, dispatch }; const builtinControls = { - [SELECT]: createRegistryControl(registry => _ref => { - let { - storeKey, - selectorName, - args - } = _ref; - return registry.select(storeKey)[selectorName](...args); - }), - [RESOLVE_SELECT]: createRegistryControl(registry => _ref2 => { - let { - storeKey, - selectorName, - args - } = _ref2; + [SELECT]: createRegistryControl(registry => ({ + storeKey, + selectorName, + args + }) => registry.select(storeKey)[selectorName](...args)), + [RESOLVE_SELECT]: createRegistryControl(registry => ({ + storeKey, + selectorName, + args + }) => { const method = registry.select(storeKey)[selectorName].hasResolver ? 'resolveSelect' : 'select'; return registry[method](storeKey)[selectorName](...args); }), - [DISPATCH]: createRegistryControl(registry => _ref3 => { - let { - storeKey, - actionName, - args - } = _ref3; - return registry.dispatch(storeKey)[actionName](...args); - }) + [DISPATCH]: createRegistryControl(registry => ({ + storeKey, + actionName, + args + }) => registry.dispatch(storeKey)[actionName](...args)) }; +;// CONCATENATED MODULE: external ["wp","privateApis"] +const external_wp_privateApis_namespaceObject = window["wp"]["privateApis"]; +;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/lock-unlock.js +/** + * WordPress dependencies + */ + +const { + lock, + unlock +} = (0,external_wp_privateApis_namespaceObject.__dangerousOptInToUnstableAPIsOnlyForCoreModules)('I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.', '@wordpress/data'); + ;// CONCATENATED MODULE: ./node_modules/is-promise/index.mjs function isPromise(obj) { return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'; @@ -1523,12 +1639,12 @@ * External dependencies */ + /** * Simplest possible promise redux middleware. * * @type {import('redux').Middleware} */ - const promiseMiddleware = () => next => action => { if (isPromise(action)) { return action.then(resolvedAction => { @@ -1537,105 +1653,53 @@ } }); } - return next(action); }; - -/* harmony default export */ var promise_middleware = (promiseMiddleware); - -;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/store/index.js -const coreDataStore = { - name: 'core/data', - - instantiate(registry) { - const getCoreDataSelector = selectorName => function (key) { - for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - return registry.select(key)[selectorName](...args); - }; - - const getCoreDataAction = actionName => function (key) { - for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { - args[_key2 - 1] = arguments[_key2]; - } - - return registry.dispatch(key)[actionName](...args); - }; - - return { - getSelectors() { - return Object.fromEntries(['getIsResolving', 'hasStartedResolution', 'hasFinishedResolution', 'isResolving', 'getCachedResolvers'].map(selectorName => [selectorName, getCoreDataSelector(selectorName)])); - }, - - getActions() { - return Object.fromEntries(['startResolution', 'finishResolution', 'invalidateResolution', 'invalidateResolutionForStore', 'invalidateResolutionForStoreSelector'].map(actionName => [actionName, getCoreDataAction(actionName)])); - }, - - subscribe() { - // There's no reasons to trigger any listener when we subscribe to this store - // because there's no state stored in this store that need to retrigger selectors - // if a change happens, the corresponding store where the tracking stated live - // would have already triggered a "subscribe" call. - return () => () => {}; - } - - }; - } - -}; -/* harmony default export */ var store = (coreDataStore); +/* harmony default export */ const promise_middleware = (promiseMiddleware); ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/resolvers-cache-middleware.js -/** - * External dependencies - */ - -/** - * Internal dependencies - */ - - /** @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(store).getCachedResolvers(reducerKey); - Object.entries(resolvers).forEach(_ref => { - let [selectorName, resolversByArgs] = _ref; - const resolver = (0,external_lodash_namespaceObject.get)(registry.stores, [reducerKey, 'resolvers', selectorName]); - +const createResolversCacheMiddleware = (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) => { + // 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 === null || value === void 0 ? void 0 : value.status) !== 'finished' && (value === null || value === void 0 ? void 0 : value.status) !== 'error' || !resolver.shouldInvalidate(action, ...args)) { + if (value.status !== 'finished' && value.status !== 'error') { + return; + } + if (!resolver.shouldInvalidate(action, ...args)) { return; - } // Trigger cache invalidation - - - registry.dispatch(store).invalidateResolution(reducerKey, selectorName, args); + } + + // Trigger cache invalidation + registry.dispatch(storeName).invalidateResolution(selectorName, args); }); }); return next(action); }; - -/* harmony default export */ var resolvers_cache_middleware = (createResolversCacheMiddleware); +/* harmony default export */ const resolvers_cache_middleware = (createResolversCacheMiddleware); ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/redux-store/thunk-middleware.js function createThunkMiddleware(args) { @@ -1643,7 +1707,6 @@ if (typeof action === 'function') { return action(args); } - return next(action); }; } @@ -1657,52 +1720,45 @@ * Higher-order reducer creator which creates a combined reducer object, keyed * by a property on the action object. * - * @param actionProperty Action property by which to key object. + * @param actionProperty Action property by which to key object. * @return Higher-order reducer. */ -const onSubKey = actionProperty => reducer => function () { - let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - let action = arguments.length > 1 ? arguments[1] : undefined; +const onSubKey = actionProperty => reducer => (state = {}, action) => { // Retrieve subkey from action. Do not track if undefined; useful for cases // where reducer is scoped by action shape. const key = action[actionProperty]; - if (key === undefined) { return state; - } // Avoid updating state if unchanged. Note that this also accounts for a + } + + // Avoid updating state if unchanged. Note that this also accounts for a // reducer which returns undefined on a key which is not yet tracked. - - const nextKeyState = reducer(state[key], action); - if (nextKeyState === state[key]) { return state; } - - return { ...state, + return { + ...state, [key]: nextKeyState }; }; + /** * Normalize selector argument array by defaulting `undefined` value to an empty array * and removing trailing `undefined` values. * - * @param args Selector argument array + * @param args Selector argument array * @return Normalized state key array */ - function selectorArgsToStateKey(args) { if (args === undefined || args === null) { return []; } - const len = args.length; let idx = len; - while (idx > 0 && args[idx - 1] === undefined) { idx--; } - return idx === len ? args : args.slice(0, idx); } @@ -1711,23 +1767,17 @@ * External dependencies */ - - /** * Internal dependencies */ - /** * Reducer function returning next state for selector resolution of * subkeys, object form: * * selectorName -> EquivalentKeyMap */ -const subKeysIsResolved = onSubKey('selectorName')(function () { - let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new (equivalent_key_map_default())(); - let action = arguments.length > 1 ? arguments[1] : undefined; - +const subKeysIsResolved = onSubKey('selectorName')((state = new (equivalent_key_map_default())(), action) => { switch (action.type) { case 'START_RESOLUTION': { @@ -1737,7 +1787,6 @@ }); return nextState; } - case 'FINISH_RESOLUTION': { const nextState = new (equivalent_key_map_default())(state); @@ -1746,7 +1795,6 @@ }); return nextState; } - case 'FAIL_RESOLUTION': { const nextState = new (equivalent_key_map_default())(state); @@ -1756,33 +1804,26 @@ }); return nextState; } - case 'START_RESOLUTIONS': { const nextState = new (equivalent_key_map_default())(state); - for (const resolutionArgs of action.args) { nextState.set(selectorArgsToStateKey(resolutionArgs), { status: 'resolving' }); } - return nextState; } - case 'FINISH_RESOLUTIONS': { const nextState = new (equivalent_key_map_default())(state); - for (const resolutionArgs of action.args) { nextState.set(selectorArgsToStateKey(resolutionArgs), { status: 'finished' }); } - return nextState; } - case 'FAIL_RESOLUTIONS': { const nextState = new (equivalent_key_map_default())(state); @@ -1792,16 +1833,13 @@ error: undefined }; const error = action.errors[idx]; - if (error) { resolutionState.error = error; } - nextState.set(selectorArgsToStateKey(resolutionArgs), resolutionState); }); return nextState; } - case 'INVALIDATE_RESOLUTION': { const nextState = new (equivalent_key_map_default())(state); @@ -1809,31 +1847,34 @@ return nextState; } } - return state; }); + /** * Reducer function returning next state for selector resolution, object form: * * selectorName -> EquivalentKeyMap * - * @param state Current state. - * @param action Dispatched action. + * @param state Current state. + * @param action Dispatched action. * * @return Next state. */ - -const isResolved = function () { - let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - let action = arguments.length > 1 ? arguments[1] : undefined; - +const isResolved = (state = {}, action) => { switch (action.type) { case 'INVALIDATE_RESOLUTION_FOR_STORE': return {}; - case 'INVALIDATE_RESOLUTION_FOR_STORE_SELECTOR': - return (0,external_lodash_namespaceObject.has)(state, [action.selectorName]) ? (0,external_lodash_namespaceObject.omit)(state, [action.selectorName]) : state; - + { + if (action.selectorName in state) { + const { + [action.selectorName]: removedSelector, + ...restState + } = state; + return restState; + } + return state; + } case 'START_RESOLUTION': case 'FINISH_RESOLUTION': case 'FAIL_RESOLUTION': @@ -1843,26 +1884,322 @@ case 'INVALIDATE_RESOLUTION': return subKeysIsResolved(state, action); } - return state; }; - -/* harmony default export */ var metadata_reducer = (isResolved); +/* harmony default export */ const metadata_reducer = (isResolved); + +;// CONCATENATED MODULE: ./node_modules/rememo/rememo.js + + +/** @typedef {(...args: any[]) => *[]} GetDependants */ + +/** @typedef {() => void} Clear */ + +/** + * @typedef {{ + * getDependants: GetDependants, + * clear: Clear + * }} EnhancedSelector + */ + +/** + * Internal cache entry. + * + * @typedef CacheNode + * + * @property {?CacheNode|undefined} [prev] Previous node. + * @property {?CacheNode|undefined} [next] Next node. + * @property {*[]} args Function arguments for cache entry. + * @property {*} val Function result. + */ + +/** + * @typedef Cache + * + * @property {Clear} clear Function to clear cache. + * @property {boolean} [isUniqueByDependants] Whether dependants are valid in + * considering cache uniqueness. A cache is unique if dependents are all arrays + * or objects. + * @property {CacheNode?} [head] Cache head. + * @property {*[]} [lastDependants] Dependants from previous invocation. + */ + +/** + * Arbitrary value used as key for referencing cache object in WeakMap tree. + * + * @type {{}} + */ +var LEAF_KEY = {}; + +/** + * Returns the first argument as the sole entry in an array. + * + * @template T + * + * @param {T} value Value to return. + * + * @return {[T]} Value returned as entry in array. + */ +function arrayOf(value) { + return [value]; +} + +/** + * Returns true if the value passed is object-like, or false otherwise. A value + * is object-like if it can support property assignment, e.g. object or array. + * + * @param {*} value Value to test. + * + * @return {boolean} Whether value is object-like. + */ +function isObjectLike(value) { + return !!value && 'object' === typeof value; +} + +/** + * Creates and returns a new cache object. + * + * @return {Cache} Cache object. + */ +function createCache() { + /** @type {Cache} */ + var cache = { + clear: function () { + cache.head = null; + }, + }; + + return cache; +} + +/** + * Returns true if entries within the two arrays are strictly equal by + * reference from a starting index. + * + * @param {*[]} a First array. + * @param {*[]} b Second array. + * @param {number} fromIndex Index from which to start comparison. + * + * @return {boolean} Whether arrays are shallowly equal. + */ +function isShallowEqual(a, b, fromIndex) { + var i; + + if (a.length !== b.length) { + return false; + } + + for (i = fromIndex; i < a.length; i++) { + if (a[i] !== b[i]) { + return false; + } + } + + return true; +} + +/** + * Returns a memoized selector function. The getDependants function argument is + * called before the memoized selector and is expected to return an immutable + * reference or array of references on which the selector depends for computing + * its own return value. The memoize cache is preserved only as long as those + * dependant references remain the same. If getDependants returns a different + * reference(s), the cache is cleared and the selector value regenerated. + * + * @template {(...args: *[]) => *} S + * + * @param {S} selector Selector function. + * @param {GetDependants=} getDependants Dependant getter returning an array of + * references used in cache bust consideration. + */ +/* harmony default export */ function rememo(selector, getDependants) { + /** @type {WeakMap<*,*>} */ + var rootCache; + + /** @type {GetDependants} */ + var normalizedGetDependants = getDependants ? getDependants : arrayOf; + + /** + * Returns the cache for a given dependants array. When possible, a WeakMap + * will be used to create a unique cache for each set of dependants. This + * is feasible due to the nature of WeakMap in allowing garbage collection + * to occur on entries where the key object is no longer referenced. Since + * WeakMap requires the key to be an object, this is only possible when the + * dependant is object-like. The root cache is created as a hierarchy where + * each top-level key is the first entry in a dependants set, the value a + * WeakMap where each key is the next dependant, and so on. This continues + * so long as the dependants are object-like. If no dependants are object- + * like, then the cache is shared across all invocations. + * + * @see isObjectLike + * + * @param {*[]} dependants Selector dependants. + * + * @return {Cache} Cache object. + */ + function getCache(dependants) { + var caches = rootCache, + isUniqueByDependants = true, + i, + dependant, + map, + cache; + + for (i = 0; i < dependants.length; i++) { + dependant = dependants[i]; + + // Can only compose WeakMap from object-like key. + if (!isObjectLike(dependant)) { + isUniqueByDependants = false; + break; + } + + // Does current segment of cache already have a WeakMap? + if (caches.has(dependant)) { + // Traverse into nested WeakMap. + caches = caches.get(dependant); + } else { + // Create, set, and traverse into a new one. + map = new WeakMap(); + caches.set(dependant, map); + caches = map; + } + } + + // We use an arbitrary (but consistent) object as key for the last item + // in the WeakMap to serve as our running cache. + if (!caches.has(LEAF_KEY)) { + cache = createCache(); + cache.isUniqueByDependants = isUniqueByDependants; + caches.set(LEAF_KEY, cache); + } + + return caches.get(LEAF_KEY); + } + + /** + * Resets root memoization cache. + */ + function clear() { + rootCache = new WeakMap(); + } + + /* eslint-disable jsdoc/check-param-names */ + /** + * The augmented selector call, considering first whether dependants have + * changed before passing it to underlying memoize function. + * + * @param {*} source Source object for derivation. + * @param {...*} extraArgs Additional arguments to pass to selector. + * + * @return {*} Selector result. + */ + /* eslint-enable jsdoc/check-param-names */ + function callSelector(/* source, ...extraArgs */) { + var len = arguments.length, + cache, + node, + i, + args, + dependants; + + // Create copy of arguments (avoid leaking deoptimization). + args = new Array(len); + for (i = 0; i < len; i++) { + args[i] = arguments[i]; + } + + dependants = normalizedGetDependants.apply(null, args); + cache = getCache(dependants); + + // If not guaranteed uniqueness by dependants (primitive type), shallow + // compare against last dependants and, if references have changed, + // destroy cache to recalculate result. + if (!cache.isUniqueByDependants) { + if ( + cache.lastDependants && + !isShallowEqual(dependants, cache.lastDependants, 0) + ) { + cache.clear(); + } + + cache.lastDependants = dependants; + } + + node = cache.head; + while (node) { + // Check whether node arguments match arguments + if (!isShallowEqual(node.args, args, 1)) { + node = node.next; + continue; + } + + // At this point we can assume we've found a match + + // Surface matched node to head if not already + if (node !== cache.head) { + // Adjust siblings to point to each other. + /** @type {CacheNode} */ (node.prev).next = node.next; + if (node.next) { + node.next.prev = node.prev; + } + + node.next = cache.head; + node.prev = null; + /** @type {CacheNode} */ (cache.head).prev = node; + cache.head = node; + } + + // Return immediately + return node.val; + } + + // No cached value found. Continue to insertion phase: + + node = /** @type {CacheNode} */ ({ + // Generate the result from original function + val: selector.apply(null, args), + }); + + // Avoid including the source object in the cache. + args[0] = null; + node.args = args; + + // Don't need to check whether node is already head, since it would + // have been returned above already if it was + + // Shift existing head down list + if (cache.head) { + cache.head.prev = node; + node.next = cache.head; + } + + cache.head = node; + + return node.val; + } + + callSelector.getDependants = normalizedGetDependants; + callSelector.clear = clear; + clear(); + + return /** @type {S & EnhancedSelector} */ (callSelector); +} ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/redux-store/metadata/selectors.js /** - * External dependencies + * WordPress dependencies */ + /** * Internal dependencies */ + /** @typedef {Record} State */ - /** @typedef {import('./reducer').StateValue} StateValue */ - /** @typedef {import('./reducer').Status} Status */ /** @@ -1877,21 +2214,25 @@ * * @return {StateValue|undefined} isResolving value. */ - function getResolutionState(state, selectorName, args) { - const map = (0,external_lodash_namespaceObject.get)(state, [selectorName]); - + const map = state[selectorName]; if (!map) { return; } - return map.get(selectorArgsToStateKey(args)); } + /** - * Returns the raw `isResolving` value for a given selector name, - * and arguments set. May be undefined if the selector has never been resolved - * or not resolved for the given set of arguments, otherwise true or false for - * resolution started and completed respectively. + * Returns an `isResolving`-like value for a given selector name and arguments set. + * Its value is either `undefined` if the selector has never been resolved or has been + * invalidated, or a `true`/`false` boolean value if the resolution is in progress or + * has finished, respectively. + * + * This is a legacy selector that was implemented when the "raw" internal data had + * this `undefined | boolean` format. Nowadays the internal value is an object that + * can be retrieved with `getResolutionState`. + * + * @deprecated * * @param {State} state Data state. * @param {string} selectorName Selector name. @@ -1899,11 +2240,16 @@ * * @return {boolean | undefined} isResolving value. */ - function getIsResolving(state, selectorName, args) { + external_wp_deprecated_default()('wp.data.select( store ).getIsResolving', { + since: '6.6', + version: '6.8', + alternative: 'wp.data.select( store ).getResolutionState' + }); const resolutionState = getResolutionState(state, selectorName, args); return resolutionState && resolutionState.status === 'resolving'; } + /** * Returns true if resolution has already been triggered for a given * selector name, and arguments set. @@ -1914,10 +2260,10 @@ * * @return {boolean} Whether resolution has been triggered. */ - function hasStartedResolution(state, selectorName, args) { return getResolutionState(state, selectorName, args) !== undefined; } + /** * Returns true if resolution has completed for a given selector * name, and arguments set. @@ -1928,13 +2274,11 @@ * * @return {boolean} Whether resolution has completed. */ - function hasFinishedResolution(state, selectorName, args) { - var _getResolutionState; - - const status = (_getResolutionState = getResolutionState(state, selectorName, args)) === null || _getResolutionState === void 0 ? void 0 : _getResolutionState.status; + const status = getResolutionState(state, selectorName, args)?.status; return status === 'finished' || status === 'error'; } + /** * Returns true if resolution has failed for a given selector * name, and arguments set. @@ -1945,12 +2289,10 @@ * * @return {boolean} Has resolution failed */ - function hasResolutionFailed(state, selectorName, args) { - var _getResolutionState2; - - return ((_getResolutionState2 = getResolutionState(state, selectorName, args)) === null || _getResolutionState2 === void 0 ? void 0 : _getResolutionState2.status) === 'error'; + return getResolutionState(state, selectorName, args)?.status === 'error'; } + /** * Returns the resolution error for a given selector name, and arguments set. * Note it may be of an Error type, but may also be null, undefined, or anything else @@ -1962,11 +2304,11 @@ * * @return {Error|unknown} Last resolution error */ - function getResolutionError(state, selectorName, args) { const resolutionState = getResolutionState(state, selectorName, args); - return (resolutionState === null || resolutionState === void 0 ? void 0 : resolutionState.status) === 'error' ? resolutionState.error : null; + return resolutionState?.status === 'error' ? resolutionState.error : null; } + /** * Returns true if resolution has been triggered but has not yet completed for * a given selector name, and arguments set. @@ -1977,12 +2319,10 @@ * * @return {boolean} Whether resolution is in progress. */ - function isResolving(state, selectorName, args) { - var _getResolutionState3; - - return ((_getResolutionState3 = getResolutionState(state, selectorName, args)) === null || _getResolutionState3 === void 0 ? void 0 : _getResolutionState3.status) === 'resolving'; + return getResolutionState(state, selectorName, args)?.status === 'resolving'; } + /** * Returns the list of the cached resolvers. * @@ -1990,11 +2330,57 @@ * * @return {State} Resolvers mapped by args and selectorName. */ - function getCachedResolvers(state) { return state; } +/** + * Whether the store has any currently resolving selectors. + * + * @param {State} state Data state. + * + * @return {boolean} True if one or more selectors are resolving, false otherwise. + */ +function hasResolvingSelectors(state) { + return Object.values(state).some(selectorState => + /** + * This uses the internal `_map` property of `EquivalentKeyMap` for + * optimization purposes, since the `EquivalentKeyMap` implementation + * does not support a `.values()` implementation. + * + * @see https://github.com/aduth/equivalent-key-map + */ + Array.from(selectorState._map.values()).some(resolution => resolution[1]?.status === 'resolving')); +} + +/** + * Retrieves the total number of selectors, grouped per status. + * + * @param {State} state Data state. + * + * @return {Object} Object, containing selector totals by status. + */ +const countSelectorsByStatus = rememo(state => { + const selectorsByStatus = {}; + Object.values(state).forEach(selectorState => + /** + * This uses the internal `_map` property of `EquivalentKeyMap` for + * optimization purposes, since the `EquivalentKeyMap` implementation + * does not support a `.values()` implementation. + * + * @see https://github.com/aduth/equivalent-key-map + */ + Array.from(selectorState._map.values()).forEach(resolution => { + var _resolution$1$status; + const currentStatus = (_resolution$1$status = resolution[1]?.status) !== null && _resolution$1$status !== void 0 ? _resolution$1$status : 'error'; + if (!selectorsByStatus[currentStatus]) { + selectorsByStatus[currentStatus] = 0; + } + selectorsByStatus[currentStatus]++; + })); + return selectorsByStatus; +}, state => [state]); + ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/redux-store/metadata/actions.js /** * Returns an action object used in signalling that selector resolution has @@ -2012,6 +2398,7 @@ args }; } + /** * Returns an action object used in signalling that selector resolution has * completed. @@ -2021,7 +2408,6 @@ * * @return {{ type: 'FINISH_RESOLUTION', selectorName: string, args: unknown[] }} Action object. */ - function finishResolution(selectorName, args) { return { type: 'FINISH_RESOLUTION', @@ -2029,6 +2415,7 @@ args }; } + /** * Returns an action object used in signalling that selector resolution has * failed. @@ -2039,7 +2426,6 @@ * * @return {{ type: 'FAIL_RESOLUTION', selectorName: string, args: unknown[], error: Error|unknown }} Action object. */ - function failResolution(selectorName, args, error) { return { type: 'FAIL_RESOLUTION', @@ -2048,6 +2434,7 @@ error }; } + /** * Returns an action object used in signalling that a batch of selector resolutions has * started. @@ -2058,7 +2445,6 @@ * * @return {{ type: 'START_RESOLUTIONS', selectorName: string, args: unknown[][] }} Action object. */ - function startResolutions(selectorName, args) { return { type: 'START_RESOLUTIONS', @@ -2066,6 +2452,7 @@ args }; } + /** * Returns an action object used in signalling that a batch of selector resolutions has * completed. @@ -2076,7 +2463,6 @@ * * @return {{ type: 'FINISH_RESOLUTIONS', selectorName: string, args: unknown[][] }} Action object. */ - function finishResolutions(selectorName, args) { return { type: 'FINISH_RESOLUTIONS', @@ -2084,6 +2470,7 @@ args }; } + /** * Returns an action object used in signalling that a batch of selector resolutions has * completed and at least one of them has failed. @@ -2095,7 +2482,6 @@ * is associated to a resolution. * @return {{ type: 'FAIL_RESOLUTIONS', selectorName: string, args: unknown[], errors: Array }} Action object. */ - function failResolutions(selectorName, args, errors) { return { type: 'FAIL_RESOLUTIONS', @@ -2104,6 +2490,7 @@ errors }; } + /** * Returns an action object used in signalling that we should invalidate the resolution cache. * @@ -2112,7 +2499,6 @@ * * @return {{ type: 'INVALIDATE_RESOLUTION', selectorName: string, args: any[] }} Action object. */ - function invalidateResolution(selectorName, args) { return { type: 'INVALIDATE_RESOLUTION', @@ -2120,18 +2506,19 @@ args }; } + /** * Returns an action object used in signalling that the resolution * should be invalidated. * * @return {{ type: 'INVALIDATE_RESOLUTION_FOR_STORE' }} Action object. */ - function invalidateResolutionForStore() { return { type: 'INVALIDATE_RESOLUTION_FOR_STORE' }; } + /** * Returns an action object used in signalling that the resolution cache for a * given selectorName should be invalidated. @@ -2141,7 +2528,6 @@ * * @return {{ type: 'INVALIDATE_RESOLUTION_FOR_STORE_SELECTOR', selectorName: string }} Action object. */ - function invalidateResolutionForStoreSelector(selectorName) { return { type: 'INVALIDATE_RESOLUTION_FOR_STORE_SELECTOR', @@ -2156,12 +2542,12 @@ - /** * WordPress dependencies */ + /** * Internal dependencies */ @@ -2173,53 +2559,91 @@ + + + /** @typedef {import('../types').DataRegistry} DataRegistry */ - -/** @typedef {import('../types').StoreDescriptor} StoreDescriptor */ - -/** @typedef {import('../types').ReduxStoreConfig} ReduxStoreConfig */ +/** @typedef {import('../types').ListenerFunction} ListenerFunction */ +/** + * @typedef {import('../types').StoreDescriptor} StoreDescriptor + * @template {import('../types').AnyConfig} C + */ +/** + * @typedef {import('../types').ReduxStoreConfig} ReduxStoreConfig + * @template State + * @template {Record} Actions + * @template Selectors + */ const trimUndefinedValues = array => { const result = [...array]; - for (let i = result.length - 1; i >= 0; i--) { if (result[i] === undefined) { result.splice(i, 1); } } - return result; }; + +/** + * 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) { + return null; + } + return state; +}; + /** * Create a cache to track whether resolvers started running or not. * * @return {Object} Resolvers Cache. */ - - function createResolversCache() { const cache = {}; return { 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(); + return { + get(item, itemName) { + let boundItem = cache.get(item); + if (!boundItem) { + boundItem = bind(item, itemName); + cache.set(item, boundItem); + } + return boundItem; + } + }; +} + /** * Creates a data store descriptor for the provided Redux store configuration containing * properties describing reducer, actions, selectors, controls and resolvers. @@ -2236,104 +2660,178 @@ * } ); * ``` * - * @param {string} key Unique namespace identifier. - * @param {ReduxStoreConfig} options Registered store options, with properties - * describing reducer, actions, selectors, - * and resolvers. - * - * @return {StoreDescriptor} Store Object. + * @template State + * @template {Record} Actions + * @template Selectors + * @param {string} key Unique namespace identifier. + * @param {ReduxStoreConfig} options Registered store options, with properties + * describing reducer, actions, selectors, + * and resolvers. + * + * @return {StoreDescriptor>} Store Object. */ - - function createReduxStore(key, options) { - return { + const privateActions = {}; + const privateSelectors = {}; + const privateRegistrationFunctions = { + privateActions, + registerPrivateActions: actions => { + Object.assign(privateActions, actions); + }, + privateSelectors, + registerPrivateSelectors: selectors => { + Object.assign(privateSelectors, selectors); + } + }; + const storeDescriptor = { name: key, 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 + * each listener. + * + * @type {Set} + */ + const listeners = new Set(); const reducer = options.reducer; const thunkArgs = { registry, - get dispatch() { - return Object.assign(action => store.dispatch(action), getActions()); + return thunkActions; }, - get select() { - return Object.assign(selector => selector(store.__unstableOriginalGetState()), getSelectors()); + return thunkSelectors; }, - get resolveSelect() { 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(); - let resolvers; - const actions = mapActions({ ...actions_namespaceObject, - ...options.actions - }, store); - let selectors = mapSelectors({ ...(0,external_lodash_namespaceObject.mapValues)(selectors_namespaceObject, selector => function (state) { - for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - return selector(state.metadata, ...args); - }), - ...(0,external_lodash_namespaceObject.mapValues)(options.selectors, selector => { + function bindAction(action) { + return (...args) => Promise.resolve(store.dispatch(action(...args))); + } + const actions = { + ...mapValues(actions_namespaceObject, bindAction), + ...mapValues(options.actions, bindAction) + }; + const boundPrivateActions = createBindingCache(bindAction); + const allActions = new Proxy(() => {}, { + get: (target, prop) => { + 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 + // registry. if (selector.isRegistrySelector) { selector.registry = registry; } - - return function (state) { - for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { - args[_key2 - 1] = arguments[_key2]; - } - - return selector(state.root, ...args); - }; - }) - }, store); - - if (options.resolvers) { - const result = mapResolvers(options.resolvers, selectors, store, resolversCache); - resolvers = result.resolvers; - selectors = result.selectors; + return selector(state.root, ...args); + }; + + // Expose normalization method on the bound selector + // in order that it can be called when fullfilling + // the resolver. + boundSelector.__unstableNormalizeArgs = selector.__unstableNormalizeArgs; + const resolver = resolvers[selectorName]; + if (!resolver) { + boundSelector.hasResolver = false; + return boundSelector; + } + 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; + return boundSelector; } - + const selectors = { + ...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(() => {}, { + get: (target, prop) => { + 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; // We have some modules monkey-patching the store object + 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, + store.getState = () => store.__unstableOriginalGetState().root; + + // Customize subscribe behavior to call listeners only on effective change, // not on every dispatch. - - const subscribe = store && (listener => { - let lastState = store.__unstableOriginalGetState(); - - return store.subscribe(() => { - const state = store.__unstableOriginalGetState(); - - const hasChanged = state !== lastState; - lastState = state; - - if (hasChanged) { + listeners.add(listener); + return () => listeners.delete(listener); + }); + let lastState = store.__unstableOriginalGetState(); + store.subscribe(() => { + const state = store.__unstableOriginalGetState(); + const hasChanged = state !== lastState; + lastState = state; + if (hasChanged) { + for (const listener of listeners) { listener(); } - }); - }); // This can be simplified to just { subscribe, getSelectors, getActions } + } + }); + + // This can be simplified to just { subscribe, getSelectors, getActions } // Once we remove the use function. - - return { reducer, store, @@ -2342,12 +2840,20 @@ resolvers, getSelectors, getResolveSelectors, + getSuspendSelectors, getActions, subscribe }; } }; + + // 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); + return storeDescriptor; } + /** * Creates a redux store for a namespace. * @@ -2359,89 +2865,36 @@ * @param {Object} thunkArgs Argument object for the thunk middleware. * @return {Object} Newly created redux store. */ - function instantiateReduxStore(key, options, registry, thunkArgs) { - const controls = { ...options.controls, + const controls = { + ...options.controls, ...builtinControls }; - const normalizedControls = (0,external_lodash_namespaceObject.mapValues)(controls, control => control.isRegistryControl ? control(registry) : control); + 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__({ name: key, - instanceId: key + instanceId: key, + serialize: { + replacer: devToolsReplacer + } })); } - const { reducer, initialState } = options; - const enhancedReducer = turbo_combine_reducers_default()({ + const enhancedReducer = combine_reducers_combineReducers({ metadata: metadata_reducer, root: reducer }); return createStore(enhancedReducer, { root: initialState - }, (0,external_lodash_namespaceObject.flowRight)(enhancers)); + }, (0,external_wp_compose_namespaceObject.compose)(enhancers)); } -/** - * Maps selectors to a store. - * - * @param {Object} selectors Selectors to register. Keys will be used as the - * public facing API. Selectors will get passed the - * state as first argument. - * @param {Object} store The store to which the selectors should be mapped. - * @return {Object} Selectors mapped to the provided store. - */ - - -function mapSelectors(selectors, store) { - const createStateSelector = registrySelector => { - const selector = function runSelector() { - // This function is an optimized implementation of: - // - // selector( store.getState(), ...arguments ) - // - // Where the above would incur an `Array#concat` in its application, - // the logic here instead efficiently constructs an arguments array via - // direct assignment. - const argsLength = arguments.length; - const args = new Array(argsLength + 1); - args[0] = store.__unstableOriginalGetState(); - - for (let i = 0; i < argsLength; i++) { - args[i + 1] = arguments[i]; - } - - return registrySelector(...args); - }; - - selector.hasResolver = false; - return selector; - }; - - return (0,external_lodash_namespaceObject.mapValues)(selectors, createStateSelector); -} -/** - * Maps actions to dispatch from a given store. - * - * @param {Object} actions Actions to register. - * @param {Object} store The redux store to which the actions should be mapped. - * - * @return {Object} Actions mapped to the redux store provided. - */ - - -function mapActions(actions, store) { - const createBoundAction = action => function () { - return Promise.resolve(store.dispatch(action(...arguments))); - }; - - return (0,external_lodash_namespaceObject.mapValues)(actions, createBoundAction); -} + /** * Maps selectors to functions that return a resolution promise for them * @@ -2450,34 +2903,31 @@ * * @return {Object} Selectors mapped to their resolution functions. */ - - function mapResolveSelectors(selectors, store) { - const storeSelectors = (0,external_lodash_namespaceObject.omit)(selectors, ['getIsResolving', 'hasStartedResolution', 'hasFinishedResolution', 'hasResolutionFailed', 'isResolving', 'getCachedResolvers', 'getResolutionState', 'getResolutionError']); - return (0,external_lodash_namespaceObject.mapValues)(storeSelectors, (selector, selectorName) => { + const { + getIsResolving, + hasStartedResolution, + hasFinishedResolution, + hasResolutionFailed, + isResolving, + getCachedResolvers, + getResolutionState, + getResolutionError, + hasResolvingSelectors, + countSelectorsByStatus, + ...storeSelectors + } = selectors; + 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 function () { - for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { - args[_key3] = arguments[_key3]; - } - - return selector.apply(null, args); - }; + return async (...args) => selector.apply(null, args); } - - return function () { - for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { - args[_key4] = arguments[_key4]; - } - + return (...args) => { return new Promise((resolve, reject) => { const hasFinished = () => selectors.hasFinishedResolution(selectorName, args); - const finalize = result => { const hasFailed = selectors.hasResolutionFailed(selectorName, args); - if (hasFailed) { const error = selectors.getResolutionError(selectorName, args); reject(error); @@ -2485,16 +2935,12 @@ resolve(result); } }; - - const getResult = () => selector.apply(null, args); // Trigger the selector (to trigger the resolver) - - + const getResult = () => selector.apply(null, args); + // Trigger the selector (to trigger the resolver) const result = getResult(); - if (hasFinished()) { return finalize(result); } - const unsubscribe = store.subscribe(() => { if (hasFinished()) { unsubscribe(); @@ -2505,116 +2951,150 @@ }; }); } + /** - * Returns resolvers with matched selectors for a given namespace. - * Resolvers are side effects invoked once per argument set of a given selector call, - * used in ensuring that the data needs for the selector are satisfied. - * - * @param {Object} resolvers Resolvers to register. - * @param {Object} selectors The current selectors to be modified. - * @param {Object} store The redux store to which the resolvers should be mapped. - * @param {Object} resolversCache Resolvers Cache. + * 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 mapResolvers(resolvers, selectors, store, resolversCache) { - // The `resolver` can be either a function that does the resolution, or, in more advanced - // cases, an object with a `fullfill` method and other optional methods like `isFulfilled`. - // Here we normalize the `resolver` function to an object with `fulfill` method. - const mappedResolvers = (0,external_lodash_namespaceObject.mapValues)(resolvers, resolver => { +function mapSuspendSelectors(selectors, store) { + return mapValues(selectors, (selector, selectorName) => { + // Selector without a resolver doesn't have any extra suspense behavior. + if (!selector.hasResolver) { + return selector; + } + return (...args) => { + const result = selector.apply(null, args); + if (selectors.hasFinishedResolution(selectorName, args)) { + if (selectors.hasResolutionFailed(selectorName, args)) { + throw selectors.getResolutionError(selectorName, args); + } + return result; + } + throw new Promise(resolve => { + const unsubscribe = store.subscribe(() => { + if (selectors.hasFinishedResolution(selectorName, args)) { + resolve(); + unsubscribe(); + } + }); + }); + }; + }); +} + +/** + * 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 => { if (resolver.fulfill) { return resolver; } - - return { ...resolver, + return { + ...resolver, // Copy the enumerable properties of the resolver function. fulfill: resolver // Add the fulfill method. - }; }); - - const mapSelector = (selector, selectorName) => { - const resolver = resolvers[selectorName]; - - if (!resolver) { - selector.hasResolver = false; - return selector; +} + +/** + * Returns a selector with a matched resolver. + * Resolvers are side effects invoked once per argument set of a given selector call, + * used in ensuring that the data needs for the selector are satisfied. + * + * @param {Object} selector The selector function to be bound. + * @param {string} selectorName The selector name. + * @param {Object} resolver Resolver to call. + * @param {Object} store The redux store to which the resolvers should be mapped. + * @param {Object} resolversCache Resolvers Cache. + */ +function mapSelectorWithResolver(selector, selectorName, resolver, store, resolversCache) { + function fulfillSelector(args) { + const state = store.getState(); + if (resolversCache.isRunning(selectorName, args) || typeof resolver.isFulfilled === 'function' && resolver.isFulfilled(state, ...args)) { + return; } - - const selectorResolver = function () { - for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { - args[_key5] = arguments[_key5]; - } - - async function fulfillSelector() { - const state = store.getState(); - - if (resolversCache.isRunning(selectorName, args) || typeof resolver.isFulfilled === 'function' && resolver.isFulfilled(state, ...args)) { - return; + const { + metadata + } = store.__unstableOriginalGetState(); + if (hasStartedResolution(metadata, selectorName, args)) { + return; + } + resolversCache.markAsRunning(selectorName, args); + setTimeout(async () => { + resolversCache.clear(selectorName, args); + store.dispatch(startResolution(selectorName, args)); + try { + const action = resolver.fulfill(...args); + if (action) { + await store.dispatch(action); } - - const { - metadata - } = store.__unstableOriginalGetState(); - - if (hasStartedResolution(metadata, selectorName, args)) { - return; - } - - resolversCache.markAsRunning(selectorName, args); - setTimeout(async () => { - resolversCache.clear(selectorName, args); - store.dispatch(startResolution(selectorName, args)); - - try { - await fulfillResolver(store, mappedResolvers, selectorName, ...args); - store.dispatch(finishResolution(selectorName, args)); - } catch (error) { - store.dispatch(failResolution(selectorName, args, error)); - } - }); + store.dispatch(finishResolution(selectorName, args)); + } catch (error) { + store.dispatch(failResolution(selectorName, args, error)); } - - fulfillSelector(...args); - return selector(...args); - }; - - selectorResolver.hasResolver = true; - return selectorResolver; + }, 0); + } + const selectorResolver = (...args) => { + args = normalize(selector, args); + fulfillSelector(args); + return selector(...args); }; - - return { - resolvers: mappedResolvers, - selectors: (0,external_lodash_namespaceObject.mapValues)(selectors, mapSelector) - }; + selectorResolver.hasResolver = true; + return selectorResolver; } + /** - * Calls a resolver given arguments - * - * @param {Object} store Store reference, for fulfilling via resolvers - * @param {Object} resolvers Store Resolvers - * @param {string} selectorName Selector name to fulfill. - * @param {Array} args Selector Arguments. + * Applies selector's normalization function to the given arguments + * if it exists. + * + * @param {Object} selector The selector potentially with a normalization method property. + * @param {Array} args selector arguments to normalize. + * @return {Array} Potentially normalized arguments. */ - - -async function fulfillResolver(store, resolvers, selectorName) { - const resolver = (0,external_lodash_namespaceObject.get)(resolvers, [selectorName]); - - if (!resolver) { - return; +function normalize(selector, args) { + if (selector.__unstableNormalizeArgs && typeof selector.__unstableNormalizeArgs === 'function' && args?.length) { + return selector.__unstableNormalizeArgs(args); } - - for (var _len6 = arguments.length, args = new Array(_len6 > 3 ? _len6 - 3 : 0), _key6 = 3; _key6 < _len6; _key6++) { - args[_key6 - 3] = arguments[_key6]; + return args; +} + +;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/store/index.js +const coreDataStore = { + name: 'core/data', + instantiate(registry) { + const getCoreDataSelector = selectorName => (key, ...args) => { + return registry.select(key)[selectorName](...args); + }; + const getCoreDataAction = actionName => (key, ...args) => { + return registry.dispatch(key)[actionName](...args); + }; + return { + getSelectors() { + return Object.fromEntries(['getIsResolving', 'hasStartedResolution', 'hasFinishedResolution', 'isResolving', 'getCachedResolvers'].map(selectorName => [selectorName, getCoreDataSelector(selectorName)])); + }, + getActions() { + return Object.fromEntries(['startResolution', 'finishResolution', 'invalidateResolution', 'invalidateResolutionForStore', 'invalidateResolutionForStoreSelector'].map(actionName => [actionName, getCoreDataAction(actionName)])); + }, + subscribe() { + // There's no reasons to trigger any listener when we subscribe to this store + // because there's no state stored in this store that need to retrigger selectors + // if a change happens, the corresponding store where the tracking stated live + // would have already triggered a "subscribe" call. + return () => () => {}; + } + }; } - - const action = resolver.fulfill(...args); - - if (action) { - await store.dispatch(action); - } -} +}; +/* harmony default export */ const store = (coreDataStore); ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/utils/emitter.js /** @@ -2626,53 +3106,41 @@ let isPaused = false; let isPending = false; const listeners = new Set(); - - const notifyListeners = () => // We use Array.from to clone the listeners Set + const notifyListeners = () => + // We use Array.from to clone the listeners Set // This ensures that we don't run a listener // that was added as a response to another listener. Array.from(listeners).forEach(listener => listener()); - return { get isPaused() { return isPaused; }, - subscribe(listener) { listeners.add(listener); return () => listeners.delete(listener); }, - pause() { isPaused = true; }, - resume() { isPaused = false; - if (isPending) { isPending = false; notifyListeners(); } }, - emit() { if (isPaused) { isPending = true; return; } - notifyListeners(); } - }; } ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/registry.js /** - * External dependencies - */ - -/** * WordPress dependencies */ @@ -2684,6 +3152,7 @@ + /** @typedef {import('./types').StoreDescriptor} StoreDescriptor */ /** @@ -2712,6 +3181,9 @@ * @property {Function} registerStore registers store. */ +function getStoreName(storeNameOrDescriptor) { + return typeof storeNameOrDescriptor === 'string' ? storeNameOrDescriptor : storeNameOrDescriptor.name; +} /** * Creates a new store registry, given an optional object of initial store * configurations. @@ -2721,32 +3193,50 @@ * * @return {WPDataRegistry} Data registry. */ - -function createRegistry() { - let storeConfigs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - let parent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; +function createRegistry(storeConfigs = {}, parent = null) { const stores = {}; const emitter = createEmitter(); - const listeningStores = new Set(); + let listeningStores = null; + /** * Global listener called for each store's update. */ - function globalListener() { emitter.emit(); } + /** - * Subscribe to changes to any data. + * Subscribe to changes to any data, either in all stores in registry, or + * in one specific store. * - * @param {Function} listener Listener function. + * @param {Function} listener Listener function. + * @param {string|StoreDescriptor?} storeNameOrDescriptor Optional store name. * * @return {Function} Unsubscribe function. */ - - - const subscribe = listener => { - return emitter.subscribe(listener); + const subscribe = (listener, storeNameOrDescriptor) => { + // subscribe to all stores + if (!storeNameOrDescriptor) { + return emitter.subscribe(listener); + } + + // subscribe to one store + const storeName = getStoreName(storeNameOrDescriptor); + const store = stores[storeName]; + if (store) { + return store.subscribe(listener); + } + + // Trying to access a store that hasn't been registered, + // this is a pattern rarely used but seen in some places. + // We fallback to global `subscribe` here for backward-compatibility for now. + // See https://github.com/WordPress/gutenberg/pull/27466 for more info. + if (!parent) { + return emitter.subscribe(listener); + } + return parent.subscribe(listener, storeNameOrDescriptor); }; + /** * Calls a selector given the current state and extra arguments. * @@ -2755,50 +3245,67 @@ * * @return {*} The selector's returned value. */ - - function select(storeNameOrDescriptor) { - const storeName = (0,external_lodash_namespaceObject.isObject)(storeNameOrDescriptor) ? storeNameOrDescriptor.name : storeNameOrDescriptor; - listeningStores.add(storeName); + const storeName = getStoreName(storeNameOrDescriptor); + listeningStores?.add(storeName); const store = stores[storeName]; - if (store) { return store.getSelectors(); } - - return parent && parent.select(storeName); + return parent?.select(storeName); } - function __unstableMarkListeningStores(callback, ref) { - listeningStores.clear(); - const result = callback.call(this); - ref.current = Array.from(listeningStores); - return result; + listeningStores = new Set(); + try { + return callback.call(this); + } finally { + ref.current = Array.from(listeningStores); + listeningStores = null; + } } + /** - * Given the name of a registered store, returns an object containing the store's - * selectors pre-bound to state so that you only need to supply additional arguments, - * and modified so that they return promises that resolve to their eventual values, - * after any resolvers have ran. + * Given a store descriptor, returns an object containing the store's selectors pre-bound to + * state so that you only need to supply additional arguments, and modified so that they return + * promises that resolve to their eventual values, after any resolvers have ran. * - * @param {string|StoreDescriptor} storeNameOrDescriptor Unique namespace identifier for the store - * or the store descriptor. + * @param {StoreDescriptor|string} storeNameOrDescriptor The store descriptor. The legacy calling + * convention of passing the store name is + * also supported. * * @return {Object} Each key of the object matches the name of a selector. */ - - function resolveSelect(storeNameOrDescriptor) { - const storeName = (0,external_lodash_namespaceObject.isObject)(storeNameOrDescriptor) ? storeNameOrDescriptor.name : storeNameOrDescriptor; - listeningStores.add(storeName); + const storeName = getStoreName(storeNameOrDescriptor); + listeningStores?.add(storeName); const store = stores[storeName]; - if (store) { return store.getResolveSelectors(); } - return parent && parent.resolveSelect(storeName); } + + /** + * Given a store descriptor, returns an object containing the store's selectors pre-bound to + * state so that you only need to supply additional arguments, and modified so that they throw + * promises in case the selector is not resolved yet. + * + * @param {StoreDescriptor|string} storeNameOrDescriptor The store descriptor. The legacy calling + * convention of passing the store name is + * also supported. + * + * @return {Object} Object containing the store's suspense-wrapped selectors. + */ + function suspendSelect(storeNameOrDescriptor) { + const storeName = getStoreName(storeNameOrDescriptor); + listeningStores?.add(storeName); + const store = stores[storeName]; + if (store) { + return store.getSuspendSelectors(); + } + return parent && parent.suspendSelect(storeName); + } + /** * Returns the available actions for a part of the state. * @@ -2807,60 +3314,56 @@ * * @return {*} The action's returned value. */ - - function dispatch(storeNameOrDescriptor) { - const storeName = (0,external_lodash_namespaceObject.isObject)(storeNameOrDescriptor) ? storeNameOrDescriptor.name : storeNameOrDescriptor; + const storeName = getStoreName(storeNameOrDescriptor); const store = stores[storeName]; - if (store) { return store.getActions(); } - return parent && parent.dispatch(storeName); - } // + } + + // // Deprecated // TODO: Remove this after `use()` is removed. - - function withPlugins(attributes) { - return (0,external_lodash_namespaceObject.mapValues)(attributes, (attribute, key) => { + return Object.fromEntries(Object.entries(attributes).map(([key, attribute]) => { if (typeof attribute !== 'function') { - return attribute; + return [key, attribute]; } - - return function () { + return [key, function () { return registry[key].apply(null, arguments); - }; - }); + }]; + })); } + /** * Registers a store instance. * - * @param {string} name Store registry name. - * @param {Object} store Store instance object (getSelectors, getActions, subscribe). + * @param {string} name Store registry name. + * @param {Function} createStore Function that creates a store object (getSelectors, getActions, subscribe). */ - - - function registerStoreInstance(name, store) { + function registerStoreInstance(name, createStore) { + if (stores[name]) { + // eslint-disable-next-line no-console + console.error('Store "' + name + '" is already registered.'); + return stores[name]; + } + const store = createStore(); if (typeof store.getSelectors !== 'function') { throw new TypeError('store.getSelectors must be a function'); } - if (typeof store.getActions !== 'function') { throw new TypeError('store.getActions must be a function'); } - if (typeof store.subscribe !== 'function') { throw new TypeError('store.subscribe must be a function'); - } // The emitter is used to keep track of active listeners when the registry + } + // The emitter is used to keep track of active listeners when the registry // get paused, that way, when resumed we should be able to call all these // pending listeners. - - store.emitter = createEmitter(); const currentSubscribe = store.subscribe; - store.subscribe = listener => { const unsubscribeFromEmitter = store.emitter.subscribe(listener); const unsubscribeFromStore = currentSubscribe(() => { @@ -2868,36 +3371,46 @@ store.emitter.emit(); return; } - listener(); }); return () => { - unsubscribeFromStore === null || unsubscribeFromStore === void 0 ? void 0 : unsubscribeFromStore(); - unsubscribeFromEmitter === null || unsubscribeFromEmitter === void 0 ? void 0 : unsubscribeFromEmitter(); + unsubscribeFromStore?.(); + unsubscribeFromEmitter?.(); }; }; - stores[name] = store; store.subscribe(globalListener); + + // Copy private actions and selectors from the parent store. + if (parent) { + try { + unlock(store.store).registerPrivateActions(unlock(parent).privateActionsOf(name)); + unlock(store.store).registerPrivateSelectors(unlock(parent).privateSelectorsOf(name)); + } catch (e) { + // unlock() throws if store.store was not locked. + // The error indicates there's nothing to do here so let's + // ignore it. + } + } + return store; } + /** * Registers a new store given a store descriptor. * * @param {StoreDescriptor} store Store descriptor. */ - - function register(store) { - registerStoreInstance(store.name, store.instantiate(registry)); + registerStoreInstance(store.name, () => store.instantiate(registry)); } - function registerGenericStore(name, store) { external_wp_deprecated_default()('wp.data.registerGenericStore', { since: '5.9', alternative: 'wp.data.register( storeDescriptor )' }); - registerStoreInstance(name, store); + registerStoreInstance(name, () => store); } + /** * Registers a standard `@wordpress/data` store. * @@ -2906,50 +3419,28 @@ * * @return {Object} Registered store object. */ - - function registerStore(storeName, options) { if (!options.reducer) { throw new TypeError('Must specify store reducer'); } - - const store = createReduxStore(storeName, options).instantiate(registry); - registerStoreInstance(storeName, store); + const store = registerStoreInstance(storeName, () => createReduxStore(storeName, options).instantiate(registry)); return store.store; } - /** - * Subscribe handler to a store. - * - * @param {string[]} storeName The store name. - * @param {Function} handler The function subscribed to the store. - * @return {Function} A function to unsubscribe the handler. - */ - - - function __unstableSubscribeStore(storeName, handler) { - if (storeName in stores) { - return stores[storeName].subscribe(handler); - } // Trying to access a store that hasn't been registered, - // this is a pattern rarely used but seen in some places. - // We fallback to regular `subscribe` here for backward-compatibility for now. - // See https://github.com/WordPress/gutenberg/pull/27466 for more info. - - - if (!parent) { - return subscribe(handler); + function batch(callback) { + // If we're already batching, just call the callback. + if (emitter.isPaused) { + callback(); + return; } - - return parent.__unstableSubscribeStore(storeName, handler); + emitter.pause(); + Object.values(stores).forEach(store => store.emitter.pause()); + try { + callback(); + } finally { + emitter.resume(); + Object.values(stores).forEach(store => store.emitter.resume()); + } } - - function batch(callback) { - emitter.pause(); - (0,external_lodash_namespaceObject.forEach)(stores, store => store.emitter.pause()); - callback(); - emitter.resume(); - (0,external_lodash_namespaceObject.forEach)(stores, store => store.emitter.resume()); - } - let registry = { batch, stores, @@ -2958,39 +3449,55 @@ subscribe, select, resolveSelect, + suspendSelect, dispatch, use, register, registerGenericStore, registerStore, - __unstableMarkListeningStores, - __unstableSubscribeStore - }; // + __unstableMarkListeningStores + }; + + // // TODO: // This function will be deprecated as soon as it is no longer internally referenced. - function use(plugin, options) { if (!plugin) { return; } - - registry = { ...registry, + registry = { + ...registry, ...plugin(registry, options) }; return registry; } - registry.register(store); - for (const [name, config] of Object.entries(storeConfigs)) { registry.register(createReduxStore(name, config)); } - if (parent) { parent.subscribe(globalListener); } - - return withPlugins(registry); + const registryWithPlugins = withPlugins(registry); + lock(registryWithPlugins, { + privateActionsOf: name => { + try { + return unlock(stores[name].store).privateActions; + } catch (e) { + // unlock() throws an error the store was not locked – this means + // there no private actions are available + return {}; + } + }, + privateSelectorsOf: name => { + try { + return unlock(stores[name].store).privateSelectors; + } catch (e) { + return {}; + } + } + }); + return registryWithPlugins; } ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/default-registry.js @@ -2998,8 +3505,47 @@ * Internal dependencies */ -/* harmony default export */ var default_registry = (createRegistry()); - +/* harmony default export */ const default_registry = (createRegistry()); + +;// CONCATENATED MODULE: ./node_modules/is-plain-object/dist/is-plain-object.mjs +/*! + * is-plain-object + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ + +function is_plain_object_isObject(o) { + return Object.prototype.toString.call(o) === '[object Object]'; +} + +function is_plain_object_isPlainObject(o) { + var ctor,prot; + + if (is_plain_object_isObject(o) === false) return false; + + // If has modified constructor + ctor = o.constructor; + if (ctor === undefined) return true; + + // If has modified prototype + prot = ctor.prototype; + if (is_plain_object_isObject(prot) === false) return false; + + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } + + // Most likely a plain Object + return true; +} + + + +// EXTERNAL MODULE: ./node_modules/deepmerge/dist/cjs.js +var cjs = __webpack_require__(66); +var cjs_default = /*#__PURE__*/__webpack_require__.n(cjs); ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/plugins/persistence/storage/object.js let objectStorage; const storage = { @@ -3007,24 +3553,19 @@ if (!objectStorage || !objectStorage[key]) { return null; } - return objectStorage[key]; }, - setItem(key, value) { if (!objectStorage) { storage.clear(); } - objectStorage[key] = String(value); }, - clear() { objectStorage = Object.create(null); } - }; -/* harmony default export */ var object = (storage); +/* harmony default export */ const object = (storage); ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/plugins/persistence/storage/default.js /** @@ -3032,7 +3573,6 @@ */ let default_storage; - try { // Private Browsing in Safari 10 and earlier will throw an error when // attempting to set into localStorage. The test here is intentional in @@ -3043,14 +3583,15 @@ } catch (error) { default_storage = object; } - -/* harmony default export */ var storage_default = (default_storage); +/* harmony default export */ const storage_default = (default_storage); ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/plugins/persistence/index.js /** * External dependencies */ + + /** * Internal dependencies */ @@ -3068,7 +3609,6 @@ * at least implement `getItem` and `setItem` of * the Web Storage API. * @property {string} storageKey Key on which to set in persistent storage. - * */ /** @@ -3076,15 +3616,15 @@ * * @type {Storage} */ - const DEFAULT_STORAGE = storage_default; + /** * Default plugin storage key. * * @type {string} */ - const DEFAULT_STORAGE_KEY = 'WP_DATA'; + /** * Higher-order reducer which invokes the original reducer only if state is * inequal from that of the action's `nextState` property, otherwise returning @@ -3094,14 +3634,13 @@ * * @return {Function} Enhanced reducer. */ - const withLazySameState = reducer => (state, action) => { if (action.nextState === state) { return state; } - return reducer(state, action); }; + /** * Creates a persistence interface, exposing getter and setter methods (`get` * and `set` respectively). @@ -3110,25 +3649,23 @@ * * @return {Object} Persistence interface. */ - function createPersistenceInterface(options) { const { storage = DEFAULT_STORAGE, storageKey = DEFAULT_STORAGE_KEY } = options; let data; + /** * Returns the persisted data as an object, defaulting to an empty object. * * @return {Object} Persisted data. */ - function getData() { if (data === undefined) { // If unset, getItem is expected to return null. Fall back to // empty object. const persisted = storage.getItem(storageKey); - if (persisted === null) { data = {}; } else { @@ -3141,29 +3678,28 @@ } } } - return data; } + /** * Merges an updated reducer state into the persisted data. * * @param {string} key Key to update. * @param {*} value Updated value. */ - - function setData(key, value) { - data = { ...data, + data = { + ...data, [key]: value }; storage.setItem(storageKey, JSON.stringify(data)); } - return { get: getData, set: setData }; } + /** * Data plugin to persist store state into a single storage key. * @@ -3172,9 +3708,9 @@ * * @return {WPDataPlugin} Data plugin. */ - function persistencePlugin(registry, pluginOptions) { const persistence = createPersistenceInterface(pluginOptions); + /** * Creates an enhanced store dispatch function, triggering the state of the * given store name to be persisted when changed. @@ -3185,10 +3721,8 @@ * * @return {Function} Enhanced dispatch function. */ - function createPersistOnChange(getState, storeName, keys) { let getPersistedState; - if (Array.isArray(keys)) { // Given keys, the persisted state should by produced as an object // of the subset of keys. This implementation uses combineReducers @@ -3198,11 +3732,10 @@ const reducers = keys.reduce((accumulator, key) => Object.assign(accumulator, { [key]: (state, action) => action.nextState[key] }), {}); - getPersistedState = withLazySameState(turbo_combine_reducers_default()(reducers)); + getPersistedState = withLazySameState(build_module_combineReducers(reducers)); } else { getPersistedState = (state, action) => action.nextState; } - let lastState = getPersistedState(undefined, { nextState: getState() }); @@ -3210,514 +3743,78 @@ const state = getPersistedState(lastState, { nextState: getState() }); - if (state !== lastState) { persistence.set(storeName, state); lastState = state; } }; } - return { registerStore(storeName, options) { if (!options.persist) { return registry.registerStore(storeName, options); - } // Load from persistence to use as initial state. - - + } + + // Load from persistence to use as initial state. const persistedState = persistence.get()[storeName]; - if (persistedState !== undefined) { let initialState = options.reducer(options.initialState, { type: '@@WP/PERSISTENCE_RESTORE' }); - - if ((0,external_lodash_namespaceObject.isPlainObject)(initialState) && (0,external_lodash_namespaceObject.isPlainObject)(persistedState)) { + if (is_plain_object_isPlainObject(initialState) && is_plain_object_isPlainObject(persistedState)) { // If state is an object, ensure that: // - Other keys are left intact when persisting only a // subset of keys. // - New keys in what would otherwise be used as initial // state are deeply merged as base for persisted value. - initialState = (0,external_lodash_namespaceObject.merge)({}, initialState, persistedState); + initialState = cjs_default()(initialState, persistedState, { + isMergeableObject: is_plain_object_isPlainObject + }); } else { // If there is a mismatch in object-likeness of default // initial or persisted state, defer to persisted value. initialState = persistedState; } - - options = { ...options, + options = { + ...options, initialState }; } - const store = registry.registerStore(storeName, options); store.subscribe(createPersistOnChange(store.getState, storeName, options.persist)); return store; } - }; } -/** - * Move the 'features' object in local storage from the sourceStoreName to the - * preferences store. - * - * @param {Object} persistence The persistence interface. - * @param {string} sourceStoreName The name of the store that has persisted - * preferences to migrate to the preferences - * package. - */ - - -function migrateFeaturePreferencesToPreferencesStore(persistence, sourceStoreName) { - var _state$interfaceStore, _state$interfaceStore2, _state$interfaceStore3, _state$sourceStoreNam, _state$sourceStoreNam2; - - const preferencesStoreName = 'core/preferences'; - const interfaceStoreName = 'core/interface'; - const state = persistence.get(); // Features most recently (and briefly) lived in the interface package. - // If data exists there, prioritize using that for the migration. If not - // also check the original package as the user may have updated from an - // older block editor version. - - const interfaceFeatures = (_state$interfaceStore = state[interfaceStoreName]) === null || _state$interfaceStore === void 0 ? void 0 : (_state$interfaceStore2 = _state$interfaceStore.preferences) === null || _state$interfaceStore2 === void 0 ? void 0 : (_state$interfaceStore3 = _state$interfaceStore2.features) === null || _state$interfaceStore3 === void 0 ? void 0 : _state$interfaceStore3[sourceStoreName]; - const sourceFeatures = (_state$sourceStoreNam = state[sourceStoreName]) === null || _state$sourceStoreNam === void 0 ? void 0 : (_state$sourceStoreNam2 = _state$sourceStoreNam.preferences) === null || _state$sourceStoreNam2 === void 0 ? void 0 : _state$sourceStoreNam2.features; - const featuresToMigrate = interfaceFeatures ? interfaceFeatures : sourceFeatures; - - if (featuresToMigrate) { - var _state$preferencesSto; - - const existingPreferences = (_state$preferencesSto = state[preferencesStoreName]) === null || _state$preferencesSto === void 0 ? void 0 : _state$preferencesSto.preferences; // Avoid migrating features again if they've previously been migrated. - - if (!(existingPreferences !== null && existingPreferences !== void 0 && existingPreferences[sourceStoreName])) { - // Set the feature values in the interface store, the features - // object is keyed by 'scope', which matches the store name for - // the source. - persistence.set(preferencesStoreName, { - preferences: { ...existingPreferences, - [sourceStoreName]: featuresToMigrate - } - }); // Remove migrated feature preferences from `interface`. - - if (interfaceFeatures) { - var _state$interfaceStore4, _state$interfaceStore5; - - const otherInterfaceState = state[interfaceStoreName]; - const otherInterfaceScopes = (_state$interfaceStore4 = state[interfaceStoreName]) === null || _state$interfaceStore4 === void 0 ? void 0 : (_state$interfaceStore5 = _state$interfaceStore4.preferences) === null || _state$interfaceStore5 === void 0 ? void 0 : _state$interfaceStore5.features; - persistence.set(interfaceStoreName, { ...otherInterfaceState, - preferences: { - features: { ...otherInterfaceScopes, - [sourceStoreName]: undefined - } - } - }); - } // Remove migrated feature preferences from the source. - - - if (sourceFeatures) { - var _state$sourceStoreNam3; - - const otherSourceState = state[sourceStoreName]; - const sourcePreferences = (_state$sourceStoreNam3 = state[sourceStoreName]) === null || _state$sourceStoreNam3 === void 0 ? void 0 : _state$sourceStoreNam3.preferences; - persistence.set(sourceStoreName, { ...otherSourceState, - preferences: { ...sourcePreferences, - features: undefined - } - }); - } - } - } -} -/** - * Migrates an individual item inside the `preferences` object for a store. - * - * @param {Object} persistence The persistence interface. - * @param {Object} migrate An options object that contains details of the migration. - * @param {string} migrate.from The name of the store to migrate from. - * @param {string} migrate.scope The scope in the preferences store to migrate to. - * @param {string} key The key in the preferences object to migrate. - * @param {?Function} convert A function that converts preferences from one format to another. - */ - -function migrateIndividualPreferenceToPreferencesStore(persistence, _ref, key) { - var _state$sourceStoreNam4, _state$sourceStoreNam5, _state$preferencesSto2, _state$preferencesSto3, _state$preferencesSto4, _state$preferencesSto5, _state$preferencesSto6, _state$preferencesSto7, _state$sourceStoreNam6; - - let { - from: sourceStoreName, - scope - } = _ref; - let convert = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : external_lodash_namespaceObject.identity; - const preferencesStoreName = 'core/preferences'; - const state = persistence.get(); - const sourcePreference = (_state$sourceStoreNam4 = state[sourceStoreName]) === null || _state$sourceStoreNam4 === void 0 ? void 0 : (_state$sourceStoreNam5 = _state$sourceStoreNam4.preferences) === null || _state$sourceStoreNam5 === void 0 ? void 0 : _state$sourceStoreNam5[key]; // There's nothing to migrate, exit early. - - if (sourcePreference === undefined) { - return; - } - - const targetPreference = (_state$preferencesSto2 = state[preferencesStoreName]) === null || _state$preferencesSto2 === void 0 ? void 0 : (_state$preferencesSto3 = _state$preferencesSto2.preferences) === null || _state$preferencesSto3 === void 0 ? void 0 : (_state$preferencesSto4 = _state$preferencesSto3[scope]) === null || _state$preferencesSto4 === void 0 ? void 0 : _state$preferencesSto4[key]; // There's existing data at the target, so don't overwrite it, exit early. - - if (targetPreference) { - return; - } - - const otherScopes = (_state$preferencesSto5 = state[preferencesStoreName]) === null || _state$preferencesSto5 === void 0 ? void 0 : _state$preferencesSto5.preferences; - const otherPreferences = (_state$preferencesSto6 = state[preferencesStoreName]) === null || _state$preferencesSto6 === void 0 ? void 0 : (_state$preferencesSto7 = _state$preferencesSto6.preferences) === null || _state$preferencesSto7 === void 0 ? void 0 : _state$preferencesSto7[scope]; // Pass an object with the key and value as this allows the convert - // function to convert to a data structure that has different keys. - - const convertedPreferences = convert({ - [key]: sourcePreference - }); - persistence.set(preferencesStoreName, { - preferences: { ...otherScopes, - [scope]: { ...otherPreferences, - ...convertedPreferences - } - } - }); // Remove migrated feature preferences from the source. - - const otherSourceState = state[sourceStoreName]; - const allSourcePreferences = (_state$sourceStoreNam6 = state[sourceStoreName]) === null || _state$sourceStoreNam6 === void 0 ? void 0 : _state$sourceStoreNam6.preferences; - persistence.set(sourceStoreName, { ...otherSourceState, - preferences: { ...allSourcePreferences, - [key]: undefined - } - }); -} -/** - * Convert from: - * ``` - * { - * panels: { - * tags: { - * enabled: true, - * opened: true, - * }, - * permalinks: { - * enabled: false, - * opened: false, - * }, - * }, - * } - * ``` - * - * to: - * { - * inactivePanels: [ - * 'permalinks', - * ], - * openPanels: [ - * 'tags', - * ], - * } - * - * @param {Object} preferences A preferences object. - * - * @return {Object} The converted data. - */ - -function convertEditPostPanels(preferences) { - var _preferences$panels; - - const panels = (_preferences$panels = preferences === null || preferences === void 0 ? void 0 : preferences.panels) !== null && _preferences$panels !== void 0 ? _preferences$panels : {}; - return Object.keys(panels).reduce((convertedData, panelName) => { - const panel = panels[panelName]; - - if ((panel === null || panel === void 0 ? void 0 : panel.enabled) === false) { - convertedData.inactivePanels.push(panelName); - } - - if ((panel === null || panel === void 0 ? void 0 : panel.opened) === true) { - convertedData.openPanels.push(panelName); - } - - return convertedData; - }, { - inactivePanels: [], - openPanels: [] - }); -} -function migrateThirdPartyFeaturePreferencesToPreferencesStore(persistence) { - var _state$interfaceStore6, _state$interfaceStore7; - - const interfaceStoreName = 'core/interface'; - const preferencesStoreName = 'core/preferences'; - let state = persistence.get(); - const interfaceScopes = (_state$interfaceStore6 = state[interfaceStoreName]) === null || _state$interfaceStore6 === void 0 ? void 0 : (_state$interfaceStore7 = _state$interfaceStore6.preferences) === null || _state$interfaceStore7 === void 0 ? void 0 : _state$interfaceStore7.features; - - for (const scope in interfaceScopes) { - var _state$preferencesSto8, _state$interfaceStore8, _state$interfaceStore9; - - // Don't migrate any core 'scopes'. - if (scope.startsWith('core')) { - continue; - } // Skip this scope if there are no features to migrate. - - - const featuresToMigrate = interfaceScopes[scope]; - - if (!featuresToMigrate) { - continue; - } - - const existingPreferences = (_state$preferencesSto8 = state[preferencesStoreName]) === null || _state$preferencesSto8 === void 0 ? void 0 : _state$preferencesSto8.preferences; // Add the data to the preferences store structure. - - persistence.set(preferencesStoreName, { - preferences: { ...existingPreferences, - [scope]: featuresToMigrate - } - }); // Remove the data from the interface store structure. - // Call `persistence.get` again to make sure `state` is up-to-date with - // any changes from the previous iteration of this loop. - - state = persistence.get(); - const otherInterfaceState = state[interfaceStoreName]; - const otherInterfaceScopes = (_state$interfaceStore8 = state[interfaceStoreName]) === null || _state$interfaceStore8 === void 0 ? void 0 : (_state$interfaceStore9 = _state$interfaceStore8.preferences) === null || _state$interfaceStore9 === void 0 ? void 0 : _state$interfaceStore9.features; - persistence.set(interfaceStoreName, { ...otherInterfaceState, - preferences: { - features: { ...otherInterfaceScopes, - [scope]: undefined - } - } - }); - } -} -/** - * Migrates interface 'enableItems' data to the preferences store. - * - * The interface package stores this data in this format: - * ```js - * { - * enableItems: { - * singleEnableItems: { - * complementaryArea: { - * 'core/edit-post': 'edit-post/document', - * 'core/edit-site': 'edit-site/global-styles', - * } - * }, - * multipleEnableItems: { - * pinnedItems: { - * 'core/edit-post': { - * 'plugin-1': true, - * }, - * 'core/edit-site': { - * 'plugin-2': true, - * }, - * }, - * } - * } - * } - * ``` - * and it should be migrated it to: - * ```js - * { - * 'core/edit-post': { - * complementaryArea: 'edit-post/document', - * pinnedItems: { - * 'plugin-1': true, - * }, - * }, - * 'core/edit-site': { - * complementaryArea: 'edit-site/global-styles', - * pinnedItems: { - * 'plugin-2': true, - * }, - * }, - * } - * ``` - * - * @param {Object} persistence The persistence interface. - */ - -function migrateInterfaceEnableItemsToPreferencesStore(persistence) { - var _state$interfaceStore10, _state$preferencesSto9, _state$preferencesSto10, _sourceEnableItems$si, _sourceEnableItems$si2, _sourceEnableItems$mu, _sourceEnableItems$mu2; - - const interfaceStoreName = 'core/interface'; - const preferencesStoreName = 'core/preferences'; - const state = persistence.get(); - const sourceEnableItems = (_state$interfaceStore10 = state[interfaceStoreName]) === null || _state$interfaceStore10 === void 0 ? void 0 : _state$interfaceStore10.enableItems; // There's nothing to migrate, exit early. - - if (!sourceEnableItems) { - return; - } - - const allPreferences = (_state$preferencesSto9 = (_state$preferencesSto10 = state[preferencesStoreName]) === null || _state$preferencesSto10 === void 0 ? void 0 : _state$preferencesSto10.preferences) !== null && _state$preferencesSto9 !== void 0 ? _state$preferencesSto9 : {}; // First convert complementaryAreas into the right format. - // Use the existing preferences as the accumulator so that the data is - // merged. - - const sourceComplementaryAreas = (_sourceEnableItems$si = sourceEnableItems === null || sourceEnableItems === void 0 ? void 0 : (_sourceEnableItems$si2 = sourceEnableItems.singleEnableItems) === null || _sourceEnableItems$si2 === void 0 ? void 0 : _sourceEnableItems$si2.complementaryArea) !== null && _sourceEnableItems$si !== void 0 ? _sourceEnableItems$si : {}; - const convertedComplementaryAreas = Object.keys(sourceComplementaryAreas).reduce((accumulator, scope) => { - var _accumulator$scope; - - const data = sourceComplementaryAreas[scope]; // Don't overwrite any existing data in the preferences store. - - if ((_accumulator$scope = accumulator[scope]) !== null && _accumulator$scope !== void 0 && _accumulator$scope.complementaryArea) { - return accumulator; - } - - return { ...accumulator, - [scope]: { ...accumulator[scope], - complementaryArea: data - } - }; - }, allPreferences); // Next feed the converted complementary areas back into a reducer that - // converts the pinned items, resulting in the fully migrated data. - - const sourcePinnedItems = (_sourceEnableItems$mu = sourceEnableItems === null || sourceEnableItems === void 0 ? void 0 : (_sourceEnableItems$mu2 = sourceEnableItems.multipleEnableItems) === null || _sourceEnableItems$mu2 === void 0 ? void 0 : _sourceEnableItems$mu2.pinnedItems) !== null && _sourceEnableItems$mu !== void 0 ? _sourceEnableItems$mu : {}; - const allConvertedData = Object.keys(sourcePinnedItems).reduce((accumulator, scope) => { - var _accumulator$scope2; - - const data = sourcePinnedItems[scope]; // Don't overwrite any existing data in the preferences store. - - if ((_accumulator$scope2 = accumulator[scope]) !== null && _accumulator$scope2 !== void 0 && _accumulator$scope2.pinnedItems) { - return accumulator; - } - - return { ...accumulator, - [scope]: { ...accumulator[scope], - pinnedItems: data - } - }; - }, convertedComplementaryAreas); - persistence.set(preferencesStoreName, { - preferences: allConvertedData - }); // Remove migrated preferences. - - const otherInterfaceItems = state[interfaceStoreName]; - persistence.set(interfaceStoreName, { ...otherInterfaceItems, - enableItems: undefined - }); -} - -persistencePlugin.__unstableMigrate = pluginOptions => { - const persistence = createPersistenceInterface(pluginOptions); // Boolean feature preferences. - - migrateFeaturePreferencesToPreferencesStore(persistence, 'core/edit-widgets'); - migrateFeaturePreferencesToPreferencesStore(persistence, 'core/customize-widgets'); - migrateFeaturePreferencesToPreferencesStore(persistence, 'core/edit-post'); - migrateFeaturePreferencesToPreferencesStore(persistence, 'core/edit-site'); - migrateThirdPartyFeaturePreferencesToPreferencesStore(persistence); // Other ad-hoc preferences. - - migrateIndividualPreferenceToPreferencesStore(persistence, { - from: 'core/edit-post', - scope: 'core/edit-post' - }, 'hiddenBlockTypes'); - migrateIndividualPreferenceToPreferencesStore(persistence, { - from: 'core/edit-post', - scope: 'core/edit-post' - }, 'editorMode'); - migrateIndividualPreferenceToPreferencesStore(persistence, { - from: 'core/edit-post', - scope: 'core/edit-post' - }, 'preferredStyleVariations'); - migrateIndividualPreferenceToPreferencesStore(persistence, { - from: 'core/edit-post', - scope: 'core/edit-post' - }, 'panels', convertEditPostPanels); - migrateIndividualPreferenceToPreferencesStore(persistence, { - from: 'core/editor', - scope: 'core/edit-post' - }, 'isPublishSidebarEnabled'); - migrateIndividualPreferenceToPreferencesStore(persistence, { - from: 'core/edit-site', - scope: 'core/edit-site' - }, 'editorMode'); - migrateInterfaceEnableItemsToPreferencesStore(persistence); -}; - -/* harmony default export */ var persistence = (persistencePlugin); +persistencePlugin.__unstableMigrate = () => {}; +/* harmony default export */ const persistence = (persistencePlugin); ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/plugins/index.js -;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/extends.js -function _extends() { - _extends = Object.assign ? Object.assign.bind() : function (target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - - return target; - }; - return _extends.apply(this, arguments); -} -;// CONCATENATED MODULE: external ["wp","element"] -var external_wp_element_namespaceObject = window["wp"]["element"]; -;// CONCATENATED MODULE: external ["wp","compose"] -var external_wp_compose_namespaceObject = window["wp"]["compose"]; -;// CONCATENATED MODULE: external "React" -var external_React_namespaceObject = window["React"]; -;// CONCATENATED MODULE: ./node_modules/use-memo-one/dist/use-memo-one.esm.js - - -function areInputsEqual(newInputs, lastInputs) { - if (newInputs.length !== lastInputs.length) { - return false; - } - - for (var i = 0; i < newInputs.length; i++) { - if (newInputs[i] !== lastInputs[i]) { - return false; - } - } - - return true; -} - -function useMemoOne(getResult, inputs) { - var initial = (0,external_React_namespaceObject.useState)(function () { - return { - inputs: inputs, - result: getResult() - }; - })[0]; - var isFirstRun = (0,external_React_namespaceObject.useRef)(true); - var committed = (0,external_React_namespaceObject.useRef)(initial); - var useCache = isFirstRun.current || Boolean(inputs && committed.current.inputs && areInputsEqual(inputs, committed.current.inputs)); - var cache = useCache ? committed.current : { - inputs: inputs, - result: getResult() - }; - (0,external_React_namespaceObject.useEffect)(function () { - isFirstRun.current = false; - committed.current = cache; - }, [cache]); - return cache.result; -} -function useCallbackOne(callback, inputs) { - return useMemoOne(function () { - return callback; - }, inputs); -} -var useMemo = (/* unused pure expression or super */ null && (useMemoOne)); -var useCallback = (/* unused pure expression or super */ null && (useCallbackOne)); - - - ;// CONCATENATED MODULE: external ["wp","priorityQueue"] -var external_wp_priorityQueue_namespaceObject = window["wp"]["priorityQueue"]; +const external_wp_priorityQueue_namespaceObject = window["wp"]["priorityQueue"]; +;// CONCATENATED MODULE: external ["wp","element"] +const external_wp_element_namespaceObject = window["wp"]["element"]; ;// CONCATENATED MODULE: external ["wp","isShallowEqual"] -var external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"]; +const external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"]; var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject); ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/components/registry-provider/context.js /** * WordPress dependencies */ + /** * Internal dependencies */ - const Context = (0,external_wp_element_namespaceObject.createContext)(default_registry); const { Consumer, Provider } = Context; + /** * A custom react Context consumer exposing the provided `registry` to * children components. Used along with the RegistryProvider. @@ -3749,8 +3846,8 @@ * } * ``` */ - const RegistryConsumer = Consumer; + /** * A custom Context provider for exposing the provided `registry` to children * components via a consumer. @@ -3758,14 +3855,14 @@ * See RegistryConsumer documentation for * example. */ - -/* harmony default export */ var context = (Provider); +/* harmony default export */ const context = (Provider); ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/components/registry-provider/use-registry.js /** * WordPress dependencies */ + /** * Internal dependencies */ @@ -3810,7 +3907,6 @@ * * @return {Function} A custom react hook exposing the registry context value. */ - function useRegistry() { return (0,external_wp_element_namespaceObject.useContext)(Context); } @@ -3826,6 +3922,7 @@ Provider: context_Provider } = context_Context; const AsyncModeConsumer = (/* unused pure expression or super */ null && (context_Consumer)); + /** * Context Provider Component used to switch the data module component rerendering * between Sync and Async modes. @@ -3834,10 +3931,11 @@ * * ```js * import { useSelect, AsyncModeProvider } from '@wordpress/data'; + * import { store as blockEditorStore } from '@wordpress/block-editor'; * * function BlockCount() { * const count = useSelect( ( select ) => { - * return select( 'core/block-editor' ).getBlockCount() + * return select( blockEditorStore ).getBlockCount() * }, [] ); * * return count; @@ -3858,49 +3956,222 @@ * It is possible to nest multiple levels of AsyncModeProvider to fine-tune the rendering behavior. * * @param {boolean} props.value Enable Async Mode. - * @return {WPComponent} The component to be rendered. + * @return {Component} The component to be rendered. */ - -/* harmony default export */ var async_mode_provider_context = (context_Provider); +/* harmony default export */ const async_mode_provider_context = (context_Provider); ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/components/async-mode-provider/use-async-mode.js /** * WordPress dependencies */ + /** * Internal dependencies */ - function useAsyncMode() { return (0,external_wp_element_namespaceObject.useContext)(context_Context); } ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/components/use-select/index.js /** - * External dependencies - */ - -/** * WordPress dependencies */ - /** * Internal dependencies */ - - -const noop = () => {}; - const renderQueue = (0,external_wp_priorityQueue_namespaceObject.createQueue)(); -/** @typedef {import('../../types').StoreDescriptor} StoreDescriptor */ + +/** + * @typedef {import('../../types').StoreDescriptor} StoreDescriptor + * @template {import('../../types').AnyConfig} C + */ +/** + * @typedef {import('../../types').ReduxStoreConfig} ReduxStoreConfig + * @template State + * @template {Record} Actions + * @template Selectors + */ +/** @typedef {import('../../types').MapSelect} MapSelect */ +/** + * @typedef {import('../../types').UseSelectReturn} UseSelectReturn + * @template {MapSelect|StoreDescriptor} T + */ + +function Store(registry, suspense) { + const select = suspense ? registry.suspendSelect : registry.select; + const queueContext = {}; + let lastMapSelect; + let lastMapResult; + let lastMapResultValid = false; + let lastIsAsync; + let subscriber; + let didWarnUnstableReference; + const storeStatesOnMount = new Map(); + function getStoreState(name) { + var _registry$stores$name; + // If there's no store property (custom generic store), return an empty + // object. When comparing the state, the empty objects will cause the + // equality check to fail, setting `lastMapResultValid` to false. + return (_registry$stores$name = registry.stores[name]?.store?.getState?.()) !== null && _registry$stores$name !== void 0 ? _registry$stores$name : {}; + } + const createSubscriber = stores => { + // The set of stores the `subscribe` function is supposed to subscribe to. Here it is + // initialized, and then the `updateStores` function can add new stores to it. + const activeStores = [...stores]; + + // The `subscribe` function, which is passed to the `useSyncExternalStore` hook, could + // be called multiple times to establish multiple subscriptions. That's why we need to + // keep a set of active subscriptions; + const activeSubscriptions = new Set(); + function subscribe(listener) { + // Maybe invalidate the value right after subscription was created. + // React will call `getValue` after subscribing, to detect store + // updates that happened in the interval between the `getValue` call + // during render and creating the subscription, which is slightly + // delayed. We need to ensure that this second `getValue` call will + // compute a fresh value only if any of the store states have + // changed in the meantime. + if (lastMapResultValid) { + for (const name of activeStores) { + if (storeStatesOnMount.get(name) !== getStoreState(name)) { + lastMapResultValid = false; + } + } + } + storeStatesOnMount.clear(); + const onStoreChange = () => { + // Invalidate the value on store update, so that a fresh value is computed. + lastMapResultValid = false; + listener(); + }; + const onChange = () => { + if (lastIsAsync) { + renderQueue.add(queueContext, onStoreChange); + } else { + onStoreChange(); + } + }; + const unsubs = []; + function subscribeStore(storeName) { + unsubs.push(registry.subscribe(onChange, storeName)); + } + for (const storeName of activeStores) { + subscribeStore(storeName); + } + activeSubscriptions.add(subscribeStore); + return () => { + activeSubscriptions.delete(subscribeStore); + for (const unsub of unsubs.values()) { + // The return value of the subscribe function could be undefined if the store is a custom generic store. + unsub?.(); + } + // Cancel existing store updates that were already scheduled. + renderQueue.cancel(queueContext); + }; + } + + // Check if `newStores` contains some stores we're not subscribed to yet, and add them. + function updateStores(newStores) { + for (const newStore of newStores) { + if (activeStores.includes(newStore)) { + continue; + } + + // New `subscribe` calls will subscribe to `newStore`, too. + activeStores.push(newStore); + + // Add `newStore` to existing subscriptions. + for (const subscription of activeSubscriptions) { + subscription(newStore); + } + } + } + return { + subscribe, + updateStores + }; + }; + return (mapSelect, isAsync) => { + function updateValue() { + // If the last value is valid, and the `mapSelect` callback hasn't changed, + // then we can safely return the cached value. The value can change only on + // store update, and in that case value will be invalidated by the listener. + if (lastMapResultValid && mapSelect === lastMapSelect) { + return lastMapResult; + } + const listeningStores = { + current: null + }; + const mapResult = registry.__unstableMarkListeningStores(() => mapSelect(select, registry), listeningStores); + if (false) {} + if (!subscriber) { + for (const name of listeningStores.current) { + storeStatesOnMount.set(name, getStoreState(name)); + } + subscriber = createSubscriber(listeningStores.current); + } else { + subscriber.updateStores(listeningStores.current); + } + + // If the new value is shallow-equal to the old one, keep the old one so + // that we don't trigger unwanted updates that do a `===` check. + if (!external_wp_isShallowEqual_default()(lastMapResult, mapResult)) { + lastMapResult = mapResult; + } + lastMapSelect = mapSelect; + lastMapResultValid = true; + } + function getValue() { + // Update the value in case it's been invalidated or `mapSelect` has changed. + updateValue(); + return lastMapResult; + } + + // When transitioning from async to sync mode, cancel existing store updates + // that have been scheduled, and invalidate the value so that it's freshly + // computed. It might have been changed by the update we just cancelled. + if (lastIsAsync && !isAsync) { + lastMapResultValid = false; + renderQueue.cancel(queueContext); + } + updateValue(); + lastIsAsync = isAsync; + + // Return a pair of functions that can be passed to `useSyncExternalStore`. + return { + subscribe: subscriber.subscribe, + getValue + }; + }; +} +function useStaticSelect(storeName) { + return useRegistry().select(storeName); +} +function useMappingSelect(suspense, mapSelect, deps) { + const registry = useRegistry(); + const isAsync = useAsyncMode(); + const store = (0,external_wp_element_namespaceObject.useMemo)(() => Store(registry, suspense), [registry, suspense]); + + // These are "pass-through" dependencies from the parent hook, + // and the parent should catch any hook rule violations. + // eslint-disable-next-line react-hooks/exhaustive-deps + const selector = (0,external_wp_element_namespaceObject.useCallback)(mapSelect, deps); + const { + subscribe, + getValue + } = store(selector, isAsync); + const result = (0,external_wp_element_namespaceObject.useSyncExternalStore)(subscribe, getValue, getValue); + (0,external_wp_element_namespaceObject.useDebugValue)(result); + return result; +} /** * Custom react hook for retrieving props from registered selectors. @@ -3908,28 +4179,25 @@ * In general, this custom React hook follows the * [rules of hooks](https://reactjs.org/docs/hooks-rules.html). * - * @param {Function|StoreDescriptor|string} mapSelect Function called on every state change. The - * returned value is exposed to the component - * implementing this hook. The function receives - * the `registry.select` method on the first - * argument and the `registry` on the second - * argument. - * When a store key is passed, all selectors for - * the store will be returned. This is only meant - * for usage of these selectors in event - * callbacks, not for data needed to create the - * element tree. - * @param {Array} deps If provided, this memoizes the mapSelect so the - * same `mapSelect` is invoked on every state - * change unless the dependencies change. + * @template {MapSelect | StoreDescriptor} T + * @param {T} mapSelect Function called on every state change. The returned value is + * exposed to the component implementing this hook. The function + * receives the `registry.select` method on the first argument + * and the `registry` on the second argument. + * When a store key is passed, all selectors for the store will be + * returned. This is only meant for usage of these selectors in event + * callbacks, not for data needed to create the element tree. + * @param {unknown[]} deps If provided, this memoizes the mapSelect so the same `mapSelect` is + * invoked on every state change unless the dependencies change. * * @example * ```js * import { useSelect } from '@wordpress/data'; + * import { store as myCustomStore } from 'my-custom-store'; * * function HammerPriceDisplay( { currency } ) { * const price = useSelect( ( select ) => { - * return select( 'my-shop' ).getPrice( 'hammer', currency ) + * return select( myCustomStore ).getPrice( 'hammer', currency ); * }, [ currency ] ); * return new Intl.NumberFormat( 'en-US', { * style: 'currency', @@ -3956,9 +4224,10 @@ * * ```js * import { useSelect } from '@wordpress/data'; + * import { store as myCustomStore } from 'my-custom-store'; * * function Paste( { children } ) { - * const { getSettings } = useSelect( 'my-shop' ); + * const { getSettings } = useSelect( myCustomStore ); * function onPaste() { * // Do something with the settings. * const settings = getSettings(); @@ -3966,153 +4235,64 @@ * return
{ children }
; * } * ``` - * - * @return {Function} A custom react hook. + * @return {UseSelectReturn} A custom react hook. */ - function useSelect(mapSelect, deps) { - const hasMappingFunction = 'function' === typeof mapSelect; // If we're recalling a store by its name or by - // its descriptor then we won't be caching the - // calls to `mapSelect` because we won't be calling it. - - if (!hasMappingFunction) { - deps = []; - } // Because of the "rule of hooks" we have to call `useCallback` - // on every invocation whether or not we have a real function - // for `mapSelect`. we'll create this intermediate variable to - // fulfill that need and then reference it with our "real" - // `_mapSelect` if we can. - - - const callbackMapper = (0,external_wp_element_namespaceObject.useCallback)(hasMappingFunction ? mapSelect : noop, deps); - - const _mapSelect = hasMappingFunction ? callbackMapper : null; - - const registry = useRegistry(); - const isAsync = useAsyncMode(); // React can sometimes clear the `useMemo` cache. - // We use the cache-stable `useMemoOne` to avoid - // losing queues. - - const queueContext = useMemoOne(() => ({ - queue: true - }), [registry]); - const [, forceRender] = (0,external_wp_element_namespaceObject.useReducer)(s => s + 1, 0); - const latestMapSelect = (0,external_wp_element_namespaceObject.useRef)(); - const latestIsAsync = (0,external_wp_element_namespaceObject.useRef)(isAsync); - const latestMapOutput = (0,external_wp_element_namespaceObject.useRef)(); - const latestMapOutputError = (0,external_wp_element_namespaceObject.useRef)(); - const isMountedAndNotUnsubscribing = (0,external_wp_element_namespaceObject.useRef)(); // Keep track of the stores being selected in the _mapSelect function, - // and only subscribe to those stores later. - - const listeningStores = (0,external_wp_element_namespaceObject.useRef)([]); - const wrapSelect = (0,external_wp_element_namespaceObject.useCallback)(callback => registry.__unstableMarkListeningStores(() => callback(registry.select, registry), listeningStores), [registry]); // Generate a "flag" for used in the effect dependency array. - // It's different than just using `mapSelect` since deps could be undefined, - // in that case, we would still want to memoize it. - - const depsChangedFlag = (0,external_wp_element_namespaceObject.useMemo)(() => ({}), deps || []); - let mapOutput; - - if (_mapSelect) { - mapOutput = latestMapOutput.current; - const hasReplacedMapSelect = latestMapSelect.current !== _mapSelect; - const lastMapSelectFailed = !!latestMapOutputError.current; - - if (hasReplacedMapSelect || lastMapSelectFailed) { - try { - mapOutput = wrapSelect(_mapSelect); - } catch (error) { - let errorMessage = `An error occurred while running 'mapSelect': ${error.message}`; - - if (latestMapOutputError.current) { - errorMessage += `\nThe error may be correlated with this previous error:\n`; - errorMessage += `${latestMapOutputError.current.stack}\n\n`; - errorMessage += 'Original stack trace:'; - } // eslint-disable-next-line no-console - - - console.error(errorMessage); - } - } + // On initial call, on mount, determine the mode of this `useSelect` call + // and then never allow it to change on subsequent updates. + const staticSelectMode = typeof mapSelect !== 'function'; + const staticSelectModeRef = (0,external_wp_element_namespaceObject.useRef)(staticSelectMode); + if (staticSelectMode !== staticSelectModeRef.current) { + const prevMode = staticSelectModeRef.current ? 'static' : 'mapping'; + const nextMode = staticSelectMode ? 'static' : 'mapping'; + throw new Error(`Switching useSelect from ${prevMode} to ${nextMode} is not allowed`); } - (0,external_wp_compose_namespaceObject.useIsomorphicLayoutEffect)(() => { - if (!hasMappingFunction) { - return; - } - - latestMapSelect.current = _mapSelect; - latestMapOutput.current = mapOutput; - latestMapOutputError.current = undefined; - isMountedAndNotUnsubscribing.current = true; // This has to run after the other ref updates - // to avoid using stale values in the flushed - // callbacks or potentially overwriting a - // changed `latestMapOutput.current`. - - if (latestIsAsync.current !== isAsync) { - latestIsAsync.current = isAsync; - renderQueue.flush(queueContext); - } - }); - (0,external_wp_compose_namespaceObject.useIsomorphicLayoutEffect)(() => { - if (!hasMappingFunction) { - return; - } - - const onStoreChange = () => { - if (isMountedAndNotUnsubscribing.current) { - try { - const newMapOutput = wrapSelect(latestMapSelect.current); - - if (external_wp_isShallowEqual_default()(latestMapOutput.current, newMapOutput)) { - return; - } - - latestMapOutput.current = newMapOutput; - } catch (error) { - latestMapOutputError.current = error; - } - - forceRender(); - } - }; - - const onChange = () => { - if (latestIsAsync.current) { - renderQueue.add(queueContext, onStoreChange); - } else { - onStoreChange(); - } - }; // Catch any possible state changes during mount before the subscription - // could be set. - - - onChange(); - const unsubscribers = listeningStores.current.map(storeName => registry.__unstableSubscribeStore(storeName, onChange)); - return () => { - isMountedAndNotUnsubscribing.current = false; // The return value of the subscribe function could be undefined if the store is a custom generic store. - - unsubscribers.forEach(unsubscribe => unsubscribe === null || unsubscribe === void 0 ? void 0 : unsubscribe()); - renderQueue.flush(queueContext); - }; // If you're tempted to eliminate the spread dependencies below don't do it! - // We're passing these in from the calling function and want to make sure we're - // examining every individual value inside the `deps` array. - }, [registry, wrapSelect, hasMappingFunction, depsChangedFlag]); - return hasMappingFunction ? mapOutput : registry.select(mapSelect); + /* eslint-disable react-hooks/rules-of-hooks */ + // `staticSelectMode` is not allowed to change during the hook instance's, + // lifetime, so the rules of hooks are not really violated. + return staticSelectMode ? useStaticSelect(mapSelect) : useMappingSelect(false, mapSelect, deps); + /* eslint-enable react-hooks/rules-of-hooks */ } +/** + * A variant of the `useSelect` hook that has the same API, but is a compatible + * Suspense-enabled data source. + * + * @template {MapSelect} T + * @param {T} mapSelect Function called on every state change. The + * returned value is exposed to the component + * using this hook. The function receives the + * `registry.suspendSelect` method as the first + * argument and the `registry` as the second one. + * @param {Array} deps A dependency array used to memoize the `mapSelect` + * so that the same `mapSelect` is invoked on every + * state change unless the dependencies change. + * + * @throws {Promise} A suspense Promise that is thrown if any of the called + * selectors is in an unresolved state. + * + * @return {ReturnType} Data object returned by the `mapSelect` function. + */ +function useSuspenseSelect(mapSelect, deps) { + return useMappingSelect(true, mapSelect, deps); +} + +;// CONCATENATED MODULE: external "ReactJSXRuntime" +const external_ReactJSXRuntime_namespaceObject = window["ReactJSXRuntime"]; ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/components/with-select/index.js - - - /** * WordPress dependencies */ + /** * Internal dependencies */ +/** @typedef {import('react').ComponentType} ComponentType */ + /** * Higher-order component used to inject state-derived props using registered * selectors. @@ -4124,6 +4304,7 @@ * @example * ```js * import { withSelect } from '@wordpress/data'; + * import { store as myCustomStore } from 'my-custom-store'; * * function PriceDisplay( { price, currency } ) { * return new Intl.NumberFormat( 'en-US', { @@ -4133,7 +4314,7 @@ * } * * const HammerPriceDisplay = withSelect( ( select, ownProps ) => { - * const { getPrice } = select( 'my-shop' ); + * const { getPrice } = select( myCustomStore ); * const { currency } = ownProps; * * return { @@ -4150,24 +4331,21 @@ * component and update automatically if the price of a hammer ever changes in * the store. * - * @return {WPComponent} Enhanced component with merged state data props. + * @return {ComponentType} Enhanced component with merged state data props. */ const withSelect = mapSelectToProps => (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => (0,external_wp_compose_namespaceObject.pure)(ownProps => { const mapSelect = (select, registry) => mapSelectToProps(select, ownProps, registry); - const mergeProps = useSelect(mapSelect); - return (0,external_wp_element_namespaceObject.createElement)(WrappedComponent, _extends({}, ownProps, mergeProps)); + return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WrappedComponent, { + ...ownProps, + ...mergeProps + }); }), 'withSelect'); - -/* harmony default export */ var with_select = (withSelect); +/* harmony default export */ const with_select = (withSelect); ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/components/use-dispatch/use-dispatch-with-map.js /** - * External dependencies - */ - -/** * WordPress dependencies */ @@ -4192,7 +4370,6 @@ * @return {Object} An object mapping props to functions created by the passed * in dispatchMap. */ - const useDispatchWithMap = (dispatchMap, deps) => { const registry = useRegistry(); const currentDispatchMap = (0,external_wp_element_namespaceObject.useRef)(dispatchMap); @@ -4201,34 +4378,30 @@ }); return (0,external_wp_element_namespaceObject.useMemo)(() => { const currentDispatchProps = currentDispatchMap.current(registry.dispatch, registry); - return (0,external_lodash_namespaceObject.mapValues)(currentDispatchProps, (dispatcher, propName) => { + return Object.fromEntries(Object.entries(currentDispatchProps).map(([propName, dispatcher]) => { if (typeof dispatcher !== 'function') { // eslint-disable-next-line no-console console.warn(`Property ${propName} returned from dispatchMap in useDispatchWithMap must be a function.`); } - - return function () { - return currentDispatchMap.current(registry.dispatch, registry)[propName](...arguments); - }; - }); + return [propName, (...args) => currentDispatchMap.current(registry.dispatch, registry)[propName](...args)]; + })); }, [registry, ...deps]); }; - -/* harmony default export */ var use_dispatch_with_map = (useDispatchWithMap); +/* harmony default export */ const use_dispatch_with_map = (useDispatchWithMap); ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/components/with-dispatch/index.js - - - /** * WordPress dependencies */ + /** * Internal dependencies */ +/** @typedef {import('react').ComponentType} ComponentType */ + /** * Higher-order component used to add dispatch props using registered action * creators. @@ -4247,9 +4420,10 @@ * } * * import { withDispatch } from '@wordpress/data'; + * import { store as myCustomStore } from 'my-custom-store'; * * const SaleButton = withDispatch( ( dispatch, ownProps ) => { - * const { startSale } = dispatch( 'my-shop' ); + * const { startSale } = dispatch( myCustomStore ); * const { discountPercent } = ownProps; * * return { @@ -4284,11 +4458,12 @@ * } * * import { withDispatch } from '@wordpress/data'; + * import { store as myCustomStore } from 'my-custom-store'; * * const SaleButton = withDispatch( ( dispatch, ownProps, { select } ) => { * // Stock number changes frequently. - * const { getStockNumber } = select( 'my-shop' ); - * const { startSale } = dispatch( 'my-shop' ); + * const { getStockNumber } = select( myCustomStore ); + * const { startSale } = dispatch( myCustomStore ); * return { * onClick() { * const discountPercent = getStockNumber() > 50 ? 10 : 20; @@ -4306,26 +4481,25 @@ * returns an object with the same keys. For example, it should not contain * conditions under which a different value would be returned. * - * @return {WPComponent} Enhanced component with merged dispatcher props. + * @return {ComponentType} Enhanced component with merged dispatcher props. */ const withDispatch = mapDispatchToProps => (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => ownProps => { const mapDispatch = (dispatch, registry) => mapDispatchToProps(dispatch, ownProps, registry); - const dispatchProps = use_dispatch_with_map(mapDispatch, []); - return (0,external_wp_element_namespaceObject.createElement)(WrappedComponent, _extends({}, ownProps, dispatchProps)); + return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WrappedComponent, { + ...ownProps, + ...dispatchProps + }); }, 'withDispatch'); - -/* harmony default export */ var with_dispatch = (withDispatch); +/* harmony default export */ const with_dispatch = (withDispatch); ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/components/with-registry/index.js - - - /** * WordPress dependencies */ + /** * Internal dependencies */ @@ -4335,22 +4509,33 @@ * Higher-order component which renders the original component with the current * registry context passed as its `registry` prop. * - * @param {WPComponent} OriginalComponent Original component. - * - * @return {WPComponent} Enhanced component. + * @param {Component} OriginalComponent Original component. + * + * @return {Component} Enhanced component. */ -const withRegistry = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(OriginalComponent => props => (0,external_wp_element_namespaceObject.createElement)(RegistryConsumer, null, registry => (0,external_wp_element_namespaceObject.createElement)(OriginalComponent, _extends({}, props, { - registry: registry -}))), 'withRegistry'); -/* harmony default export */ var with_registry = (withRegistry); +const withRegistry = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(OriginalComponent => props => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(RegistryConsumer, { + children: registry => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(OriginalComponent, { + ...props, + registry: registry + }) +}), 'withRegistry'); +/* harmony default export */ const with_registry = (withRegistry); ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/components/use-dispatch/use-dispatch.js /** * Internal dependencies */ -/** @typedef {import('../../types').StoreDescriptor} StoreDescriptor */ + +/** + * @typedef {import('../../types').StoreDescriptor} StoreDescriptor + * @template {import('../../types').AnyConfig} StoreConfig + */ +/** + * @typedef {import('../../types').UseDispatchReturn} UseDispatchReturn + * @template StoreNameOrDescriptor + */ /** * A custom react hook returning the current registry dispatch actions creators. @@ -4358,11 +4543,12 @@ * Note: The component using this hook must be within the context of a * RegistryProvider. * - * @param {string|StoreDescriptor} [storeNameOrDescriptor] Optionally provide the name of the - * store or its descriptor from which to - * retrieve action creators. If not - * provided, the registry.dispatch - * function is returned instead. + * @template {undefined | string | StoreDescriptor} StoreNameOrDescriptor + * @param {StoreNameOrDescriptor} [storeNameOrDescriptor] Optionally provide the name of the + * store or its descriptor from which to + * retrieve action creators. If not + * provided, the registry.dispatch + * function is returned instead. * * @example * This illustrates a pattern where you may need to retrieve dynamic data from @@ -4370,8 +4556,9 @@ * action. * * ```jsx + * import { useCallback } from 'react'; * import { useDispatch, useSelect } from '@wordpress/data'; - * import { useCallback } from '@wordpress/element'; + * import { store as myCustomStore } from 'my-custom-store'; * * function Button( { onClick, children } ) { * return @@ -4379,10 +4566,10 @@ * * const SaleButton = ( { children } ) => { * const { stockNumber } = useSelect( - * ( select ) => select( 'my-shop' ).getStockNumber(), + * ( select ) => select( myCustomStore ).getStockNumber(), * [] * ); - * const { startSale } = useDispatch( 'my-shop' ); + * const { startSale } = useDispatch( myCustomStore ); * const onClick = useCallback( () => { * const discountPercent = stockNumber > 50 ? 10: 20; * startSale( discountPercent ); @@ -4394,29 +4581,84 @@ * // * // Start Sale! * ``` - * @return {Function} A custom react hook. + * @return {UseDispatchReturn} A custom react hook. */ - const useDispatch = storeNameOrDescriptor => { const { dispatch } = useRegistry(); return storeNameOrDescriptor === void 0 ? dispatch : dispatch(storeNameOrDescriptor); }; - -/* harmony default export */ var use_dispatch = (useDispatch); +/* harmony default export */ const use_dispatch = (useDispatch); + +;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/dispatch.js +/** + * Internal dependencies + */ + + + +/** + * Given a store descriptor, returns an object of the store's action creators. + * Calling an action creator will cause it to be dispatched, updating the state value accordingly. + * + * Note: Action creators returned by the dispatch will return a promise when + * they are called. + * + * @param storeNameOrDescriptor The store descriptor. The legacy calling convention of passing + * the store name is also supported. + * + * @example + * ```js + * import { dispatch } from '@wordpress/data'; + * import { store as myCustomStore } from 'my-custom-store'; + * + * dispatch( myCustomStore ).setPrice( 'hammer', 9.75 ); + * ``` + * @return Object containing the action creators. + */ +function dispatch_dispatch(storeNameOrDescriptor) { + return default_registry.dispatch(storeNameOrDescriptor); +} + +;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/select.js +/** + * Internal dependencies + */ + + + +/** + * Given a store descriptor, returns an object of the store's selectors. + * The selector functions are been pre-bound to pass the current state automatically. + * As a consumer, you need only pass arguments of the selector, if applicable. + * + * + * @param storeNameOrDescriptor The store descriptor. The legacy calling convention + * of passing the store name is also supported. + * + * @example + * ```js + * import { select } from '@wordpress/data'; + * import { store as myCustomStore } from 'my-custom-store'; + * + * select( myCustomStore ).getPrice( 'hammer' ); + * ``` + * + * @return Object containing the store's selectors. + */ +function select_select(storeNameOrDescriptor) { + return default_registry.select(storeNameOrDescriptor); +} ;// CONCATENATED MODULE: ./node_modules/@wordpress/data/build-module/index.js /** - * External dependencies - */ - -/** * Internal dependencies */ + /** @typedef {import('./types').StoreDescriptor} StoreDescriptor */ @@ -4430,6 +4672,10 @@ + + + + /** * Object of available plugins to use with a registry. * @@ -4443,6 +4689,7 @@ * The combineReducers helper function turns an object whose values are different * reducing functions into a single reducing function you can pass to registerReducer. * + * @type {import('./types').combineReducers} * @param {Object} reducers An object whose values correspond to different reducing * functions that need to be combined into one. * @@ -4477,73 +4724,52 @@ * @return {Function} A reducer that invokes every reducer inside the reducers * object, and constructs a state object with the same shape. */ - +const build_module_combineReducers = combine_reducers_combineReducers; /** - * Given the name or descriptor of a registered store, returns an object of the store's selectors. - * The selector functions are been pre-bound to pass the current state automatically. - * As a consumer, you need only pass arguments of the selector, if applicable. - * - * @param {string|StoreDescriptor} storeNameOrDescriptor Unique namespace identifier for the store - * or the store descriptor. - * - * @example - * ```js - * import { select } from '@wordpress/data'; - * - * select( 'my-shop' ).getPrice( 'hammer' ); - * ``` - * - * @return {Object} Object containing the store's selectors. - */ - -const build_module_select = default_registry.select; -/** - * Given the name of a registered store, returns an object containing the store's - * selectors pre-bound to state so that you only need to supply additional arguments, - * and modified so that they return promises that resolve to their eventual values, - * after any resolvers have ran. - * - * @param {string|StoreDescriptor} storeNameOrDescriptor Unique namespace identifier for the store - * or the store descriptor. + * Given a store descriptor, returns an object containing the store's selectors pre-bound to state + * so that you only need to supply additional arguments, and modified so that they return promises + * that resolve to their eventual values, after any resolvers have ran. + * + * @param {StoreDescriptor|string} storeNameOrDescriptor The store descriptor. The legacy calling + * convention of passing the store name is + * also supported. * * @example * ```js * import { resolveSelect } from '@wordpress/data'; - * - * resolveSelect( 'my-shop' ).getPrice( 'hammer' ).then(console.log) + * import { store as myCustomStore } from 'my-custom-store'; + * + * resolveSelect( myCustomStore ).getPrice( 'hammer' ).then(console.log) * ``` * * @return {Object} Object containing the store's promise-wrapped selectors. */ - const build_module_resolveSelect = default_registry.resolveSelect; + /** - * Given the name of a registered store, returns an object of the store's action creators. - * Calling an action creator will cause it to be dispatched, updating the state value accordingly. - * - * Note: Action creators returned by the dispatch will return a promise when - * they are called. - * - * @param {string|StoreDescriptor} storeNameOrDescriptor Unique namespace identifier for the store - * or the store descriptor. - * - * @example - * ```js - * import { dispatch } from '@wordpress/data'; - * - * dispatch( 'my-shop' ).setPrice( 'hammer', 9.75 ); - * ``` - * @return {Object} Object containing the action creators. + * Given a store descriptor, returns an object containing the store's selectors pre-bound to state + * so that you only need to supply additional arguments, and modified so that they throw promises + * in case the selector is not resolved yet. + * + * @param {StoreDescriptor|string} storeNameOrDescriptor The store descriptor. The legacy calling + * convention of passing the store name is + * also supported. + * + * @return {Object} Object containing the store's suspense-wrapped selectors. */ - -const build_module_dispatch = default_registry.dispatch; +const suspendSelect = default_registry.suspendSelect; + /** * Given a listener function, the function will be called any time the state value - * of one of the registered stores has changed. This function returns a `unsubscribe` - * function used to stop the subscription. - * - * @param {Function} listener Callback function. + * of one of the registered stores has changed. If you specify the optional + * `storeNameOrDescriptor` parameter, the listener function will be called only + * on updates on that one specific registered store. + * + * This function returns an `unsubscribe` function used to stop the subscription. + * + * @param {Function} listener Callback function. + * @param {string|StoreDescriptor?} storeNameOrDescriptor Optional store name. * * @example * ```js @@ -4558,8 +4784,8 @@ * unsubscribe(); * ``` */ - const subscribe = default_registry.subscribe; + /** * Registers a generic store instance. * @@ -4568,8 +4794,8 @@ * @param {string} name Store registry name. * @param {Object} store Store instance (`{ getSelectors, getActions, subscribe }`). */ - const registerGenericStore = default_registry.registerGenericStore; + /** * Registers a standard `@wordpress/data` store. * @@ -4580,8 +4806,8 @@ * * @return {Object} Registered store object. */ - const registerStore = default_registry.registerStore; + /** * Extends a registry to inherit functionality provided by a given plugin. A * plugin is an object with properties aligning to that of a registry, merged @@ -4589,8 +4815,8 @@ * * @param {Object} plugin Plugin object. */ - const use = default_registry.use; + /** * Registers a standard `@wordpress/data` store descriptor. * @@ -4609,10 +4835,10 @@ * * @param {StoreDescriptor} store Store descriptor. */ - const register = default_registry.register; -}(); +})(); + (window.wp = window.wp || {}).data = __webpack_exports__; /******/ })() ; \ No newline at end of file