| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 (function() { 2 "use strict"; 3 var wp; 4 (wp ||= {}).coreData = (() => { 5 var __create = Object.create; 6 var __defProp = Object.defineProperty; 7 var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 8 var __getOwnPropNames = Object.getOwnPropertyNames; 9 var __getProtoOf = Object.getPrototypeOf; 10 var __hasOwnProp = Object.prototype.hasOwnProperty; 11 var __commonJS = (cb, mod) => function __require() { 12 return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; 13 }; 14 var __export = (target, all) => { 15 for (var name in all) 16 __defProp(target, name, { get: all[name], enumerable: true }); 17 }; 18 var __copyProps = (to, from, except, desc) => { 19 if (from && typeof from === "object" || typeof from === "function") { 20 for (let key of __getOwnPropNames(from)) 21 if (!__hasOwnProp.call(to, key) && key !== except) 22 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 23 } 24 return to; 25 }; 26 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( 27 // If the importer is in node compatibility mode or this is not an ESM 28 // file that has been converted to a CommonJS file using a Babel- 29 // compatible transform (i.e. "__esModule" has not been set), then set 30 // "default" to the CommonJS "module.exports" for node compatibility. 31 isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, 32 mod 33 )); 34 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 35 36 // package-external:@wordpress/data 37 var require_data = __commonJS({ 38 "package-external:@wordpress/data"(exports, module) { 39 module.exports = window.wp.data; 40 } 41 }); 42 43 // node_modules/fast-deep-equal/es6/index.js 44 var require_es6 = __commonJS({ 45 "node_modules/fast-deep-equal/es6/index.js"(exports, module) { 46 "use strict"; 47 module.exports = function equal(a, b) { 48 if (a === b) return true; 49 if (a && b && typeof a == "object" && typeof b == "object") { 50 if (a.constructor !== b.constructor) return false; 51 var length, i, keys; 52 if (Array.isArray(a)) { 53 length = a.length; 54 if (length != b.length) return false; 55 for (i = length; i-- !== 0; ) 56 if (!equal(a[i], b[i])) return false; 57 return true; 58 } 59 if (a instanceof Map && b instanceof Map) { 60 if (a.size !== b.size) return false; 61 for (i of a.entries()) 62 if (!b.has(i[0])) return false; 63 for (i of a.entries()) 64 if (!equal(i[1], b.get(i[0]))) return false; 65 return true; 66 } 67 if (a instanceof Set && b instanceof Set) { 68 if (a.size !== b.size) return false; 69 for (i of a.entries()) 70 if (!b.has(i[0])) return false; 71 return true; 72 } 73 if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { 74 length = a.length; 75 if (length != b.length) return false; 76 for (i = length; i-- !== 0; ) 77 if (a[i] !== b[i]) return false; 78 return true; 79 } 80 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; 81 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); 82 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); 83 keys = Object.keys(a); 84 length = keys.length; 85 if (length !== Object.keys(b).length) return false; 86 for (i = length; i-- !== 0; ) 87 if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; 88 for (i = length; i-- !== 0; ) { 89 var key = keys[i]; 90 if (!equal(a[key], b[key])) return false; 91 } 92 return true; 93 } 94 return a !== a && b !== b; 95 }; 96 } 97 }); 98 99 // package-external:@wordpress/compose 100 var require_compose = __commonJS({ 101 "package-external:@wordpress/compose"(exports, module) { 102 module.exports = window.wp.compose; 103 } 104 }); 105 106 // package-external:@wordpress/undo-manager 107 var require_undo_manager = __commonJS({ 108 "package-external:@wordpress/undo-manager"(exports, module) { 109 module.exports = window.wp.undoManager; 110 } 111 }); 112 113 // package-external:@wordpress/api-fetch 114 var require_api_fetch = __commonJS({ 115 "package-external:@wordpress/api-fetch"(exports, module) { 116 module.exports = window.wp.apiFetch; 117 } 118 }); 119 120 // package-external:@wordpress/sync 121 var require_sync = __commonJS({ 122 "package-external:@wordpress/sync"(exports, module) { 123 module.exports = window.wp.sync; 124 } 125 }); 126 127 // package-external:@wordpress/private-apis 128 var require_private_apis = __commonJS({ 129 "package-external:@wordpress/private-apis"(exports, module) { 130 module.exports = window.wp.privateApis; 131 } 132 }); 133 134 // node_modules/equivalent-key-map/equivalent-key-map.js 135 var require_equivalent_key_map = __commonJS({ 136 "node_modules/equivalent-key-map/equivalent-key-map.js"(exports, module) { 137 "use strict"; 138 function _typeof(obj) { 139 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { 140 _typeof = function(obj2) { 141 return typeof obj2; 142 }; 143 } else { 144 _typeof = function(obj2) { 145 return obj2 && typeof Symbol === "function" && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2; 146 }; 147 } 148 return _typeof(obj); 149 } 150 function _classCallCheck(instance, Constructor) { 151 if (!(instance instanceof Constructor)) { 152 throw new TypeError("Cannot call a class as a function"); 153 } 154 } 155 function _defineProperties(target, props) { 156 for (var i = 0; i < props.length; i++) { 157 var descriptor = props[i]; 158 descriptor.enumerable = descriptor.enumerable || false; 159 descriptor.configurable = true; 160 if ("value" in descriptor) descriptor.writable = true; 161 Object.defineProperty(target, descriptor.key, descriptor); 162 } 163 } 164 function _createClass(Constructor, protoProps, staticProps) { 165 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 166 if (staticProps) _defineProperties(Constructor, staticProps); 167 return Constructor; 168 } 169 function getValuePair(instance, key) { 170 var _map = instance._map, _arrayTreeMap = instance._arrayTreeMap, _objectTreeMap = instance._objectTreeMap; 171 if (_map.has(key)) { 172 return _map.get(key); 173 } 174 var properties = Object.keys(key).sort(); 175 var map = Array.isArray(key) ? _arrayTreeMap : _objectTreeMap; 176 for (var i = 0; i < properties.length; i++) { 177 var property = properties[i]; 178 map = map.get(property); 179 if (map === void 0) { 180 return; 181 } 182 var propertyValue = key[property]; 183 map = map.get(propertyValue); 184 if (map === void 0) { 185 return; 186 } 187 } 188 var valuePair = map.get("_ekm_value"); 189 if (!valuePair) { 190 return; 191 } 192 _map.delete(valuePair[0]); 193 valuePair[0] = key; 194 map.set("_ekm_value", valuePair); 195 _map.set(key, valuePair); 196 return valuePair; 197 } 198 var EquivalentKeyMap2 = /* @__PURE__ */ (function() { 199 function EquivalentKeyMap3(iterable) { 200 _classCallCheck(this, EquivalentKeyMap3); 201 this.clear(); 202 if (iterable instanceof EquivalentKeyMap3) { 203 var iterablePairs = []; 204 iterable.forEach(function(value, key) { 205 iterablePairs.push([key, value]); 206 }); 207 iterable = iterablePairs; 208 } 209 if (iterable != null) { 210 for (var i = 0; i < iterable.length; i++) { 211 this.set(iterable[i][0], iterable[i][1]); 212 } 213 } 214 } 215 _createClass(EquivalentKeyMap3, [{ 216 key: "set", 217 /** 218 * Add or update an element with a specified key and value. 219 * 220 * @param {*} key The key of the element to add. 221 * @param {*} value The value of the element to add. 222 * 223 * @return {EquivalentKeyMap} Map instance. 224 */ 225 value: function set(key, value) { 226 if (key === null || _typeof(key) !== "object") { 227 this._map.set(key, value); 228 return this; 229 } 230 var properties = Object.keys(key).sort(); 231 var valuePair = [key, value]; 232 var map = Array.isArray(key) ? this._arrayTreeMap : this._objectTreeMap; 233 for (var i = 0; i < properties.length; i++) { 234 var property = properties[i]; 235 if (!map.has(property)) { 236 map.set(property, new EquivalentKeyMap3()); 237 } 238 map = map.get(property); 239 var propertyValue = key[property]; 240 if (!map.has(propertyValue)) { 241 map.set(propertyValue, new EquivalentKeyMap3()); 242 } 243 map = map.get(propertyValue); 244 } 245 var previousValuePair = map.get("_ekm_value"); 246 if (previousValuePair) { 247 this._map.delete(previousValuePair[0]); 248 } 249 map.set("_ekm_value", valuePair); 250 this._map.set(key, valuePair); 251 return this; 252 } 253 /** 254 * Returns a specified element. 255 * 256 * @param {*} key The key of the element to return. 257 * 258 * @return {?*} The element associated with the specified key or undefined 259 * if the key can't be found. 260 */ 261 }, { 262 key: "get", 263 value: function get(key) { 264 if (key === null || _typeof(key) !== "object") { 265 return this._map.get(key); 266 } 267 var valuePair = getValuePair(this, key); 268 if (valuePair) { 269 return valuePair[1]; 270 } 271 } 272 /** 273 * Returns a boolean indicating whether an element with the specified key 274 * exists or not. 275 * 276 * @param {*} key The key of the element to test for presence. 277 * 278 * @return {boolean} Whether an element with the specified key exists. 279 */ 280 }, { 281 key: "has", 282 value: function has(key) { 283 if (key === null || _typeof(key) !== "object") { 284 return this._map.has(key); 285 } 286 return getValuePair(this, key) !== void 0; 287 } 288 /** 289 * Removes the specified element. 290 * 291 * @param {*} key The key of the element to remove. 292 * 293 * @return {boolean} Returns true if an element existed and has been 294 * removed, or false if the element does not exist. 295 */ 296 }, { 297 key: "delete", 298 value: function _delete(key) { 299 if (!this.has(key)) { 300 return false; 301 } 302 this.set(key, void 0); 303 return true; 304 } 305 /** 306 * Executes a provided function once per each key/value pair, in insertion 307 * order. 308 * 309 * @param {Function} callback Function to execute for each element. 310 * @param {*} thisArg Value to use as `this` when executing 311 * `callback`. 312 */ 313 }, { 314 key: "forEach", 315 value: function forEach(callback) { 316 var _this = this; 317 var thisArg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : this; 318 this._map.forEach(function(value, key) { 319 if (key !== null && _typeof(key) === "object") { 320 value = value[1]; 321 } 322 callback.call(thisArg, value, key, _this); 323 }); 324 } 325 /** 326 * Removes all elements. 327 */ 328 }, { 329 key: "clear", 330 value: function clear() { 331 this._map = /* @__PURE__ */ new Map(); 332 this._arrayTreeMap = /* @__PURE__ */ new Map(); 333 this._objectTreeMap = /* @__PURE__ */ new Map(); 334 } 335 }, { 336 key: "size", 337 get: function get() { 338 return this._map.size; 339 } 340 }]); 341 return EquivalentKeyMap3; 342 })(); 343 module.exports = EquivalentKeyMap2; 344 } 345 }); 346 347 // package-external:@wordpress/url 348 var require_url = __commonJS({ 349 "package-external:@wordpress/url"(exports, module) { 350 module.exports = window.wp.url; 351 } 352 }); 353 354 // package-external:@wordpress/blocks 355 var require_blocks = __commonJS({ 356 "package-external:@wordpress/blocks"(exports, module) { 357 module.exports = window.wp.blocks; 358 } 359 }); 360 361 // package-external:@wordpress/i18n 362 var require_i18n = __commonJS({ 363 "package-external:@wordpress/i18n"(exports, module) { 364 module.exports = window.wp.i18n; 365 } 366 }); 367 368 // package-external:@wordpress/block-editor 369 var require_block_editor = __commonJS({ 370 "package-external:@wordpress/block-editor"(exports, module) { 371 module.exports = window.wp.blockEditor; 372 } 373 }); 374 375 // package-external:@wordpress/rich-text 376 var require_rich_text = __commonJS({ 377 "package-external:@wordpress/rich-text"(exports, module) { 378 module.exports = window.wp.richText; 379 } 380 }); 381 382 // package-external:@wordpress/deprecated 383 var require_deprecated = __commonJS({ 384 "package-external:@wordpress/deprecated"(exports, module) { 385 module.exports = window.wp.deprecated; 386 } 387 }); 388 389 // package-external:@wordpress/notices 390 var require_notices = __commonJS({ 391 "package-external:@wordpress/notices"(exports, module) { 392 module.exports = window.wp.notices; 393 } 394 }); 395 396 // package-external:@wordpress/html-entities 397 var require_html_entities = __commonJS({ 398 "package-external:@wordpress/html-entities"(exports, module) { 399 module.exports = window.wp.htmlEntities; 400 } 401 }); 402 403 // package-external:@wordpress/element 404 var require_element = __commonJS({ 405 "package-external:@wordpress/element"(exports, module) { 406 module.exports = window.wp.element; 407 } 408 }); 409 410 // vendor-external:react/jsx-runtime 411 var require_jsx_runtime = __commonJS({ 412 "vendor-external:react/jsx-runtime"(exports, module) { 413 module.exports = window.ReactJSXRuntime; 414 } 415 }); 416 417 // package-external:@wordpress/warning 418 var require_warning = __commonJS({ 419 "package-external:@wordpress/warning"(exports, module) { 420 module.exports = window.wp.warning; 421 } 422 }); 423 424 // package-external:@wordpress/primitives 425 var require_primitives = __commonJS({ 426 "package-external:@wordpress/primitives"(exports, module) { 427 module.exports = window.wp.primitives; 428 } 429 }); 430 431 // package-external:@wordpress/components 432 var require_components = __commonJS({ 433 "package-external:@wordpress/components"(exports, module) { 434 module.exports = window.wp.components; 435 } 436 }); 437 438 // packages/core-data/build-module/index.mjs 439 var index_exports = {}; 440 __export(index_exports, { 441 EntityProvider: () => EntityProvider, 442 __experimentalFetchLinkSuggestions: () => fetchLinkSuggestions, 443 __experimentalFetchUrlData: () => experimental_fetch_url_data_default, 444 __experimentalUseEntityRecord: () => useDeprecatedEntityRecord, 445 __experimentalUseEntityRecords: () => useDeprecatedEntityRecords, 446 __experimentalUseResourcePermissions: () => useDeprecatedResourcePermissions, 447 fetchBlockPatterns: () => fetchBlockPatterns, 448 privateApis: () => privateApis, 449 store: () => store, 450 useEntityBlockEditor: () => useEntityBlockEditor, 451 useEntityId: () => useEntityId, 452 useEntityProp: () => useEntityProp, 453 useEntityRecord: () => useEntityRecord, 454 useEntityRecords: () => useEntityRecords, 455 useResourcePermissions: () => use_resource_permissions_default 456 }); 457 var import_data20 = __toESM(require_data(), 1); 458 459 // packages/core-data/build-module/reducer.mjs 460 var import_es65 = __toESM(require_es6(), 1); 461 var import_compose2 = __toESM(require_compose(), 1); 462 var import_data7 = __toESM(require_data(), 1); 463 var import_undo_manager = __toESM(require_undo_manager(), 1); 464 465 // packages/core-data/build-module/utils/clear-unchanged-edits.mjs 466 var import_es6 = __toESM(require_es6(), 1); 467 function clearUnchangedEdits(edits, persistedRecord) { 468 if (!persistedRecord) { 469 return edits; 470 } 471 return Object.fromEntries( 472 Object.entries(edits).map(([key, value]) => { 473 const persisted = persistedRecord[key]?.raw ?? persistedRecord[key]; 474 return [ 475 key, 476 (0, import_es6.default)(value, persisted) ? void 0 : value 477 ]; 478 }) 479 ); 480 } 481 482 // packages/core-data/build-module/utils/conservative-map-item.mjs 483 var import_es62 = __toESM(require_es6(), 1); 484 function conservativeMapItem(item, nextItem) { 485 if (!item) { 486 return nextItem; 487 } 488 let hasChanges = false; 489 const result = {}; 490 for (const key in nextItem) { 491 if ((0, import_es62.default)(item[key], nextItem[key])) { 492 result[key] = item[key]; 493 } else { 494 hasChanges = true; 495 result[key] = nextItem[key]; 496 } 497 } 498 if (!hasChanges) { 499 return item; 500 } 501 for (const key in item) { 502 if (!result.hasOwnProperty(key)) { 503 result[key] = item[key]; 504 } 505 } 506 return result; 507 } 508 509 // packages/core-data/build-module/utils/get-normalized-comma-separable.mjs 510 function getNormalizedCommaSeparable(value) { 511 if (typeof value === "string") { 512 return value.split(","); 513 } else if (Array.isArray(value)) { 514 return value; 515 } 516 return null; 517 } 518 var get_normalized_comma_separable_default = getNormalizedCommaSeparable; 519 520 // packages/core-data/build-module/utils/set-nested-value.mjs 521 function setNestedValue(object, path, value) { 522 if (!object || typeof object !== "object") { 523 return object; 524 } 525 const normalizedPath = Array.isArray(path) ? path : path.split("."); 526 normalizedPath.reduce((acc, key, idx) => { 527 if (acc[key] === void 0) { 528 if (Number.isInteger(normalizedPath[idx + 1])) { 529 acc[key] = []; 530 } else { 531 acc[key] = {}; 532 } 533 } 534 if (idx === normalizedPath.length - 1) { 535 acc[key] = value; 536 } 537 return acc[key]; 538 }, object); 539 return object; 540 } 541 542 // packages/core-data/build-module/utils/get-filtered-item.mjs 543 var filteredItemCache = /* @__PURE__ */ new WeakMap(); 544 function getFilteredItem(item, _fields) { 545 const fields = get_normalized_comma_separable_default(_fields) ?? []; 546 const fieldsKey = fields.join(","); 547 let itemCache = filteredItemCache.get(item); 548 if (itemCache) { 549 const filtered = itemCache.get(fieldsKey); 550 if (filtered !== void 0) { 551 return filtered; 552 } 553 } else if (item !== null && typeof item === "object") { 554 itemCache = /* @__PURE__ */ new Map(); 555 filteredItemCache.set(item, itemCache); 556 } 557 const filteredItem = {}; 558 for (let f = 0; f < fields.length; f++) { 559 const field = fields[f].split("."); 560 let value = item; 561 field.forEach((fieldName) => { 562 value = value?.[fieldName]; 563 }); 564 setNestedValue(filteredItem, field, value); 565 } 566 itemCache?.set(fieldsKey, filteredItem); 567 return filteredItem; 568 } 569 570 // packages/core-data/build-module/utils/if-matching-action.mjs 571 var ifMatchingAction = (isMatch) => (reducer) => (state, action) => { 572 if (state === void 0 || isMatch(action)) { 573 return reducer(state, action); 574 } 575 return state; 576 }; 577 var if_matching_action_default = ifMatchingAction; 578 579 // packages/core-data/build-module/utils/forward-resolver.mjs 580 var forwardResolver = (resolverName) => (...args) => async ({ resolveSelect: resolveSelect2 }) => { 581 await resolveSelect2[resolverName](...args); 582 }; 583 var forward_resolver_default = forwardResolver; 584 585 // packages/core-data/build-module/utils/replace-action.mjs 586 var replaceAction = (replacer) => (reducer) => (state, action) => { 587 return reducer(state, replacer(action)); 588 }; 589 var replace_action_default = replaceAction; 590 591 // packages/core-data/build-module/utils/with-weak-map-cache.mjs 592 function withWeakMapCache(fn) { 593 const cache3 = /* @__PURE__ */ new WeakMap(); 594 return (key) => { 595 let value; 596 if (cache3.has(key)) { 597 value = cache3.get(key); 598 } else { 599 value = fn(key); 600 if (key !== null && typeof key === "object") { 601 cache3.set(key, value); 602 } 603 } 604 return value; 605 }; 606 } 607 var with_weak_map_cache_default = withWeakMapCache; 608 609 // packages/core-data/build-module/utils/get-nested-value.mjs 610 function getNestedValue(object, path, defaultValue) { 611 if (!object || typeof object !== "object" || typeof path !== "string" && !Array.isArray(path)) { 612 return object; 613 } 614 const normalizedPath = Array.isArray(path) ? path : path.split("."); 615 let value = object; 616 normalizedPath.forEach((fieldName) => { 617 value = value?.[fieldName]; 618 }); 619 return value !== void 0 ? value : defaultValue; 620 } 621 622 // packages/core-data/build-module/utils/is-numeric-id.mjs 623 function isNumericID(id) { 624 return /^\s*\d+\s*$/.test(id); 625 } 626 627 // packages/core-data/build-module/utils/user-permissions.mjs 628 var ALLOWED_RESOURCE_ACTIONS = [ 629 "create", 630 "read", 631 "update", 632 "delete" 633 ]; 634 function getUserPermissionsFromAllowHeader(allowedMethods) { 635 const permissions = {}; 636 const methods = { 637 create: "POST", 638 read: "GET", 639 update: "PUT", 640 delete: "DELETE" 641 }; 642 for (const [actionName, methodName] of Object.entries(methods)) { 643 permissions[actionName] = allowedMethods ? allowedMethods.includes(methodName) : false; 644 } 645 return permissions; 646 } 647 function getUserPermissionCacheKey(action, resource, id) { 648 const key = (typeof resource === "object" ? [action, resource.kind, resource.name, resource.id] : [action, resource, id]).filter(Boolean).join("/"); 649 return key; 650 } 651 652 // packages/core-data/build-module/utils/receive-intermediate-results.mjs 653 var RECEIVE_INTERMEDIATE_RESULTS = /* @__PURE__ */ Symbol( 654 "RECEIVE_INTERMEDIATE_RESULTS" 655 ); 656 657 // packages/core-data/build-module/utils/normalize-query-for-resolution.mjs 658 function normalizeQueryForResolution(query) { 659 if (!query) { 660 return void 0; 661 } 662 const entries = Object.entries(query).filter( 663 ([k, v]) => (k === "context" || k === "_fields") && v !== void 0 && v !== null 664 ); 665 return entries.length > 0 ? Object.fromEntries(entries) : void 0; 666 } 667 668 // packages/core-data/build-module/utils/save-crdt-doc.mjs 669 var import_api_fetch = __toESM(require_api_fetch(), 1); 670 671 // packages/core-data/build-module/sync.mjs 672 var import_sync = __toESM(require_sync(), 1); 673 674 // packages/core-data/build-module/lock-unlock.mjs 675 var import_private_apis = __toESM(require_private_apis(), 1); 676 var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)( 677 "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.", 678 "@wordpress/core-data" 679 ); 680 681 // packages/core-data/build-module/sync.mjs 682 var { 683 ConnectionErrorCode, 684 createSyncManager, 685 Delta, 686 CRDT_DOC_META_PERSISTENCE_KEY, 687 CRDT_RECORD_MAP_KEY, 688 LOCAL_EDITOR_ORIGIN, 689 LOCAL_UNDO_IGNORED_ORIGIN, 690 retrySyncConnection 691 } = unlock(import_sync.privateApis); 692 var CRDT_AUTOSAVE_SNAPSHOT_KEY = "crdt_snapshot"; 693 var syncManager; 694 function getSyncManager() { 695 if (syncManager) { 696 return syncManager; 697 } 698 if (!globalThis.window?.__experimentalEnableRealTimeCollaboration) { 699 return void 0; 700 } 701 syncManager = createSyncManager(); 702 return syncManager; 703 } 704 function hasSyncManager() { 705 return Boolean(syncManager); 706 } 707 function getEntitySnapshot(kind, name, recordId) { 708 if (!hasSyncManager()) { 709 return void 0; 710 } 711 return getSyncManager()?.getEntitySnapshot( 712 `$kind}/$name}`, 713 `$recordId}` 714 ); 715 } 716 function entityContainsSnapshot(kind, name, recordId, encodedSnapshot) { 717 if (!hasSyncManager()) { 718 return false; 719 } 720 return getSyncManager()?.entityContainsSnapshot( 721 `$kind}/$name}`, 722 `$recordId}`, 723 encodedSnapshot 724 ) ?? false; 725 } 726 727 // packages/core-data/build-module/utils/save-crdt-doc.mjs 728 var SYNC_SAVE_API_PATH = "/wp-sync/v1/save"; 729 var saveCRDTDocQueues = /* @__PURE__ */ new Map(); 730 async function serializeAndSaveCRDTDoc(objectType, objectId, room) { 731 const serializedDoc = await getSyncManager()?.createPersistedCRDTDoc( 732 objectType, 733 objectId 734 ); 735 if (!serializedDoc) { 736 return; 737 } 738 await (0, import_api_fetch.default)({ 739 path: SYNC_SAVE_API_PATH, 740 method: "POST", 741 data: { 742 room, 743 doc: serializedDoc 744 } 745 }); 746 } 747 async function saveCRDTDoc(objectType, objectId) { 748 const room = `$objectType}:$objectId}`; 749 const previousSave = saveCRDTDocQueues.get(room) || Promise.resolve(); 750 const currentSave = previousSave.catch(() => { 751 }).then(() => serializeAndSaveCRDTDoc(objectType, objectId, room)); 752 saveCRDTDocQueues.set(room, currentSave); 753 try { 754 await currentSave; 755 } finally { 756 if (saveCRDTDocQueues.get(room) === currentSave) { 757 saveCRDTDocQueues.delete(room); 758 } 759 } 760 } 761 762 // packages/core-data/build-module/utils/get-pagination-meta.mjs 763 function getPaginationMeta(headers) { 764 const totalItems = parseInt(headers.get("X-WP-Total") ?? ""); 765 const totalPages = parseInt(headers.get("X-WP-TotalPages") ?? ""); 766 return { 767 totalItems: Number.isFinite(totalItems) ? totalItems : null, 768 totalPages: Number.isFinite(totalPages) ? totalPages : null 769 }; 770 } 771 772 // packages/core-data/build-module/queried-data/actions.mjs 773 function receiveItems(items2, edits, meta) { 774 return { 775 type: "RECEIVE_ITEMS", 776 items: items2, 777 persistedEdits: edits, 778 meta 779 }; 780 } 781 function removeItems(kind, name, records, invalidateCache = false) { 782 return { 783 type: "REMOVE_ITEMS", 784 itemIds: Array.isArray(records) ? records : [records], 785 kind, 786 name, 787 invalidateCache 788 }; 789 } 790 function receiveQueriedItems(items2, query = {}, edits, meta) { 791 return { 792 ...receiveItems(items2, edits, meta), 793 query 794 }; 795 } 796 797 // packages/core-data/build-module/queried-data/selectors.mjs 798 var import_equivalent_key_map = __toESM(require_equivalent_key_map(), 1); 799 800 // packages/core-data/build-module/queried-data/get-query-parts.mjs 801 var import_url = __toESM(require_url(), 1); 802 function getQueryParts(query) { 803 const parts = { 804 stableKey: "", 805 page: 1, 806 perPage: 10, 807 offset: null, 808 fields: null, 809 include: null, 810 context: "default" 811 }; 812 const keys = Object.keys(query).sort(); 813 for (let i = 0; i < keys.length; i++) { 814 const key = keys[i]; 815 let value = query[key]; 816 switch (key) { 817 case "page": 818 parts[key] = Number(value); 819 break; 820 case "per_page": 821 parts.perPage = Number(value); 822 break; 823 case "offset": { 824 const numericOffset = Number(value); 825 if (Number.isFinite(numericOffset)) { 826 parts.offset = numericOffset; 827 } 828 break; 829 } 830 case "context": 831 parts.context = value; 832 break; 833 default: 834 if (key === "_fields") { 835 parts.fields = get_normalized_comma_separable_default(value) ?? []; 836 value = parts.fields.join(); 837 } 838 if (key === "include") { 839 if (typeof value === "number") { 840 value = value.toString(); 841 } 842 parts.include = (get_normalized_comma_separable_default(value) ?? []).map(Number); 843 value = parts.include.join(); 844 } 845 parts.stableKey += (parts.stableKey ? "&" : "") + (0, import_url.addQueryArgs)("", { [key]: value }).slice(1); 846 } 847 } 848 return parts; 849 } 850 var get_query_parts_default = with_weak_map_cache_default(getQueryParts); 851 852 // packages/core-data/build-module/queried-data/selectors.mjs 853 var queriedItemsCacheByState = /* @__PURE__ */ new WeakMap(); 854 function getQueriedItemsUncached(state, query, options = {}) { 855 const { supportsPagination = true } = options; 856 const { 857 stableKey, 858 page, 859 perPage, 860 offset: queryOffset, 861 include, 862 fields, 863 context 864 } = get_query_parts_default(query); 865 const itemIds = state.queries?.[context]?.[stableKey]?.itemIds; 866 if (!itemIds) { 867 return null; 868 } 869 const isPaginated = supportsPagination && perPage !== -1; 870 const startOffset = isPaginated ? queryOffset ?? (page - 1) * perPage : 0; 871 const endOffset = isPaginated ? Math.min(startOffset + perPage, itemIds.length) : itemIds.length; 872 if (isPaginated && itemIds.length < startOffset + perPage) { 873 const totalItems = state.queries[context][stableKey].meta?.totalItems; 874 if (Number.isFinite(totalItems) && itemIds.length < totalItems) { 875 return null; 876 } 877 } 878 const items2 = []; 879 for (let i = startOffset; i < endOffset; i++) { 880 const itemId = itemIds[i]; 881 if (Array.isArray(include) && !include.includes(itemId)) { 882 continue; 883 } 884 if (itemId === void 0) { 885 continue; 886 } 887 if (!state.items[context]?.hasOwnProperty(itemId)) { 888 return null; 889 } 890 const item = state.items[context][itemId]; 891 let filteredItem; 892 if (Array.isArray(fields)) { 893 filteredItem = {}; 894 for (let f = 0; f < fields.length; f++) { 895 const field = fields[f].split("."); 896 let value = item; 897 field.forEach((fieldName) => { 898 value = value?.[fieldName]; 899 }); 900 setNestedValue(filteredItem, field, value); 901 } 902 } else { 903 if (!state.itemIsComplete[context]?.[itemId]) { 904 return null; 905 } 906 filteredItem = item; 907 } 908 items2.push(filteredItem); 909 } 910 return items2; 911 } 912 function getQueriedItems(state, query = {}, options = {}) { 913 let queriedItemsCache = queriedItemsCacheByState.get(state); 914 if (queriedItemsCache) { 915 const queriedItems = queriedItemsCache.get(query); 916 if (queriedItems !== void 0) { 917 return queriedItems; 918 } 919 } else { 920 queriedItemsCache = new import_equivalent_key_map.default(); 921 queriedItemsCacheByState.set(state, queriedItemsCache); 922 } 923 const items2 = getQueriedItemsUncached(state, query, options); 924 queriedItemsCache.set(query, items2); 925 return items2; 926 } 927 function getQueriedTotalItems(state, query = {}) { 928 const { stableKey, context } = get_query_parts_default(query); 929 return state.queries?.[context]?.[stableKey]?.meta?.totalItems ?? null; 930 } 931 function getQueriedTotalPages(state, query = {}) { 932 const { stableKey, context } = get_query_parts_default(query); 933 return state.queries?.[context]?.[stableKey]?.meta?.totalPages ?? null; 934 } 935 936 // packages/core-data/build-module/queried-data/reducer.mjs 937 var import_data6 = __toESM(require_data(), 1); 938 var import_compose = __toESM(require_compose(), 1); 939 940 // node_modules/tslib/tslib.es6.mjs 941 var __assign = function() { 942 __assign = Object.assign || function __assign2(t) { 943 for (var s, i = 1, n = arguments.length; i < n; i++) { 944 s = arguments[i]; 945 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 946 } 947 return t; 948 }; 949 return __assign.apply(this, arguments); 950 }; 951 952 // node_modules/lower-case/dist.es2015/index.js 953 function lowerCase(str) { 954 return str.toLowerCase(); 955 } 956 957 // node_modules/no-case/dist.es2015/index.js 958 var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g]; 959 var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi; 960 function noCase(input, options) { 961 if (options === void 0) { 962 options = {}; 963 } 964 var _a = options.splitRegexp, splitRegexp = _a === void 0 ? DEFAULT_SPLIT_REGEXP : _a, _b = options.stripRegexp, stripRegexp = _b === void 0 ? DEFAULT_STRIP_REGEXP : _b, _c = options.transform, transform = _c === void 0 ? lowerCase : _c, _d = options.delimiter, delimiter = _d === void 0 ? " " : _d; 965 var result = replace(replace(input, splitRegexp, "$1\0$2"), stripRegexp, "\0"); 966 var start = 0; 967 var end = result.length; 968 while (result.charAt(start) === "\0") 969 start++; 970 while (result.charAt(end - 1) === "\0") 971 end--; 972 return result.slice(start, end).split("\0").map(transform).join(delimiter); 973 } 974 function replace(input, re, value) { 975 if (re instanceof RegExp) 976 return input.replace(re, value); 977 return re.reduce(function(input2, re2) { 978 return input2.replace(re2, value); 979 }, input); 980 } 981 982 // node_modules/pascal-case/dist.es2015/index.js 983 function pascalCaseTransform(input, index) { 984 var firstChar = input.charAt(0); 985 var lowerChars = input.substr(1).toLowerCase(); 986 if (index > 0 && firstChar >= "0" && firstChar <= "9") { 987 return "_" + firstChar + lowerChars; 988 } 989 return "" + firstChar.toUpperCase() + lowerChars; 990 } 991 function pascalCase(input, options) { 992 if (options === void 0) { 993 options = {}; 994 } 995 return noCase(input, __assign({ delimiter: "", transform: pascalCaseTransform }, options)); 996 } 997 998 // node_modules/camel-case/dist.es2015/index.js 999 function camelCaseTransform(input, index) { 1000 if (index === 0) 1001 return input.toLowerCase(); 1002 return pascalCaseTransform(input, index); 1003 } 1004 function camelCase(input, options) { 1005 if (options === void 0) { 1006 options = {}; 1007 } 1008 return pascalCase(input, __assign({ transform: camelCaseTransform }, options)); 1009 } 1010 1011 // node_modules/upper-case-first/dist.es2015/index.js 1012 function upperCaseFirst(input) { 1013 return input.charAt(0).toUpperCase() + input.substr(1); 1014 } 1015 1016 // node_modules/capital-case/dist.es2015/index.js 1017 function capitalCaseTransform(input) { 1018 return upperCaseFirst(input.toLowerCase()); 1019 } 1020 function capitalCase(input, options) { 1021 if (options === void 0) { 1022 options = {}; 1023 } 1024 return noCase(input, __assign({ delimiter: " ", transform: capitalCaseTransform }, options)); 1025 } 1026 1027 // packages/core-data/build-module/entities.mjs 1028 var import_api_fetch2 = __toESM(require_api_fetch(), 1); 1029 var import_blocks4 = __toESM(require_blocks(), 1); 1030 var import_i18n = __toESM(require_i18n(), 1); 1031 1032 // packages/core-data/build-module/awareness/post-editor-awareness.mjs 1033 var import_data4 = __toESM(require_data(), 1); 1034 var import_sync9 = __toESM(require_sync(), 1); 1035 var import_block_editor3 = __toESM(require_block_editor(), 1); 1036 1037 // packages/core-data/build-module/awareness/base-awareness.mjs 1038 var import_data = __toESM(require_data(), 1); 1039 1040 // packages/core-data/build-module/awareness/config.mjs 1041 var AWARENESS_CURSOR_UPDATE_THROTTLE_IN_MS = 100; 1042 var LOCAL_CURSOR_UPDATE_DEBOUNCE_IN_MS = 5; 1043 var REMOVAL_DELAY_IN_MS = 5e3; 1044 1045 // packages/core-data/build-module/awareness/typed-awareness.mjs 1046 var import_sync3 = __toESM(require_sync(), 1); 1047 1048 // packages/core-data/build-module/awareness/utils.mjs 1049 function getBrowserName() { 1050 const userAgent = window.navigator.userAgent; 1051 let browserName = "Unknown"; 1052 if (userAgent.includes("Firefox")) { 1053 browserName = "Firefox"; 1054 } else if (userAgent.includes("Edg")) { 1055 browserName = "Microsoft Edge"; 1056 } else if (userAgent.includes("Chrome") && !userAgent.includes("Edg")) { 1057 browserName = "Chrome"; 1058 } else if (userAgent.includes("Safari") && !userAgent.includes("Chrome")) { 1059 browserName = "Safari"; 1060 } else if (userAgent.includes("MSIE") || userAgent.includes("Trident")) { 1061 browserName = "Internet Explorer"; 1062 } else if (userAgent.includes("Opera") || userAgent.includes("OPR")) { 1063 browserName = "Opera"; 1064 } 1065 return browserName; 1066 } 1067 function areMapsEqual(map1, map2, comparatorFn) { 1068 if (map1.size !== map2.size) { 1069 return false; 1070 } 1071 for (const [key, value1] of map1.entries()) { 1072 if (!map2.has(key)) { 1073 return false; 1074 } 1075 if (!comparatorFn(value1, map2.get(key))) { 1076 return false; 1077 } 1078 } 1079 return true; 1080 } 1081 function areCollaboratorInfosEqual(collaboratorInfo1, collaboratorInfo2) { 1082 if (!collaboratorInfo1 || !collaboratorInfo2) { 1083 return collaboratorInfo1 === collaboratorInfo2; 1084 } 1085 if (Object.keys(collaboratorInfo1).length !== Object.keys(collaboratorInfo2).length) { 1086 return false; 1087 } 1088 return Object.entries(collaboratorInfo1).every(([key, value]) => { 1089 return value === collaboratorInfo2[key]; 1090 }); 1091 } 1092 function hasValidAvatarUrls(value) { 1093 if ("object" !== typeof value || null === value || Array.isArray(value)) { 1094 return false; 1095 } 1096 return ["24", "48", "96"].every( 1097 (size) => !(size in value) || "string" === typeof value[size] 1098 ); 1099 } 1100 function isCollaboratorInfo(value) { 1101 if ("object" !== typeof value || null === value) { 1102 return false; 1103 } 1104 return "id" in value && "name" in value && "slug" in value && "browserType" in value && "enteredAt" in value && (null === value.id || "number" === typeof value.id && Number.isInteger(value.id) && value.id > 0) && "string" === typeof value.name && "" !== value.name.trim() && "string" === typeof value.slug && (!("avatar_urls" in value) || hasValidAvatarUrls(value.avatar_urls)) && "string" === typeof value.browserType && "number" === typeof value.enteredAt && Number.isFinite(value.enteredAt); 1105 } 1106 function generateCollaboratorInfo(currentCollaborator, clientId) { 1107 const presentationInfo = { 1108 browserType: getBrowserName(), 1109 enteredAt: Date.now() 1110 }; 1111 if ("object" === typeof currentCollaborator && currentCollaborator) { 1112 const user = currentCollaborator; 1113 if ("id" in user && "name" in user) { 1114 const collaboratorInfo = { 1115 ...presentationInfo, 1116 ..."avatar_urls" in user && hasValidAvatarUrls(user.avatar_urls) ? { avatar_urls: user.avatar_urls } : {}, 1117 id: user.id, 1118 name: user.name, 1119 slug: "slug" in user && "string" === typeof user.slug ? user.slug : "" 1120 }; 1121 if (isCollaboratorInfo(collaboratorInfo) && null !== collaboratorInfo.id) { 1122 return collaboratorInfo; 1123 } 1124 } 1125 } 1126 return { 1127 ...presentationInfo, 1128 id: null, 1129 // Keep shared awareness data language-neutral. The editor localizes this 1130 // fallback name for the viewer when it is displayed. 1131 name: "Anonymous User", 1132 slug: `anonymous-$clientId}` 1133 }; 1134 } 1135 function getRecordValue(obj, key) { 1136 if ("object" === typeof obj && null !== obj && key in obj) { 1137 return obj[key]; 1138 } 1139 return null; 1140 } 1141 function getTypedKeys(obj) { 1142 return Object.keys(obj); 1143 } 1144 1145 // packages/core-data/build-module/awareness/typed-awareness.mjs 1146 var TypedAwareness = class extends import_sync3.Awareness { 1147 /** 1148 * Get the states from an awareness document. 1149 */ 1150 getStates() { 1151 return super.getStates(); 1152 } 1153 /** 1154 * Get a local state field from an awareness document. 1155 * @param field 1156 */ 1157 getLocalStateField(field) { 1158 const state = this.getLocalState(); 1159 return getRecordValue(state, field); 1160 } 1161 /** 1162 * Set a local state field on an awareness document. 1163 * @param field 1164 * @param value 1165 */ 1166 setLocalStateField(field, value) { 1167 super.setLocalStateField(field, value); 1168 } 1169 }; 1170 1171 // packages/core-data/build-module/awareness/awareness-state.mjs 1172 var AwarenessWithEqualityChecks = class extends TypedAwareness { 1173 /** OVERRIDDEN METHODS */ 1174 /** 1175 * Set a local state field on an awareness document. Calling this method may 1176 * trigger rerenders of any subscribed components. 1177 * 1178 * Equality checks are provided by the abstract `equalityFieldChecks` property. 1179 * @param field - The field to set. 1180 * @param value - The value to set. 1181 */ 1182 setLocalStateField(field, value) { 1183 if (this.isFieldEqual( 1184 field, 1185 value, 1186 this.getLocalStateField(field) ?? void 0 1187 )) { 1188 return; 1189 } 1190 super.setLocalStateField(field, value); 1191 } 1192 /** CUSTOM METHODS */ 1193 /** 1194 * Determine if a field value has changed using the provided equality checks. 1195 * @param field - The field to check. 1196 * @param value1 - The first value to compare. 1197 * @param value2 - The second value to compare. 1198 */ 1199 isFieldEqual(field, value1, value2) { 1200 if (["clientId", "isConnected", "isMe"].includes(field)) { 1201 return value1 === value2; 1202 } 1203 if (field in this.equalityFieldChecks) { 1204 const fn = this.equalityFieldChecks[field]; 1205 return fn(value1, value2); 1206 } 1207 throw new Error( 1208 `No equality check implemented for awareness state field "$field.toString()}".` 1209 ); 1210 } 1211 /** 1212 * Determine if two states are equal by comparing each field using the 1213 * provided equality checks. 1214 * @param state1 - The first state to compare. 1215 * @param state2 - The second state to compare. 1216 */ 1217 isStateEqual(state1, state2) { 1218 return [ 1219 .../* @__PURE__ */ new Set([ 1220 ...getTypedKeys(state1), 1221 ...getTypedKeys(state2) 1222 ]) 1223 ].every((field) => { 1224 const value1 = state1[field]; 1225 const value2 = state2[field]; 1226 return this.isFieldEqual(field, value1, value2); 1227 }); 1228 } 1229 }; 1230 var AwarenessState = class extends AwarenessWithEqualityChecks { 1231 /** CUSTOM PROPERTIES */ 1232 /** 1233 * Whether the setUp method has been called, to avoid running it multiple 1234 * times. 1235 */ 1236 hasSetupRun = false; 1237 /** 1238 * We keep track of all seen states during the current session for two reasons: 1239 * 1240 * 1. So that we can represent recently disconnected collaborators in our UI, even 1241 * after they have been removed from the awareness document. 1242 * 2. So that we can provide debug information about all collaborators seen during 1243 * the session. 1244 */ 1245 disconnectedCollaborators = /* @__PURE__ */ new Set(); 1246 seenStates = /* @__PURE__ */ new Map(); 1247 /** 1248 * Hold a snapshot of the previous awareness state allows us to compare the 1249 * state values and avoid unnecessary updates to subscribers. 1250 */ 1251 previousSnapshot = /* @__PURE__ */ new Map(); 1252 stateSubscriptions = []; 1253 /** 1254 * In some cases, we may want to throttle setting local state fields to avoid 1255 * overwhelming the awareness document with rapid updates. At the same time, we 1256 * want to ensure that when we read our own state locally, we get the latest 1257 * value -- even if it hasn't yet been set on the awareness instance. 1258 */ 1259 myThrottledState = {}; 1260 throttleTimeouts = /* @__PURE__ */ new Map(); 1261 /** CUSTOM METHODS */ 1262 /** 1263 * Set up the awareness state. This method is idempotent and will only run 1264 * once. Subclasses should override `onSetUp()` instead of this method to 1265 * add their own setup logic. 1266 * 1267 * This is defined as a readonly arrow function property to prevent 1268 * subclasses from overriding it. 1269 */ 1270 setUp = () => { 1271 if (this.hasSetupRun) { 1272 return; 1273 } 1274 this.hasSetupRun = true; 1275 this.onSetUp(); 1276 this.on( 1277 "change", 1278 ({ added, removed, updated }) => { 1279 [...added, ...updated].forEach((id) => { 1280 this.disconnectedCollaborators.delete(id); 1281 }); 1282 removed.forEach((id) => { 1283 this.disconnectedCollaborators.add(id); 1284 setTimeout(() => { 1285 this.disconnectedCollaborators.delete(id); 1286 this.updateSubscribers( 1287 true 1288 /* force update */ 1289 ); 1290 }, REMOVAL_DELAY_IN_MS); 1291 }); 1292 this.updateSubscribers(); 1293 } 1294 ); 1295 }; 1296 /** 1297 * Get the most recent state from the last processed change event. 1298 * 1299 * @return An array of EnhancedState< State >. 1300 */ 1301 getCurrentState() { 1302 return Array.from(this.previousSnapshot.values()); 1303 } 1304 /** 1305 * Get all seen states in this session to enable debug reporting. 1306 */ 1307 getSeenStates() { 1308 return this.seenStates; 1309 } 1310 /** 1311 * Allow external code to subscribe to awareness state changes. 1312 * @param callback - The callback to subscribe to. 1313 */ 1314 onStateChange(callback) { 1315 this.stateSubscriptions.push(callback); 1316 return () => { 1317 this.stateSubscriptions = this.stateSubscriptions.filter( 1318 (cb) => cb !== callback 1319 ); 1320 }; 1321 } 1322 /** 1323 * Set a local state field on an awareness document with throttle. See caveats 1324 * of this.setLocalStateField. 1325 * @param field - The field to set. 1326 * @param value - The value to set. 1327 * @param wait - The wait time in milliseconds. 1328 */ 1329 setThrottledLocalStateField(field, value, wait) { 1330 this.setLocalStateField(field, value); 1331 this.throttleTimeouts.set( 1332 field, 1333 setTimeout(() => { 1334 this.throttleTimeouts.delete(field); 1335 if (this.myThrottledState[field]) { 1336 this.setLocalStateField( 1337 field, 1338 this.myThrottledState[field] 1339 ); 1340 delete this.myThrottledState[field]; 1341 } 1342 }, wait) 1343 ); 1344 } 1345 /** 1346 * Set the current collaborator's connection status as awareness state. 1347 * @param isConnected - The connection status. 1348 */ 1349 setConnectionStatus(isConnected) { 1350 if (isConnected) { 1351 this.disconnectedCollaborators.delete(this.clientID); 1352 } else { 1353 this.disconnectedCollaborators.add(this.clientID); 1354 } 1355 this.updateSubscribers( 1356 true 1357 /* force update */ 1358 ); 1359 } 1360 /** 1361 * Update all subscribed listeners with the latest awareness state. 1362 * @param forceUpdate - Whether to force an update. 1363 */ 1364 updateSubscribers(forceUpdate = false) { 1365 if (!this.stateSubscriptions.length) { 1366 return; 1367 } 1368 const states = this.getStates(); 1369 this.seenStates = new Map([ 1370 ...this.seenStates.entries(), 1371 ...states.entries() 1372 ]); 1373 const updatedStates = new Map( 1374 [...this.disconnectedCollaborators, ...states.keys()].filter((clientId) => { 1375 return Object.keys(this.seenStates.get(clientId) ?? {}).length > 0; 1376 }).map((clientId) => { 1377 const rawState = this.seenStates.get(clientId); 1378 const isConnected = !this.disconnectedCollaborators.has(clientId); 1379 const isMe = clientId === this.clientID; 1380 const myState = isMe ? this.myThrottledState : {}; 1381 const state = { 1382 ...rawState, 1383 ...myState, 1384 clientId, 1385 isConnected, 1386 isMe 1387 }; 1388 return [clientId, state]; 1389 }) 1390 ); 1391 if (!forceUpdate) { 1392 if (areMapsEqual( 1393 this.previousSnapshot, 1394 updatedStates, 1395 this.isStateEqual.bind(this) 1396 )) { 1397 return; 1398 } 1399 } 1400 this.previousSnapshot = updatedStates; 1401 this.stateSubscriptions.forEach((callback) => { 1402 callback(Array.from(updatedStates.values())); 1403 }); 1404 } 1405 }; 1406 1407 // packages/core-data/build-module/name.mjs 1408 var STORE_NAME = "core"; 1409 1410 // packages/core-data/build-module/awareness/base-awareness.mjs 1411 var BaseAwarenessState = class extends AwarenessState { 1412 onSetUp() { 1413 void this.setCurrentCollaboratorInfo(); 1414 } 1415 /** 1416 * Set the current collaborator info in the local state. 1417 */ 1418 async setCurrentCollaboratorInfo() { 1419 let currentUser2; 1420 try { 1421 currentUser2 = await (0, import_data.resolveSelect)(STORE_NAME).getCurrentUser(); 1422 } catch { 1423 } 1424 this.setLocalStateField( 1425 "collaboratorInfo", 1426 generateCollaboratorInfo(currentUser2, this.clientID) 1427 ); 1428 } 1429 }; 1430 var baseEqualityFieldChecks = { 1431 collaboratorInfo: areCollaboratorInfosEqual 1432 }; 1433 var BaseAwareness = class extends BaseAwarenessState { 1434 equalityFieldChecks = baseEqualityFieldChecks; 1435 }; 1436 1437 // packages/core-data/build-module/awareness/block-lookup.mjs 1438 var import_data2 = __toESM(require_data(), 1); 1439 var import_sync4 = __toESM(require_sync(), 1); 1440 var import_block_editor = __toESM(require_block_editor(), 1); 1441 function getContainingBlockYMap(yType) { 1442 let current = yType; 1443 while (current) { 1444 const parent = current.parent; 1445 if (parent instanceof import_sync4.Y.Map && parent.parent instanceof import_sync4.Y.Array && parent.get("clientId") !== void 0 && parent.get("innerBlocks") instanceof import_sync4.Y.Array) { 1446 return parent; 1447 } 1448 current = parent instanceof import_sync4.Y.AbstractType ? parent : null; 1449 } 1450 return null; 1451 } 1452 function getBlockPathInYdoc(yType) { 1453 const path = []; 1454 let current = yType; 1455 while (current) { 1456 const parentArray = current.parent; 1457 if (!parentArray || !(parentArray instanceof import_sync4.Y.Array)) { 1458 return null; 1459 } 1460 let index = -1; 1461 for (let i = 0; i < parentArray.length; i++) { 1462 if (parentArray.get(i) === current) { 1463 index = i; 1464 break; 1465 } 1466 } 1467 if (index === -1) { 1468 return null; 1469 } 1470 path.unshift(index); 1471 const grandparent = parentArray.parent; 1472 if (grandparent instanceof import_sync4.Y.Map && grandparent.get("clientId") !== void 0) { 1473 current = grandparent; 1474 } else { 1475 break; 1476 } 1477 } 1478 return path; 1479 } 1480 function resolveBlockClientIdByPath(path, blocks) { 1481 if (path.length === 0) { 1482 return null; 1483 } 1484 for (let i = 0; i < path.length; i++) { 1485 const block = blocks[path[i]]; 1486 if (!block) { 1487 return null; 1488 } 1489 if (i === path.length - 1) { 1490 return block.clientId; 1491 } 1492 blocks = block.innerBlocks; 1493 } 1494 return null; 1495 } 1496 function usePostContentBlocks() { 1497 return (0, import_data2.useSelect)((select5) => { 1498 const { getBlocksByName, getClientIdsTree } = unlock( 1499 select5(import_block_editor.store) 1500 ); 1501 const [postContentClientId] = getBlocksByName("core/post-content"); 1502 return getClientIdsTree(postContentClientId ?? ""); 1503 }, []); 1504 } 1505 1506 // packages/core-data/build-module/utils/crdt-utils.mjs 1507 var import_sync5 = __toESM(require_sync(), 1); 1508 var import_rich_text = __toESM(require_rich_text(), 1); 1509 function getRootMap(doc, key) { 1510 return doc.getMap(key); 1511 } 1512 function createYMap(partial = {}) { 1513 return new import_sync5.Y.Map(Object.entries(partial)); 1514 } 1515 function isYMap(value) { 1516 return value instanceof import_sync5.Y.Map; 1517 } 1518 function asRichTextOffset(offset) { 1519 return offset; 1520 } 1521 function asHtmlStringIndex(index) { 1522 return index; 1523 } 1524 function getYTextByAttributeKey(attributes, attributeKey) { 1525 const directValue = attributes.get(attributeKey); 1526 if (directValue instanceof import_sync5.Y.Text) { 1527 return directValue; 1528 } 1529 let value = attributes; 1530 for (const pathPart of attributeKey.split(".")) { 1531 if (value instanceof import_sync5.Y.Map) { 1532 value = value.get(pathPart); 1533 } else if (value instanceof import_sync5.Y.Array) { 1534 const index = Number.parseInt(pathPart, 10); 1535 if (!Number.isSafeInteger(index) || index < 0 || index.toString() !== pathPart) { 1536 return null; 1537 } 1538 value = value.get(index); 1539 } else { 1540 return null; 1541 } 1542 } 1543 return value instanceof import_sync5.Y.Text ? value : null; 1544 } 1545 function findBlockByClientIdInDoc(blockId, ydoc) { 1546 const ymap = getRootMap(ydoc, CRDT_RECORD_MAP_KEY); 1547 const blocks = ymap.get("blocks"); 1548 if (!(blocks instanceof import_sync5.Y.Array)) { 1549 return null; 1550 } 1551 return findBlockByClientIdInBlocks(blockId, blocks); 1552 } 1553 var MARKER_START = 57344; 1554 function pickMarker(text) { 1555 const tryCount = 16; 1556 for (let code = MARKER_START; code < MARKER_START + tryCount; code++) { 1557 const candidate = String.fromCharCode(code); 1558 if (!text.includes(candidate)) { 1559 return candidate; 1560 } 1561 } 1562 return null; 1563 } 1564 function htmlIndexToRichTextOffset(html, htmlIndex) { 1565 if (!html.includes("<") && !html.includes("&")) { 1566 return asRichTextOffset(htmlIndex); 1567 } 1568 const marker = pickMarker(html); 1569 if (!marker) { 1570 return asRichTextOffset(htmlIndex); 1571 } 1572 const withMarker = html.slice(0, htmlIndex) + marker + html.slice(htmlIndex); 1573 const value = (0, import_rich_text.create)({ html: withMarker }); 1574 const markerPos = value.text.indexOf(marker); 1575 return asRichTextOffset(markerPos === -1 ? htmlIndex : markerPos); 1576 } 1577 function richTextOffsetToHtmlIndex(html, richTextOffset) { 1578 if (!html.includes("<") && !html.includes("&")) { 1579 return asHtmlStringIndex(richTextOffset); 1580 } 1581 const marker = pickMarker(html); 1582 if (!marker) { 1583 return asHtmlStringIndex(richTextOffset); 1584 } 1585 const value = (0, import_rich_text.create)({ html }); 1586 const markerValue = (0, import_rich_text.create)({ text: marker }); 1587 if (value.formats[richTextOffset]) { 1588 markerValue.formats[0] = value.formats[richTextOffset]; 1589 } 1590 const withMarker = (0, import_rich_text.insert)( 1591 value, 1592 markerValue, 1593 richTextOffset, 1594 richTextOffset 1595 ); 1596 const htmlWithMarker = (0, import_rich_text.toHTMLString)({ value: withMarker }); 1597 const markerIndex = htmlWithMarker.indexOf(marker); 1598 return asHtmlStringIndex( 1599 markerIndex === -1 ? richTextOffset : markerIndex 1600 ); 1601 } 1602 function findBlockByClientIdInBlocks(blockId, blocks) { 1603 for (const block of blocks) { 1604 if (block.get("clientId") === blockId) { 1605 return block; 1606 } 1607 const innerBlocks = block.get("innerBlocks"); 1608 if (innerBlocks && innerBlocks.length > 0) { 1609 const innerBlock = findBlockByClientIdInBlocks( 1610 blockId, 1611 innerBlocks 1612 ); 1613 if (innerBlock) { 1614 return innerBlock; 1615 } 1616 } 1617 } 1618 return null; 1619 } 1620 1621 // packages/core-data/build-module/utils/crdt-user-selections.mjs 1622 var import_data3 = __toESM(require_data(), 1); 1623 var import_sync7 = __toESM(require_sync(), 1); 1624 var import_block_editor2 = __toESM(require_block_editor(), 1); 1625 var SelectionType = /* @__PURE__ */ ((SelectionType2) => { 1626 SelectionType2["None"] = "none"; 1627 SelectionType2["Cursor"] = "cursor"; 1628 SelectionType2["SelectionInOneBlock"] = "selection-in-one-block"; 1629 SelectionType2["SelectionInMultipleBlocks"] = "selection-in-multiple-blocks"; 1630 SelectionType2["WholeBlock"] = "whole-block"; 1631 return SelectionType2; 1632 })(SelectionType || {}); 1633 var SelectionDirection = /* @__PURE__ */ ((SelectionDirection2) => { 1634 SelectionDirection2["Forward"] = "f"; 1635 SelectionDirection2["Backward"] = "b"; 1636 return SelectionDirection2; 1637 })(SelectionDirection || {}); 1638 function getSelectionState(selectionStart, selectionEnd, yDoc, options) { 1639 const { selectionDirection } = options ?? {}; 1640 const ymap = getRootMap(yDoc, CRDT_RECORD_MAP_KEY); 1641 const yBlocks = ymap.get("blocks"); 1642 const isSelectionEmpty = Object.keys(selectionStart).length === 0; 1643 const noSelection = { 1644 type: "none" 1645 /* None */ 1646 }; 1647 if (isSelectionEmpty || !yBlocks) { 1648 return noSelection; 1649 } 1650 const isSelectionInOneBlock = selectionStart.clientId === selectionEnd.clientId; 1651 const isCursorOnly = isSelectionInOneBlock && selectionStart.offset === selectionEnd.offset; 1652 const isSelectionAWholeBlock = isSelectionInOneBlock && selectionStart.offset === void 0 && selectionEnd.offset === void 0; 1653 if (isSelectionAWholeBlock) { 1654 const path = getBlockPathForLocalClientId(selectionStart.clientId); 1655 const blockPosition = path ? createRelativePositionForBlockPath(path, yBlocks) : null; 1656 if (!blockPosition) { 1657 return noSelection; 1658 } 1659 return { 1660 type: "whole-block", 1661 blockPosition 1662 }; 1663 } else if (isCursorOnly) { 1664 const cursorPosition = getCursorPosition(selectionStart, yBlocks); 1665 if (!cursorPosition) { 1666 return noSelection; 1667 } 1668 return { 1669 type: "cursor", 1670 cursorPosition 1671 }; 1672 } else if (isSelectionInOneBlock) { 1673 const cursorStartPosition = getCursorPosition( 1674 selectionStart, 1675 yBlocks 1676 ); 1677 const cursorEndPosition = getCursorPosition(selectionEnd, yBlocks); 1678 if (!cursorStartPosition || !cursorEndPosition) { 1679 return noSelection; 1680 } 1681 return { 1682 type: "selection-in-one-block", 1683 cursorStartPosition, 1684 cursorEndPosition, 1685 selectionDirection 1686 }; 1687 } 1688 const startEndpoint = getSelectionEndpoint(selectionStart, yBlocks); 1689 const endEndpoint = getSelectionEndpoint(selectionEnd, yBlocks); 1690 if (!startEndpoint || !endEndpoint) { 1691 return noSelection; 1692 } 1693 return { 1694 type: "selection-in-multiple-blocks", 1695 startEndpoint, 1696 endEndpoint, 1697 selectionDirection 1698 }; 1699 } 1700 function getCursorPosition(selection, blocks) { 1701 const path = getBlockPathForLocalClientId(selection.clientId); 1702 const block = path ? findBlockByPath(path, blocks) : null; 1703 if (!block || !selection.attributeKey || void 0 === selection.offset) { 1704 return null; 1705 } 1706 const attributes = block.get("attributes"); 1707 const currentYText = attributes ? getYTextByAttributeKey(attributes, selection.attributeKey) : null; 1708 if (!(currentYText instanceof import_sync7.Y.Text)) { 1709 return null; 1710 } 1711 const relativePosition = import_sync7.Y.createRelativePositionFromTypeIndex( 1712 currentYText, 1713 richTextOffsetToHtmlIndex( 1714 currentYText.toString(), 1715 asRichTextOffset(selection.offset) 1716 ) 1717 ); 1718 return { 1719 relativePosition, 1720 absoluteOffset: selection.offset, 1721 attributeKey: selection.attributeKey 1722 }; 1723 } 1724 function getSelectionEndpoint(selection, blocks) { 1725 const cursorPosition = getCursorPosition(selection, blocks); 1726 if (cursorPosition) { 1727 return { type: "cursor", cursorPosition }; 1728 } 1729 const path = getBlockPathForLocalClientId(selection.clientId); 1730 const blockPosition = path ? createRelativePositionForBlockPath(path, blocks) : null; 1731 if (blockPosition) { 1732 return { type: "whole-block", blockPosition }; 1733 } 1734 return null; 1735 } 1736 function getBlockPathForLocalClientId(clientId) { 1737 const { getBlockIndex, getBlockRootClientId, getBlockName } = (0, import_data3.select)(import_block_editor2.store); 1738 const path = []; 1739 let current = clientId; 1740 while (current) { 1741 const index = getBlockIndex(current); 1742 if (index === -1) { 1743 return null; 1744 } 1745 path.unshift(index); 1746 const parent = getBlockRootClientId(current); 1747 if (!parent) { 1748 break; 1749 } 1750 const parentName = getBlockName(parent); 1751 if (parentName === "core/post-content") { 1752 break; 1753 } 1754 current = parent; 1755 } 1756 return path.length > 0 ? path : null; 1757 } 1758 function findBlockByPath(path, blocks) { 1759 let currentBlocks = blocks; 1760 for (let i = 0; i < path.length; i++) { 1761 if (path[i] >= currentBlocks.length) { 1762 return null; 1763 } 1764 const block = currentBlocks.get(path[i]); 1765 if (!block) { 1766 return null; 1767 } 1768 if (i === path.length - 1) { 1769 return block; 1770 } 1771 currentBlocks = block.get("innerBlocks") ?? new import_sync7.Y.Array(); 1772 } 1773 return null; 1774 } 1775 function createRelativePositionForBlockPath(path, blocks) { 1776 let currentBlocks = blocks; 1777 for (let i = 0; i < path.length; i++) { 1778 if (path[i] >= currentBlocks.length) { 1779 return null; 1780 } 1781 if (i === path.length - 1) { 1782 return import_sync7.Y.createRelativePositionFromTypeIndex( 1783 currentBlocks, 1784 path[i] 1785 ); 1786 } 1787 const block = currentBlocks.get(path[i]); 1788 currentBlocks = block?.get("innerBlocks") ?? new import_sync7.Y.Array(); 1789 } 1790 return null; 1791 } 1792 function areSelectionsStatesEqual(selection1, selection2) { 1793 if (selection1.type !== selection2.type) { 1794 return false; 1795 } 1796 switch (selection1.type) { 1797 case "none": 1798 return true; 1799 case "cursor": 1800 return areCursorPositionsEqual( 1801 selection1.cursorPosition, 1802 selection2.cursorPosition 1803 ); 1804 case "selection-in-one-block": 1805 return areCursorPositionsEqual( 1806 selection1.cursorStartPosition, 1807 selection2.cursorStartPosition 1808 ) && areCursorPositionsEqual( 1809 selection1.cursorEndPosition, 1810 selection2.cursorEndPosition 1811 ) && selection1.selectionDirection === selection2.selectionDirection; 1812 case "selection-in-multiple-blocks": 1813 return areEndpointsEqual( 1814 selection1.startEndpoint, 1815 selection2.startEndpoint 1816 ) && areEndpointsEqual( 1817 selection1.endEndpoint, 1818 selection2.endEndpoint 1819 ) && selection1.selectionDirection === selection2.selectionDirection; 1820 case "whole-block": 1821 return import_sync7.Y.compareRelativePositions( 1822 selection1.blockPosition, 1823 selection2.blockPosition 1824 ); 1825 default: 1826 return false; 1827 } 1828 } 1829 function areEndpointsEqual(ep1, ep2) { 1830 if (ep1.type !== ep2.type) { 1831 return false; 1832 } 1833 if (ep1.type === "cursor" && ep2.type === "cursor") { 1834 return areCursorPositionsEqual( 1835 ep1.cursorPosition, 1836 ep2.cursorPosition 1837 ); 1838 } 1839 return import_sync7.Y.compareRelativePositions( 1840 ep1.blockPosition, 1841 ep2.blockPosition 1842 ); 1843 } 1844 function areCursorPositionsEqual(cursorPosition1, cursorPosition2) { 1845 const isRelativePositionEqual = import_sync7.Y.compareRelativePositions( 1846 cursorPosition1.relativePosition, 1847 cursorPosition2.relativePosition 1848 ); 1849 const isAbsoluteOffsetEqual = cursorPosition1.absoluteOffset === cursorPosition2.absoluteOffset; 1850 return isRelativePositionEqual && isAbsoluteOffsetEqual; 1851 } 1852 1853 // packages/core-data/build-module/awareness/post-editor-awareness.mjs 1854 var PostEditorAwareness = class extends BaseAwarenessState { 1855 constructor(doc, kind, name, postId) { 1856 super(doc); 1857 this.kind = kind; 1858 this.name = name; 1859 this.postId = postId; 1860 } 1861 equalityFieldChecks = { 1862 ...baseEqualityFieldChecks, 1863 editorState: this.areEditorStatesEqual 1864 }; 1865 onSetUp() { 1866 super.onSetUp(); 1867 this.subscribeToCollaboratorSelectionChanges(); 1868 } 1869 /** 1870 * Subscribe to collaborator selection changes and update the selection state. 1871 */ 1872 subscribeToCollaboratorSelectionChanges() { 1873 const { 1874 getSelectionStart, 1875 getSelectionEnd, 1876 getSelectedBlocksInitialCaretPosition 1877 } = (0, import_data4.select)(import_block_editor3.store); 1878 let selectionStart = getSelectionStart(); 1879 let selectionEnd = getSelectionEnd(); 1880 let localCursorTimeout = null; 1881 let selectionBeforeDebounce = null; 1882 (0, import_data4.subscribe)(() => { 1883 const newSelectionStart = getSelectionStart(); 1884 const newSelectionEnd = getSelectionEnd(); 1885 if (newSelectionStart === selectionStart && newSelectionEnd === selectionEnd) { 1886 return; 1887 } 1888 if (!selectionBeforeDebounce) { 1889 selectionBeforeDebounce = { 1890 start: selectionStart, 1891 end: selectionEnd 1892 }; 1893 } 1894 selectionStart = newSelectionStart; 1895 selectionEnd = newSelectionEnd; 1896 const initialPosition = getSelectedBlocksInitialCaretPosition(); 1897 void this.updateSelectionInEntityRecord( 1898 selectionStart, 1899 selectionEnd, 1900 initialPosition 1901 ); 1902 if (localCursorTimeout) { 1903 clearTimeout(localCursorTimeout); 1904 } 1905 localCursorTimeout = setTimeout(() => { 1906 const selectionStateOptions = {}; 1907 if (selectionBeforeDebounce) { 1908 selectionStateOptions.selectionDirection = detectSelectionDirection( 1909 selectionBeforeDebounce.start, 1910 selectionBeforeDebounce.end, 1911 selectionStart, 1912 selectionEnd 1913 ); 1914 selectionBeforeDebounce = null; 1915 } 1916 const selectionState = getSelectionState( 1917 selectionStart, 1918 selectionEnd, 1919 this.doc, 1920 selectionStateOptions 1921 ); 1922 this.setThrottledLocalStateField( 1923 "editorState", 1924 { selection: selectionState }, 1925 AWARENESS_CURSOR_UPDATE_THROTTLE_IN_MS 1926 ); 1927 }, LOCAL_CURSOR_UPDATE_DEBOUNCE_IN_MS); 1928 }); 1929 } 1930 /** 1931 * Update the entity record with the current collaborator's selection. 1932 * 1933 * @param selectionStart - The start position of the selection. 1934 * @param selectionEnd - The end position of the selection. 1935 * @param initialPosition - The initial position of the selection. 1936 */ 1937 async updateSelectionInEntityRecord(selectionStart, selectionEnd, initialPosition) { 1938 const edits = { 1939 selection: { selectionStart, selectionEnd, initialPosition } 1940 }; 1941 const options = { 1942 undoIgnore: true 1943 }; 1944 (0, import_data4.dispatch)(STORE_NAME).editEntityRecord( 1945 this.kind, 1946 this.name, 1947 this.postId, 1948 edits, 1949 options 1950 ); 1951 } 1952 /** 1953 * Check if two editor states are equal. 1954 * 1955 * @param state1 - The first editor state. 1956 * @param state2 - The second editor state. 1957 * @return True if the editor states are equal, false otherwise. 1958 */ 1959 areEditorStatesEqual(state1, state2) { 1960 if (!state1 || !state2) { 1961 return state1 === state2; 1962 } 1963 if (!state1.selection || !state2.selection) { 1964 return state1.selection === state2.selection; 1965 } 1966 return areSelectionsStatesEqual(state1.selection, state2.selection); 1967 } 1968 /** 1969 * Resolve a selection state to a text index and block client ID. 1970 * 1971 * For text-based selections, navigates up from the resolved Y.Text via 1972 * AbstractType.parent to find the containing block, then resolves the 1973 * local clientId via the block's tree path. 1974 * For WholeBlock selections, resolves the block's relative position and 1975 * then finds the local clientId via tree path. 1976 * 1977 * Tree-path resolution is used instead of reading the clientId directly 1978 * from the Yjs block because the local block-editor store may use different 1979 * clientIds (e.g. in "Show Template" mode where blocks are cloned). 1980 * 1981 * @param selection - The selection state. 1982 * @param blocks - The tree of block-editor store post content blocks. 1983 * @return The rich-text offset and block client ID, or nulls if not resolvable. 1984 */ 1985 convertSelectionStateToAbsolute(selection, blocks) { 1986 if (selection.type === SelectionType.None) { 1987 return { 1988 richTextOffset: null, 1989 localClientId: null, 1990 attributeKey: null 1991 }; 1992 } 1993 if (selection.type === SelectionType.WholeBlock) { 1994 const absolutePos = import_sync9.Y.createAbsolutePositionFromRelativePosition( 1995 selection.blockPosition, 1996 this.doc 1997 ); 1998 let localClientId2 = null; 1999 if (absolutePos && absolutePos.type instanceof import_sync9.Y.Array) { 2000 const parentArray = absolutePos.type; 2001 const block = parentArray.get(absolutePos.index); 2002 if (block instanceof import_sync9.Y.Map) { 2003 const path2 = getBlockPathInYdoc(block); 2004 localClientId2 = path2 ? resolveBlockClientIdByPath(path2, blocks) : null; 2005 } 2006 } 2007 return { 2008 richTextOffset: null, 2009 localClientId: localClientId2, 2010 attributeKey: null 2011 }; 2012 } 2013 if (selection.type === SelectionType.SelectionInMultipleBlocks) { 2014 return { 2015 richTextOffset: null, 2016 localClientId: null, 2017 attributeKey: null 2018 }; 2019 } 2020 const cursorPos = "cursorPosition" in selection ? selection.cursorPosition : selection.cursorStartPosition; 2021 const absolutePosition = import_sync9.Y.createAbsolutePositionFromRelativePosition( 2022 cursorPos.relativePosition, 2023 this.doc 2024 ); 2025 if (!absolutePosition) { 2026 return { 2027 richTextOffset: null, 2028 localClientId: null, 2029 attributeKey: null 2030 }; 2031 } 2032 const yType = getContainingBlockYMap(absolutePosition.type); 2033 const path = yType ? getBlockPathInYdoc(yType) : null; 2034 const localClientId = path ? resolveBlockClientIdByPath(path, blocks) : null; 2035 return { 2036 richTextOffset: htmlIndexToRichTextOffset( 2037 absolutePosition.type.toString(), 2038 asHtmlStringIndex(absolutePosition.index) 2039 ), 2040 localClientId, 2041 attributeKey: cursorPos.attributeKey ?? null 2042 }; 2043 } 2044 /** 2045 * Type guard to check if a struct is a Y.Item (not Y.GC) 2046 * @param struct - The struct to check. 2047 * @return True if the struct is a Y.Item, false otherwise. 2048 */ 2049 isYItem(struct) { 2050 return "content" in struct; 2051 } 2052 /** 2053 * Get data for debugging, using the awareness state. 2054 * 2055 * @return {YDocDebugData} The debug data. 2056 */ 2057 getDebugData() { 2058 const ydoc = this.doc; 2059 const docData = Object.fromEntries( 2060 Array.from(ydoc.share, ([key, value]) => [ 2061 key, 2062 value.toJSON() 2063 ]) 2064 ); 2065 const collaboratorMapData = new Map( 2066 Array.from(this.getSeenStates().entries()).filter( 2067 ([, collaboratorState]) => isCollaboratorInfo(collaboratorState.collaboratorInfo) 2068 ).map(([clientId, collaboratorState]) => [ 2069 String(clientId), 2070 { 2071 name: collaboratorState.collaboratorInfo.name, 2072 wpUserId: collaboratorState.collaboratorInfo.id 2073 } 2074 ]) 2075 ); 2076 const serializableClientItems = {}; 2077 ydoc.store.clients.forEach((structs, clientId) => { 2078 const items2 = structs.filter(this.isYItem); 2079 serializableClientItems[clientId] = items2.map((item) => { 2080 const { left, right, ...rest } = item; 2081 return { 2082 ...rest, 2083 left: left ? { 2084 id: left.id, 2085 length: left.length, 2086 origin: left.origin, 2087 content: left.content 2088 } : null, 2089 right: right ? { 2090 id: right.id, 2091 length: right.length, 2092 origin: right.origin, 2093 content: right.content 2094 } : null 2095 }; 2096 }); 2097 }); 2098 return { 2099 doc: docData, 2100 clients: serializableClientItems, 2101 collaboratorMap: Object.fromEntries(collaboratorMapData) 2102 }; 2103 } 2104 }; 2105 function detectSelectionDirection(prevStart, prevEnd, newStart, newEnd) { 2106 const startMoved = !areBlockSelectionsEqual(prevStart, newStart); 2107 const endMoved = !areBlockSelectionsEqual(prevEnd, newEnd); 2108 if (startMoved && !endMoved) { 2109 return SelectionDirection.Backward; 2110 } 2111 return SelectionDirection.Forward; 2112 } 2113 function areBlockSelectionsEqual(a, b) { 2114 return a.clientId === b.clientId && a.attributeKey === b.attributeKey && a.offset === b.offset; 2115 } 2116 2117 // packages/core-data/build-module/utils/crdt.mjs 2118 var import_es64 = __toESM(require_es6(), 1); 2119 var import_blocks3 = __toESM(require_blocks(), 1); 2120 var import_sync14 = __toESM(require_sync(), 1); 2121 2122 // node_modules/uuid/dist/stringify.js 2123 var byteToHex = []; 2124 for (let i = 0; i < 256; ++i) { 2125 byteToHex.push((i + 256).toString(16).slice(1)); 2126 } 2127 function unsafeStringify(arr, offset = 0) { 2128 return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); 2129 } 2130 2131 // node_modules/uuid/dist/rng.js 2132 var rnds8 = new Uint8Array(16); 2133 function rng() { 2134 return crypto.getRandomValues(rnds8); 2135 } 2136 2137 // node_modules/uuid/dist/v4.js 2138 function v4(options, buf, offset) { 2139 if (!buf && !options && crypto.randomUUID) { 2140 return crypto.randomUUID(); 2141 } 2142 return _v4(options, buf, offset); 2143 } 2144 function _v4(options, buf, offset) { 2145 options = options || {}; 2146 const rnds = options.random ?? options.rng?.() ?? rng(); 2147 if (rnds.length < 16) { 2148 throw new Error("Random bytes length must be >= 16"); 2149 } 2150 rnds[6] = rnds[6] & 15 | 64; 2151 rnds[8] = rnds[8] & 63 | 128; 2152 if (buf) { 2153 offset = offset || 0; 2154 if (offset < 0 || offset + 16 > buf.length) { 2155 throw new RangeError(`UUID byte range $offset}:$offset + 15} is out of buffer bounds`); 2156 } 2157 for (let i = 0; i < 16; ++i) { 2158 buf[offset + i] = rnds[i]; 2159 } 2160 return buf; 2161 } 2162 return unsafeStringify(rnds); 2163 } 2164 var v4_default = v4; 2165 2166 // packages/core-data/build-module/utils/crdt-blocks.mjs 2167 var import_es63 = __toESM(require_es6(), 1); 2168 var import_blocks = __toESM(require_blocks(), 1); 2169 var import_rich_text3 = __toESM(require_rich_text(), 1); 2170 var import_sync10 = __toESM(require_sync(), 1); 2171 2172 // packages/core-data/build-module/utils/crdt-text.mjs 2173 var import_rich_text2 = __toESM(require_rich_text(), 1); 2174 var RICH_TEXT_CACHE_MAX_SIZE = 500; 2175 function createRichTextDataCache(maxSize) { 2176 const cache3 = /* @__PURE__ */ new Map(); 2177 return function(value) { 2178 const cached = cache3.get(value); 2179 if (cached) { 2180 return cached; 2181 } 2182 const result = import_rich_text2.RichTextData.fromHTMLString(value); 2183 if (cache3.size >= maxSize) { 2184 cache3.delete(cache3.keys().next().value); 2185 } 2186 cache3.set(value, result); 2187 return result; 2188 }; 2189 } 2190 var getCachedRichTextData = createRichTextDataCache( 2191 RICH_TEXT_CACHE_MAX_SIZE 2192 ); 2193 2194 // packages/core-data/build-module/utils/crdt-blocks.mjs 2195 var serializableBlocksCache = /* @__PURE__ */ new WeakMap(); 2196 function serializeAttributeValue(value) { 2197 if (value instanceof import_rich_text3.RichTextData) { 2198 return value.valueOf(); 2199 } 2200 if (Array.isArray(value)) { 2201 return value.map(serializeAttributeValue); 2202 } 2203 if (value && typeof value === "object") { 2204 const result = {}; 2205 for (const [k, v] of Object.entries(value)) { 2206 result[k] = serializeAttributeValue(v); 2207 } 2208 return result; 2209 } 2210 return value; 2211 } 2212 function makeBlockAttributesSerializable(blockName, attributes) { 2213 const newAttributes = { ...attributes }; 2214 for (const [key, value] of Object.entries(attributes)) { 2215 if (isLocalAttribute(blockName, key)) { 2216 delete newAttributes[key]; 2217 continue; 2218 } 2219 newAttributes[key] = serializeAttributeValue(value); 2220 } 2221 return newAttributes; 2222 } 2223 function makeBlocksSerializable(blocks) { 2224 return blocks.map((block) => { 2225 const { 2226 name, 2227 innerBlocks, 2228 attributes, 2229 /* 2230 * Any validation issues discovered when loading a block are appended 2231 * to the block node with a logging function, which cannot be serialized. 2232 * 2233 * @see import("@wordpress/blocks/src/api/parser").parseRawBlock() 2234 */ 2235 validationIssues, 2236 ...rest 2237 } = block; 2238 return { 2239 ...rest, 2240 name, 2241 attributes: makeBlockAttributesSerializable(name, attributes), 2242 innerBlocks: makeBlocksSerializable(innerBlocks) 2243 }; 2244 }); 2245 } 2246 function deserializeAttributeValue(schema, value) { 2247 if (schema?.type === "rich-text" && typeof value === "string") { 2248 return getCachedRichTextData(value); 2249 } 2250 if (Array.isArray(value)) { 2251 return value.map( 2252 (item) => deserializeAttributeValue(schema, item) 2253 ); 2254 } 2255 if (value && typeof value === "object") { 2256 const result = {}; 2257 for (const [key, innerValue] of Object.entries( 2258 value 2259 )) { 2260 result[key] = deserializeAttributeValue( 2261 schema?.query?.[key], 2262 innerValue 2263 ); 2264 } 2265 return result; 2266 } 2267 return value; 2268 } 2269 function deserializeBlockAttributes(blocks) { 2270 return blocks.map((block) => { 2271 const { name, innerBlocks, attributes, ...rest } = block; 2272 const newAttributes = { ...attributes }; 2273 for (const [key, value] of Object.entries(attributes)) { 2274 const schema = getBlockAttributeSchema(name, key); 2275 if (schema) { 2276 newAttributes[key] = deserializeAttributeValue( 2277 schema, 2278 value 2279 ); 2280 } 2281 } 2282 return { 2283 ...rest, 2284 name, 2285 attributes: newAttributes, 2286 innerBlocks: deserializeBlockAttributes(innerBlocks ?? []) 2287 }; 2288 }); 2289 } 2290 function areBlocksEqual(gblock, yblock) { 2291 const yblockAsJson = yblock.toJSON(); 2292 const overwrites = { 2293 innerBlocks: null, 2294 clientId: null 2295 }; 2296 const res = (0, import_es63.default)( 2297 Object.assign({}, gblock, overwrites), 2298 Object.assign({}, yblockAsJson, overwrites) 2299 ); 2300 const inners = gblock.innerBlocks || []; 2301 const yinners = yblock.get("innerBlocks"); 2302 return res && inners.length === yinners?.length && inners.every( 2303 (block, i) => areBlocksEqual(block, yinners.get(i)) 2304 ); 2305 } 2306 function createNewYAttributeMap(blockName, attributes) { 2307 return new import_sync10.Y.Map( 2308 Object.entries(attributes).map( 2309 ([attributeName, attributeValue]) => { 2310 return [ 2311 attributeName, 2312 createNewYAttributeValue( 2313 blockName, 2314 attributeName, 2315 attributeValue 2316 ) 2317 ]; 2318 } 2319 ) 2320 ); 2321 } 2322 function createNewYAttributeValue(blockName, attributeName, attributeValue) { 2323 const schema = getBlockAttributeSchema(blockName, attributeName); 2324 return createYValueFromSchema(schema, attributeValue); 2325 } 2326 function createYValueFromSchema(schema, value) { 2327 if (!schema) { 2328 return value; 2329 } 2330 if (schema.type === "rich-text") { 2331 return new import_sync10.Y.Text(value?.toString() ?? ""); 2332 } 2333 if (schema.type === "array" && schema.query && Array.isArray(value)) { 2334 const query = schema.query; 2335 const yArray = new import_sync10.Y.Array(); 2336 yArray.insert( 2337 0, 2338 value.map((item) => createYMapFromQuery(query, item)) 2339 ); 2340 return yArray; 2341 } 2342 if (schema.type === "object" && schema.query && isRecord(value)) { 2343 return createYMapFromQuery(schema.query, value); 2344 } 2345 return value; 2346 } 2347 function isRecord(value) { 2348 return !!value && typeof value === "object" && !Array.isArray(value); 2349 } 2350 function createYMapFromQuery(query, obj) { 2351 if (!isRecord(obj)) { 2352 return new import_sync10.Y.Map(); 2353 } 2354 const entries = Object.entries(obj).map( 2355 ([key, val]) => { 2356 const subSchema = query[key]; 2357 return [key, createYValueFromSchema(subSchema, val)]; 2358 } 2359 ); 2360 return new import_sync10.Y.Map(entries); 2361 } 2362 function createNewYBlock(block) { 2363 return createYMap( 2364 Object.fromEntries( 2365 Object.entries(block).map(([key, value]) => { 2366 switch (key) { 2367 case "attributes": { 2368 return [ 2369 key, 2370 createNewYAttributeMap(block.name, value) 2371 ]; 2372 } 2373 case "innerBlocks": { 2374 const innerBlocks = new import_sync10.Y.Array(); 2375 if (!Array.isArray(value)) { 2376 return [key, innerBlocks]; 2377 } 2378 innerBlocks.insert( 2379 0, 2380 value.map( 2381 (innerBlock) => createNewYBlock(innerBlock) 2382 ) 2383 ); 2384 return [key, innerBlocks]; 2385 } 2386 default: 2387 return [key, value]; 2388 } 2389 }) 2390 ) 2391 ); 2392 } 2393 function mergeCrdtBlocks(yblocks, incomingBlocks, attributeCursor, options = {}) { 2394 if (!serializableBlocksCache.has(incomingBlocks)) { 2395 serializableBlocksCache.set( 2396 incomingBlocks, 2397 makeBlocksSerializable(incomingBlocks) 2398 ); 2399 } 2400 const incomingBlocksToSync = serializableBlocksCache.get(incomingBlocks) ?? []; 2401 const numOfCommonEntries = Math.min( 2402 incomingBlocksToSync.length ?? 0, 2403 yblocks.length 2404 ); 2405 let left = 0; 2406 let right = 0; 2407 for (; left < numOfCommonEntries && areBlocksEqual(incomingBlocksToSync[left], yblocks.get(left)); left++) { 2408 } 2409 for (; right < numOfCommonEntries - left && areBlocksEqual( 2410 incomingBlocksToSync[incomingBlocksToSync.length - right - 1], 2411 yblocks.get(yblocks.length - right - 1) 2412 ); right++) { 2413 } 2414 const numOfUpdatesNeeded = numOfCommonEntries - left - right; 2415 const numOfInsertionsNeeded = Math.max( 2416 0, 2417 incomingBlocksToSync.length - yblocks.length 2418 ); 2419 const numOfDeletionsNeeded = Math.max( 2420 0, 2421 yblocks.length - incomingBlocksToSync.length 2422 ); 2423 for (let i = 0; i < numOfUpdatesNeeded; i++, left++) { 2424 const incomingYBlock = incomingBlocksToSync[left]; 2425 const localYBlock = yblocks.get(left); 2426 Object.entries(incomingYBlock).forEach( 2427 ([incomingBlockProperty, incomingBlockPropertyValue]) => { 2428 switch (incomingBlockProperty) { 2429 case "attributes": { 2430 const localAttributes = localYBlock.get( 2431 incomingBlockProperty 2432 ); 2433 const incomingAttributes = incomingBlockPropertyValue; 2434 if (!localAttributes) { 2435 localYBlock.set( 2436 incomingBlockProperty, 2437 createNewYAttributeMap( 2438 incomingYBlock.name, 2439 incomingAttributes 2440 ) 2441 ); 2442 break; 2443 } 2444 Object.entries(incomingAttributes).forEach( 2445 ([ 2446 incomingAttributeName, 2447 incomingAttributeValue 2448 ]) => { 2449 const currentAttribute = localAttributes?.get( 2450 incomingAttributeName 2451 ); 2452 const isExpectedType = isExpectedAttributeType( 2453 incomingYBlock.name, 2454 incomingAttributeName, 2455 currentAttribute 2456 ); 2457 const isYType = currentAttribute instanceof import_sync10.Y.AbstractType; 2458 const isAttributeChanged = !isExpectedType || isYType || !(0, import_es63.default)( 2459 currentAttribute, 2460 incomingAttributeValue 2461 ); 2462 if (isAttributeChanged) { 2463 updateYBlockAttribute( 2464 incomingYBlock.name, 2465 incomingYBlock.clientId, 2466 incomingAttributeName, 2467 incomingAttributeValue, 2468 localAttributes, 2469 attributeCursor 2470 ); 2471 } 2472 } 2473 ); 2474 localAttributes.forEach( 2475 (_attrValue, attrName) => { 2476 if (!incomingBlockPropertyValue.hasOwnProperty( 2477 attrName 2478 )) { 2479 localAttributes.delete(attrName); 2480 } 2481 } 2482 ); 2483 break; 2484 } 2485 case "innerBlocks": { 2486 let yInnerBlocks = localYBlock.get( 2487 incomingBlockProperty 2488 ); 2489 if (!(yInnerBlocks instanceof import_sync10.Y.Array)) { 2490 yInnerBlocks = new import_sync10.Y.Array(); 2491 localYBlock.set( 2492 incomingBlockProperty, 2493 yInnerBlocks 2494 ); 2495 } 2496 mergeCrdtBlocks( 2497 yInnerBlocks, 2498 incomingBlockPropertyValue ?? [], 2499 attributeCursor, 2500 options 2501 ); 2502 break; 2503 } 2504 case "clientId": { 2505 if (options.preserveClientIds) { 2506 break; 2507 } 2508 if (incomingBlockPropertyValue !== localYBlock.get(incomingBlockProperty)) { 2509 localYBlock.set( 2510 incomingBlockProperty, 2511 incomingBlockPropertyValue 2512 ); 2513 } 2514 break; 2515 } 2516 default: 2517 if (!(0, import_es63.default)( 2518 incomingYBlock[incomingBlockProperty], 2519 localYBlock.get(incomingBlockProperty) 2520 )) { 2521 localYBlock.set( 2522 incomingBlockProperty, 2523 incomingBlockPropertyValue 2524 ); 2525 } 2526 } 2527 } 2528 ); 2529 localYBlock.forEach((_v, k) => { 2530 if (!incomingYBlock.hasOwnProperty(k)) { 2531 localYBlock.delete(k); 2532 } 2533 }); 2534 } 2535 yblocks.delete(left, numOfDeletionsNeeded); 2536 for (let i = 0; i < numOfInsertionsNeeded; i++, left++) { 2537 const newBlock = [createNewYBlock(incomingBlocksToSync[left])]; 2538 yblocks.insert(left, newBlock); 2539 } 2540 const knownClientIds = /* @__PURE__ */ new Set(); 2541 for (let j = 0; j < yblocks.length; j++) { 2542 const yblock = yblocks.get(j); 2543 let clientId = yblock.get("clientId"); 2544 if (!clientId) { 2545 continue; 2546 } 2547 if (knownClientIds.has(clientId)) { 2548 clientId = v4_default(); 2549 yblock.set("clientId", clientId); 2550 } 2551 knownClientIds.add(clientId); 2552 } 2553 } 2554 function areArrayElementsEqual(newElement, yElement) { 2555 if (yElement instanceof import_sync10.Y.Map && isRecord(newElement)) { 2556 return (0, import_es63.default)(newElement, yElement.toJSON()); 2557 } 2558 return (0, import_es63.default)(newElement, yElement); 2559 } 2560 function mergeYArray(yArray, newValue, schema, cursorPosition, cursorScope) { 2561 if (!schema.query) { 2562 return; 2563 } 2564 const query = schema.query; 2565 const numOfCommonEntries = Math.min(newValue.length, yArray.length); 2566 let left = 0; 2567 let right = 0; 2568 for (; left < numOfCommonEntries && areArrayElementsEqual(newValue[left], yArray.get(left)); left++) { 2569 } 2570 for (; right < numOfCommonEntries - left && areArrayElementsEqual( 2571 newValue[newValue.length - right - 1], 2572 yArray.get(yArray.length - right - 1) 2573 ); right++) { 2574 } 2575 const numOfUpdatesNeeded = numOfCommonEntries - left - right; 2576 for (let i = 0; i < numOfUpdatesNeeded; i++) { 2577 const currentElement = yArray.get(left + i); 2578 const newElement = newValue[left + i]; 2579 if (currentElement instanceof import_sync10.Y.Map && isRecord(newElement)) { 2580 mergeYMapValues( 2581 currentElement, 2582 newElement, 2583 query, 2584 cursorPosition, 2585 cursorScope 2586 ); 2587 } else { 2588 yArray.delete(0, yArray.length); 2589 yArray.insert( 2590 0, 2591 newValue.map((item) => createYMapFromQuery(query, item)) 2592 ); 2593 return; 2594 } 2595 } 2596 const numOfDeletionsNeeded = Math.max(0, yArray.length - newValue.length); 2597 if (numOfDeletionsNeeded > 0) { 2598 yArray.delete(left + numOfUpdatesNeeded, numOfDeletionsNeeded); 2599 } 2600 const numOfInsertionsNeeded = Math.max( 2601 0, 2602 newValue.length - yArray.length 2603 ); 2604 if (numOfInsertionsNeeded > 0) { 2605 const insertAt = left + numOfUpdatesNeeded; 2606 const itemsToInsert = new Array( 2607 numOfInsertionsNeeded 2608 ); 2609 for (let i = 0; i < numOfInsertionsNeeded; i++) { 2610 itemsToInsert[i] = createYMapFromQuery( 2611 query, 2612 newValue[insertAt + i] 2613 ); 2614 } 2615 yArray.insert(insertAt, itemsToInsert); 2616 } 2617 } 2618 function mergeYValue(schema, newVal, yMap, key, cursorPosition, cursorScope) { 2619 const currentVal = yMap.get(key); 2620 if (schema?.type === "rich-text" && typeof newVal === "string" && currentVal instanceof import_sync10.Y.Text) { 2621 mergeRichTextUpdate( 2622 currentVal, 2623 newVal, 2624 resolveRichTextCursorPosition(cursorPosition, cursorScope, newVal) 2625 ); 2626 } else if (schema?.type === "array" && schema.query && Array.isArray(newVal) && currentVal instanceof import_sync10.Y.Array) { 2627 mergeYArray(currentVal, newVal, schema, cursorPosition, cursorScope); 2628 } else if (schema?.type === "object" && schema.query && isRecord(newVal) && currentVal instanceof import_sync10.Y.Map) { 2629 mergeYMapValues( 2630 currentVal, 2631 newVal, 2632 schema.query, 2633 cursorPosition, 2634 cursorScope 2635 ); 2636 } else { 2637 const newYValue = createYValueFromSchema(schema, newVal); 2638 if (newYValue !== newVal || !(0, import_es63.default)(currentVal, newVal)) { 2639 yMap.set(key, newYValue); 2640 } 2641 } 2642 } 2643 function mergeYMapValues(yMap, newObj, query, cursorPosition, cursorScope) { 2644 for (const [key, newVal] of Object.entries(newObj)) { 2645 mergeYValue( 2646 query[key], 2647 newVal, 2648 yMap, 2649 key, 2650 cursorPosition, 2651 cursorScope 2652 ); 2653 } 2654 for (const key of yMap.keys()) { 2655 if (!Object.hasOwn(newObj, key)) { 2656 yMap.delete(key); 2657 } 2658 } 2659 } 2660 function updateYBlockAttribute(blockName, clientId, attributeName, attributeValue, currentAttributes, newCursorPosition) { 2661 const schema = getBlockAttributeSchema(blockName, attributeName); 2662 mergeYValue( 2663 schema, 2664 attributeValue, 2665 currentAttributes, 2666 attributeName, 2667 newCursorPosition, 2668 { attributeKey: attributeName, clientId } 2669 ); 2670 } 2671 function resolveRichTextCursorPosition(cursorPosition, cursorScope, updatedValue) { 2672 return cursorPosition && cursorPosition.clientId === cursorScope.clientId && cursorPosition.attributeKey === cursorScope.attributeKey && "number" === typeof cursorPosition.offset && Number.isInteger(cursorPosition.offset) ? richTextOffsetToHtmlIndex( 2673 updatedValue, 2674 asRichTextOffset(cursorPosition.offset) 2675 ) : null; 2676 } 2677 var cachedBlockAttributeSchemas; 2678 function getBlockAttributeSchema(blockName, attributeName) { 2679 if (!cachedBlockAttributeSchemas) { 2680 cachedBlockAttributeSchemas = /* @__PURE__ */ new Map(); 2681 for (const blockType of (0, import_blocks.getBlockTypes)()) { 2682 cachedBlockAttributeSchemas.set( 2683 blockType.name, 2684 new Map( 2685 Object.entries(blockType.attributes ?? {}).map( 2686 ([name, definition]) => { 2687 const { role, type, query } = definition; 2688 return [name, { role, type, query }]; 2689 } 2690 ) 2691 ) 2692 ); 2693 } 2694 } 2695 return cachedBlockAttributeSchemas.get(blockName)?.get(attributeName); 2696 } 2697 function isExpectedAttributeType(blockName, attributeName, attributeValue) { 2698 const schema = getBlockAttributeSchema(blockName, attributeName); 2699 if (schema?.type === "rich-text") { 2700 return attributeValue instanceof import_sync10.Y.Text; 2701 } 2702 if (schema?.type === "string") { 2703 return typeof attributeValue === "string"; 2704 } 2705 if (schema?.type === "array" && schema.query) { 2706 return attributeValue instanceof import_sync10.Y.Array; 2707 } 2708 if (schema?.type === "object" && schema.query) { 2709 return attributeValue instanceof import_sync10.Y.Map; 2710 } 2711 return true; 2712 } 2713 function isLocalAttribute(blockName, attributeName) { 2714 return "local" === getBlockAttributeSchema(blockName, attributeName)?.role; 2715 } 2716 var localDoc; 2717 function mergeRichTextUpdate(blockYText, updatedValue, htmlCursorIndex = null) { 2718 const currentValueAsDelta = new Delta(blockYText.toDelta()); 2719 const updatedValueAsDelta = new Delta([{ insert: updatedValue }]); 2720 const deltaDiff = currentValueAsDelta.diffWithCursor( 2721 updatedValueAsDelta, 2722 htmlCursorIndex 2723 ); 2724 const safeDiff = htmlCursorIndex === null || isDeltaVerificationMatch(blockYText, deltaDiff, updatedValue) ? deltaDiff : currentValueAsDelta.diff(updatedValueAsDelta); 2725 blockYText.applyDelta(safeDiff.ops); 2726 } 2727 function isDeltaVerificationMatch(blockYText, delta, expectedValue) { 2728 if (!localDoc) { 2729 localDoc = new import_sync10.Y.Doc(); 2730 } 2731 const verificationYText = localDoc.getText("verification-text"); 2732 verificationYText.delete(0, verificationYText.length); 2733 verificationYText.insert(0, blockYText.toString()); 2734 verificationYText.applyDelta(delta.ops); 2735 return verificationYText.toString() === expectedValue; 2736 } 2737 2738 // packages/core-data/build-module/utils/crdt-selection.mjs 2739 var import_data5 = __toESM(require_data(), 1); 2740 var import_block_editor4 = __toESM(require_block_editor(), 1); 2741 var import_blocks2 = __toESM(require_blocks(), 1); 2742 var import_sync13 = __toESM(require_sync(), 1); 2743 2744 // packages/core-data/build-module/utils/block-selection-history.mjs 2745 var import_sync12 = __toESM(require_sync(), 1); 2746 var SELECTION_HISTORY_DEFAULT_SIZE = 5; 2747 var YSelectionType = /* @__PURE__ */ ((YSelectionType2) => { 2748 YSelectionType2["RelativeSelection"] = "RelativeSelection"; 2749 YSelectionType2["BlockSelection"] = "BlockSelection"; 2750 return YSelectionType2; 2751 })(YSelectionType || {}); 2752 function createBlockSelectionHistory(ydoc, historySize = SELECTION_HISTORY_DEFAULT_SIZE) { 2753 let history = []; 2754 const getSelectionHistory2 = () => { 2755 return history.slice(0); 2756 }; 2757 const updateSelection = (newSelection) => { 2758 if (!newSelection?.selectionStart?.clientId || !newSelection?.selectionEnd?.clientId) { 2759 return; 2760 } 2761 const { selectionStart, selectionEnd } = newSelection; 2762 const start = convertWPBlockSelectionToSelection( 2763 selectionStart, 2764 ydoc 2765 ); 2766 const end = convertWPBlockSelectionToSelection(selectionEnd, ydoc); 2767 addToHistory({ start, end }); 2768 }; 2769 const addToHistory = (yFullSelection) => { 2770 const startClientId = yFullSelection.start.clientId; 2771 const endClientId = yFullSelection.end.clientId; 2772 history = history.filter((entry) => { 2773 const isSameBlockCombination = entry.start.clientId === startClientId && entry.end.clientId === endClientId; 2774 return !isSameBlockCombination; 2775 }); 2776 history.unshift(yFullSelection); 2777 if (history.length > historySize + 1) { 2778 history = history.slice(0, historySize + 1); 2779 } 2780 }; 2781 return { 2782 getSelectionHistory: getSelectionHistory2, 2783 updateSelection 2784 }; 2785 } 2786 function convertWPBlockSelectionToSelection(selection, ydoc) { 2787 const clientId = selection.clientId; 2788 const block = findBlockByClientIdInDoc(clientId, ydoc); 2789 const attributes = block?.get("attributes"); 2790 const attributeKey = selection.attributeKey; 2791 let changedYText = null; 2792 if (attributeKey && attributes) { 2793 changedYText = getYTextByAttributeKey(attributes, attributeKey); 2794 } 2795 if (!(changedYText instanceof import_sync12.Y.Text) || !attributeKey || !clientId) { 2796 return { 2797 type: "BlockSelection", 2798 clientId 2799 }; 2800 } 2801 const offset = selection.offset ?? 0; 2802 const relativePosition = import_sync12.Y.createRelativePositionFromTypeIndex( 2803 changedYText, 2804 richTextOffsetToHtmlIndex( 2805 changedYText.toString(), 2806 asRichTextOffset(offset) 2807 ) 2808 ); 2809 return { 2810 type: "RelativeSelection", 2811 attributeKey, 2812 relativePosition, 2813 clientId, 2814 offset 2815 }; 2816 } 2817 2818 // packages/core-data/build-module/utils/crdt-selection.mjs 2819 var selectionHistoryMap = /* @__PURE__ */ new WeakMap(); 2820 function getBlockSelectionHistory(ydoc) { 2821 let history = selectionHistoryMap.get(ydoc); 2822 if (!history) { 2823 history = createBlockSelectionHistory(ydoc); 2824 selectionHistoryMap.set(ydoc, history); 2825 } 2826 return history; 2827 } 2828 function getSelectionHistory(ydoc) { 2829 return getBlockSelectionHistory(ydoc).getSelectionHistory(); 2830 } 2831 function updateSelectionHistory(ydoc, wpSelection) { 2832 return getBlockSelectionHistory(ydoc).updateSelection(wpSelection); 2833 } 2834 function convertYSelectionToBlockSelection(ySelection, ydoc) { 2835 if (ySelection.type === YSelectionType.RelativeSelection) { 2836 const { relativePosition, attributeKey, clientId } = ySelection; 2837 const absolutePosition = import_sync13.Y.createAbsolutePositionFromRelativePosition( 2838 relativePosition, 2839 ydoc 2840 ); 2841 if (absolutePosition) { 2842 return { 2843 clientId, 2844 attributeKey, 2845 offset: htmlIndexToRichTextOffset( 2846 absolutePosition.type.toString(), 2847 asHtmlStringIndex(absolutePosition.index) 2848 ) 2849 }; 2850 } 2851 } else if (ySelection.type === YSelectionType.BlockSelection) { 2852 return { 2853 clientId: ySelection.clientId, 2854 attributeKey: void 0, 2855 offset: void 0 2856 }; 2857 } 2858 return null; 2859 } 2860 function convertYFullSelectionToWPSelection(yFullSelection, ydoc) { 2861 const { start, end } = yFullSelection; 2862 const startBlock = findBlockByClientIdInDoc(start.clientId, ydoc); 2863 const endBlock = findBlockByClientIdInDoc(end.clientId, ydoc); 2864 if (!startBlock || !endBlock) { 2865 return null; 2866 } 2867 const startBlockSelection = convertYSelectionToBlockSelection( 2868 start, 2869 ydoc 2870 ); 2871 const endBlockSelection = convertYSelectionToBlockSelection(end, ydoc); 2872 if (startBlockSelection === null || endBlockSelection === null) { 2873 return null; 2874 } 2875 return { 2876 selectionStart: startBlockSelection, 2877 selectionEnd: endBlockSelection 2878 }; 2879 } 2880 function findSelectionFromHistory(ydoc, selectionHistory) { 2881 for (const positionToTry of selectionHistory) { 2882 const result = convertYFullSelectionToWPSelection( 2883 positionToTry, 2884 ydoc 2885 ); 2886 if (result !== null) { 2887 return result; 2888 } 2889 } 2890 return null; 2891 } 2892 function restoreSelection(selectionHistory, ydoc) { 2893 const selectionToRestore = findSelectionFromHistory( 2894 ydoc, 2895 selectionHistory 2896 ); 2897 if (selectionToRestore === null) { 2898 return; 2899 } 2900 const { getBlock } = (0, import_data5.select)(import_block_editor4.store); 2901 const { resetSelection } = (0, import_data5.dispatch)(import_block_editor4.store); 2902 const { selectionStart, selectionEnd } = selectionToRestore; 2903 const isSelectionInSameBlock = selectionStart.clientId === selectionEnd.clientId; 2904 if (isSelectionInSameBlock) { 2905 const block = getBlock(selectionStart.clientId); 2906 const isBlockEmpty = block && (0, import_blocks2.isUnmodifiedBlock)(block); 2907 const isBeginningOfEmptyBlock = 0 === selectionStart.offset && 0 === selectionEnd.offset && isBlockEmpty && !selectionStart.attributeKey && !selectionEnd.attributeKey; 2908 if (isBeginningOfEmptyBlock) { 2909 const selectionStartWithoutOffset = { 2910 clientId: selectionStart.clientId 2911 }; 2912 const selectionEndWithoutOffset = { 2913 clientId: selectionEnd.clientId 2914 }; 2915 resetSelection( 2916 selectionStartWithoutOffset, 2917 selectionEndWithoutOffset, 2918 0 2919 ); 2920 } else { 2921 resetSelection(selectionStart, selectionEnd, 0); 2922 } 2923 } else { 2924 resetSelection(selectionEnd, selectionEnd, 0); 2925 } 2926 } 2927 function getShiftedSelection(ydoc, selectionHistory) { 2928 if (selectionHistory.length === 0) { 2929 return null; 2930 } 2931 const { start, end } = selectionHistory[0]; 2932 if (start.type === YSelectionType.BlockSelection || end.type === YSelectionType.BlockSelection) { 2933 return null; 2934 } 2935 const selectionStart = convertYSelectionToBlockSelection(start, ydoc); 2936 const selectionEnd = convertYSelectionToBlockSelection(end, ydoc); 2937 if (!selectionStart || !selectionEnd) { 2938 return null; 2939 } 2940 const startShifted = selectionStart.offset !== start.offset; 2941 const endShifted = selectionEnd.offset !== end.offset; 2942 if (!startShifted && !endShifted) { 2943 return null; 2944 } 2945 return { selectionStart, selectionEnd }; 2946 } 2947 2948 // packages/core-data/build-module/utils/crdt.mjs 2949 var POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE = "_crdt_document"; 2950 var disallowedPostMetaKeys = /* @__PURE__ */ new Set([ 2951 POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE 2952 ]); 2953 function defaultApplyChangesToCRDTDoc(ydoc, changes) { 2954 const ymap = getRootMap(ydoc, CRDT_RECORD_MAP_KEY); 2955 Object.entries(changes).forEach(([key, newValue]) => { 2956 if ("function" === typeof newValue) { 2957 return; 2958 } 2959 switch (key) { 2960 // Add support for additional data types here. 2961 default: { 2962 const currentValue = ymap.get(key); 2963 updateMapValue(ymap, key, currentValue, newValue); 2964 } 2965 } 2966 }); 2967 } 2968 function applyPostChangesToCRDTDoc(ydoc, changes, syncedProperties) { 2969 const ymap = getRootMap(ydoc, CRDT_RECORD_MAP_KEY); 2970 Object.keys(changes).forEach((key) => { 2971 if (!syncedProperties.has(key)) { 2972 return; 2973 } 2974 const newValue = changes[key]; 2975 if ("function" === typeof newValue) { 2976 return; 2977 } 2978 switch (key) { 2979 case "blocks": { 2980 const newCursorPosition = parseCursorSelection( 2981 changes.selection 2982 ); 2983 const rawContent = getRawValue(changes.content); 2984 if (!newValue && typeof rawContent === "string") { 2985 mergeContentWithoutBlocks( 2986 ymap, 2987 rawContent, 2988 newCursorPosition 2989 ); 2990 break; 2991 } else if (!newValue) { 2992 ymap.set(key, void 0); 2993 break; 2994 } 2995 let currentBlocks = ymap.get(key); 2996 if (!(currentBlocks instanceof import_sync14.Y.Array)) { 2997 currentBlocks = new import_sync14.Y.Array(); 2998 ymap.set(key, currentBlocks); 2999 } 3000 mergeCrdtBlocks(currentBlocks, newValue, newCursorPosition); 3001 break; 3002 } 3003 case "content": 3004 case "excerpt": 3005 case "title": { 3006 const currentValue = ymap.get(key); 3007 let rawValue = getRawValue(newValue); 3008 if (key === "title" && !currentValue?.toString() && "Auto Draft" === rawValue) { 3009 rawValue = ""; 3010 } 3011 if (currentValue instanceof import_sync14.Y.Text) { 3012 mergeRichTextUpdate(currentValue, rawValue ?? ""); 3013 } else { 3014 const newYText = new import_sync14.Y.Text(rawValue ?? ""); 3015 ymap.set(key, newYText); 3016 } 3017 break; 3018 } 3019 // "Meta" is overloaded term; here, it refers to post meta. 3020 case "meta": { 3021 let metaMap = ymap.get("meta"); 3022 if (!isYMap(metaMap)) { 3023 metaMap = createYMap(); 3024 ymap.set("meta", metaMap); 3025 } 3026 Object.entries(newValue ?? {}).forEach( 3027 ([metaKey, metaValue]) => { 3028 if (disallowedPostMetaKeys.has(metaKey)) { 3029 return; 3030 } 3031 updateMapValue( 3032 metaMap, 3033 metaKey, 3034 metaMap.get(metaKey), 3035 // current value in CRDT 3036 metaValue 3037 // new value from changes 3038 ); 3039 } 3040 ); 3041 break; 3042 } 3043 case "slug": { 3044 if (!newValue) { 3045 break; 3046 } 3047 const currentValue = ymap.get(key); 3048 updateMapValue(ymap, key, currentValue, newValue); 3049 break; 3050 } 3051 // Add support for additional properties here. 3052 default: { 3053 const currentValue = ymap.get(key); 3054 updateMapValue(ymap, key, currentValue, newValue); 3055 } 3056 } 3057 }); 3058 if (changes.selection) { 3059 const selection = changes.selection; 3060 setTimeout(() => { 3061 updateSelectionHistory(ydoc, selection); 3062 }, 0); 3063 } 3064 } 3065 function mergeContentWithoutBlocks(ymap, rawContent, cursorPosition) { 3066 let currentBlocks = ymap.get("blocks"); 3067 if (!(currentBlocks instanceof import_sync14.Y.Array)) { 3068 currentBlocks = new import_sync14.Y.Array(); 3069 ymap.set("blocks", currentBlocks); 3070 } 3071 mergeCrdtBlocks( 3072 currentBlocks, 3073 (0, import_blocks3.parse)(rawContent), 3074 cursorPosition, 3075 { preserveClientIds: true } 3076 ); 3077 } 3078 function parseCursorSelection(selection) { 3079 const selectionStart = selection?.selectionStart; 3080 return selectionStart?.clientId && selectionStart.attributeKey && "number" === typeof selectionStart.offset && Number.isInteger(selectionStart.offset) ? { 3081 attributeKey: selectionStart.attributeKey, 3082 clientId: selectionStart.clientId, 3083 offset: asRichTextOffset(selectionStart.offset) 3084 } : null; 3085 } 3086 function defaultGetChangesFromCRDTDoc(crdtDoc, editedRecord) { 3087 const docRecord = getRootMap(crdtDoc, CRDT_RECORD_MAP_KEY).toJSON(); 3088 return Object.fromEntries( 3089 Object.entries(docRecord).filter( 3090 ([key, newValue]) => haveValuesChanged(editedRecord?.[key], newValue) 3091 ) 3092 ); 3093 } 3094 function getPostChangesFromCRDTDoc(ydoc, editedRecord, syncedProperties) { 3095 const ymap = getRootMap(ydoc, CRDT_RECORD_MAP_KEY); 3096 let allowedMetaChanges = {}; 3097 const changes = Object.fromEntries( 3098 Object.entries(ymap.toJSON()).filter(([key, newValue]) => { 3099 if (!syncedProperties.has(key)) { 3100 return false; 3101 } 3102 const currentValue = editedRecord[key]; 3103 switch (key) { 3104 case "blocks": { 3105 if (ydoc.meta?.get(CRDT_DOC_META_PERSISTENCE_KEY) && editedRecord.content) { 3106 const blocksJson = ymap.get("blocks")?.toJSON() ?? []; 3107 return (0, import_blocks3.__unstableSerializeAndClean)(blocksJson).trim() !== getRawValue(editedRecord.content); 3108 } 3109 return true; 3110 } 3111 case "date": { 3112 const currentDateIsFloating = null === currentValue || editedRecord.modified === currentValue; 3113 if (currentDateIsFloating) { 3114 return false; 3115 } 3116 return haveValuesChanged(currentValue, newValue); 3117 } 3118 case "meta": { 3119 const currentMeta = currentValue ?? {}; 3120 allowedMetaChanges = Object.fromEntries( 3121 Object.entries(newValue ?? {}).filter( 3122 ([metaKey]) => { 3123 if (disallowedPostMetaKeys.has(metaKey)) { 3124 return false; 3125 } 3126 return metaKey in currentMeta; 3127 } 3128 ) 3129 ); 3130 const mergedValue = { 3131 ...currentMeta, 3132 ...allowedMetaChanges 3133 }; 3134 return haveValuesChanged(currentValue, mergedValue); 3135 } 3136 case "status": { 3137 if ("auto-draft" === newValue) { 3138 return false; 3139 } 3140 return haveValuesChanged(currentValue, newValue); 3141 } 3142 case "content": 3143 case "excerpt": 3144 case "title": { 3145 return haveValuesChanged( 3146 getRawValue(currentValue), 3147 newValue 3148 ); 3149 } 3150 // Add support for additional data types here. 3151 default: { 3152 return haveValuesChanged(currentValue, newValue); 3153 } 3154 } 3155 }) 3156 ); 3157 if (changes.blocks) { 3158 changes.blocks = deserializeBlockAttributes( 3159 changes.blocks 3160 ); 3161 } 3162 if (changes.blocks && !changes.content) { 3163 const capturedBlocks = changes.blocks; 3164 changes.content = () => (0, import_blocks3.__unstableSerializeAndClean)(capturedBlocks); 3165 } 3166 if ("object" === typeof changes.meta) { 3167 changes.meta = { 3168 ...editedRecord.meta, 3169 ...allowedMetaChanges 3170 }; 3171 } 3172 const selectionHistory = getSelectionHistory(ydoc); 3173 const shiftedSelection = getShiftedSelection(ydoc, selectionHistory); 3174 if (shiftedSelection) { 3175 changes.selection = { 3176 ...shiftedSelection, 3177 initialPosition: 0 3178 }; 3179 } 3180 return changes; 3181 } 3182 var defaultSyncConfig = { 3183 applyChangesToCRDTDoc: defaultApplyChangesToCRDTDoc, 3184 createAwareness: (ydoc) => new BaseAwareness(ydoc), 3185 getChangesFromCRDTDoc: defaultGetChangesFromCRDTDoc 3186 }; 3187 var defaultCollectionSyncConfig = { 3188 applyChangesToCRDTDoc: () => { 3189 }, 3190 getChangesFromCRDTDoc: () => ({}), 3191 shouldSync: (_, objectId) => null === objectId 3192 }; 3193 function getRawValue(value) { 3194 if ("string" === typeof value) { 3195 return value; 3196 } 3197 if (value && "object" === typeof value && "raw" in value && "string" === typeof value.raw) { 3198 return value.raw; 3199 } 3200 return void 0; 3201 } 3202 function haveValuesChanged(currentValue, newValue) { 3203 return !(0, import_es64.default)(currentValue, newValue); 3204 } 3205 function updateMapValue(map, key, currentValue, newValue) { 3206 if (void 0 === newValue) { 3207 map.delete(key); 3208 return; 3209 } 3210 if (haveValuesChanged(currentValue, newValue)) { 3211 map.set(key, newValue); 3212 } 3213 } 3214 3215 // packages/core-data/build-module/entities.mjs 3216 var DEFAULT_ENTITY_KEY = "id"; 3217 var POST_RAW_ATTRIBUTES = ["title", "excerpt", "content"]; 3218 var blocksTransientEdits = { 3219 blocks: { 3220 read: (record) => (0, import_blocks4.parse)(record.content?.raw ?? ""), 3221 write: (record) => ({ 3222 content: (0, import_blocks4.__unstableSerializeAndClean)(record.blocks) 3223 }) 3224 } 3225 }; 3226 var rootEntitiesConfig = [ 3227 { 3228 label: (0, import_i18n.__)("Base"), 3229 kind: "root", 3230 key: false, 3231 name: "__unstableBase", 3232 baseURL: "/", 3233 baseURLParams: { 3234 // Please also change the preload path when changing this. 3235 // @see lib/compat/wordpress-7.1/preload.php 3236 _fields: [ 3237 "description", 3238 "gmt_offset", 3239 "home", 3240 "image_max_bit_depth", 3241 "image_sizes", 3242 "image_size_threshold", 3243 "image_strip_meta", 3244 "name", 3245 "site_icon", 3246 "site_icon_url", 3247 "site_logo", 3248 "timezone_string", 3249 "url", 3250 "page_for_posts", 3251 "page_on_front", 3252 "show_on_front" 3253 ].join(",") 3254 }, 3255 // The entity doesn't support selecting multiple records. 3256 // The property is maintained for backward compatibility. 3257 plural: "__unstableBases", 3258 supportsPagination: false 3259 }, 3260 { 3261 label: (0, import_i18n.__)("Post Type"), 3262 name: "postType", 3263 kind: "root", 3264 key: "slug", 3265 baseURL: "/wp/v2/types", 3266 baseURLParams: { context: "edit" }, 3267 plural: "postTypes", 3268 supportsPagination: false 3269 }, 3270 { 3271 name: "media", 3272 kind: "root", 3273 baseURL: "/wp/v2/media", 3274 baseURLParams: { context: "edit" }, 3275 plural: "mediaItems", 3276 label: (0, import_i18n.__)("Media"), 3277 rawAttributes: ["caption", "title", "description"], 3278 supportsPagination: true 3279 }, 3280 { 3281 name: "taxonomy", 3282 kind: "root", 3283 key: "slug", 3284 baseURL: "/wp/v2/taxonomies", 3285 baseURLParams: { context: "edit" }, 3286 plural: "taxonomies", 3287 label: (0, import_i18n.__)("Taxonomy"), 3288 supportsPagination: false 3289 }, 3290 { 3291 name: "sidebar", 3292 kind: "root", 3293 baseURL: "/wp/v2/sidebars", 3294 baseURLParams: { context: "edit" }, 3295 plural: "sidebars", 3296 transientEdits: { blocks: true }, 3297 label: (0, import_i18n.__)("Widget areas"), 3298 supportsPagination: false 3299 }, 3300 { 3301 name: "widget", 3302 kind: "root", 3303 baseURL: "/wp/v2/widgets", 3304 baseURLParams: { context: "edit" }, 3305 plural: "widgets", 3306 transientEdits: { blocks: true }, 3307 label: (0, import_i18n.__)("Widgets"), 3308 supportsPagination: false 3309 }, 3310 { 3311 name: "widgetType", 3312 kind: "root", 3313 baseURL: "/wp/v2/widget-types", 3314 baseURLParams: { context: "edit" }, 3315 plural: "widgetTypes", 3316 label: (0, import_i18n.__)("Widget types"), 3317 supportsPagination: false 3318 }, 3319 { 3320 label: (0, import_i18n.__)("User"), 3321 name: "user", 3322 kind: "root", 3323 baseURL: "/wp/v2/users", 3324 getTitle: (record) => record?.name || record?.slug, 3325 baseURLParams: { context: "edit" }, 3326 plural: "users", 3327 supportsPagination: true 3328 }, 3329 { 3330 name: "comment", 3331 kind: "root", 3332 baseURL: "/wp/v2/comments", 3333 baseURLParams: { context: "edit" }, 3334 plural: "comments", 3335 label: (0, import_i18n.__)("Comment"), 3336 supportsPagination: true, 3337 ...globalThis.window?.__experimentalEnableRealTimeCollaboration ? { syncConfig: defaultCollectionSyncConfig } : {} 3338 }, 3339 { 3340 name: "menu", 3341 kind: "root", 3342 baseURL: "/wp/v2/menus", 3343 baseURLParams: { context: "edit" }, 3344 plural: "menus", 3345 label: (0, import_i18n.__)("Menu"), 3346 supportsPagination: true 3347 }, 3348 { 3349 name: "menuItem", 3350 kind: "root", 3351 baseURL: "/wp/v2/menu-items", 3352 baseURLParams: { context: "edit" }, 3353 plural: "menuItems", 3354 label: (0, import_i18n.__)("Menu Item"), 3355 rawAttributes: ["title"], 3356 supportsPagination: true 3357 }, 3358 { 3359 name: "menuLocation", 3360 kind: "root", 3361 baseURL: "/wp/v2/menu-locations", 3362 baseURLParams: { context: "edit" }, 3363 plural: "menuLocations", 3364 label: (0, import_i18n.__)("Menu Location"), 3365 key: "name", 3366 supportsPagination: false 3367 }, 3368 { 3369 label: (0, import_i18n.__)("Global Styles"), 3370 name: "globalStyles", 3371 kind: "root", 3372 baseURL: "/wp/v2/global-styles", 3373 baseURLParams: { context: "edit" }, 3374 plural: "globalStylesVariations", 3375 // Should be different from name. 3376 getTitle: () => (0, import_i18n.__)("Custom Styles"), 3377 getRevisionsUrl: (parentId, revisionId) => `/wp/v2/global-styles/$parentId}/revisions$revisionId ? "/" + revisionId : ""}`, 3378 supportsPagination: true 3379 }, 3380 { 3381 label: (0, import_i18n.__)("Themes"), 3382 name: "theme", 3383 kind: "root", 3384 baseURL: "/wp/v2/themes", 3385 baseURLParams: { context: "edit" }, 3386 plural: "themes", 3387 key: "stylesheet", 3388 supportsPagination: false 3389 }, 3390 { 3391 label: (0, import_i18n.__)("Plugins"), 3392 name: "plugin", 3393 kind: "root", 3394 baseURL: "/wp/v2/plugins", 3395 baseURLParams: { context: "edit" }, 3396 plural: "plugins", 3397 key: "plugin", 3398 supportsPagination: false 3399 }, 3400 { 3401 label: (0, import_i18n.__)("Status"), 3402 name: "status", 3403 kind: "root", 3404 baseURL: "/wp/v2/statuses", 3405 baseURLParams: { context: "edit" }, 3406 plural: "statuses", 3407 key: "slug", 3408 supportsPagination: false 3409 }, 3410 { 3411 label: (0, import_i18n.__)("Font Collections"), 3412 name: "fontCollection", 3413 kind: "root", 3414 baseURL: "/wp/v2/font-collections", 3415 baseURLParams: { context: "view" }, 3416 plural: "fontCollections", 3417 key: "slug", 3418 supportsPagination: true 3419 }, 3420 { 3421 label: (0, import_i18n.__)("Icons"), 3422 name: "icon", 3423 kind: "root", 3424 baseURL: "/wp/v2/icons", 3425 baseURLParams: { context: "view" }, 3426 plural: "icons", 3427 key: "name", 3428 supportsPagination: false 3429 }, 3430 { 3431 label: (0, import_i18n.__)("Icon Collections"), 3432 name: "iconCollection", 3433 kind: "root", 3434 baseURL: "/wp/v2/icon-collections", 3435 baseURLParams: { context: "view" }, 3436 plural: "iconCollections", 3437 key: "slug", 3438 supportsPagination: false 3439 } 3440 ]; 3441 var deprecatedEntities = { 3442 root: { 3443 media: { 3444 since: "6.9", 3445 alternative: { 3446 kind: "postType", 3447 name: "attachment" 3448 } 3449 } 3450 } 3451 }; 3452 var additionalEntityConfigLoaders = [ 3453 { kind: "postType", loadEntities: loadPostTypeEntities }, 3454 { kind: "taxonomy", loadEntities: loadTaxonomyEntities }, 3455 { 3456 kind: "root", 3457 name: "site", 3458 plural: "sites", 3459 loadEntities: loadSiteEntity 3460 } 3461 ]; 3462 var prePersistPostType = async (persistedRecord, edits, name, isTemplate) => { 3463 const newEdits = {}; 3464 if (!isTemplate && persistedRecord?.status === "auto-draft") { 3465 if (!edits.status && !newEdits.status) { 3466 newEdits.status = "draft"; 3467 } 3468 if ((!edits.title || edits.title === "Auto Draft") && !newEdits.title && (!persistedRecord?.title || persistedRecord?.title === "Auto Draft")) { 3469 newEdits.title = ""; 3470 } 3471 } 3472 if (window.__experimentalEnableRealTimeCollaboration && persistedRecord) { 3473 const objectType = `postType/$name}`; 3474 const objectId = persistedRecord.id; 3475 const serializedDoc = await getSyncManager()?.createPersistedCRDTDoc( 3476 objectType, 3477 objectId 3478 ); 3479 if (serializedDoc) { 3480 newEdits.meta = { 3481 ...edits.meta, 3482 [POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE]: serializedDoc 3483 }; 3484 } 3485 } 3486 return newEdits; 3487 }; 3488 async function loadPostTypeEntities() { 3489 const postTypesPromise = (0, import_api_fetch2.default)({ path: "/wp/v2/types?context=view" }); 3490 const taxonomiesPromise = window.__experimentalEnableRealTimeCollaboration ? (0, import_api_fetch2.default)({ path: "/wp/v2/taxonomies?context=view" }) : Promise.resolve({}); 3491 const [postTypes, taxonomies] = await Promise.all([ 3492 postTypesPromise, 3493 taxonomiesPromise 3494 ]); 3495 return Object.entries(postTypes ?? {}).map(([name, postType]) => { 3496 const isTemplate = ["wp_template", "wp_template_part"].includes( 3497 name 3498 ); 3499 const namespace = postType?.rest_namespace ?? "wp/v2"; 3500 const syncedProperties = /* @__PURE__ */ new Set([ 3501 "author", 3502 "blocks", 3503 "content", 3504 "comment_status", 3505 "date", 3506 "excerpt", 3507 "featured_media", 3508 "format", 3509 "meta", 3510 "ping_status", 3511 "slug", 3512 "status", 3513 "sticky", 3514 "template", 3515 "title", 3516 ...postType.taxonomies?.map((taxonomy) => taxonomies?.[taxonomy]?.rest_base)?.filter(Boolean) ?? [] 3517 ]); 3518 const entity2 = { 3519 kind: "postType", 3520 baseURL: `/$namespace}/$postType.rest_base}`, 3521 baseURLParams: { context: "edit" }, 3522 name, 3523 label: postType.name, 3524 transientEdits: { 3525 ...blocksTransientEdits, 3526 selection: true 3527 }, 3528 mergedEdits: { meta: true }, 3529 rawAttributes: POST_RAW_ATTRIBUTES, 3530 getTitle: (record) => record?.title?.rendered || record?.title || (isTemplate ? capitalCase(record.slug ?? "") : String(record.id)), 3531 __unstablePrePersist: (persistedRecord, edits) => prePersistPostType(persistedRecord, edits, name, isTemplate), 3532 __unstable_rest_base: postType.rest_base, 3533 // The templates controller returns the whole collection and never 3534 // paginates. 3535 supportsPagination: !isTemplate, 3536 getRevisionsUrl: (parentId, revisionId) => `/$namespace}/$postType.rest_base}/$parentId}/revisions$revisionId ? "/" + revisionId : ""}`, 3537 revisionKey: isTemplate ? "wp_id" : DEFAULT_ENTITY_KEY 3538 }; 3539 if (!window.__experimentalEnableRealTimeCollaboration) { 3540 return entity2; 3541 } 3542 entity2.syncConfig = { 3543 // Save a CRDT document with this entity 3544 supportsPersistence: true, 3545 /** 3546 * Apply changes from the local editor to the local CRDT document so 3547 * that those changes can be synced to other peers (via the provider). 3548 * 3549 * @param {import('@wordpress/sync').CRDTDoc} crdtDoc 3550 * @param {Partial< import('@wordpress/sync').ObjectData >} changes 3551 * @return {void} 3552 */ 3553 applyChangesToCRDTDoc: (crdtDoc, changes) => applyPostChangesToCRDTDoc(crdtDoc, changes, syncedProperties), 3554 /** 3555 * Create the awareness instance for the entity's CRDT document. 3556 * 3557 * @param {import('@wordpress/sync').CRDTDoc} ydoc 3558 * @param {import('@wordpress/sync').ObjectID} objectId 3559 * @return {import('@wordpress/sync').Awareness} Awareness instance 3560 */ 3561 createAwareness: (ydoc, objectId) => { 3562 const kind = "postType"; 3563 const id = parseInt(objectId, 10); 3564 return new PostEditorAwareness(ydoc, kind, name, id); 3565 }, 3566 /** 3567 * Extract changes from a CRDT document that can be used to update the 3568 * local editor state. 3569 * 3570 * @param {import('@wordpress/sync').CRDTDoc} crdtDoc 3571 * @param {import('@wordpress/sync').ObjectData} editedRecord 3572 * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record 3573 */ 3574 getChangesFromCRDTDoc: (crdtDoc, editedRecord) => getPostChangesFromCRDTDoc( 3575 crdtDoc, 3576 editedRecord, 3577 syncedProperties 3578 ), 3579 /** 3580 * Extract changes from a CRDT document that can be used to update the 3581 * local editor state. 3582 * 3583 * @param {import('@wordpress/sync').ObjectData} record 3584 * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record 3585 */ 3586 getPersistedCRDTDoc: (record) => { 3587 return record?.meta?.[POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE] || null; 3588 }, 3589 shouldSync: () => !(Array.isArray(window._wpCollaborationDisabledPostTypes) && window._wpCollaborationDisabledPostTypes.includes(name)) 3590 }; 3591 return entity2; 3592 }); 3593 } 3594 async function loadTaxonomyEntities() { 3595 const taxonomies = await (0, import_api_fetch2.default)({ 3596 path: "/wp/v2/taxonomies?context=view" 3597 }); 3598 return Object.entries(taxonomies ?? {}).map(([name, taxonomy]) => { 3599 const namespace = taxonomy?.rest_namespace ?? "wp/v2"; 3600 const entity2 = { 3601 kind: "taxonomy", 3602 baseURL: `/$namespace}/$taxonomy.rest_base}`, 3603 baseURLParams: { context: "edit" }, 3604 name, 3605 label: taxonomy.name, 3606 getTitle: (record) => record?.name, 3607 supportsPagination: true 3608 }; 3609 if (window.__experimentalEnableRealTimeCollaboration) { 3610 entity2.syncConfig = defaultSyncConfig; 3611 } 3612 return entity2; 3613 }); 3614 } 3615 async function loadSiteEntity() { 3616 const entity2 = { 3617 label: (0, import_i18n.__)("Site"), 3618 name: "site", 3619 kind: "root", 3620 key: false, 3621 baseURL: "/wp/v2/settings", 3622 supportsPagination: false, 3623 meta: {} 3624 }; 3625 const site = await (0, import_api_fetch2.default)({ 3626 path: entity2.baseURL, 3627 method: "OPTIONS" 3628 }); 3629 const labels = {}; 3630 Object.entries(site?.schema?.properties ?? {}).forEach( 3631 ([key, value]) => { 3632 if (typeof value === "object" && value.title) { 3633 labels[key] = value.title; 3634 } 3635 } 3636 ); 3637 return [{ ...entity2, meta: { labels } }]; 3638 } 3639 var getMethodName = (kind, name, prefix = "get") => { 3640 const kindPrefix = kind === "root" ? "" : pascalCase(kind); 3641 const suffix = pascalCase(name); 3642 return `$prefix}$kindPrefix}$suffix}`; 3643 }; 3644 3645 // packages/core-data/build-module/queried-data/reducer.mjs 3646 function getContextFromAction(action) { 3647 const { query } = action; 3648 if (!query) { 3649 return "default"; 3650 } 3651 const queryParts = get_query_parts_default(query); 3652 return queryParts.context; 3653 } 3654 function getMergedItemIds(itemIds = [], nextItemIds, { page = 1, offset, perPage = 10 } = {}) { 3655 if (perPage === -1) { 3656 return nextItemIds; 3657 } 3658 const nextItemIdsStartIndex = offset ?? (page - 1) * perPage; 3659 const nextItemIdsRange = Math.max(perPage, nextItemIds.length); 3660 const size = Math.max( 3661 itemIds.length, 3662 nextItemIdsStartIndex + nextItemIds.length 3663 ); 3664 const mergedItemIds = new Array(size); 3665 for (let i = 0; i < size; i++) { 3666 const isInNextItemsRange = i >= nextItemIdsStartIndex && i < nextItemIdsStartIndex + nextItemIdsRange; 3667 if (isInNextItemsRange) { 3668 mergedItemIds[i] = nextItemIds[i - nextItemIdsStartIndex]; 3669 } else { 3670 mergedItemIds[i] = itemIds[i]; 3671 } 3672 } 3673 return mergedItemIds; 3674 } 3675 function removeEntitiesById(entities2, ids) { 3676 return Object.fromEntries( 3677 Object.entries(entities2).filter( 3678 ([id]) => !ids.some((itemId) => { 3679 if (Number.isInteger(itemId)) { 3680 return itemId === +id; 3681 } 3682 return itemId === id; 3683 }) 3684 ) 3685 ); 3686 } 3687 function items(state = {}, action) { 3688 switch (action.type) { 3689 case "RECEIVE_ITEMS": { 3690 const context = getContextFromAction(action); 3691 const key = action.key || DEFAULT_ENTITY_KEY; 3692 const itemsList = Array.isArray(action.items) ? action.items : [action.items]; 3693 return { 3694 ...state, 3695 [context]: { 3696 ...state[context], 3697 ...Object.fromEntries( 3698 itemsList.map((item) => [ 3699 item?.[key], 3700 conservativeMapItem( 3701 state?.[context]?.[item?.[key]], 3702 item 3703 ) 3704 ]) 3705 ) 3706 } 3707 }; 3708 } 3709 case "REMOVE_ITEMS": 3710 return Object.fromEntries( 3711 Object.entries(state).map(([itemId, contextState]) => [ 3712 itemId, 3713 removeEntitiesById(contextState, action.itemIds) 3714 ]) 3715 ); 3716 } 3717 return state; 3718 } 3719 function itemIsComplete(state = {}, action) { 3720 switch (action.type) { 3721 case "RECEIVE_ITEMS": { 3722 const context = getContextFromAction(action); 3723 const { query, key = DEFAULT_ENTITY_KEY } = action; 3724 const itemsList = Array.isArray(action.items) ? action.items : [action.items]; 3725 const queryParts = query ? get_query_parts_default(query) : {}; 3726 const isCompleteQuery = !query || !Array.isArray(queryParts.fields); 3727 return { 3728 ...state, 3729 [context]: { 3730 ...state[context], 3731 ...itemsList.reduce((result, item) => { 3732 const itemId = item?.[key]; 3733 result[itemId] = state?.[context]?.[itemId] || isCompleteQuery; 3734 return result; 3735 }, {}) 3736 } 3737 }; 3738 } 3739 case "REMOVE_ITEMS": 3740 return Object.fromEntries( 3741 Object.entries(state).map(([itemId, contextState]) => [ 3742 itemId, 3743 removeEntitiesById(contextState, action.itemIds) 3744 ]) 3745 ); 3746 } 3747 return state; 3748 } 3749 var receiveQueries = (0, import_compose.compose)([ 3750 // Limit to matching action type so we don't attempt to replace action on 3751 // an unhandled action. 3752 if_matching_action_default((action) => "query" in action), 3753 // Inject query parts into action for use both in `keyedReducer` and reducer. 3754 replace_action_default((action) => { 3755 if (action.query) { 3756 return { 3757 ...action, 3758 ...get_query_parts_default(action.query) 3759 }; 3760 } 3761 return action; 3762 }), 3763 (0, import_data6.keyedReducer)("context"), 3764 // Queries shape is shared, but keyed by query `stableKey` part. Original 3765 // reducer tracks only a single query object. 3766 (0, import_data6.keyedReducer)("stableKey") 3767 ])((state = {}, action) => { 3768 if (action.type !== "RECEIVE_ITEMS") { 3769 return state; 3770 } 3771 if (!Array.isArray(action.items)) { 3772 return state; 3773 } 3774 const key = action.key ?? DEFAULT_ENTITY_KEY; 3775 return { 3776 itemIds: getMergedItemIds( 3777 state.itemIds, 3778 action.items.map((item) => item?.[key]).filter(Boolean), 3779 { 3780 page: action.page, 3781 offset: action.offset, 3782 perPage: action.perPage 3783 } 3784 ), 3785 meta: action.meta 3786 }; 3787 }); 3788 function removeQueryItems(queryItems, removedItems) { 3789 const itemIds = queryItems.itemIds.filter( 3790 (itemId) => !removedItems[itemId] 3791 ); 3792 const removedCount = queryItems.itemIds.length - itemIds.length; 3793 if (removedCount === 0) { 3794 return queryItems; 3795 } 3796 const nextQueryItems = { ...queryItems, itemIds }; 3797 if (Number.isFinite(queryItems.meta?.totalItems)) { 3798 nextQueryItems.meta = { 3799 ...queryItems.meta, 3800 totalItems: Math.max( 3801 0, 3802 queryItems.meta.totalItems - removedCount 3803 ), 3804 totalPages: null 3805 }; 3806 } 3807 return nextQueryItems; 3808 } 3809 var queries = (state = {}, action) => { 3810 switch (action.type) { 3811 case "RECEIVE_ITEMS": 3812 return receiveQueries(state, action); 3813 case "REMOVE_ITEMS": 3814 const removedItems = action.itemIds.reduce((result, itemId) => { 3815 result[itemId] = true; 3816 return result; 3817 }, {}); 3818 return Object.fromEntries( 3819 Object.entries(state).map( 3820 ([queryGroup, contextQueries]) => [ 3821 queryGroup, 3822 Object.fromEntries( 3823 Object.entries(contextQueries).map( 3824 ([query, queryItems]) => [ 3825 query, 3826 removeQueryItems( 3827 queryItems, 3828 removedItems 3829 ) 3830 ] 3831 ) 3832 ) 3833 ] 3834 ) 3835 ); 3836 default: 3837 return state; 3838 } 3839 }; 3840 var reducer_default = (0, import_data6.combineReducers)({ 3841 items, 3842 itemIsComplete, 3843 queries 3844 }); 3845 3846 // packages/core-data/build-module/reducer.mjs 3847 function users(state = { byId: {}, queries: {} }, action) { 3848 switch (action.type) { 3849 case "RECEIVE_USER_QUERY": 3850 return { 3851 byId: { 3852 ...state.byId, 3853 // Key users by their ID. 3854 ...action.users.reduce( 3855 (newUsers, user) => ({ 3856 ...newUsers, 3857 [user.id]: user 3858 }), 3859 {} 3860 ) 3861 }, 3862 queries: { 3863 ...state.queries, 3864 [action.queryID]: action.users.map((user) => user.id) 3865 } 3866 }; 3867 } 3868 return state; 3869 } 3870 function currentUser(state = {}, action) { 3871 switch (action.type) { 3872 case "RECEIVE_CURRENT_USER": 3873 return action.currentUser; 3874 } 3875 return state; 3876 } 3877 function currentTheme(state = void 0, action) { 3878 switch (action.type) { 3879 case "RECEIVE_CURRENT_THEME": 3880 return action.currentTheme.stylesheet; 3881 } 3882 return state; 3883 } 3884 function currentGlobalStylesId(state = void 0, action) { 3885 switch (action.type) { 3886 case "RECEIVE_CURRENT_GLOBAL_STYLES_ID": 3887 return action.id; 3888 } 3889 return state; 3890 } 3891 function themeBaseGlobalStyles(state = {}, action) { 3892 switch (action.type) { 3893 case "RECEIVE_THEME_GLOBAL_STYLES": 3894 return { 3895 ...state, 3896 [action.stylesheet]: action.globalStyles 3897 }; 3898 } 3899 return state; 3900 } 3901 function themeGlobalStyleVariations(state = {}, action) { 3902 switch (action.type) { 3903 case "RECEIVE_THEME_GLOBAL_STYLE_VARIATIONS": 3904 return { 3905 ...state, 3906 [action.stylesheet]: action.variations 3907 }; 3908 } 3909 return state; 3910 } 3911 var withMultiEntityRecordEdits = (reducer) => (state, action) => { 3912 if (action.type === "UNDO" || action.type === "REDO") { 3913 const { record } = action; 3914 let newState = state; 3915 record.forEach(({ id: { kind, name, recordId }, changes }) => { 3916 const persistedRecord = state?.queriedData?.items?.default?.[recordId]; 3917 const edits = Object.fromEntries( 3918 Object.entries(changes).map(([key, value]) => [ 3919 key, 3920 action.type === "UNDO" ? value.from : value.to 3921 ]) 3922 ); 3923 newState = reducer(newState, { 3924 type: "EDIT_ENTITY_RECORD", 3925 kind, 3926 name, 3927 recordId, 3928 // Clear edits matching the persisted record so the entity is 3929 // no longer dirty after undoing back to its saved state. 3930 edits: clearUnchangedEdits(edits, persistedRecord) 3931 }); 3932 }); 3933 return newState; 3934 } 3935 return reducer(state, action); 3936 }; 3937 function entity(entityConfig) { 3938 return (0, import_compose2.compose)([ 3939 withMultiEntityRecordEdits, 3940 // Limit to matching action type so we don't attempt to replace action on 3941 // an unhandled action. 3942 if_matching_action_default( 3943 (action) => action.name && action.kind && action.name === entityConfig.name && action.kind === entityConfig.kind 3944 ), 3945 // Inject the entity config into the action. 3946 replace_action_default((action) => { 3947 return { 3948 key: entityConfig.key || DEFAULT_ENTITY_KEY, 3949 ...action 3950 }; 3951 }) 3952 ])( 3953 (0, import_data7.combineReducers)({ 3954 queriedData: reducer_default, 3955 edits: (state = {}, action) => { 3956 switch (action.type) { 3957 case "RECEIVE_ITEMS": 3958 const context = action?.query?.context ?? "default"; 3959 if (context !== "default") { 3960 return state; 3961 } 3962 const nextState = { ...state }; 3963 const itemsList = Array.isArray(action.items) ? action.items : [action.items]; 3964 for (const record of itemsList) { 3965 const recordId = record?.[action.key]; 3966 const edits = nextState[recordId]; 3967 if (!edits) { 3968 continue; 3969 } 3970 const nextEdits2 = Object.keys(edits).reduce( 3971 (acc, key) => { 3972 if ( 3973 // Edits are the "raw" attribute values, but records may have 3974 // objects with more properties, so we use `get` here for the 3975 // comparison. 3976 !(0, import_es65.default)( 3977 edits[key], 3978 record[key]?.raw ?? record[key] 3979 ) && // Sometimes the server alters the sent value which means 3980 // we need to also remove the edits before the api request. 3981 (!action.persistedEdits || !(0, import_es65.default)( 3982 edits[key], 3983 action.persistedEdits[key] 3984 )) 3985 ) { 3986 acc[key] = edits[key]; 3987 } 3988 return acc; 3989 }, 3990 {} 3991 ); 3992 if (Object.keys(nextEdits2).length) { 3993 nextState[recordId] = nextEdits2; 3994 } else { 3995 delete nextState[recordId]; 3996 } 3997 } 3998 return nextState; 3999 case "EDIT_ENTITY_RECORD": 4000 const nextEdits = { 4001 ...state[action.recordId], 4002 ...action.edits 4003 }; 4004 Object.keys(nextEdits).forEach((key) => { 4005 if (nextEdits[key] === void 0) { 4006 delete nextEdits[key]; 4007 } 4008 }); 4009 return { 4010 ...state, 4011 [action.recordId]: nextEdits 4012 }; 4013 } 4014 return state; 4015 }, 4016 saving: (state = {}, action) => { 4017 switch (action.type) { 4018 case "SAVE_ENTITY_RECORD_START": 4019 case "SAVE_ENTITY_RECORD_FINISH": 4020 return { 4021 ...state, 4022 [action.recordId]: { 4023 pending: action.type === "SAVE_ENTITY_RECORD_START", 4024 error: action.error, 4025 isAutosave: action.isAutosave 4026 } 4027 }; 4028 } 4029 return state; 4030 }, 4031 deleting: (state = {}, action) => { 4032 switch (action.type) { 4033 case "DELETE_ENTITY_RECORD_START": 4034 case "DELETE_ENTITY_RECORD_FINISH": 4035 return { 4036 ...state, 4037 [action.recordId]: { 4038 pending: action.type === "DELETE_ENTITY_RECORD_START", 4039 error: action.error 4040 } 4041 }; 4042 } 4043 return state; 4044 }, 4045 revisions: (state = {}, action) => { 4046 if (action.type === "RECEIVE_ITEM_REVISIONS") { 4047 const recordKey = action.recordKey; 4048 delete action.recordKey; 4049 const newState = reducer_default(state[recordKey], { 4050 ...action, 4051 type: "RECEIVE_ITEMS" 4052 }); 4053 return { 4054 ...state, 4055 [recordKey]: newState 4056 }; 4057 } 4058 if (action.type === "REMOVE_ITEMS") { 4059 return Object.fromEntries( 4060 Object.entries(state).filter( 4061 ([id]) => !action.itemIds.some((itemId) => { 4062 if (Number.isInteger(itemId)) { 4063 return itemId === +id; 4064 } 4065 return itemId === id; 4066 }) 4067 ) 4068 ); 4069 } 4070 return state; 4071 } 4072 }) 4073 ); 4074 } 4075 function entitiesConfig(state = rootEntitiesConfig, action) { 4076 switch (action.type) { 4077 case "ADD_ENTITIES": 4078 return [...state, ...action.entities]; 4079 } 4080 return state; 4081 } 4082 var entities = (state = {}, action) => { 4083 const newConfig = entitiesConfig(state.config, action); 4084 let entitiesDataReducer = state.reducer; 4085 if (!entitiesDataReducer || newConfig !== state.config) { 4086 const entitiesByKind = newConfig.reduce((acc, record) => { 4087 const { kind } = record; 4088 if (!acc[kind]) { 4089 acc[kind] = []; 4090 } 4091 acc[kind].push(record); 4092 return acc; 4093 }, {}); 4094 entitiesDataReducer = (0, import_data7.combineReducers)( 4095 Object.fromEntries( 4096 Object.entries(entitiesByKind).map( 4097 ([kind, subEntities]) => { 4098 const kindReducer = (0, import_data7.combineReducers)( 4099 Object.fromEntries( 4100 subEntities.map((entityConfig) => [ 4101 entityConfig.name, 4102 entity(entityConfig) 4103 ]) 4104 ) 4105 ); 4106 return [kind, kindReducer]; 4107 } 4108 ) 4109 ) 4110 ); 4111 } 4112 const newData = entitiesDataReducer(state.records, action); 4113 if (newData === state.records && newConfig === state.config && entitiesDataReducer === state.reducer) { 4114 return state; 4115 } 4116 return { 4117 reducer: entitiesDataReducer, 4118 records: newData, 4119 config: newConfig 4120 }; 4121 }; 4122 function undoManager(state = (0, import_undo_manager.createUndoManager)()) { 4123 return state; 4124 } 4125 function syncUndoManagerState(state = { hasRedo: false, hasUndo: false }, action) { 4126 switch (action.type) { 4127 case "SYNC_UNDO_MANAGER_CHANGE": 4128 return { 4129 hasRedo: action.hasRedo, 4130 hasUndo: action.hasUndo 4131 }; 4132 } 4133 return state; 4134 } 4135 function editsReference(state = {}, action) { 4136 switch (action.type) { 4137 case "EDIT_ENTITY_RECORD": 4138 case "UNDO": 4139 case "REDO": 4140 return {}; 4141 } 4142 return state; 4143 } 4144 function embedPreviews(state = {}, action) { 4145 switch (action.type) { 4146 case "RECEIVE_EMBED_PREVIEW": 4147 const { url, preview } = action; 4148 return { 4149 ...state, 4150 [url]: preview 4151 }; 4152 } 4153 return state; 4154 } 4155 function userPermissions(state = {}, action) { 4156 switch (action.type) { 4157 case "RECEIVE_USER_PERMISSION": 4158 return { 4159 ...state, 4160 [action.key]: action.isAllowed 4161 }; 4162 case "RECEIVE_USER_PERMISSIONS": 4163 return { 4164 ...state, 4165 ...action.permissions 4166 }; 4167 } 4168 return state; 4169 } 4170 function autosaves(state = {}, action) { 4171 switch (action.type) { 4172 case "RECEIVE_AUTOSAVES": 4173 const { postId, autosaves: autosavesData } = action; 4174 return { 4175 ...state, 4176 [postId]: autosavesData 4177 }; 4178 } 4179 return state; 4180 } 4181 function blockPatterns(state = [], action) { 4182 switch (action.type) { 4183 case "RECEIVE_BLOCK_PATTERNS": 4184 return action.patterns; 4185 } 4186 return state; 4187 } 4188 function blockPatternCategories(state = [], action) { 4189 switch (action.type) { 4190 case "RECEIVE_BLOCK_PATTERN_CATEGORIES": 4191 return action.categories; 4192 } 4193 return state; 4194 } 4195 function userPatternCategories(state = [], action) { 4196 switch (action.type) { 4197 case "RECEIVE_USER_PATTERN_CATEGORIES": 4198 return action.patternCategories; 4199 } 4200 return state; 4201 } 4202 function navigationFallbackId(state = null, action) { 4203 switch (action.type) { 4204 case "RECEIVE_NAVIGATION_FALLBACK_ID": 4205 return action.fallbackId; 4206 } 4207 return state; 4208 } 4209 function themeGlobalStyleRevisions(state = {}, action) { 4210 switch (action.type) { 4211 case "RECEIVE_THEME_GLOBAL_STYLE_REVISIONS": 4212 return { 4213 ...state, 4214 [action.currentId]: action.revisions 4215 }; 4216 } 4217 return state; 4218 } 4219 function defaultTemplates(state = {}, action) { 4220 switch (action.type) { 4221 case "RECEIVE_DEFAULT_TEMPLATE": 4222 return { 4223 ...state, 4224 [JSON.stringify(action.query)]: action.templateId 4225 }; 4226 } 4227 return state; 4228 } 4229 function registeredPostMeta(state = {}, action) { 4230 switch (action.type) { 4231 case "RECEIVE_REGISTERED_POST_META": 4232 return { 4233 ...state, 4234 [action.postType]: action.registeredPostMeta 4235 }; 4236 } 4237 return state; 4238 } 4239 function editorSettings(state = null, action) { 4240 switch (action.type) { 4241 case "RECEIVE_EDITOR_SETTINGS": 4242 return action.settings; 4243 } 4244 return state; 4245 } 4246 function editorAssets(state = null, action) { 4247 switch (action.type) { 4248 case "RECEIVE_EDITOR_ASSETS": 4249 return action.assets; 4250 } 4251 return state; 4252 } 4253 function syncConnectionStatuses(state = {}, action) { 4254 switch (action.type) { 4255 case "SET_SYNC_CONNECTION_STATUS": { 4256 const key = `$action.kind}/$action.name}:$action.key}`; 4257 return { 4258 ...state, 4259 [key]: action.status 4260 }; 4261 } 4262 case "CLEAR_SYNC_CONNECTION_STATUS": { 4263 const key = `$action.kind}/$action.name}:$action.key}`; 4264 const { [key]: _, ...rest } = state; 4265 return rest; 4266 } 4267 } 4268 return state; 4269 } 4270 function collaborationSupported(state = true, action) { 4271 switch (action.type) { 4272 case "SET_COLLABORATION_SUPPORTED": 4273 return action.supported; 4274 case "SET_SYNC_CONNECTION_STATUS": 4275 if (ConnectionErrorCode.DOCUMENT_SIZE_LIMIT_EXCEEDED === action.status?.error?.code) { 4276 return false; 4277 } 4278 return state; 4279 } 4280 return state; 4281 } 4282 function viewConfigs(state = {}, action) { 4283 switch (action.type) { 4284 case "RECEIVE_VIEW_CONFIG": { 4285 const key = `$action.kind}/$action.name}`; 4286 return { 4287 ...state, 4288 [key]: { 4289 ...state[key], 4290 ...action.config 4291 } 4292 }; 4293 } 4294 } 4295 return state; 4296 } 4297 var reducer_default2 = (0, import_data7.combineReducers)({ 4298 users, 4299 currentTheme, 4300 currentGlobalStylesId, 4301 currentUser, 4302 themeGlobalStyleVariations, 4303 themeBaseGlobalStyles, 4304 themeGlobalStyleRevisions, 4305 entities, 4306 editsReference, 4307 syncUndoManagerState, 4308 undoManager, 4309 embedPreviews, 4310 userPermissions, 4311 autosaves, 4312 blockPatterns, 4313 blockPatternCategories, 4314 userPatternCategories, 4315 navigationFallbackId, 4316 defaultTemplates, 4317 registeredPostMeta, 4318 editorSettings, 4319 editorAssets, 4320 syncConnectionStatuses, 4321 collaborationSupported, 4322 viewConfigs 4323 }); 4324 4325 // packages/core-data/build-module/selectors.mjs 4326 var selectors_exports = {}; 4327 __export(selectors_exports, { 4328 __experimentalGetCurrentGlobalStylesId: () => __experimentalGetCurrentGlobalStylesId, 4329 __experimentalGetCurrentThemeBaseGlobalStyles: () => __experimentalGetCurrentThemeBaseGlobalStyles, 4330 __experimentalGetCurrentThemeGlobalStylesVariations: () => __experimentalGetCurrentThemeGlobalStylesVariations, 4331 __experimentalGetDirtyEntityRecords: () => __experimentalGetDirtyEntityRecords, 4332 __experimentalGetEntitiesBeingSaved: () => __experimentalGetEntitiesBeingSaved, 4333 __experimentalGetEntityRecordNoResolver: () => __experimentalGetEntityRecordNoResolver, 4334 canUser: () => canUser, 4335 canUserEditEntityRecord: () => canUserEditEntityRecord, 4336 getAuthors: () => getAuthors, 4337 getAutosave: () => getAutosave, 4338 getAutosaves: () => getAutosaves, 4339 getBlockPatternCategories: () => getBlockPatternCategories, 4340 getBlockPatterns: () => getBlockPatterns, 4341 getCurrentTheme: () => getCurrentTheme, 4342 getCurrentThemeGlobalStylesRevisions: () => getCurrentThemeGlobalStylesRevisions, 4343 getCurrentUser: () => getCurrentUser, 4344 getDefaultTemplateId: () => getDefaultTemplateId, 4345 getEditedEntityRecord: () => getEditedEntityRecord, 4346 getEmbedPreview: () => getEmbedPreview, 4347 getEntitiesByKind: () => getEntitiesByKind, 4348 getEntitiesConfig: () => getEntitiesConfig, 4349 getEntity: () => getEntity, 4350 getEntityConfig: () => getEntityConfig, 4351 getEntityRecord: () => getEntityRecord, 4352 getEntityRecordEdits: () => getEntityRecordEdits, 4353 getEntityRecordNonTransientEdits: () => getEntityRecordNonTransientEdits, 4354 getEntityRecords: () => getEntityRecords, 4355 getEntityRecordsTotalItems: () => getEntityRecordsTotalItems, 4356 getEntityRecordsTotalPages: () => getEntityRecordsTotalPages, 4357 getLastEntityDeleteError: () => getLastEntityDeleteError, 4358 getLastEntitySaveError: () => getLastEntitySaveError, 4359 getRawEntityRecord: () => getRawEntityRecord, 4360 getRedoEdit: () => getRedoEdit, 4361 getReferenceByDistinctEdits: () => getReferenceByDistinctEdits, 4362 getRevision: () => getRevision, 4363 getRevisions: () => getRevisions, 4364 getThemeSupports: () => getThemeSupports, 4365 getUndoEdit: () => getUndoEdit, 4366 getUserPatternCategories: () => getUserPatternCategories, 4367 getUserQueryResults: () => getUserQueryResults, 4368 hasEditsForEntityRecord: () => hasEditsForEntityRecord, 4369 hasEntityRecord: () => hasEntityRecord, 4370 hasEntityRecords: () => hasEntityRecords, 4371 hasFetchedAutosaves: () => hasFetchedAutosaves, 4372 hasRedo: () => hasRedo, 4373 hasRevision: () => hasRevision, 4374 hasUndo: () => hasUndo, 4375 isAutosavingEntityRecord: () => isAutosavingEntityRecord, 4376 isDeletingEntityRecord: () => isDeletingEntityRecord, 4377 isPreviewEmbedFallback: () => isPreviewEmbedFallback, 4378 isRequestingEmbedPreview: () => isRequestingEmbedPreview, 4379 isSavingEntityRecord: () => isSavingEntityRecord 4380 }); 4381 var import_data9 = __toESM(require_data(), 1); 4382 var import_url2 = __toESM(require_url(), 1); 4383 var import_deprecated2 = __toESM(require_deprecated(), 1); 4384 4385 // packages/core-data/build-module/private-selectors.mjs 4386 var private_selectors_exports = {}; 4387 __export(private_selectors_exports, { 4388 getBlockPatternsForPostType: () => getBlockPatternsForPostType, 4389 getEditorAssets: () => getEditorAssets, 4390 getEditorSettings: () => getEditorSettings, 4391 getEntityRecordPermissions: () => getEntityRecordPermissions, 4392 getEntityRecordsPermissions: () => getEntityRecordsPermissions, 4393 getEntitySyncConnectionStatus: () => getEntitySyncConnectionStatus, 4394 getHomePage: () => getHomePage, 4395 getNavigationFallbackId: () => getNavigationFallbackId, 4396 getPostsPageId: () => getPostsPageId, 4397 getRegisteredPostMeta: () => getRegisteredPostMeta, 4398 getSyncConnectionStatus: () => getSyncConnectionStatus, 4399 getTemplateId: () => getTemplateId, 4400 getUndoManager: () => getUndoManager, 4401 getViewConfig: () => getViewConfig, 4402 isCollaborationSupported: () => isCollaborationSupported 4403 }); 4404 var import_data8 = __toESM(require_data(), 1); 4405 4406 // packages/core-data/build-module/utils/log-entity-deprecation.mjs 4407 var import_deprecated = __toESM(require_deprecated(), 1); 4408 var loggedAlready = false; 4409 function logEntityDeprecation(kind, name, functionName, { 4410 alternativeFunctionName, 4411 isShorthandSelector = false 4412 } = {}) { 4413 const deprecation = deprecatedEntities[kind]?.[name]; 4414 if (!deprecation) { 4415 return; 4416 } 4417 if (!loggedAlready) { 4418 const { alternative } = deprecation; 4419 const message = isShorthandSelector ? `'$functionName}'` : `The '$kind}', '$name}' entity (used via '$functionName}')`; 4420 let alternativeMessage = `the '$alternative.kind}', '$alternative.name}' entity`; 4421 if (alternativeFunctionName) { 4422 alternativeMessage += ` via the '$alternativeFunctionName}' function`; 4423 } 4424 (0, import_deprecated.default)(message, { 4425 ...deprecation, 4426 alternative: alternativeMessage 4427 }); 4428 } 4429 loggedAlready = true; 4430 setTimeout(() => { 4431 loggedAlready = false; 4432 }, 0); 4433 } 4434 4435 // packages/core-data/build-module/private-selectors.mjs 4436 var EMPTY_OBJECT = {}; 4437 function getUndoManager(state) { 4438 return getSyncManager()?.undoManager ?? state.undoManager; 4439 } 4440 function getNavigationFallbackId(state) { 4441 return state.navigationFallbackId; 4442 } 4443 var getBlockPatternsForPostType = (0, import_data8.createRegistrySelector)( 4444 (select5) => (0, import_data8.createSelector)( 4445 (state, postType) => select5(STORE_NAME).getBlockPatterns().filter( 4446 ({ postTypes }) => !postTypes || Array.isArray(postTypes) && postTypes.includes(postType) 4447 ), 4448 () => [select5(STORE_NAME).getBlockPatterns()] 4449 ) 4450 ); 4451 var getEntityRecordsPermissions = (0, import_data8.createRegistrySelector)( 4452 (select5) => (0, import_data8.createSelector)( 4453 (state, kind, name, ids) => { 4454 const normalizedIds = Array.isArray(ids) ? ids : [ids]; 4455 return normalizedIds.map((id) => ({ 4456 delete: select5(STORE_NAME).canUser("delete", { 4457 kind, 4458 name, 4459 id 4460 }), 4461 update: select5(STORE_NAME).canUser("update", { 4462 kind, 4463 name, 4464 id 4465 }) 4466 })); 4467 }, 4468 (state) => [state.userPermissions] 4469 ) 4470 ); 4471 function getEntityRecordPermissions(state, kind, name, id) { 4472 logEntityDeprecation(kind, name, "getEntityRecordPermissions"); 4473 return getEntityRecordsPermissions(state, kind, name, id)[0]; 4474 } 4475 function getRegisteredPostMeta(state, postType) { 4476 return state.registeredPostMeta?.[postType] ?? {}; 4477 } 4478 function normalizePageId(value) { 4479 if (!value || !["number", "string"].includes(typeof value)) { 4480 return null; 4481 } 4482 if (Number(value) === 0) { 4483 return null; 4484 } 4485 return value.toString(); 4486 } 4487 var getHomePage = (0, import_data8.createRegistrySelector)( 4488 (select5) => (0, import_data8.createSelector)( 4489 () => { 4490 const siteData = select5(STORE_NAME).getEntityRecord( 4491 "root", 4492 "__unstableBase" 4493 ); 4494 if (!siteData) { 4495 return null; 4496 } 4497 const homepageId = siteData?.show_on_front === "page" ? normalizePageId(siteData.page_on_front) : null; 4498 if (homepageId) { 4499 return { postType: "page", postId: homepageId }; 4500 } 4501 const frontPageTemplateId = select5( 4502 STORE_NAME 4503 ).getDefaultTemplateId({ 4504 slug: "front-page" 4505 }); 4506 if (frontPageTemplateId) { 4507 return { 4508 postType: "wp_template", 4509 postId: frontPageTemplateId 4510 }; 4511 } 4512 if (frontPageTemplateId === "") { 4513 return EMPTY_OBJECT; 4514 } 4515 return null; 4516 }, 4517 (state) => [ 4518 // Even though getDefaultTemplateId.shouldInvalidate returns true when root/site changes, 4519 // it doesn't seem to invalidate this cache, I'm not sure why. 4520 getEntityRecord(state, "root", "site"), 4521 getEntityRecord(state, "root", "__unstableBase"), 4522 getDefaultTemplateId(state, { 4523 slug: "front-page" 4524 }) 4525 ] 4526 ) 4527 ); 4528 var getPostsPageId = (0, import_data8.createRegistrySelector)((select5) => () => { 4529 const siteData = select5(STORE_NAME).getEntityRecord( 4530 "root", 4531 "__unstableBase" 4532 ); 4533 return siteData?.show_on_front === "page" ? normalizePageId(siteData.page_for_posts) : null; 4534 }); 4535 var getTemplateId = (0, import_data8.createRegistrySelector)( 4536 (select5) => (state, postType, postId) => { 4537 const homepage = unlock(select5(STORE_NAME)).getHomePage(); 4538 if (!homepage) { 4539 return; 4540 } 4541 if (postType === "page" && postType === homepage?.postType && postId.toString() === homepage?.postId) { 4542 const templates = select5(STORE_NAME).getEntityRecords( 4543 "postType", 4544 "wp_template", 4545 { 4546 per_page: -1 4547 } 4548 ); 4549 if (!templates) { 4550 return; 4551 } 4552 const id = templates.find(({ slug }) => slug === "front-page")?.id; 4553 if (id) { 4554 return id; 4555 } 4556 } 4557 const editedEntity = select5(STORE_NAME).getEditedEntityRecord( 4558 "postType", 4559 postType, 4560 postId 4561 ); 4562 if (!editedEntity) { 4563 return; 4564 } 4565 const postsPageId = unlock(select5(STORE_NAME)).getPostsPageId(); 4566 if (postType === "page" && postsPageId === postId.toString()) { 4567 return select5(STORE_NAME).getDefaultTemplateId({ 4568 slug: "home" 4569 }); 4570 } 4571 const currentTemplateSlug = editedEntity.template; 4572 if (currentTemplateSlug) { 4573 const currentTemplate = select5(STORE_NAME).getEntityRecords("postType", "wp_template", { 4574 per_page: -1 4575 })?.find(({ slug }) => slug === currentTemplateSlug); 4576 if (currentTemplate) { 4577 return currentTemplate.id; 4578 } 4579 } 4580 let slugToCheck; 4581 if (editedEntity.slug) { 4582 slugToCheck = postType === "page" ? `$postType}-$editedEntity.slug}` : `single-$postType}-$editedEntity.slug}`; 4583 } else { 4584 slugToCheck = postType === "page" ? "page" : `single-$postType}`; 4585 } 4586 return select5(STORE_NAME).getDefaultTemplateId({ 4587 slug: slugToCheck 4588 }); 4589 } 4590 ); 4591 function getEditorSettings(state) { 4592 return state.editorSettings; 4593 } 4594 function getEditorAssets(state) { 4595 return state.editorAssets; 4596 } 4597 function isCollaborationSupported(state) { 4598 return state.collaborationSupported; 4599 } 4600 function getViewConfig(state, kind, name) { 4601 return state.viewConfigs?.[`$kind}/$name}`] ?? { 4602 default_view: void 0, 4603 default_layouts: void 0, 4604 view_list: void 0, 4605 form: void 0 4606 }; 4607 } 4608 function getSyncConnectionStatus(state) { 4609 if (!state.syncConnectionStatuses) { 4610 return void 0; 4611 } 4612 const PRIORITIZED_STATUSES = ["disconnected", "connecting", "connected"]; 4613 let coalesced; 4614 for (const status of Object.values(state.syncConnectionStatuses)) { 4615 if (!coalesced || PRIORITIZED_STATUSES.indexOf(status.status) < PRIORITIZED_STATUSES.indexOf(coalesced.status)) { 4616 coalesced = status; 4617 } 4618 } 4619 return coalesced; 4620 } 4621 function getEntitySyncConnectionStatus(state, kind, name, recordId) { 4622 return state.syncConnectionStatuses?.[`$kind}/$name}:$recordId}`]; 4623 } 4624 4625 // packages/core-data/build-module/selectors.mjs 4626 var EMPTY_OBJECT2 = {}; 4627 var isRequestingEmbedPreview = (0, import_data9.createRegistrySelector)( 4628 (select5) => (state, url) => { 4629 return select5(STORE_NAME).isResolving("getEmbedPreview", [ 4630 url 4631 ]); 4632 } 4633 ); 4634 function getAuthors(state, query) { 4635 (0, import_deprecated2.default)("select( 'core' ).getAuthors()", { 4636 since: "5.9", 4637 alternative: "select( 'core' ).getUsers({ who: 'authors' })" 4638 }); 4639 const path = (0, import_url2.addQueryArgs)( 4640 "/wp/v2/users/?who=authors&per_page=100", 4641 query 4642 ); 4643 return getUserQueryResults(state, path); 4644 } 4645 function getCurrentUser(state) { 4646 return state.currentUser; 4647 } 4648 var getUserQueryResults = (0, import_data9.createSelector)( 4649 (state, queryID) => { 4650 const queryResults = state.users.queries[queryID] ?? []; 4651 return queryResults.map((id) => state.users.byId[id]); 4652 }, 4653 (state, queryID) => [ 4654 state.users.queries[queryID], 4655 state.users.byId 4656 ] 4657 ); 4658 function getEntitiesByKind(state, kind) { 4659 (0, import_deprecated2.default)("wp.data.select( 'core' ).getEntitiesByKind()", { 4660 since: "6.0", 4661 alternative: "wp.data.select( 'core' ).getEntitiesConfig()" 4662 }); 4663 return getEntitiesConfig(state, kind); 4664 } 4665 var getEntitiesConfig = (0, import_data9.createSelector)( 4666 (state, kind) => state.entities.config.filter((entity2) => entity2.kind === kind), 4667 /* eslint-disable @typescript-eslint/no-unused-vars */ 4668 (state, kind) => state.entities.config 4669 /* eslint-enable @typescript-eslint/no-unused-vars */ 4670 ); 4671 function getEntity(state, kind, name) { 4672 (0, import_deprecated2.default)("wp.data.select( 'core' ).getEntity()", { 4673 since: "6.0", 4674 alternative: "wp.data.select( 'core' ).getEntityConfig()" 4675 }); 4676 return getEntityConfig(state, kind, name); 4677 } 4678 function getEntityConfig(state, kind, name) { 4679 logEntityDeprecation(kind, name, "getEntityConfig"); 4680 return state.entities.config?.find( 4681 (config) => config.kind === kind && config.name === name 4682 ); 4683 } 4684 var getEntityRecord = ((state, kind, name, recordId, query) => { 4685 logEntityDeprecation(kind, name, "getEntityRecord"); 4686 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 4687 if (!queriedState) { 4688 return void 0; 4689 } 4690 const context = query?.context ?? "default"; 4691 if (!query || !query._fields) { 4692 if (!queriedState.itemIsComplete[context]?.[recordId]) { 4693 return void 0; 4694 } 4695 return queriedState.items[context][recordId]; 4696 } 4697 const item = queriedState.items[context]?.[recordId]; 4698 if (!item) { 4699 return item; 4700 } 4701 return getFilteredItem(item, query._fields); 4702 }); 4703 getEntityRecord.__unstableNormalizeArgs = (args) => { 4704 const newArgs = [...args]; 4705 const recordKey = newArgs?.[2]; 4706 newArgs[2] = isNumericID(recordKey) ? Number(recordKey) : recordKey; 4707 return newArgs; 4708 }; 4709 function hasEntityRecord(state, kind, name, recordId, query) { 4710 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 4711 if (!queriedState) { 4712 return false; 4713 } 4714 const context = query?.context ?? "default"; 4715 if (!query || !query._fields) { 4716 return !!queriedState.itemIsComplete[context]?.[recordId]; 4717 } 4718 const item = queriedState.items[context]?.[recordId]; 4719 if (!item) { 4720 return false; 4721 } 4722 const fields = get_normalized_comma_separable_default(query._fields) ?? []; 4723 for (let i = 0; i < fields.length; i++) { 4724 const path = fields[i].split("."); 4725 let value = item; 4726 for (let p = 0; p < path.length; p++) { 4727 const part = path[p]; 4728 if (!value || !Object.hasOwn(value, part)) { 4729 return false; 4730 } 4731 value = value[part]; 4732 } 4733 } 4734 return true; 4735 } 4736 function __experimentalGetEntityRecordNoResolver(state, kind, name, recordId) { 4737 return getEntityRecord(state, kind, name, recordId); 4738 } 4739 var getRawEntityRecord = (0, import_data9.createSelector)( 4740 (state, kind, name, recordId) => { 4741 logEntityDeprecation(kind, name, "getRawEntityRecord"); 4742 const record = getEntityRecord( 4743 state, 4744 kind, 4745 name, 4746 recordId 4747 ); 4748 const config = getEntityConfig(state, kind, name); 4749 if (!record || !config?.rawAttributes?.length) { 4750 return record; 4751 } 4752 return Object.fromEntries( 4753 Object.keys(record).map((key) => { 4754 if (config.rawAttributes.includes(key)) { 4755 const rawValue = record[key]?.raw; 4756 return [ 4757 key, 4758 rawValue !== void 0 ? rawValue : record[key] 4759 ]; 4760 } 4761 return [key, record[key]]; 4762 }) 4763 ); 4764 }, 4765 (state, kind, name, recordId, query) => { 4766 const context = query?.context ?? "default"; 4767 return [ 4768 state.entities.config, 4769 state.entities.records?.[kind]?.[name]?.queriedData?.items[context]?.[recordId], 4770 state.entities.records?.[kind]?.[name]?.queriedData?.itemIsComplete[context]?.[recordId] 4771 ]; 4772 } 4773 ); 4774 function hasEntityRecords(state, kind, name, query) { 4775 logEntityDeprecation(kind, name, "hasEntityRecords"); 4776 return Array.isArray(getEntityRecords(state, kind, name, query)); 4777 } 4778 var getEntityRecords = ((state, kind, name, query) => { 4779 logEntityDeprecation(kind, name, "getEntityRecords"); 4780 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 4781 if (!queriedState) { 4782 return null; 4783 } 4784 return getQueriedItems(queriedState, query, { 4785 supportsPagination: !!getEntityConfig(state, kind, name)?.supportsPagination 4786 }); 4787 }); 4788 var getEntityRecordsTotalItems = (state, kind, name, query) => { 4789 logEntityDeprecation(kind, name, "getEntityRecordsTotalItems"); 4790 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 4791 if (!queriedState) { 4792 return null; 4793 } 4794 return getQueriedTotalItems(queriedState, query); 4795 }; 4796 var getEntityRecordsTotalPages = (state, kind, name, query) => { 4797 logEntityDeprecation(kind, name, "getEntityRecordsTotalPages"); 4798 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 4799 if (!queriedState) { 4800 return null; 4801 } 4802 if (!getEntityConfig(state, kind, name)?.supportsPagination || query?.per_page === -1) { 4803 return 1; 4804 } 4805 const totalItems = getQueriedTotalItems(queriedState, query); 4806 if (!totalItems) { 4807 return totalItems; 4808 } 4809 if (!query?.per_page) { 4810 return getQueriedTotalPages(queriedState, query); 4811 } 4812 return Math.ceil(totalItems / query.per_page); 4813 }; 4814 var __experimentalGetDirtyEntityRecords = (0, import_data9.createSelector)( 4815 (state) => { 4816 const { 4817 entities: { records } 4818 } = state; 4819 const dirtyRecords = []; 4820 Object.keys(records).forEach((kind) => { 4821 Object.keys(records[kind]).forEach((name) => { 4822 const primaryKeys = Object.keys(records[kind][name].edits).filter( 4823 (primaryKey) => ( 4824 // The entity record must exist (not be deleted), 4825 // and it must have edits. 4826 getEntityRecord(state, kind, name, primaryKey) && hasEditsForEntityRecord(state, kind, name, primaryKey) 4827 ) 4828 ); 4829 if (primaryKeys.length) { 4830 const entityConfig = getEntityConfig(state, kind, name); 4831 primaryKeys.forEach((primaryKey) => { 4832 const entityRecord = getEditedEntityRecord( 4833 state, 4834 kind, 4835 name, 4836 primaryKey 4837 ); 4838 dirtyRecords.push({ 4839 // We avoid using primaryKey because it's transformed into a string 4840 // when it's used as an object key. 4841 key: entityRecord ? entityRecord[entityConfig.key || DEFAULT_ENTITY_KEY] : void 0, 4842 title: entityConfig?.getTitle?.(entityRecord) || "", 4843 name, 4844 kind 4845 }); 4846 }); 4847 } 4848 }); 4849 }); 4850 return dirtyRecords; 4851 }, 4852 (state) => [state.entities.records] 4853 ); 4854 var __experimentalGetEntitiesBeingSaved = (0, import_data9.createSelector)( 4855 (state) => { 4856 const { 4857 entities: { records } 4858 } = state; 4859 const recordsBeingSaved = []; 4860 Object.keys(records).forEach((kind) => { 4861 Object.keys(records[kind]).forEach((name) => { 4862 const primaryKeys = Object.keys(records[kind][name].saving).filter( 4863 (primaryKey) => isSavingEntityRecord(state, kind, name, primaryKey) 4864 ); 4865 if (primaryKeys.length) { 4866 const entityConfig = getEntityConfig(state, kind, name); 4867 primaryKeys.forEach((primaryKey) => { 4868 const entityRecord = getEditedEntityRecord( 4869 state, 4870 kind, 4871 name, 4872 primaryKey 4873 ); 4874 recordsBeingSaved.push({ 4875 // We avoid using primaryKey because it's transformed into a string 4876 // when it's used as an object key. 4877 key: entityRecord ? entityRecord[entityConfig.key || DEFAULT_ENTITY_KEY] : void 0, 4878 title: entityConfig?.getTitle?.(entityRecord) || "", 4879 name, 4880 kind 4881 }); 4882 }); 4883 } 4884 }); 4885 }); 4886 return recordsBeingSaved; 4887 }, 4888 (state) => [state.entities.records] 4889 ); 4890 function getEntityRecordEdits(state, kind, name, recordId) { 4891 logEntityDeprecation(kind, name, "getEntityRecordEdits"); 4892 return state.entities.records?.[kind]?.[name]?.edits?.[String(recordId)]; 4893 } 4894 var getEntityRecordNonTransientEdits = (0, import_data9.createSelector)( 4895 (state, kind, name, recordId) => { 4896 logEntityDeprecation(kind, name, "getEntityRecordNonTransientEdits"); 4897 const { transientEdits } = getEntityConfig(state, kind, name) || {}; 4898 const edits = getEntityRecordEdits(state, kind, name, recordId) || {}; 4899 if (!transientEdits) { 4900 return edits; 4901 } 4902 return Object.keys(edits).reduce((acc, key) => { 4903 if (!transientEdits[key]) { 4904 acc[key] = edits[key]; 4905 } 4906 return acc; 4907 }, {}); 4908 }, 4909 (state, kind, name, recordId) => [ 4910 state.entities.config, 4911 state.entities.records?.[kind]?.[name]?.edits?.[String(recordId)] 4912 ] 4913 ); 4914 function hasEditsForEntityRecord(state, kind, name, recordId) { 4915 logEntityDeprecation(kind, name, "hasEditsForEntityRecord"); 4916 return isSavingEntityRecord(state, kind, name, recordId) || Object.keys( 4917 getEntityRecordNonTransientEdits(state, kind, name, recordId) 4918 ).length > 0; 4919 } 4920 var getEditedEntityRecord = (0, import_data9.createSelector)( 4921 (state, kind, name, recordId) => { 4922 logEntityDeprecation(kind, name, "getEditedEntityRecord"); 4923 const raw = getRawEntityRecord(state, kind, name, recordId); 4924 const edited = getEntityRecordEdits(state, kind, name, recordId); 4925 if (!raw && !edited) { 4926 return false; 4927 } 4928 return { 4929 ...raw, 4930 ...edited 4931 }; 4932 }, 4933 (state, kind, name, recordId, query) => { 4934 const context = query?.context ?? "default"; 4935 return [ 4936 state.entities.config, 4937 state.entities.records?.[kind]?.[name]?.queriedData.items[context]?.[recordId], 4938 state.entities.records?.[kind]?.[name]?.queriedData.itemIsComplete[context]?.[recordId], 4939 state.entities.records?.[kind]?.[name]?.edits?.[String(recordId)] 4940 ]; 4941 } 4942 ); 4943 function isAutosavingEntityRecord(state, kind, name, recordId) { 4944 logEntityDeprecation(kind, name, "isAutosavingEntityRecord"); 4945 const { pending, isAutosave } = state.entities.records?.[kind]?.[name]?.saving?.[recordId] ?? {}; 4946 return Boolean(pending && isAutosave); 4947 } 4948 function isSavingEntityRecord(state, kind, name, recordId) { 4949 logEntityDeprecation(kind, name, "isSavingEntityRecord"); 4950 return state.entities.records?.[kind]?.[name]?.saving?.[String(recordId)]?.pending ?? false; 4951 } 4952 function isDeletingEntityRecord(state, kind, name, recordId) { 4953 logEntityDeprecation(kind, name, "isDeletingEntityRecord"); 4954 return state.entities.records?.[kind]?.[name]?.deleting?.[String(recordId)]?.pending ?? false; 4955 } 4956 function getLastEntitySaveError(state, kind, name, recordId) { 4957 logEntityDeprecation(kind, name, "getLastEntitySaveError"); 4958 return state.entities.records?.[kind]?.[name]?.saving?.[String(recordId)]?.error; 4959 } 4960 function getLastEntityDeleteError(state, kind, name, recordId) { 4961 logEntityDeprecation(kind, name, "getLastEntityDeleteError"); 4962 return state.entities.records?.[kind]?.[name]?.deleting?.[recordId]?.error; 4963 } 4964 function getUndoEdit(state) { 4965 (0, import_deprecated2.default)("select( 'core' ).getUndoEdit()", { 4966 since: "6.3" 4967 }); 4968 return void 0; 4969 } 4970 function getRedoEdit(state) { 4971 (0, import_deprecated2.default)("select( 'core' ).getRedoEdit()", { 4972 since: "6.3" 4973 }); 4974 return void 0; 4975 } 4976 function hasUndo(state) { 4977 if (getSyncManager()?.undoManager) { 4978 return state.syncUndoManagerState.hasUndo; 4979 } 4980 return getUndoManager(state).hasUndo(); 4981 } 4982 function hasRedo(state) { 4983 if (getSyncManager()?.undoManager) { 4984 return state.syncUndoManagerState.hasRedo; 4985 } 4986 return getUndoManager(state).hasRedo(); 4987 } 4988 function getCurrentTheme(state) { 4989 if (!state.currentTheme) { 4990 return null; 4991 } 4992 return getEntityRecord(state, "root", "theme", state.currentTheme); 4993 } 4994 function __experimentalGetCurrentGlobalStylesId(state) { 4995 return state.currentGlobalStylesId; 4996 } 4997 function getThemeSupports(state) { 4998 return getCurrentTheme(state)?.theme_supports ?? EMPTY_OBJECT2; 4999 } 5000 function getEmbedPreview(state, url) { 5001 return state.embedPreviews[url]; 5002 } 5003 function isPreviewEmbedFallback(state, url) { 5004 const preview = state.embedPreviews[url]; 5005 const oEmbedLinkCheck = '<a href="' + url + '">' + url + "</a>"; 5006 if (!preview) { 5007 return false; 5008 } 5009 return preview.html === oEmbedLinkCheck; 5010 } 5011 function canUser(state, action, resource, id) { 5012 const isEntity = typeof resource === "object"; 5013 if (isEntity && (!resource.kind || !resource.name)) { 5014 return false; 5015 } 5016 if (isEntity) { 5017 logEntityDeprecation(resource.kind, resource.name, "canUser"); 5018 } 5019 const key = getUserPermissionCacheKey(action, resource, id); 5020 return state.userPermissions[key]; 5021 } 5022 function canUserEditEntityRecord(state, kind, name, recordId) { 5023 (0, import_deprecated2.default)(`wp.data.select( 'core' ).canUserEditEntityRecord()`, { 5024 since: "6.7", 5025 alternative: `wp.data.select( 'core' ).canUser( 'update', { kind, name, id } )` 5026 }); 5027 return canUser(state, "update", { kind, name, id: recordId }); 5028 } 5029 function getAutosaves(state, postType, postId) { 5030 return state.autosaves[postId]; 5031 } 5032 function getAutosave(state, postType, postId, authorId) { 5033 if (authorId === void 0) { 5034 return; 5035 } 5036 const autosaves2 = state.autosaves[postId]; 5037 return autosaves2?.find( 5038 (autosave) => autosave.author === authorId 5039 ); 5040 } 5041 var hasFetchedAutosaves = (0, import_data9.createRegistrySelector)( 5042 (select5) => (state, postType, postId) => { 5043 return select5(STORE_NAME).hasFinishedResolution("getAutosaves", [ 5044 postType, 5045 postId 5046 ]); 5047 } 5048 ); 5049 function getReferenceByDistinctEdits(state) { 5050 return state.editsReference; 5051 } 5052 function __experimentalGetCurrentThemeBaseGlobalStyles(state) { 5053 const currentTheme2 = getCurrentTheme(state); 5054 if (!currentTheme2) { 5055 return null; 5056 } 5057 return state.themeBaseGlobalStyles[currentTheme2.stylesheet]; 5058 } 5059 function __experimentalGetCurrentThemeGlobalStylesVariations(state) { 5060 const currentTheme2 = getCurrentTheme(state); 5061 if (!currentTheme2) { 5062 return null; 5063 } 5064 return state.themeGlobalStyleVariations[currentTheme2.stylesheet]; 5065 } 5066 function getBlockPatterns(state) { 5067 return state.blockPatterns; 5068 } 5069 function getBlockPatternCategories(state) { 5070 return state.blockPatternCategories; 5071 } 5072 function getUserPatternCategories(state) { 5073 return state.userPatternCategories; 5074 } 5075 function getCurrentThemeGlobalStylesRevisions(state) { 5076 (0, import_deprecated2.default)("select( 'core' ).getCurrentThemeGlobalStylesRevisions()", { 5077 since: "6.5.0", 5078 alternative: "select( 'core' ).getRevisions( 'root', 'globalStyles', ${ recordKey } )" 5079 }); 5080 const currentGlobalStylesId2 = __experimentalGetCurrentGlobalStylesId(state); 5081 if (!currentGlobalStylesId2) { 5082 return null; 5083 } 5084 return state.themeGlobalStyleRevisions[currentGlobalStylesId2]; 5085 } 5086 function getDefaultTemplateId(state, query) { 5087 return state.defaultTemplates[JSON.stringify(query)]; 5088 } 5089 var getRevisions = (state, kind, name, recordKey, query) => { 5090 logEntityDeprecation(kind, name, "getRevisions"); 5091 const queriedStateRevisions = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey]; 5092 if (!queriedStateRevisions) { 5093 return null; 5094 } 5095 return getQueriedItems(queriedStateRevisions, query); 5096 }; 5097 function hasRevision(state, kind, name, recordKey, revisionKey, query) { 5098 const queriedState = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey]; 5099 if (!queriedState) { 5100 return false; 5101 } 5102 const context = query?.context ?? "default"; 5103 if (!query || !query._fields) { 5104 return !!queriedState.itemIsComplete[context]?.[revisionKey]; 5105 } 5106 const item = queriedState.items[context]?.[revisionKey]; 5107 if (!item) { 5108 return false; 5109 } 5110 const fields = get_normalized_comma_separable_default(query._fields) ?? []; 5111 for (let i = 0; i < fields.length; i++) { 5112 const path = fields[i].split("."); 5113 let value = item; 5114 for (let p = 0; p < path.length; p++) { 5115 const part = path[p]; 5116 if (!value || !Object.hasOwn(value, part)) { 5117 return false; 5118 } 5119 value = value[part]; 5120 } 5121 } 5122 return true; 5123 } 5124 var getRevision = (state, kind, name, recordKey, revisionKey, query) => { 5125 logEntityDeprecation(kind, name, "getRevision"); 5126 const queriedState = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey]; 5127 if (!queriedState) { 5128 return void 0; 5129 } 5130 const context = query?.context ?? "default"; 5131 if (!query || !query._fields) { 5132 if (!queriedState.itemIsComplete[context]?.[revisionKey]) { 5133 return void 0; 5134 } 5135 return queriedState.items[context][revisionKey]; 5136 } 5137 const item = queriedState.items[context]?.[revisionKey]; 5138 if (!item) { 5139 return item; 5140 } 5141 return getFilteredItem(item, query._fields); 5142 }; 5143 5144 // packages/core-data/build-module/actions.mjs 5145 var actions_exports = {}; 5146 __export(actions_exports, { 5147 __experimentalBatch: () => __experimentalBatch, 5148 __experimentalReceiveCurrentGlobalStylesId: () => __experimentalReceiveCurrentGlobalStylesId, 5149 __experimentalReceiveThemeBaseGlobalStyles: () => __experimentalReceiveThemeBaseGlobalStyles, 5150 __experimentalReceiveThemeGlobalStyleVariations: () => __experimentalReceiveThemeGlobalStyleVariations, 5151 __experimentalSaveSpecifiedEntityEdits: () => __experimentalSaveSpecifiedEntityEdits, 5152 __unstableCreateUndoLevel: () => __unstableCreateUndoLevel, 5153 addEntities: () => addEntities, 5154 clearEntityRecordEdits: () => clearEntityRecordEdits, 5155 deleteEntityRecord: () => deleteEntityRecord, 5156 editEntityRecord: () => editEntityRecord, 5157 receiveAutosaves: () => receiveAutosaves, 5158 receiveCurrentTheme: () => receiveCurrentTheme, 5159 receiveCurrentUser: () => receiveCurrentUser, 5160 receiveDefaultTemplateId: () => receiveDefaultTemplateId, 5161 receiveEmbedPreview: () => receiveEmbedPreview, 5162 receiveEntityRecords: () => receiveEntityRecords, 5163 receiveNavigationFallbackId: () => receiveNavigationFallbackId, 5164 receiveRevisions: () => receiveRevisions, 5165 receiveThemeGlobalStyleRevisions: () => receiveThemeGlobalStyleRevisions, 5166 receiveThemeSupports: () => receiveThemeSupports, 5167 receiveUploadPermissions: () => receiveUploadPermissions, 5168 receiveUserPermission: () => receiveUserPermission, 5169 receiveUserPermissions: () => receiveUserPermissions, 5170 receiveUserQuery: () => receiveUserQuery, 5171 redo: () => redo, 5172 saveEditedEntityRecord: () => saveEditedEntityRecord, 5173 saveEntityRecord: () => saveEntityRecord, 5174 undo: () => undo 5175 }); 5176 var import_es66 = __toESM(require_es6(), 1); 5177 var import_api_fetch4 = __toESM(require_api_fetch(), 1); 5178 var import_url3 = __toESM(require_url(), 1); 5179 var import_deprecated3 = __toESM(require_deprecated(), 1); 5180 5181 // packages/core-data/build-module/batch/default-processor.mjs 5182 var import_api_fetch3 = __toESM(require_api_fetch(), 1); 5183 var maxItems = null; 5184 function chunk(arr, chunkSize) { 5185 const tmp = [...arr]; 5186 const cache3 = []; 5187 while (tmp.length) { 5188 cache3.push(tmp.splice(0, chunkSize)); 5189 } 5190 return cache3; 5191 } 5192 async function defaultProcessor(requests) { 5193 if (maxItems === null) { 5194 const preflightResponse = await (0, import_api_fetch3.default)({ 5195 path: "/batch/v1", 5196 method: "OPTIONS" 5197 }); 5198 maxItems = preflightResponse.endpoints[0].args.requests.maxItems; 5199 } 5200 const results = []; 5201 for (const batchRequests of chunk(requests, maxItems)) { 5202 const batchResponse = await (0, import_api_fetch3.default)({ 5203 path: "/batch/v1", 5204 method: "POST", 5205 data: { 5206 validation: "require-all-validate", 5207 requests: batchRequests.map((request) => ({ 5208 path: request.path, 5209 body: request.data, 5210 // Rename 'data' to 'body'. 5211 method: request.method, 5212 headers: request.headers 5213 })) 5214 } 5215 }); 5216 let batchResults; 5217 if (batchResponse.failed) { 5218 batchResults = batchResponse.responses.map((response) => ({ 5219 error: response?.body 5220 })); 5221 } else { 5222 batchResults = batchResponse.responses.map((response) => { 5223 const result = {}; 5224 if (response.status >= 200 && response.status < 300) { 5225 result.output = response.body; 5226 } else { 5227 result.error = response.body; 5228 } 5229 return result; 5230 }); 5231 } 5232 results.push(...batchResults); 5233 } 5234 return results; 5235 } 5236 5237 // packages/core-data/build-module/batch/create-batch.mjs 5238 function createBatch(processor = defaultProcessor) { 5239 let lastId = 0; 5240 let queue = []; 5241 const pending = new ObservableSet(); 5242 return { 5243 /** 5244 * Adds an input to the batch and returns a promise that is resolved or 5245 * rejected when the input is processed by `batch.run()`. 5246 * 5247 * You may also pass a thunk which allows inputs to be added 5248 * asynchronously. 5249 * 5250 * ``` 5251 * // Both are allowed: 5252 * batch.add( { path: '/v1/books', ... } ); 5253 * batch.add( ( add ) => add( { path: '/v1/books', ... } ) ); 5254 * ``` 5255 * 5256 * If a thunk is passed, `batch.run()` will pause until either: 5257 * 5258 * - The thunk calls its `add` argument, or; 5259 * - The thunk returns a promise and that promise resolves, or; 5260 * - The thunk returns a non-promise. 5261 * 5262 * @param {any|Function} inputOrThunk Input to add or thunk to execute. 5263 * 5264 * @return {Promise|any} If given an input, returns a promise that 5265 * is resolved or rejected when the batch is 5266 * processed. If given a thunk, returns the return 5267 * value of that thunk. 5268 */ 5269 add(inputOrThunk) { 5270 const id = ++lastId; 5271 pending.add(id); 5272 const add = (input) => new Promise((resolve, reject) => { 5273 queue.push({ 5274 input, 5275 resolve, 5276 reject 5277 }); 5278 pending.delete(id); 5279 }); 5280 if (typeof inputOrThunk === "function") { 5281 return Promise.resolve(inputOrThunk(add)).finally(() => { 5282 pending.delete(id); 5283 }); 5284 } 5285 return add(inputOrThunk); 5286 }, 5287 /** 5288 * Runs the batch. This calls `batchProcessor` and resolves or rejects 5289 * all promises returned by `add()`. 5290 * 5291 * @return {Promise<boolean>} A promise that resolves to a boolean that is true 5292 * if the processor returned no errors. 5293 */ 5294 async run() { 5295 if (pending.size) { 5296 await new Promise((resolve) => { 5297 const unsubscribe = pending.subscribe(() => { 5298 if (!pending.size) { 5299 unsubscribe(); 5300 resolve(void 0); 5301 } 5302 }); 5303 }); 5304 } 5305 let results; 5306 try { 5307 results = await processor( 5308 queue.map(({ input }) => input) 5309 ); 5310 if (results.length !== queue.length) { 5311 throw new Error( 5312 "run: Array returned by processor must be same size as input array." 5313 ); 5314 } 5315 } catch (error) { 5316 for (const { reject } of queue) { 5317 reject(error); 5318 } 5319 throw error; 5320 } 5321 let isSuccess = true; 5322 results.forEach((result, key) => { 5323 const queueItem = queue[key]; 5324 if (result?.error) { 5325 queueItem?.reject(result.error); 5326 isSuccess = false; 5327 } else { 5328 queueItem?.resolve(result?.output ?? result); 5329 } 5330 }); 5331 queue = []; 5332 return isSuccess; 5333 } 5334 }; 5335 } 5336 var ObservableSet = class { 5337 constructor(...args) { 5338 this.set = new Set(...args); 5339 this.subscribers = /* @__PURE__ */ new Set(); 5340 } 5341 get size() { 5342 return this.set.size; 5343 } 5344 add(value) { 5345 this.set.add(value); 5346 this.subscribers.forEach((subscriber) => subscriber()); 5347 return this; 5348 } 5349 delete(value) { 5350 const isSuccess = this.set.delete(value); 5351 this.subscribers.forEach((subscriber) => subscriber()); 5352 return isSuccess; 5353 } 5354 subscribe(subscriber) { 5355 this.subscribers.add(subscriber); 5356 return () => { 5357 this.subscribers.delete(subscriber); 5358 }; 5359 } 5360 }; 5361 5362 // packages/core-data/build-module/actions.mjs 5363 function addTitleToAutoDraft(record) { 5364 return record.status === "auto-draft" ? { ...record, title: "" } : record; 5365 } 5366 function getServerMutatedMetaFields(updatedMeta, persistedMeta, syncedMeta) { 5367 const baseline = { ...persistedMeta, ...syncedMeta }; 5368 return Object.fromEntries( 5369 Object.entries(updatedMeta ?? {}).filter(([key, value]) => { 5370 if (key === POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE) { 5371 return false; 5372 } 5373 return !(0, import_es66.default)(value, baseline[key]); 5374 }) 5375 ); 5376 } 5377 function getServerMutatedFields(updatedRecord, persistedRecord, syncedChanges) { 5378 return Object.fromEntries( 5379 Object.entries(updatedRecord).flatMap(([key, value]) => { 5380 if (key === "meta") { 5381 const serverMutatedMeta = getServerMutatedMetaFields( 5382 value, 5383 persistedRecord.meta, 5384 syncedChanges.meta 5385 ); 5386 return Object.keys(serverMutatedMeta).length ? [[key, serverMutatedMeta]] : []; 5387 } 5388 const baseline = key in syncedChanges ? syncedChanges[key] : persistedRecord[key]; 5389 const wasServerMutated = !(0, import_es66.default)( 5390 getRawValue(value) ?? value, 5391 getRawValue(baseline) ?? baseline 5392 ); 5393 return wasServerMutated ? [[key, value]] : []; 5394 }) 5395 ); 5396 } 5397 function receiveUserQuery(queryID, users2) { 5398 return { 5399 type: "RECEIVE_USER_QUERY", 5400 users: Array.isArray(users2) ? users2 : [users2], 5401 queryID 5402 }; 5403 } 5404 function receiveCurrentUser(currentUser2) { 5405 return { 5406 type: "RECEIVE_CURRENT_USER", 5407 currentUser: currentUser2 5408 }; 5409 } 5410 function addEntities(entities2) { 5411 return { 5412 type: "ADD_ENTITIES", 5413 entities: entities2 5414 }; 5415 } 5416 function receiveEntityRecords(kind, name, records, query = void 0, invalidateCache = false, edits = void 0, meta = void 0) { 5417 if (kind === "postType") { 5418 records = Array.isArray(records) ? records.map(addTitleToAutoDraft) : addTitleToAutoDraft(records); 5419 } 5420 let action; 5421 if (query) { 5422 action = receiveQueriedItems(records, query, edits, meta); 5423 } else { 5424 action = receiveItems(records, edits, meta); 5425 } 5426 return { 5427 ...action, 5428 kind, 5429 name, 5430 invalidateCache 5431 }; 5432 } 5433 function receiveCurrentTheme(currentTheme2) { 5434 return { 5435 type: "RECEIVE_CURRENT_THEME", 5436 currentTheme: currentTheme2 5437 }; 5438 } 5439 function __experimentalReceiveCurrentGlobalStylesId(currentGlobalStylesId2) { 5440 return { 5441 type: "RECEIVE_CURRENT_GLOBAL_STYLES_ID", 5442 id: currentGlobalStylesId2 5443 }; 5444 } 5445 function __experimentalReceiveThemeBaseGlobalStyles(stylesheet, globalStyles) { 5446 return { 5447 type: "RECEIVE_THEME_GLOBAL_STYLES", 5448 stylesheet, 5449 globalStyles 5450 }; 5451 } 5452 function __experimentalReceiveThemeGlobalStyleVariations(stylesheet, variations) { 5453 return { 5454 type: "RECEIVE_THEME_GLOBAL_STYLE_VARIATIONS", 5455 stylesheet, 5456 variations 5457 }; 5458 } 5459 function receiveThemeSupports() { 5460 (0, import_deprecated3.default)("wp.data.dispatch( 'core' ).receiveThemeSupports", { 5461 since: "5.9" 5462 }); 5463 return { 5464 type: "DO_NOTHING" 5465 }; 5466 } 5467 function receiveThemeGlobalStyleRevisions(currentId, revisions) { 5468 (0, import_deprecated3.default)( 5469 "wp.data.dispatch( 'core' ).receiveThemeGlobalStyleRevisions()", 5470 { 5471 since: "6.5.0", 5472 alternative: "wp.data.dispatch( 'core' ).receiveRevisions" 5473 } 5474 ); 5475 return { 5476 type: "RECEIVE_THEME_GLOBAL_STYLE_REVISIONS", 5477 currentId, 5478 revisions 5479 }; 5480 } 5481 function receiveEmbedPreview(url, preview) { 5482 return { 5483 type: "RECEIVE_EMBED_PREVIEW", 5484 url, 5485 preview 5486 }; 5487 } 5488 var deleteEntityRecord = (kind, name, recordId, query, { __unstableFetch = import_api_fetch4.default, throwOnError = false } = {}) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 5489 logEntityDeprecation(kind, name, "deleteEntityRecord"); 5490 const configs = await resolveSelect2.getEntitiesConfig(kind); 5491 const entityConfig = configs.find( 5492 (config) => config.kind === kind && config.name === name 5493 ); 5494 let error; 5495 let deletedRecord = false; 5496 if (!entityConfig) { 5497 return; 5498 } 5499 const lock2 = await dispatch3.__unstableAcquireStoreLock( 5500 STORE_NAME, 5501 ["entities", "records", kind, name, recordId], 5502 { exclusive: true } 5503 ); 5504 try { 5505 dispatch3({ 5506 type: "DELETE_ENTITY_RECORD_START", 5507 kind, 5508 name, 5509 recordId 5510 }); 5511 let hasError = false; 5512 const { baseURL } = entityConfig; 5513 try { 5514 let path = `$baseURL}/$recordId}`; 5515 if (query) { 5516 path = (0, import_url3.addQueryArgs)(path, query); 5517 } 5518 deletedRecord = await __unstableFetch({ 5519 path, 5520 method: "DELETE" 5521 }); 5522 await dispatch3(removeItems(kind, name, recordId, true)); 5523 if (entityConfig.syncConfig) { 5524 const objectType = `$kind}/$name}`; 5525 const objectId = recordId; 5526 getSyncManager()?.unload(objectType, objectId); 5527 } 5528 } catch (_error) { 5529 hasError = true; 5530 error = _error; 5531 } 5532 dispatch3({ 5533 type: "DELETE_ENTITY_RECORD_FINISH", 5534 kind, 5535 name, 5536 recordId, 5537 error 5538 }); 5539 if (hasError && throwOnError) { 5540 throw error; 5541 } 5542 return deletedRecord; 5543 } finally { 5544 dispatch3.__unstableReleaseStoreLock(lock2); 5545 } 5546 }; 5547 var editEntityRecord = (kind, name, recordId, edits, options = {}) => ({ select: select5, dispatch: dispatch3 }) => { 5548 logEntityDeprecation(kind, name, "editEntityRecord"); 5549 const entityConfig = select5.getEntityConfig(kind, name); 5550 if (!entityConfig) { 5551 throw new Error( 5552 `The entity being edited ($kind}, $name}) does not have a loaded config.` 5553 ); 5554 } 5555 const { mergedEdits = {} } = entityConfig; 5556 const record = select5.getRawEntityRecord(kind, name, recordId); 5557 const editedRecord = select5.getEditedEntityRecord( 5558 kind, 5559 name, 5560 recordId 5561 ); 5562 const editsWithMerges = Object.keys(edits).reduce((acc, key) => { 5563 acc[key] = mergedEdits[key] ? { ...editedRecord[key], ...edits[key] } : edits[key]; 5564 return acc; 5565 }, {}); 5566 const edit = { 5567 kind, 5568 name, 5569 recordId, 5570 // Clear edits when they are equal to their persisted counterparts 5571 // so that the property is not considered dirty. 5572 edits: clearUnchangedEdits(editsWithMerges, record) 5573 }; 5574 if (entityConfig.syncConfig) { 5575 const objectType = `$kind}/$name}`; 5576 const objectId = recordId; 5577 const isNewUndoLevel = options.undoIgnore ? false : !options.isCached; 5578 const origin = options.undoIgnore ? LOCAL_UNDO_IGNORED_ORIGIN : LOCAL_EDITOR_ORIGIN; 5579 getSyncManager()?.update( 5580 objectType, 5581 objectId, 5582 editsWithMerges, 5583 origin, 5584 { isNewUndoLevel } 5585 ); 5586 } 5587 if (!options.undoIgnore) { 5588 select5.getUndoManager().addRecord( 5589 [ 5590 { 5591 id: { kind, name, recordId }, 5592 changes: Object.keys(edits).reduce((acc, key) => { 5593 acc[key] = { 5594 from: editedRecord[key], 5595 to: edits[key] 5596 }; 5597 return acc; 5598 }, {}) 5599 } 5600 ], 5601 options.isCached 5602 ); 5603 } 5604 dispatch3({ 5605 type: "EDIT_ENTITY_RECORD", 5606 ...edit 5607 }); 5608 }; 5609 var clearEntityRecordEdits = (kind, name, recordId) => ({ select: select5, dispatch: dispatch3 }) => { 5610 const entityConfig = select5.getEntityConfig(kind, name); 5611 logEntityDeprecation(kind, name, "clearEntityRecordEdits"); 5612 if (!entityConfig) { 5613 throw new Error( 5614 `The entity being edited ($kind}, $name}) does not have a loaded config.` 5615 ); 5616 } 5617 const currentEdits = select5.getEntityRecordEdits( 5618 kind, 5619 name, 5620 recordId 5621 ); 5622 if (!currentEdits) { 5623 return; 5624 } 5625 const clearedEdits = Object.keys(currentEdits).reduce( 5626 (acc, key) => { 5627 acc[key] = void 0; 5628 return acc; 5629 }, 5630 {} 5631 ); 5632 dispatch3({ 5633 type: "EDIT_ENTITY_RECORD", 5634 kind, 5635 name, 5636 recordId, 5637 edits: clearedEdits 5638 }); 5639 }; 5640 var undo = () => ({ select: select5, dispatch: dispatch3 }) => { 5641 const undoRecord = select5.getUndoManager().undo(); 5642 if (!undoRecord) { 5643 return; 5644 } 5645 dispatch3({ 5646 type: "UNDO", 5647 record: undoRecord 5648 }); 5649 }; 5650 var redo = () => ({ select: select5, dispatch: dispatch3 }) => { 5651 const redoRecord = select5.getUndoManager().redo(); 5652 if (!redoRecord) { 5653 return; 5654 } 5655 dispatch3({ 5656 type: "REDO", 5657 record: redoRecord 5658 }); 5659 }; 5660 var __unstableCreateUndoLevel = () => ({ select: select5 }) => { 5661 select5.getUndoManager().addRecord(); 5662 }; 5663 var saveEntityRecord = (kind, name, record, options = {}) => async ({ select: select5, resolveSelect: resolveSelect2, dispatch: dispatch3 }) => { 5664 const { 5665 isAutosave = false, 5666 __unstableFetch = import_api_fetch4.default, 5667 __unstableSkipSyncUpdate = false, 5668 throwOnError = false 5669 } = options; 5670 logEntityDeprecation(kind, name, "saveEntityRecord"); 5671 const configs = await resolveSelect2.getEntitiesConfig(kind); 5672 const entityConfig = configs.find( 5673 (config) => config.kind === kind && config.name === name 5674 ); 5675 if (!entityConfig) { 5676 return; 5677 } 5678 const entityIdKey = entityConfig.key ?? DEFAULT_ENTITY_KEY; 5679 const recordId = record[entityIdKey]; 5680 const isNewRecord = !!entityIdKey && !recordId; 5681 const lock2 = await dispatch3.__unstableAcquireStoreLock( 5682 STORE_NAME, 5683 ["entities", "records", kind, name, recordId || v4_default()], 5684 { exclusive: true } 5685 ); 5686 try { 5687 for (const [key, value] of Object.entries(record)) { 5688 if (typeof value === "function") { 5689 const evaluatedValue = value( 5690 select5.getEditedEntityRecord(kind, name, recordId) 5691 ); 5692 dispatch3.editEntityRecord( 5693 kind, 5694 name, 5695 recordId, 5696 { 5697 [key]: evaluatedValue 5698 }, 5699 { undoIgnore: true } 5700 ); 5701 record[key] = evaluatedValue; 5702 } 5703 } 5704 dispatch3({ 5705 type: "SAVE_ENTITY_RECORD_START", 5706 kind, 5707 name, 5708 recordId, 5709 isAutosave 5710 }); 5711 let updatedRecord; 5712 let error; 5713 let hasError = false; 5714 const { baseURL } = entityConfig; 5715 try { 5716 const path = `$baseURL}$recordId ? "/" + recordId : ""}`; 5717 const persistedRecord = !isNewRecord ? select5.getRawEntityRecord(kind, name, recordId) : {}; 5718 if (entityConfig.syncConfig && !__unstableSkipSyncUpdate && !isNewRecord && persistedRecord) { 5719 getSyncManager()?.update( 5720 `$kind}/$name}`, 5721 recordId, 5722 record, 5723 LOCAL_UNDO_IGNORED_ORIGIN 5724 ); 5725 } 5726 if (isAutosave) { 5727 const merged = { ...persistedRecord, ...record }; 5728 const data = [ 5729 "title", 5730 "excerpt", 5731 "content", 5732 "meta" 5733 ].reduce( 5734 (acc, key) => { 5735 if (key in merged) { 5736 acc[key] = merged[key]; 5737 } 5738 return acc; 5739 }, 5740 { 5741 // Do not update the `status` if we have edited it when auto saving. 5742 // It's very important to let the user explicitly save this change, 5743 // because it can lead to unexpected results. An example would be to 5744 // have a draft post and change the status to publish. 5745 status: merged.status === "auto-draft" ? "draft" : void 0 5746 } 5747 ); 5748 if (entityConfig.syncConfig) { 5749 const crdtSnapshot = getSyncManager()?.getEntitySnapshot( 5750 `$kind}/$name}`, 5751 recordId 5752 ); 5753 if (crdtSnapshot) { 5754 data[CRDT_AUTOSAVE_SNAPSHOT_KEY] = crdtSnapshot; 5755 } 5756 } 5757 updatedRecord = await __unstableFetch({ 5758 path: `$path}/autosaves`, 5759 method: "POST", 5760 data 5761 }); 5762 if (persistedRecord.id === updatedRecord.id) { 5763 let newRecord = { 5764 ...persistedRecord, 5765 ...data, 5766 ...updatedRecord 5767 }; 5768 newRecord = Object.keys(newRecord).reduce( 5769 (acc, key) => { 5770 if ([ 5771 "title", 5772 "excerpt", 5773 "content", 5774 "meta" 5775 ].includes(key)) { 5776 acc[key] = newRecord[key]; 5777 } else if (key === "status") { 5778 acc[key] = persistedRecord.status === "auto-draft" && newRecord.status === "draft" ? newRecord.status : persistedRecord.status; 5779 } else { 5780 acc[key] = persistedRecord[key]; 5781 } 5782 return acc; 5783 }, 5784 {} 5785 ); 5786 dispatch3.receiveEntityRecords( 5787 kind, 5788 name, 5789 newRecord, 5790 void 0, 5791 true 5792 ); 5793 } else { 5794 dispatch3.receiveAutosaves( 5795 persistedRecord.id, 5796 updatedRecord 5797 ); 5798 } 5799 } else { 5800 let edits = record; 5801 if (entityConfig.__unstablePrePersist) { 5802 edits = { 5803 ...edits, 5804 ...await entityConfig.__unstablePrePersist( 5805 persistedRecord, 5806 edits 5807 ) 5808 }; 5809 } 5810 updatedRecord = await __unstableFetch({ 5811 path, 5812 method: recordId ? "PUT" : "POST", 5813 data: edits 5814 }); 5815 dispatch3.receiveEntityRecords( 5816 kind, 5817 name, 5818 updatedRecord, 5819 void 0, 5820 true, 5821 record 5822 ); 5823 if (entityConfig.syncConfig) { 5824 let syncChanges; 5825 if (__unstableSkipSyncUpdate) { 5826 syncChanges = {}; 5827 } else if (isNewRecord || !persistedRecord) { 5828 syncChanges = updatedRecord; 5829 } else { 5830 syncChanges = getServerMutatedFields( 5831 updatedRecord, 5832 persistedRecord, 5833 record 5834 ); 5835 } 5836 getSyncManager()?.update( 5837 `$kind}/$name}`, 5838 recordId, 5839 syncChanges, 5840 LOCAL_UNDO_IGNORED_ORIGIN, 5841 { isSave: true } 5842 ); 5843 } 5844 } 5845 } catch (_error) { 5846 hasError = true; 5847 error = _error; 5848 } 5849 dispatch3({ 5850 type: "SAVE_ENTITY_RECORD_FINISH", 5851 kind, 5852 name, 5853 recordId, 5854 error, 5855 isAutosave 5856 }); 5857 if (hasError && throwOnError) { 5858 throw error; 5859 } 5860 return updatedRecord; 5861 } finally { 5862 dispatch3.__unstableReleaseStoreLock(lock2); 5863 } 5864 }; 5865 var __experimentalBatch = (requests) => async ({ dispatch: dispatch3 }) => { 5866 const batch = createBatch(); 5867 const api = { 5868 saveEntityRecord(kind, name, record, options) { 5869 return batch.add( 5870 (add) => dispatch3.saveEntityRecord(kind, name, record, { 5871 ...options, 5872 __unstableFetch: add 5873 }) 5874 ); 5875 }, 5876 saveEditedEntityRecord(kind, name, recordId, options) { 5877 return batch.add( 5878 (add) => dispatch3.saveEditedEntityRecord(kind, name, recordId, { 5879 ...options, 5880 __unstableFetch: add 5881 }) 5882 ); 5883 }, 5884 deleteEntityRecord(kind, name, recordId, query, options) { 5885 return batch.add( 5886 (add) => dispatch3.deleteEntityRecord(kind, name, recordId, query, { 5887 ...options, 5888 __unstableFetch: add 5889 }) 5890 ); 5891 } 5892 }; 5893 const resultPromises = requests.map((request) => request(api)); 5894 const [, ...results] = await Promise.all([ 5895 batch.run(), 5896 ...resultPromises 5897 ]); 5898 return results; 5899 }; 5900 var saveEditedEntityRecord = (kind, name, recordId, options) => async ({ select: select5, dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 5901 logEntityDeprecation(kind, name, "saveEditedEntityRecord"); 5902 if (!select5.hasEditsForEntityRecord(kind, name, recordId)) { 5903 return; 5904 } 5905 const configs = await resolveSelect2.getEntitiesConfig(kind); 5906 const entityConfig = configs.find( 5907 (config) => config.kind === kind && config.name === name 5908 ); 5909 if (!entityConfig) { 5910 return; 5911 } 5912 const entityIdKey = entityConfig.key || DEFAULT_ENTITY_KEY; 5913 const edits = select5.getEntityRecordNonTransientEdits( 5914 kind, 5915 name, 5916 recordId 5917 ); 5918 const record = { [entityIdKey]: recordId, ...edits }; 5919 return await dispatch3.saveEntityRecord(kind, name, record, options); 5920 }; 5921 var __experimentalSaveSpecifiedEntityEdits = (kind, name, recordId, itemsToSave, options) => async ({ select: select5, dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 5922 logEntityDeprecation( 5923 kind, 5924 name, 5925 "__experimentalSaveSpecifiedEntityEdits" 5926 ); 5927 if (!select5.hasEditsForEntityRecord(kind, name, recordId)) { 5928 return; 5929 } 5930 const edits = select5.getEntityRecordNonTransientEdits( 5931 kind, 5932 name, 5933 recordId 5934 ); 5935 const editsToSave = {}; 5936 for (const item of itemsToSave) { 5937 setNestedValue(editsToSave, item, getNestedValue(edits, item)); 5938 } 5939 const configs = await resolveSelect2.getEntitiesConfig(kind); 5940 const entityConfig = configs.find( 5941 (config) => config.kind === kind && config.name === name 5942 ); 5943 const entityIdKey = entityConfig?.key || DEFAULT_ENTITY_KEY; 5944 if (recordId) { 5945 editsToSave[entityIdKey] = recordId; 5946 } 5947 return await dispatch3.saveEntityRecord( 5948 kind, 5949 name, 5950 editsToSave, 5951 options 5952 ); 5953 }; 5954 function receiveUploadPermissions(hasUploadPermissions) { 5955 (0, import_deprecated3.default)("wp.data.dispatch( 'core' ).receiveUploadPermissions", { 5956 since: "5.9", 5957 alternative: "receiveUserPermission" 5958 }); 5959 return receiveUserPermission("create/media", hasUploadPermissions); 5960 } 5961 function receiveUserPermission(key, isAllowed) { 5962 return { 5963 type: "RECEIVE_USER_PERMISSION", 5964 key, 5965 isAllowed 5966 }; 5967 } 5968 function receiveUserPermissions(permissions) { 5969 return { 5970 type: "RECEIVE_USER_PERMISSIONS", 5971 permissions 5972 }; 5973 } 5974 function receiveAutosaves(postId, autosaves2) { 5975 return { 5976 type: "RECEIVE_AUTOSAVES", 5977 postId, 5978 autosaves: Array.isArray(autosaves2) ? autosaves2 : [autosaves2] 5979 }; 5980 } 5981 function receiveNavigationFallbackId(fallbackId) { 5982 return { 5983 type: "RECEIVE_NAVIGATION_FALLBACK_ID", 5984 fallbackId 5985 }; 5986 } 5987 function receiveDefaultTemplateId(query, templateId) { 5988 return { 5989 type: "RECEIVE_DEFAULT_TEMPLATE", 5990 query, 5991 templateId 5992 }; 5993 } 5994 var receiveRevisions = (kind, name, recordKey, records, query, invalidateCache = false, meta) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 5995 logEntityDeprecation(kind, name, "receiveRevisions"); 5996 const configs = await resolveSelect2.getEntitiesConfig(kind); 5997 const entityConfig = configs.find( 5998 (config) => config.kind === kind && config.name === name 5999 ); 6000 const key = entityConfig?.revisionKey ?? DEFAULT_ENTITY_KEY; 6001 dispatch3({ 6002 type: "RECEIVE_ITEM_REVISIONS", 6003 key, 6004 items: records, 6005 recordKey, 6006 meta, 6007 query, 6008 kind, 6009 name, 6010 invalidateCache 6011 }); 6012 }; 6013 6014 // packages/core-data/build-module/private-actions.mjs 6015 var private_actions_exports = {}; 6016 __export(private_actions_exports, { 6017 __unstableNotifySyncUndoManagerChange: () => __unstableNotifySyncUndoManagerChange, 6018 editMediaEntity: () => editMediaEntity, 6019 receiveEditorAssets: () => receiveEditorAssets, 6020 receiveEditorSettings: () => receiveEditorSettings, 6021 receiveRegisteredPostMeta: () => receiveRegisteredPostMeta, 6022 receiveViewConfig: () => receiveViewConfig, 6023 saveDirtyEntities: () => saveDirtyEntities, 6024 setCollaborationSupported: () => setCollaborationSupported, 6025 setSyncConnectionStatus: () => setSyncConnectionStatus 6026 }); 6027 var import_api_fetch5 = __toESM(require_api_fetch(), 1); 6028 var import_notices = __toESM(require_notices(), 1); 6029 var import_block_editor5 = __toESM(require_block_editor(), 1); 6030 var import_html_entities = __toESM(require_html_entities(), 1); 6031 var import_i18n2 = __toESM(require_i18n(), 1); 6032 function receiveRegisteredPostMeta(postType, registeredPostMeta2) { 6033 return { 6034 type: "RECEIVE_REGISTERED_POST_META", 6035 postType, 6036 registeredPostMeta: registeredPostMeta2 6037 }; 6038 } 6039 var editMediaEntity = (recordId, edits = {}, { __unstableFetch = import_api_fetch5.default, throwOnError = false } = {}) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 6040 if (!recordId) { 6041 return; 6042 } 6043 const kind = "postType"; 6044 const name = "attachment"; 6045 const configs = await resolveSelect2.getEntitiesConfig(kind); 6046 const entityConfig = configs.find( 6047 (config) => config.kind === kind && config.name === name 6048 ); 6049 if (!entityConfig) { 6050 return; 6051 } 6052 const lock2 = await dispatch3.__unstableAcquireStoreLock( 6053 STORE_NAME, 6054 ["entities", "records", kind, name, recordId], 6055 { exclusive: true } 6056 ); 6057 let updatedRecord; 6058 let error; 6059 let hasError = false; 6060 try { 6061 dispatch3({ 6062 type: "SAVE_ENTITY_RECORD_START", 6063 kind, 6064 name, 6065 recordId 6066 }); 6067 try { 6068 const path = `$entityConfig.baseURL}/$recordId}/edit`; 6069 const newRecord = await __unstableFetch({ 6070 path, 6071 method: "POST", 6072 data: { 6073 ...edits 6074 } 6075 }); 6076 if (newRecord) { 6077 dispatch3.receiveEntityRecords( 6078 kind, 6079 name, 6080 newRecord, 6081 void 0, 6082 true, 6083 void 0, 6084 void 0 6085 ); 6086 updatedRecord = newRecord; 6087 } 6088 } catch (e) { 6089 error = e; 6090 hasError = true; 6091 } 6092 dispatch3({ 6093 type: "SAVE_ENTITY_RECORD_FINISH", 6094 kind, 6095 name, 6096 recordId, 6097 error 6098 }); 6099 if (hasError && throwOnError) { 6100 throw error; 6101 } 6102 return updatedRecord; 6103 } finally { 6104 dispatch3.__unstableReleaseStoreLock(lock2); 6105 } 6106 }; 6107 function receiveEditorSettings(settings) { 6108 return { 6109 type: "RECEIVE_EDITOR_SETTINGS", 6110 settings 6111 }; 6112 } 6113 function receiveEditorAssets(assets) { 6114 return { 6115 type: "RECEIVE_EDITOR_ASSETS", 6116 assets 6117 }; 6118 } 6119 var setCollaborationSupported = (supported) => ({ dispatch: dispatch3 }) => { 6120 dispatch3({ type: "SET_COLLABORATION_SUPPORTED", supported }); 6121 if (!supported && hasSyncManager()) { 6122 getSyncManager().unloadAll(); 6123 dispatch3.__unstableNotifySyncUndoManagerChange({ 6124 hasUndo: false, 6125 hasRedo: false 6126 }); 6127 } 6128 }; 6129 function receiveViewConfig(kind, name, config) { 6130 return { 6131 type: "RECEIVE_VIEW_CONFIG", 6132 kind, 6133 name, 6134 config 6135 }; 6136 } 6137 function __unstableNotifySyncUndoManagerChange(state) { 6138 return { 6139 type: "SYNC_UNDO_MANAGER_CHANGE", 6140 ...state 6141 }; 6142 } 6143 function setSyncConnectionStatus(kind, name, key, status) { 6144 if (!status) { 6145 return { 6146 type: "CLEAR_SYNC_CONNECTION_STATUS", 6147 kind, 6148 name, 6149 key 6150 }; 6151 } 6152 return { 6153 type: "SET_SYNC_CONNECTION_STATUS", 6154 kind, 6155 name, 6156 key, 6157 status 6158 }; 6159 } 6160 var saveDirtyEntities = ({ 6161 onSave, 6162 dirtyEntityRecords = [], 6163 entitiesToSkip = [], 6164 close, 6165 successNoticeContent 6166 } = {}) => ({ registry }) => { 6167 const PUBLISH_ON_SAVE_ENTITIES = [ 6168 { kind: "postType", name: "wp_navigation" } 6169 ]; 6170 const saveNoticeId = "site-editor-save-success"; 6171 const homeUrl = registry.select(STORE_NAME).getEntityRecord("root", "__unstableBase")?.home; 6172 registry.dispatch(import_notices.store).removeNotice(saveNoticeId); 6173 const entitiesToSave = dirtyEntityRecords.filter( 6174 ({ kind, name, key, property }) => { 6175 return !entitiesToSkip.some( 6176 (elt) => elt.kind === kind && elt.name === name && elt.key === key && elt.property === property 6177 ); 6178 } 6179 ); 6180 close?.(entitiesToSave); 6181 const siteItemsToSave = []; 6182 const pendingSavedRecords = []; 6183 entitiesToSave.forEach(({ kind, name, key, property }) => { 6184 if ("root" === kind && "site" === name) { 6185 siteItemsToSave.push(property); 6186 } else { 6187 if (PUBLISH_ON_SAVE_ENTITIES.some( 6188 (typeToPublish) => typeToPublish.kind === kind && typeToPublish.name === name 6189 )) { 6190 registry.dispatch(STORE_NAME).editEntityRecord(kind, name, key, { 6191 status: "publish" 6192 }); 6193 } 6194 pendingSavedRecords.push( 6195 registry.dispatch(STORE_NAME).saveEditedEntityRecord(kind, name, key, { 6196 throwOnError: true 6197 }).catch(ensureError) 6198 ); 6199 } 6200 }); 6201 if (siteItemsToSave.length) { 6202 pendingSavedRecords.push( 6203 registry.dispatch(STORE_NAME).__experimentalSaveSpecifiedEntityEdits( 6204 "root", 6205 "site", 6206 void 0, 6207 siteItemsToSave, 6208 { 6209 throwOnError: true 6210 } 6211 ).catch(ensureError) 6212 ); 6213 } 6214 registry.dispatch(import_block_editor5.store).__unstableMarkLastChangeAsPersistent(); 6215 return Promise.all(pendingSavedRecords).then(async (values) => { 6216 if (onSave) { 6217 await onSave(); 6218 } 6219 return values; 6220 }).then((values) => { 6221 const errors = values.filter((v) => v instanceof Error); 6222 if (errors.length) { 6223 const firstMessage = errors.find( 6224 (e) => e.message 6225 )?.message; 6226 registry.dispatch(import_notices.store).createErrorNotice( 6227 (0, import_html_entities.decodeEntities)( 6228 firstMessage || (0, import_i18n2.__)("Saving failed.") 6229 ), 6230 { 6231 type: "snackbar", 6232 id: saveNoticeId 6233 } 6234 ); 6235 } else { 6236 registry.dispatch(import_notices.store).createSuccessNotice( 6237 successNoticeContent || (0, import_i18n2.__)("Site updated."), 6238 { 6239 type: "snackbar", 6240 id: saveNoticeId, 6241 actions: [ 6242 { 6243 label: (0, import_i18n2.__)("View site"), 6244 url: homeUrl, 6245 openInNewTab: true 6246 } 6247 ] 6248 } 6249 ); 6250 } 6251 }).catch( 6252 (error) => registry.dispatch(import_notices.store).createErrorNotice( 6253 (0, import_html_entities.decodeEntities)( 6254 error?.message || (0, import_i18n2.__)("Saving failed.") 6255 ), 6256 { 6257 type: "snackbar", 6258 id: saveNoticeId 6259 } 6260 ) 6261 ); 6262 function ensureError(error) { 6263 if (error instanceof Error) { 6264 return error; 6265 } 6266 let message; 6267 if (!error) { 6268 } else if (typeof error.message === "string") { 6269 message = error.message; 6270 } else if (typeof error === "string") { 6271 message = error; 6272 } else if ( 6273 // Only consider own method, lest we erroneously end up calling 6274 // `Object#toString` at the end of the prototype chain, thereby 6275 // returning `"[object Object]"`. 6276 Object.hasOwn(error, "toString") && typeof error.toString === "function" 6277 ) { 6278 const result = error.toString(); 6279 if (typeof result === "string") { 6280 message = result; 6281 } 6282 } 6283 return new Error(message, { cause: error }); 6284 } 6285 }; 6286 6287 // packages/core-data/build-module/resolvers.mjs 6288 var resolvers_exports = {}; 6289 __export(resolvers_exports, { 6290 __experimentalGetCurrentGlobalStylesId: () => __experimentalGetCurrentGlobalStylesId2, 6291 __experimentalGetCurrentThemeBaseGlobalStyles: () => __experimentalGetCurrentThemeBaseGlobalStyles2, 6292 __experimentalGetCurrentThemeGlobalStylesVariations: () => __experimentalGetCurrentThemeGlobalStylesVariations2, 6293 canUser: () => canUser2, 6294 canUserEditEntityRecord: () => canUserEditEntityRecord2, 6295 getAuthors: () => getAuthors2, 6296 getAutosave: () => getAutosave2, 6297 getAutosaves: () => getAutosaves2, 6298 getBlockPatternCategories: () => getBlockPatternCategories2, 6299 getBlockPatterns: () => getBlockPatterns2, 6300 getCurrentTheme: () => getCurrentTheme2, 6301 getCurrentThemeGlobalStylesRevisions: () => getCurrentThemeGlobalStylesRevisions2, 6302 getCurrentUser: () => getCurrentUser2, 6303 getDefaultTemplateId: () => getDefaultTemplateId2, 6304 getEditedEntityRecord: () => getEditedEntityRecord2, 6305 getEditorAssets: () => getEditorAssets2, 6306 getEditorSettings: () => getEditorSettings2, 6307 getEmbedPreview: () => getEmbedPreview2, 6308 getEntitiesConfig: () => getEntitiesConfig2, 6309 getEntityRecord: () => getEntityRecord2, 6310 getEntityRecords: () => getEntityRecords2, 6311 getEntityRecordsTotalItems: () => getEntityRecordsTotalItems2, 6312 getEntityRecordsTotalPages: () => getEntityRecordsTotalPages2, 6313 getNavigationFallbackId: () => getNavigationFallbackId2, 6314 getRawEntityRecord: () => getRawEntityRecord2, 6315 getRegisteredPostMeta: () => getRegisteredPostMeta2, 6316 getRevision: () => getRevision2, 6317 getRevisions: () => getRevisions2, 6318 getThemeSupports: () => getThemeSupports2, 6319 getUserPatternCategories: () => getUserPatternCategories2, 6320 getViewConfig: () => getViewConfig2 6321 }); 6322 var import_url6 = __toESM(require_url(), 1); 6323 var import_html_entities3 = __toESM(require_html_entities(), 1); 6324 var import_api_fetch9 = __toESM(require_api_fetch(), 1); 6325 6326 // packages/core-data/build-module/fetch/index.mjs 6327 var import_api_fetch8 = __toESM(require_api_fetch(), 1); 6328 6329 // packages/core-data/build-module/fetch/__experimental-fetch-link-suggestions.mjs 6330 var import_api_fetch6 = __toESM(require_api_fetch(), 1); 6331 var import_url4 = __toESM(require_url(), 1); 6332 var import_html_entities2 = __toESM(require_html_entities(), 1); 6333 var import_i18n3 = __toESM(require_i18n(), 1); 6334 async function fetchLinkSuggestions(search, searchOptions = {}, editorSettings2 = {}) { 6335 const searchOptionsToUse = searchOptions.isInitialSuggestions && searchOptions.initialSuggestionsSearchOptions ? { 6336 ...searchOptions, 6337 ...searchOptions.initialSuggestionsSearchOptions 6338 } : searchOptions; 6339 const { 6340 type, 6341 subtype, 6342 page, 6343 perPage = searchOptions.isInitialSuggestions ? 3 : 20 6344 } = searchOptionsToUse; 6345 const { disablePostFormats = false } = editorSettings2; 6346 const queries2 = []; 6347 if (!type || type === "post") { 6348 queries2.push( 6349 (0, import_api_fetch6.default)({ 6350 path: (0, import_url4.addQueryArgs)("/wp/v2/search", { 6351 search, 6352 page, 6353 per_page: perPage, 6354 type: "post", 6355 subtype 6356 }) 6357 }).then((results2) => { 6358 return results2.map((result) => { 6359 return { 6360 id: result.id, 6361 url: result.url, 6362 title: (0, import_html_entities2.decodeEntities)(result.title || "") || (0, import_i18n3.__)("(no title)"), 6363 type: result.subtype || result.type, 6364 kind: "post-type" 6365 }; 6366 }); 6367 }).catch(() => []) 6368 // Fail by returning no results. 6369 ); 6370 } 6371 if (!type || type === "term") { 6372 queries2.push( 6373 (0, import_api_fetch6.default)({ 6374 path: (0, import_url4.addQueryArgs)("/wp/v2/search", { 6375 search, 6376 page, 6377 per_page: perPage, 6378 type: "term", 6379 subtype 6380 }) 6381 }).then((results2) => { 6382 return results2.map((result) => { 6383 return { 6384 id: result.id, 6385 url: result.url, 6386 title: (0, import_html_entities2.decodeEntities)(result.title || "") || (0, import_i18n3.__)("(no title)"), 6387 type: result.subtype || result.type, 6388 kind: "taxonomy" 6389 }; 6390 }); 6391 }).catch(() => []) 6392 // Fail by returning no results. 6393 ); 6394 } 6395 if (!disablePostFormats && (!type || type === "post-format")) { 6396 queries2.push( 6397 (0, import_api_fetch6.default)({ 6398 path: (0, import_url4.addQueryArgs)("/wp/v2/search", { 6399 search, 6400 page, 6401 per_page: perPage, 6402 type: "post-format", 6403 subtype 6404 }) 6405 }).then((results2) => { 6406 return results2.map((result) => { 6407 return { 6408 id: result.id, 6409 url: result.url, 6410 title: (0, import_html_entities2.decodeEntities)(result.title || "") || (0, import_i18n3.__)("(no title)"), 6411 type: result.subtype || result.type, 6412 kind: "taxonomy" 6413 }; 6414 }); 6415 }).catch(() => []) 6416 // Fail by returning no results. 6417 ); 6418 } 6419 if (!type || type === "attachment") { 6420 queries2.push( 6421 (0, import_api_fetch6.default)({ 6422 path: (0, import_url4.addQueryArgs)("/wp/v2/media", { 6423 search, 6424 page, 6425 per_page: perPage 6426 }) 6427 }).then((results2) => { 6428 return results2.map((result) => { 6429 return { 6430 id: result.id, 6431 url: result.source_url, 6432 title: (0, import_html_entities2.decodeEntities)(result.title.rendered || "") || (0, import_i18n3.__)("(no title)"), 6433 type: result.type, 6434 kind: "media" 6435 }; 6436 }); 6437 }).catch(() => []) 6438 // Fail by returning no results. 6439 ); 6440 } 6441 const responses = await Promise.all(queries2); 6442 let results = responses.flat(); 6443 results = results.filter((result) => !!result.id); 6444 results = sortResults(results, search); 6445 results = results.slice(0, perPage); 6446 return results; 6447 } 6448 function sortResults(results, search) { 6449 const searchTokens = tokenize(search); 6450 const scores = {}; 6451 for (const result of results) { 6452 if (result.title) { 6453 const titleTokens = tokenize(result.title); 6454 const exactMatchingTokens = titleTokens.filter( 6455 (titleToken) => searchTokens.some( 6456 (searchToken) => titleToken === searchToken 6457 ) 6458 ); 6459 const subMatchingTokens = titleTokens.filter( 6460 (titleToken) => searchTokens.some( 6461 (searchToken) => titleToken !== searchToken && titleToken.includes(searchToken) 6462 ) 6463 ); 6464 const exactMatchScore = exactMatchingTokens.length / titleTokens.length * 10; 6465 const subMatchScore = subMatchingTokens.length / titleTokens.length; 6466 scores[result.id] = exactMatchScore + subMatchScore; 6467 } else { 6468 scores[result.id] = 0; 6469 } 6470 } 6471 return results.sort((a, b) => scores[b.id] - scores[a.id]); 6472 } 6473 function tokenize(text) { 6474 return text.toLowerCase().match(/[\p{L}\p{N}]+/gu) || []; 6475 } 6476 6477 // packages/core-data/build-module/fetch/__experimental-fetch-url-data.mjs 6478 var import_api_fetch7 = __toESM(require_api_fetch(), 1); 6479 var import_url5 = __toESM(require_url(), 1); 6480 var CACHE = /* @__PURE__ */ new Map(); 6481 var fetchUrlData = async (url, options = {}) => { 6482 const endpoint = "/wp-block-editor/v1/url-details"; 6483 const args = { 6484 url: (0, import_url5.prependHTTP)(url) 6485 }; 6486 if (!(0, import_url5.isURL)(url)) { 6487 return Promise.reject(`$url} is not a valid URL.`); 6488 } 6489 const protocol = (0, import_url5.getProtocol)(url); 6490 if (!protocol || !(0, import_url5.isValidProtocol)(protocol) || !protocol.startsWith("http") || !/^https?:\/\/[^\/\s]/i.test(url)) { 6491 return Promise.reject( 6492 `$url} does not have a valid protocol. URLs must be "http" based` 6493 ); 6494 } 6495 if (CACHE.has(url)) { 6496 return CACHE.get(url); 6497 } 6498 return (0, import_api_fetch7.default)({ 6499 path: (0, import_url5.addQueryArgs)(endpoint, args), 6500 ...options 6501 }).then((res) => { 6502 CACHE.set(url, res); 6503 return res; 6504 }); 6505 }; 6506 var experimental_fetch_url_data_default = fetchUrlData; 6507 6508 // packages/core-data/build-module/fetch/index.mjs 6509 async function fetchBlockPatterns() { 6510 const restPatterns = await (0, import_api_fetch8.default)({ 6511 path: "/wp/v2/block-patterns/patterns" 6512 }); 6513 if (!restPatterns) { 6514 return []; 6515 } 6516 return restPatterns.map( 6517 (pattern) => Object.fromEntries( 6518 Object.entries(pattern).map(([key, value]) => [ 6519 camelCase(key), 6520 value 6521 ]) 6522 ) 6523 ); 6524 } 6525 6526 // packages/core-data/build-module/parsed-blocks-cache.mjs 6527 var import_data10 = __toESM(require_data(), 1); 6528 var import_blocks5 = __toESM(require_blocks(), 1); 6529 var caches = /* @__PURE__ */ new WeakMap(); 6530 function getCacheKey(kind, name, id) { 6531 return `$kind}:$name}:$id}`; 6532 } 6533 function getBlockTypes2() { 6534 return (0, import_data10.select)(import_blocks5.store).getBlockTypes(); 6535 } 6536 function getCachedBlocks(kind, name, id, content) { 6537 const cached = caches.get(getBlockTypes2())?.get(getCacheKey(kind, name, id)); 6538 if (cached && cached.content === content) { 6539 return cached.blocks; 6540 } 6541 } 6542 function setCachedBlocks(kind, name, id, content, blocks) { 6543 const blockTypes = getBlockTypes2(); 6544 let cache3 = caches.get(blockTypes); 6545 if (!cache3) { 6546 cache3 = /* @__PURE__ */ new Map(); 6547 caches.set(blockTypes, cache3); 6548 } 6549 cache3.set(getCacheKey(kind, name, id), { content, blocks }); 6550 } 6551 6552 // packages/core-data/build-module/resolvers.mjs 6553 var getAuthors2 = (query) => async ({ dispatch: dispatch3 }) => { 6554 const path = (0, import_url6.addQueryArgs)( 6555 "/wp/v2/users/?who=authors&per_page=100", 6556 query 6557 ); 6558 const users2 = await (0, import_api_fetch9.default)({ path }); 6559 dispatch3.receiveUserQuery(path, users2); 6560 }; 6561 var getCurrentUser2 = () => async ({ dispatch: dispatch3 }) => { 6562 const currentUser2 = await (0, import_api_fetch9.default)({ path: "/wp/v2/users/me" }); 6563 dispatch3.receiveCurrentUser(currentUser2); 6564 }; 6565 var getEntityRecord2 = (kind, name, key = "", query) => async ({ select: select5, dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => { 6566 const configs = await resolveSelect2.getEntitiesConfig(kind); 6567 const entityConfig = configs.find( 6568 (config) => config.name === name && config.kind === kind 6569 ); 6570 if (!entityConfig) { 6571 return; 6572 } 6573 const lock2 = await dispatch3.__unstableAcquireStoreLock( 6574 STORE_NAME, 6575 ["entities", "records", kind, name, key], 6576 { exclusive: false } 6577 ); 6578 try { 6579 if (query !== void 0 && query._fields) { 6580 query = { 6581 ...query, 6582 _fields: [ 6583 .../* @__PURE__ */ new Set([ 6584 ...get_normalized_comma_separable_default(query._fields) || [], 6585 entityConfig.key || DEFAULT_ENTITY_KEY 6586 ]) 6587 ].join() 6588 }; 6589 } 6590 if (query !== void 0 && query._fields) { 6591 const hasRecord = select5.hasEntityRecord( 6592 kind, 6593 name, 6594 key, 6595 query 6596 ); 6597 if (hasRecord) { 6598 return; 6599 } 6600 } 6601 const { baseURL } = entityConfig; 6602 const path = (0, import_url6.addQueryArgs)(baseURL + (key ? "/" + key : ""), { 6603 ...entityConfig.baseURLParams, 6604 ...query 6605 }); 6606 const response = await (0, import_api_fetch9.default)({ path, parse: false }); 6607 const record = await response.json(); 6608 const permissions = getUserPermissionsFromAllowHeader( 6609 response.headers?.get("allow") 6610 ); 6611 const canUserResolutionsArgs = []; 6612 const receiveUserPermissionArgs = {}; 6613 for (const action of ALLOWED_RESOURCE_ACTIONS) { 6614 receiveUserPermissionArgs[getUserPermissionCacheKey(action, { 6615 kind, 6616 name, 6617 id: key 6618 })] = permissions[action]; 6619 canUserResolutionsArgs.push([ 6620 action, 6621 { kind, name, id: key } 6622 ]); 6623 } 6624 if (entityConfig.syncConfig && isNumericID(key) && !query) { 6625 const objectType = `$kind}/$name}`; 6626 const objectId = key; 6627 const recordWithTransients = { ...record }; 6628 Object.entries(entityConfig.transientEdits ?? {}).filter( 6629 ([propName, transientConfig]) => void 0 === recordWithTransients[propName] && transientConfig && "object" === typeof transientConfig && "read" in transientConfig && "function" === typeof transientConfig.read 6630 ).forEach(([propName, transientConfig]) => { 6631 recordWithTransients[propName] = transientConfig.read(recordWithTransients); 6632 }); 6633 if (recordWithTransients.blocks && typeof recordWithTransients.content?.raw === "string") { 6634 setCachedBlocks( 6635 kind, 6636 name, 6637 key, 6638 recordWithTransients.content.raw, 6639 recordWithTransients.blocks 6640 ); 6641 } 6642 const syncManager2 = select5?.isCollaborationSupported?.() === false ? void 0 : getSyncManager(); 6643 void syncManager2?.load( 6644 entityConfig.syncConfig, 6645 objectType, 6646 objectId, 6647 recordWithTransients, 6648 { 6649 // Handle edits sourced from the sync manager. 6650 editRecord: (edits, options = {}) => { 6651 if (!Object.keys(edits).length) { 6652 return; 6653 } 6654 dispatch3({ 6655 type: "EDIT_ENTITY_RECORD", 6656 kind, 6657 name, 6658 recordId: key, 6659 edits, 6660 meta: { 6661 undo: void 0 6662 }, 6663 options 6664 }); 6665 }, 6666 // Get the current entity record (with edits) 6667 getEditedRecord: async () => await resolveSelect2.getEditedEntityRecord( 6668 kind, 6669 name, 6670 key 6671 ), 6672 // Handle sync connection status changes. 6673 onStatusChange: (status) => { 6674 dispatch3.setSyncConnectionStatus( 6675 kind, 6676 name, 6677 key, 6678 status 6679 ); 6680 }, 6681 // Refetch the current entity record from the database. 6682 refetchRecord: async () => { 6683 dispatch3.receiveEntityRecords( 6684 kind, 6685 name, 6686 await (0, import_api_fetch9.default)({ path, parse: true }), 6687 query 6688 ); 6689 }, 6690 // Persist the CRDT document. 6691 // 6692 // TODO: Currently, persisted CRDT documents are stored in post meta. 6693 // This effectively means that only post entities support CRDT 6694 // persistence. As we add support for syncing additional entity, 6695 // we'll need to revisit where persisted CRDT documents are stored. 6696 persistCRDTDoc: () => { 6697 if (!entityConfig.syncConfig?.supportsPersistence) { 6698 return; 6699 } 6700 return resolveSelect2.getEditedEntityRecord(kind, name, key).then(async (editedRecord) => { 6701 const { meta, status } = editedRecord; 6702 if ("auto-draft" === status || !meta) { 6703 return; 6704 } 6705 const entityIdKey = entityConfig.key || DEFAULT_ENTITY_KEY; 6706 const entityId = editedRecord[entityIdKey]; 6707 await saveCRDTDoc( 6708 `$kind}/$name}`, 6709 entityId 6710 ); 6711 }); 6712 }, 6713 addUndoMeta: (ydoc, meta) => { 6714 const selectionHistory = getSelectionHistory(ydoc); 6715 if (selectionHistory) { 6716 meta.set( 6717 "selectionHistory", 6718 selectionHistory 6719 ); 6720 } 6721 }, 6722 onUndoStackChange: (undoState) => { 6723 dispatch3.__unstableNotifySyncUndoManagerChange( 6724 undoState 6725 ); 6726 }, 6727 restoreUndoMeta: (ydoc, meta) => { 6728 const selectionHistory = meta.get("selectionHistory"); 6729 if (selectionHistory) { 6730 setTimeout(() => { 6731 restoreSelection(selectionHistory, ydoc); 6732 }, 0); 6733 } 6734 } 6735 } 6736 ); 6737 } 6738 registry.batch(() => { 6739 dispatch3.receiveEntityRecords(kind, name, record, query); 6740 dispatch3.receiveUserPermissions(receiveUserPermissionArgs); 6741 dispatch3.finishResolutions("canUser", canUserResolutionsArgs); 6742 }); 6743 } finally { 6744 dispatch3.__unstableReleaseStoreLock(lock2); 6745 } 6746 }; 6747 getEntityRecord2.shouldInvalidate = (action, kind, name) => { 6748 return kind === "root" && name === "site" && (action.type === "RECEIVE_ITEMS" && // Making sure persistedEdits is set seems to be the only way of 6749 // knowing whether it's an update or fetch. Only an update would 6750 // have persistedEdits. 6751 action.persistedEdits && action.persistedEdits.status !== "auto-draft" || action.type === "REMOVE_ITEMS") && action.kind === "postType" && action.name === "wp_template"; 6752 }; 6753 var getRawEntityRecord2 = forward_resolver_default("getEntityRecord"); 6754 var getEditedEntityRecord2 = forward_resolver_default("getEntityRecord"); 6755 var getEntityRecords2 = (kind, name, query = {}) => async ({ dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => { 6756 const configs = await resolveSelect2.getEntitiesConfig(kind); 6757 const entityConfig = configs.find( 6758 (config) => config.name === name && config.kind === kind 6759 ); 6760 if (!entityConfig) { 6761 return; 6762 } 6763 const lock2 = await dispatch3.__unstableAcquireStoreLock( 6764 STORE_NAME, 6765 ["entities", "records", kind, name], 6766 { exclusive: false } 6767 ); 6768 const rawQuery = { ...query }; 6769 const key = entityConfig.key || DEFAULT_ENTITY_KEY; 6770 function getResolutionsArgs(records, recordsQuery) { 6771 const normalizedQuery = normalizeQueryForResolution(recordsQuery); 6772 return records.filter((record) => record?.[key]).map((record) => [ 6773 kind, 6774 name, 6775 record[key], 6776 normalizedQuery 6777 ]); 6778 } 6779 try { 6780 if (query._fields) { 6781 query = { 6782 ...query, 6783 _fields: [ 6784 .../* @__PURE__ */ new Set([ 6785 ...get_normalized_comma_separable_default(query._fields) || [], 6786 key 6787 ]) 6788 ].join() 6789 }; 6790 } 6791 const { baseURL } = entityConfig; 6792 const path = (0, import_url6.addQueryArgs)(baseURL, { 6793 ...entityConfig.baseURLParams, 6794 ...query 6795 }); 6796 let records = [], meta; 6797 if (entityConfig.supportsPagination && query.per_page !== -1) { 6798 const response = await (0, import_api_fetch9.default)({ path, parse: false }); 6799 records = Object.values(await response.json()); 6800 meta = getPaginationMeta(response.headers); 6801 } else if (query.per_page === -1 && query[RECEIVE_INTERMEDIATE_RESULTS] === true) { 6802 let page = 1; 6803 let totalPages; 6804 do { 6805 const response = await (0, import_api_fetch9.default)({ 6806 path: (0, import_url6.addQueryArgs)(path, { page, per_page: 100 }), 6807 parse: false 6808 }); 6809 const pageRecords = Object.values(await response.json()); 6810 const pageMeta = getPaginationMeta(response.headers); 6811 totalPages = pageMeta.totalPages ?? 1; 6812 if (!meta) { 6813 meta = { 6814 totalItems: pageMeta.totalItems, 6815 totalPages: 1 6816 }; 6817 } 6818 records.push(...pageRecords); 6819 registry.batch(() => { 6820 dispatch3.receiveEntityRecords( 6821 kind, 6822 name, 6823 records, 6824 query, 6825 false, 6826 void 0, 6827 meta 6828 ); 6829 dispatch3.finishResolutions( 6830 "getEntityRecord", 6831 getResolutionsArgs(pageRecords, rawQuery) 6832 ); 6833 }); 6834 page++; 6835 } while (page <= totalPages); 6836 } else { 6837 records = Object.values(await (0, import_api_fetch9.default)({ path })); 6838 meta = { 6839 totalItems: records.length, 6840 totalPages: 1 6841 }; 6842 } 6843 if (entityConfig.syncConfig && -1 === query.per_page) { 6844 const objectType = `$kind}/$name}`; 6845 getSyncManager()?.loadCollection( 6846 entityConfig.syncConfig, 6847 objectType, 6848 { 6849 onStatusChange: (status) => { 6850 dispatch3.setSyncConnectionStatus( 6851 kind, 6852 name, 6853 null, 6854 status 6855 ); 6856 }, 6857 refetchRecords: async () => { 6858 dispatch3.receiveEntityRecords( 6859 kind, 6860 name, 6861 await (0, import_api_fetch9.default)({ path, parse: true }), 6862 query 6863 ); 6864 } 6865 } 6866 ); 6867 } 6868 if (query._fields) { 6869 records = records.map((record) => { 6870 query._fields.split(",").forEach((field) => { 6871 if (!record.hasOwnProperty(field)) { 6872 record[field] = void 0; 6873 } 6874 }); 6875 return record; 6876 }); 6877 } 6878 registry.batch(() => { 6879 dispatch3.receiveEntityRecords( 6880 kind, 6881 name, 6882 records, 6883 query, 6884 false, 6885 void 0, 6886 meta 6887 ); 6888 const targetHints = records.filter( 6889 (record) => !!record?.[key] && !!record?._links?.self?.[0]?.targetHints?.allow 6890 ).map((record) => ({ 6891 id: record[key], 6892 permissions: getUserPermissionsFromAllowHeader( 6893 record._links.self[0].targetHints.allow 6894 ) 6895 })); 6896 const canUserResolutionsArgs = []; 6897 const receiveUserPermissionArgs = {}; 6898 for (const targetHint of targetHints) { 6899 for (const action of ALLOWED_RESOURCE_ACTIONS) { 6900 canUserResolutionsArgs.push([ 6901 action, 6902 { kind, name, id: targetHint.id } 6903 ]); 6904 receiveUserPermissionArgs[getUserPermissionCacheKey(action, { 6905 kind, 6906 name, 6907 id: targetHint.id 6908 })] = targetHint.permissions[action]; 6909 } 6910 } 6911 if (targetHints.length > 0) { 6912 dispatch3.receiveUserPermissions( 6913 receiveUserPermissionArgs 6914 ); 6915 dispatch3.finishResolutions( 6916 "canUser", 6917 canUserResolutionsArgs 6918 ); 6919 } 6920 dispatch3.finishResolutions( 6921 "getEntityRecord", 6922 getResolutionsArgs(records, rawQuery) 6923 ); 6924 dispatch3.__unstableReleaseStoreLock(lock2); 6925 }); 6926 } catch { 6927 dispatch3.__unstableReleaseStoreLock(lock2); 6928 } 6929 }; 6930 getEntityRecords2.shouldInvalidate = (action, kind, name) => { 6931 return (action.type === "RECEIVE_ITEMS" || action.type === "REMOVE_ITEMS") && action.invalidateCache && kind === action.kind && name === action.name; 6932 }; 6933 var getEntityRecordsTotalItems2 = forward_resolver_default("getEntityRecords"); 6934 var getEntityRecordsTotalPages2 = forward_resolver_default("getEntityRecords"); 6935 var getCurrentTheme2 = () => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 6936 const activeThemes = await resolveSelect2.getEntityRecords( 6937 "root", 6938 "theme", 6939 { status: "active" } 6940 ); 6941 dispatch3.receiveCurrentTheme(activeThemes[0]); 6942 }; 6943 var getThemeSupports2 = forward_resolver_default("getCurrentTheme"); 6944 var getEmbedPreview2 = (url) => async ({ dispatch: dispatch3 }) => { 6945 try { 6946 const embedProxyResponse = await (0, import_api_fetch9.default)({ 6947 path: (0, import_url6.addQueryArgs)("/oembed/1.0/proxy", { url }) 6948 }); 6949 dispatch3.receiveEmbedPreview(url, embedProxyResponse); 6950 } catch { 6951 dispatch3.receiveEmbedPreview(url, false); 6952 } 6953 }; 6954 var canUser2 = (requestedAction, resource, id) => async ({ dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => { 6955 if (!ALLOWED_RESOURCE_ACTIONS.includes(requestedAction)) { 6956 throw new Error(`'$requestedAction}' is not a valid action.`); 6957 } 6958 const { hasStartedResolution } = registry.select(STORE_NAME); 6959 for (const relatedAction of ALLOWED_RESOURCE_ACTIONS) { 6960 if (relatedAction === requestedAction) { 6961 continue; 6962 } 6963 const isAlreadyResolving = hasStartedResolution("canUser", [ 6964 relatedAction, 6965 resource, 6966 id 6967 ]); 6968 if (isAlreadyResolving) { 6969 return; 6970 } 6971 } 6972 let resourcePath = null; 6973 if (typeof resource === "object") { 6974 if (!resource.kind || !resource.name) { 6975 throw new Error("The entity resource object is not valid."); 6976 } 6977 const configs = await resolveSelect2.getEntitiesConfig( 6978 resource.kind 6979 ); 6980 const entityConfig = configs.find( 6981 (config) => config.name === resource.name && config.kind === resource.kind 6982 ); 6983 if (!entityConfig) { 6984 return; 6985 } 6986 resourcePath = entityConfig.baseURL + (resource.id ? "/" + resource.id : ""); 6987 } else { 6988 resourcePath = `/wp/v2/$resource}` + (id ? "/" + id : ""); 6989 } 6990 let response; 6991 try { 6992 response = await (0, import_api_fetch9.default)({ 6993 path: resourcePath, 6994 method: "OPTIONS", 6995 parse: false 6996 }); 6997 } catch { 6998 return; 6999 } 7000 const permissions = getUserPermissionsFromAllowHeader( 7001 response.headers?.get("allow") 7002 ); 7003 const receiveUserPermissionArgs = {}; 7004 const canUserResolutionsArgs = []; 7005 for (const action of ALLOWED_RESOURCE_ACTIONS) { 7006 receiveUserPermissionArgs[getUserPermissionCacheKey(action, resource, id)] = permissions[action]; 7007 if (action !== requestedAction) { 7008 canUserResolutionsArgs.push([action, resource, id]); 7009 } 7010 } 7011 registry.batch(() => { 7012 dispatch3.receiveUserPermissions(receiveUserPermissionArgs); 7013 dispatch3.finishResolutions("canUser", canUserResolutionsArgs); 7014 }); 7015 }; 7016 var canUserEditEntityRecord2 = (kind, name, recordId) => async ({ dispatch: dispatch3 }) => { 7017 await dispatch3(canUser2("update", { kind, name, id: recordId })); 7018 }; 7019 var getAutosaves2 = (postType, postId) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 7020 const { 7021 rest_base: restBase, 7022 rest_namespace: restNamespace = "wp/v2", 7023 supports 7024 } = await resolveSelect2.getPostType(postType); 7025 if (!supports?.autosave) { 7026 return; 7027 } 7028 const autosaves2 = await (0, import_api_fetch9.default)({ 7029 path: `/$restNamespace}/$restBase}/$postId}/autosaves?context=edit` 7030 }); 7031 if (autosaves2 && autosaves2.length) { 7032 dispatch3.receiveAutosaves(postId, autosaves2); 7033 } 7034 }; 7035 var getAutosave2 = (postType, postId) => async ({ resolveSelect: resolveSelect2 }) => { 7036 await resolveSelect2.getAutosaves(postType, postId); 7037 }; 7038 var __experimentalGetCurrentGlobalStylesId2 = () => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 7039 const activeThemes = await resolveSelect2.getEntityRecords( 7040 "root", 7041 "theme", 7042 { status: "active" } 7043 ); 7044 const globalStylesURL = activeThemes?.[0]?._links?.["wp:user-global-styles"]?.[0]?.href; 7045 if (!globalStylesURL) { 7046 return; 7047 } 7048 const matches = globalStylesURL.match(/\/(\d+)(?:\?|$)/); 7049 const id = matches ? Number(matches[1]) : null; 7050 if (id) { 7051 dispatch3.__experimentalReceiveCurrentGlobalStylesId(id); 7052 } 7053 }; 7054 var __experimentalGetCurrentThemeBaseGlobalStyles2 = () => async ({ resolveSelect: resolveSelect2, dispatch: dispatch3 }) => { 7055 const currentTheme2 = await resolveSelect2.getCurrentTheme(); 7056 const themeGlobalStyles = await (0, import_api_fetch9.default)({ 7057 path: `/wp/v2/global-styles/themes/$currentTheme2.stylesheet}?context=view` 7058 }); 7059 dispatch3.__experimentalReceiveThemeBaseGlobalStyles( 7060 currentTheme2.stylesheet, 7061 themeGlobalStyles 7062 ); 7063 }; 7064 var __experimentalGetCurrentThemeGlobalStylesVariations2 = () => async ({ resolveSelect: resolveSelect2, dispatch: dispatch3 }) => { 7065 const currentTheme2 = await resolveSelect2.getCurrentTheme(); 7066 const variations = await (0, import_api_fetch9.default)({ 7067 path: `/wp/v2/global-styles/themes/$currentTheme2.stylesheet}/variations?context=view` 7068 }); 7069 dispatch3.__experimentalReceiveThemeGlobalStyleVariations( 7070 currentTheme2.stylesheet, 7071 variations 7072 ); 7073 }; 7074 var getCurrentThemeGlobalStylesRevisions2 = () => async ({ resolveSelect: resolveSelect2, dispatch: dispatch3 }) => { 7075 const globalStylesId = await resolveSelect2.__experimentalGetCurrentGlobalStylesId(); 7076 const record = globalStylesId ? await resolveSelect2.getEntityRecord( 7077 "root", 7078 "globalStyles", 7079 globalStylesId 7080 ) : void 0; 7081 const revisionsURL = record?._links?.["version-history"]?.[0]?.href; 7082 if (revisionsURL) { 7083 const resetRevisions = await (0, import_api_fetch9.default)({ 7084 url: revisionsURL 7085 }); 7086 const revisions = resetRevisions?.map( 7087 (revision) => Object.fromEntries( 7088 Object.entries(revision).map(([key, value]) => [ 7089 camelCase(key), 7090 value 7091 ]) 7092 ) 7093 ); 7094 dispatch3.receiveThemeGlobalStyleRevisions( 7095 globalStylesId, 7096 revisions 7097 ); 7098 } 7099 }; 7100 getCurrentThemeGlobalStylesRevisions2.shouldInvalidate = (action) => { 7101 return action.type === "SAVE_ENTITY_RECORD_FINISH" && action.kind === "root" && !action.error && action.name === "globalStyles"; 7102 }; 7103 var getBlockPatterns2 = () => async ({ dispatch: dispatch3 }) => { 7104 const patterns = await fetchBlockPatterns(); 7105 dispatch3({ type: "RECEIVE_BLOCK_PATTERNS", patterns }); 7106 }; 7107 var getBlockPatternCategories2 = () => async ({ dispatch: dispatch3 }) => { 7108 const categories = await (0, import_api_fetch9.default)({ 7109 path: "/wp/v2/block-patterns/categories" 7110 }); 7111 dispatch3({ type: "RECEIVE_BLOCK_PATTERN_CATEGORIES", categories }); 7112 }; 7113 var getUserPatternCategories2 = () => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 7114 const patternCategories = await resolveSelect2.getEntityRecords( 7115 "taxonomy", 7116 "wp_pattern_category", 7117 { 7118 per_page: -1, 7119 _fields: "id,name,description,slug", 7120 context: "view" 7121 } 7122 ); 7123 const mappedPatternCategories = patternCategories?.map((userCategory) => ({ 7124 ...userCategory, 7125 label: (0, import_html_entities3.decodeEntities)(userCategory.name), 7126 name: userCategory.slug 7127 })) || []; 7128 dispatch3({ 7129 type: "RECEIVE_USER_PATTERN_CATEGORIES", 7130 patternCategories: mappedPatternCategories 7131 }); 7132 }; 7133 var getNavigationFallbackId2 = () => async ({ dispatch: dispatch3, select: select5, registry }) => { 7134 const fallback = await (0, import_api_fetch9.default)({ 7135 path: (0, import_url6.addQueryArgs)("/wp-block-editor/v1/navigation-fallback", { 7136 _embed: true 7137 }) 7138 }); 7139 const record = fallback?._embedded?.self; 7140 registry.batch(() => { 7141 dispatch3.receiveNavigationFallbackId(fallback?.id); 7142 if (!record) { 7143 return; 7144 } 7145 const existingFallbackEntityRecord = select5.getEntityRecord( 7146 "postType", 7147 "wp_navigation", 7148 fallback.id 7149 ); 7150 const invalidateNavigationQueries = !existingFallbackEntityRecord; 7151 dispatch3.receiveEntityRecords( 7152 "postType", 7153 "wp_navigation", 7154 record, 7155 void 0, 7156 invalidateNavigationQueries 7157 ); 7158 dispatch3.finishResolution("getEntityRecord", [ 7159 "postType", 7160 "wp_navigation", 7161 fallback.id 7162 ]); 7163 }); 7164 }; 7165 var getDefaultTemplateId2 = (query) => async ({ dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => { 7166 const template = await (0, import_api_fetch9.default)({ 7167 path: (0, import_url6.addQueryArgs)("/wp/v2/templates/lookup", query) 7168 }); 7169 await resolveSelect2.getEntitiesConfig("postType"); 7170 const id = template?.id; 7171 registry.batch(() => { 7172 dispatch3.receiveDefaultTemplateId(query, id || ""); 7173 if (id) { 7174 template.id = id; 7175 dispatch3.receiveEntityRecords( 7176 "postType", 7177 template.type, 7178 template 7179 ); 7180 dispatch3.finishResolution("getEntityRecord", [ 7181 "postType", 7182 template.type, 7183 id 7184 ]); 7185 } 7186 }); 7187 }; 7188 var getRevisions2 = (kind, name, recordKey, query = {}) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 7189 const configs = await resolveSelect2.getEntitiesConfig(kind); 7190 const entityConfig = configs.find( 7191 (config) => config.name === name && config.kind === kind 7192 ); 7193 if (!entityConfig) { 7194 return; 7195 } 7196 const rawQuery = { ...query }; 7197 const lock2 = await dispatch3.__unstableAcquireStoreLock( 7198 STORE_NAME, 7199 ["entities", "records", kind, name, recordKey, "revisions"], 7200 { exclusive: false } 7201 ); 7202 try { 7203 if (query._fields) { 7204 query = { 7205 ...query, 7206 _fields: [ 7207 .../* @__PURE__ */ new Set([ 7208 ...get_normalized_comma_separable_default(query._fields) || [], 7209 entityConfig.revisionKey || DEFAULT_ENTITY_KEY 7210 ]) 7211 ].join() 7212 }; 7213 } 7214 const path = (0, import_url6.addQueryArgs)( 7215 entityConfig.getRevisionsUrl(recordKey), 7216 query 7217 ); 7218 let records, response; 7219 const meta = {}; 7220 const isPaginated = entityConfig.supportsPagination && query.per_page !== -1; 7221 try { 7222 response = await (0, import_api_fetch9.default)({ path, parse: !isPaginated }); 7223 } catch { 7224 return; 7225 } 7226 if (response) { 7227 if (isPaginated) { 7228 records = Object.values(await response.json()); 7229 meta.totalItems = getPaginationMeta( 7230 response.headers 7231 ).totalItems; 7232 } else { 7233 records = Object.values(response); 7234 } 7235 if (query._fields) { 7236 records = records.map((record) => { 7237 query._fields.split(",").forEach((field) => { 7238 if (!record.hasOwnProperty(field)) { 7239 record[field] = void 0; 7240 } 7241 }); 7242 return record; 7243 }); 7244 } 7245 await dispatch3.receiveRevisions( 7246 kind, 7247 name, 7248 recordKey, 7249 records, 7250 query, 7251 false, 7252 meta 7253 ); 7254 const key = entityConfig.revisionKey || DEFAULT_ENTITY_KEY; 7255 const normalizedQuery = normalizeQueryForResolution(rawQuery); 7256 const resolutionsArgs = records.filter((record) => record[key]).map((record) => [ 7257 kind, 7258 name, 7259 recordKey, 7260 record[key], 7261 normalizedQuery 7262 ]); 7263 dispatch3.finishResolutions("getRevision", resolutionsArgs); 7264 } 7265 } finally { 7266 dispatch3.__unstableReleaseStoreLock(lock2); 7267 } 7268 }; 7269 getRevisions2.shouldInvalidate = (action, kind, name, recordKey) => action.type === "SAVE_ENTITY_RECORD_FINISH" && name === action.name && kind === action.kind && !action.error && recordKey === action.recordId; 7270 var getRevision2 = (kind, name, recordKey, revisionKey, query) => async ({ select: select5, dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 7271 const configs = await resolveSelect2.getEntitiesConfig(kind); 7272 const entityConfig = configs.find( 7273 (config) => config.name === name && config.kind === kind 7274 ); 7275 if (!entityConfig) { 7276 return; 7277 } 7278 if (query !== void 0 && query._fields) { 7279 query = { 7280 ...query, 7281 _fields: [ 7282 .../* @__PURE__ */ new Set([ 7283 ...get_normalized_comma_separable_default(query._fields) || [], 7284 entityConfig.revisionKey || DEFAULT_ENTITY_KEY 7285 ]) 7286 ].join() 7287 }; 7288 } 7289 const lock2 = await dispatch3.__unstableAcquireStoreLock( 7290 STORE_NAME, 7291 [ 7292 "entities", 7293 "records", 7294 kind, 7295 name, 7296 recordKey, 7297 "revisions", 7298 revisionKey 7299 ], 7300 { exclusive: false } 7301 ); 7302 try { 7303 if (select5.hasRevision(kind, name, recordKey, revisionKey, query)) { 7304 return; 7305 } 7306 const path = (0, import_url6.addQueryArgs)( 7307 entityConfig.getRevisionsUrl(recordKey, revisionKey), 7308 query 7309 ); 7310 let record; 7311 try { 7312 record = await (0, import_api_fetch9.default)({ path }); 7313 } catch { 7314 return; 7315 } 7316 if (record) { 7317 await dispatch3.receiveRevisions( 7318 kind, 7319 name, 7320 recordKey, 7321 record, 7322 query 7323 ); 7324 } 7325 } finally { 7326 dispatch3.__unstableReleaseStoreLock(lock2); 7327 } 7328 }; 7329 var getRegisteredPostMeta2 = (postType) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 7330 let options; 7331 try { 7332 const { 7333 rest_namespace: restNamespace = "wp/v2", 7334 rest_base: restBase 7335 } = await resolveSelect2.getPostType(postType) || {}; 7336 options = await (0, import_api_fetch9.default)({ 7337 path: `$restNamespace}/$restBase}/?context=edit`, 7338 method: "OPTIONS" 7339 }); 7340 } catch { 7341 return; 7342 } 7343 if (options) { 7344 dispatch3.receiveRegisteredPostMeta( 7345 postType, 7346 options?.schema?.properties?.meta?.properties 7347 ); 7348 } 7349 }; 7350 var getEntitiesConfig2 = (kind) => async ({ dispatch: dispatch3 }) => { 7351 const loader = additionalEntityConfigLoaders.find( 7352 (l) => l.kind === kind 7353 ); 7354 if (!loader) { 7355 return; 7356 } 7357 try { 7358 const configs = await loader.loadEntities(); 7359 if (!configs.length) { 7360 return; 7361 } 7362 dispatch3.addEntities(configs); 7363 } catch { 7364 } 7365 }; 7366 var getEditorSettings2 = () => async ({ dispatch: dispatch3 }) => { 7367 const settings = await (0, import_api_fetch9.default)({ 7368 path: "/wp-block-editor/v1/settings" 7369 }); 7370 dispatch3.receiveEditorSettings(settings); 7371 }; 7372 var getEditorAssets2 = () => async ({ dispatch: dispatch3 }) => { 7373 const assets = await (0, import_api_fetch9.default)({ 7374 path: "/wp-block-editor/v1/assets" 7375 }); 7376 dispatch3.receiveEditorAssets(assets); 7377 }; 7378 var getViewConfig2 = (kind, name, options = {}) => async ({ dispatch: dispatch3 }) => { 7379 const query = { kind, name }; 7380 const fields = get_normalized_comma_separable_default(options.fields); 7381 if (fields?.length) { 7382 query._fields = fields.join(","); 7383 } 7384 const config = await (0, import_api_fetch9.default)({ 7385 path: (0, import_url6.addQueryArgs)("/wp/v2/view-config", query) 7386 }); 7387 dispatch3.receiveViewConfig(kind, name, config); 7388 }; 7389 7390 // packages/core-data/build-module/locks/utils.mjs 7391 function deepCopyLocksTreePath(tree, path) { 7392 const newTree = { ...tree }; 7393 let currentNode = newTree; 7394 for (const branchName of path) { 7395 currentNode.children = { 7396 ...currentNode.children, 7397 [branchName]: { 7398 locks: [], 7399 children: {}, 7400 ...currentNode.children[branchName] 7401 } 7402 }; 7403 currentNode = currentNode.children[branchName]; 7404 } 7405 return newTree; 7406 } 7407 function getNode(tree, path) { 7408 let currentNode = tree; 7409 for (const branchName of path) { 7410 const nextNode = currentNode.children[branchName]; 7411 if (!nextNode) { 7412 return null; 7413 } 7414 currentNode = nextNode; 7415 } 7416 return currentNode; 7417 } 7418 function* iteratePath(tree, path) { 7419 let currentNode = tree; 7420 yield currentNode; 7421 for (const branchName of path) { 7422 const nextNode = currentNode.children[branchName]; 7423 if (!nextNode) { 7424 break; 7425 } 7426 yield nextNode; 7427 currentNode = nextNode; 7428 } 7429 } 7430 function* iterateDescendants(node) { 7431 const stack = Object.values(node.children); 7432 while (stack.length) { 7433 const childNode = stack.pop(); 7434 yield childNode; 7435 stack.push(...Object.values(childNode.children)); 7436 } 7437 } 7438 function hasConflictingLock({ exclusive }, locks2) { 7439 if (exclusive && locks2.length) { 7440 return true; 7441 } 7442 if (!exclusive && locks2.filter((lock2) => lock2.exclusive).length) { 7443 return true; 7444 } 7445 return false; 7446 } 7447 7448 // packages/core-data/build-module/locks/reducer.mjs 7449 var DEFAULT_STATE = { 7450 requests: [], 7451 tree: { 7452 locks: [], 7453 children: {} 7454 } 7455 }; 7456 function locks(state = DEFAULT_STATE, action) { 7457 switch (action.type) { 7458 case "ENQUEUE_LOCK_REQUEST": { 7459 const { request } = action; 7460 return { 7461 ...state, 7462 requests: [request, ...state.requests] 7463 }; 7464 } 7465 case "GRANT_LOCK_REQUEST": { 7466 const { lock: lock2, request } = action; 7467 const { store: store2, path } = request; 7468 const storePath = [store2, ...path]; 7469 const newTree = deepCopyLocksTreePath(state.tree, storePath); 7470 const node = getNode(newTree, storePath); 7471 node.locks = [...node.locks, lock2]; 7472 return { 7473 ...state, 7474 requests: state.requests.filter((r2) => r2 !== request), 7475 tree: newTree 7476 }; 7477 } 7478 case "RELEASE_LOCK": { 7479 const { lock: lock2 } = action; 7480 const storePath = [lock2.store, ...lock2.path]; 7481 const newTree = deepCopyLocksTreePath(state.tree, storePath); 7482 const node = getNode(newTree, storePath); 7483 node.locks = node.locks.filter((l) => l !== lock2); 7484 return { 7485 ...state, 7486 tree: newTree 7487 }; 7488 } 7489 } 7490 return state; 7491 } 7492 7493 // packages/core-data/build-module/locks/selectors.mjs 7494 function getPendingLockRequests(state) { 7495 return state.requests; 7496 } 7497 function isLockAvailable(state, store2, path, { exclusive }) { 7498 const storePath = [store2, ...path]; 7499 const locks2 = state.tree; 7500 for (const node2 of iteratePath(locks2, storePath)) { 7501 if (hasConflictingLock({ exclusive }, node2.locks)) { 7502 return false; 7503 } 7504 } 7505 const node = getNode(locks2, storePath); 7506 if (!node) { 7507 return true; 7508 } 7509 for (const descendant of iterateDescendants(node)) { 7510 if (hasConflictingLock({ exclusive }, descendant.locks)) { 7511 return false; 7512 } 7513 } 7514 return true; 7515 } 7516 7517 // packages/core-data/build-module/locks/engine.mjs 7518 function createLocks() { 7519 let state = locks(void 0, { type: "@@INIT" }); 7520 function processPendingLockRequests() { 7521 for (const request of getPendingLockRequests(state)) { 7522 const { store: store2, path, exclusive, notifyAcquired } = request; 7523 if (isLockAvailable(state, store2, path, { exclusive })) { 7524 const lock2 = { store: store2, path, exclusive }; 7525 state = locks(state, { 7526 type: "GRANT_LOCK_REQUEST", 7527 lock: lock2, 7528 request 7529 }); 7530 notifyAcquired(lock2); 7531 } 7532 } 7533 } 7534 function acquire(store2, path, exclusive) { 7535 return new Promise((resolve) => { 7536 state = locks(state, { 7537 type: "ENQUEUE_LOCK_REQUEST", 7538 request: { store: store2, path, exclusive, notifyAcquired: resolve } 7539 }); 7540 processPendingLockRequests(); 7541 }); 7542 } 7543 function release(lock2) { 7544 state = locks(state, { 7545 type: "RELEASE_LOCK", 7546 lock: lock2 7547 }); 7548 processPendingLockRequests(); 7549 } 7550 return { acquire, release }; 7551 } 7552 7553 // packages/core-data/build-module/locks/actions.mjs 7554 function createLocksActions() { 7555 const locks2 = createLocks(); 7556 function __unstableAcquireStoreLock(store2, path, { exclusive }) { 7557 return () => locks2.acquire(store2, path, exclusive); 7558 } 7559 function __unstableReleaseStoreLock(lock2) { 7560 return () => locks2.release(lock2); 7561 } 7562 return { __unstableAcquireStoreLock, __unstableReleaseStoreLock }; 7563 } 7564 7565 // packages/core-data/build-module/dynamic-entities.mjs 7566 var dynamicActions; 7567 var dynamicSelectors; 7568 7569 // packages/core-data/build-module/entity-provider.mjs 7570 var import_element2 = __toESM(require_element(), 1); 7571 7572 // packages/core-data/build-module/entity-context.mjs 7573 var import_element = __toESM(require_element(), 1); 7574 var EntityContext = (0, import_element.createContext)({}); 7575 EntityContext.displayName = "EntityContext"; 7576 7577 // packages/core-data/build-module/entity-provider.mjs 7578 var import_jsx_runtime = __toESM(require_jsx_runtime(), 1); 7579 function EntityProvider({ 7580 kind, 7581 type: name, 7582 id, 7583 revisionId, 7584 children 7585 }) { 7586 const parent = (0, import_element2.useContext)(EntityContext); 7587 const childContext = (0, import_element2.useMemo)( 7588 () => ({ 7589 ...parent, 7590 ...kind && { 7591 [kind]: { 7592 ...parent?.[kind], 7593 [name]: id 7594 } 7595 }, 7596 ...revisionId !== void 0 && kind && { 7597 revision: { 7598 ...parent?.revision, 7599 [kind]: { 7600 ...parent?.revision?.[kind], 7601 [name]: revisionId 7602 } 7603 } 7604 } 7605 }), 7606 [parent, kind, name, id, revisionId] 7607 ); 7608 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EntityContext.Provider, { value: childContext, children }); 7609 } 7610 7611 // packages/core-data/build-module/hooks/use-entity-record.mjs 7612 var import_data11 = __toESM(require_data(), 1); 7613 var import_deprecated4 = __toESM(require_deprecated(), 1); 7614 var import_element3 = __toESM(require_element(), 1); 7615 7616 // packages/core-data/build-module/hooks/constants.mjs 7617 var Status = /* @__PURE__ */ ((Status2) => { 7618 Status2["Idle"] = "IDLE"; 7619 Status2["Resolving"] = "RESOLVING"; 7620 Status2["Error"] = "ERROR"; 7621 Status2["Success"] = "SUCCESS"; 7622 return Status2; 7623 })(Status || {}); 7624 7625 // packages/core-data/build-module/hooks/utils.mjs 7626 function getResolutionStatus(resolutionStatus) { 7627 let status; 7628 switch (resolutionStatus) { 7629 case "resolving": 7630 status = Status.Resolving; 7631 break; 7632 case "finished": 7633 status = Status.Success; 7634 break; 7635 case "error": 7636 status = Status.Error; 7637 break; 7638 default: 7639 status = Status.Idle; 7640 } 7641 return { 7642 status, 7643 isResolving: status === Status.Resolving, 7644 hasStarted: status !== Status.Idle, 7645 hasResolved: status === Status.Success || status === Status.Error 7646 }; 7647 } 7648 7649 // packages/core-data/build-module/hooks/use-entity-record.mjs 7650 var EMPTY_OBJECT3 = {}; 7651 function useEntityRecord(kind, name, recordId, options = { enabled: true }) { 7652 const { editEntityRecord: editEntityRecord2, saveEditedEntityRecord: saveEditedEntityRecord2 } = (0, import_data11.useDispatch)(store); 7653 const mutations = (0, import_element3.useMemo)( 7654 () => ({ 7655 edit: (record2, editOptions = {}) => editEntityRecord2(kind, name, recordId, record2, editOptions), 7656 save: (saveOptions = {}) => saveEditedEntityRecord2(kind, name, recordId, { 7657 throwOnError: true, 7658 ...saveOptions 7659 }) 7660 }), 7661 [editEntityRecord2, kind, name, recordId, saveEditedEntityRecord2] 7662 ); 7663 const { record, editedRecord, hasEdits, edits, ...resolution } = (0, import_data11.useSelect)( 7664 (select5) => { 7665 if (!options.enabled) { 7666 return { 7667 record: null, 7668 editedRecord: EMPTY_OBJECT3, 7669 hasEdits: false, 7670 edits: EMPTY_OBJECT3, 7671 ...getResolutionStatus() 7672 }; 7673 } 7674 const storeSelectors = select5(store); 7675 const resolutionStatus = storeSelectors.getResolutionState( 7676 "getEntityRecord", 7677 [kind, name, recordId] 7678 )?.status; 7679 return { 7680 record: storeSelectors.getEntityRecord( 7681 kind, 7682 name, 7683 recordId 7684 ) ?? null, 7685 editedRecord: storeSelectors.getEditedEntityRecord( 7686 kind, 7687 name, 7688 recordId 7689 ), 7690 hasEdits: storeSelectors.hasEditsForEntityRecord( 7691 kind, 7692 name, 7693 recordId 7694 ), 7695 edits: storeSelectors.getEntityRecordNonTransientEdits( 7696 kind, 7697 name, 7698 recordId 7699 ), 7700 ...getResolutionStatus(resolutionStatus) 7701 }; 7702 }, 7703 [kind, name, recordId, options.enabled] 7704 ); 7705 return { 7706 record, 7707 editedRecord, 7708 hasEdits, 7709 edits, 7710 ...resolution, 7711 ...mutations 7712 }; 7713 } 7714 function useDeprecatedEntityRecord(kind, name, recordId, options) { 7715 (0, import_deprecated4.default)(`wp.data.__experimentalUseEntityRecord`, { 7716 alternative: "wp.data.useEntityRecord", 7717 since: "6.1" 7718 }); 7719 return useEntityRecord(kind, name, recordId, options); 7720 } 7721 7722 // packages/core-data/build-module/hooks/use-entity-records.mjs 7723 var import_url7 = __toESM(require_url(), 1); 7724 var import_deprecated5 = __toESM(require_deprecated(), 1); 7725 var import_data12 = __toESM(require_data(), 1); 7726 var import_element4 = __toESM(require_element(), 1); 7727 var EMPTY_ARRAY = []; 7728 function useEntityRecords(kind, name, queryArgs = {}, options = { enabled: true }) { 7729 const queryAsString = (0, import_url7.addQueryArgs)("", queryArgs); 7730 const { records, totalItems, totalPages, ...rest } = (0, import_data12.useSelect)( 7731 (select5) => { 7732 if (!options.enabled) { 7733 return { 7734 // Avoiding returning a new reference on every execution. 7735 records: EMPTY_ARRAY, 7736 totalItems: null, 7737 totalPages: null, 7738 ...getResolutionStatus() 7739 }; 7740 } 7741 const storeSelectors = select5(store); 7742 const resolutionStatus = storeSelectors.getResolutionState( 7743 "getEntityRecords", 7744 [kind, name, queryArgs] 7745 )?.status; 7746 return { 7747 records: storeSelectors.getEntityRecords( 7748 kind, 7749 name, 7750 queryArgs 7751 ), 7752 totalItems: storeSelectors.getEntityRecordsTotalItems( 7753 kind, 7754 name, 7755 queryArgs 7756 ), 7757 totalPages: storeSelectors.getEntityRecordsTotalPages( 7758 kind, 7759 name, 7760 queryArgs 7761 ), 7762 ...getResolutionStatus(resolutionStatus) 7763 }; 7764 }, 7765 [kind, name, queryAsString, options.enabled] 7766 ); 7767 return { 7768 records, 7769 totalItems, 7770 totalPages, 7771 ...rest 7772 }; 7773 } 7774 function useDeprecatedEntityRecords(kind, name, queryArgs, options) { 7775 (0, import_deprecated5.default)(`wp.data.__experimentalUseEntityRecords`, { 7776 alternative: "wp.data.useEntityRecords", 7777 since: "6.1" 7778 }); 7779 return useEntityRecords(kind, name, queryArgs, options); 7780 } 7781 function useEntityRecordsWithPermissions(kind, name, queryArgs = {}, options = { enabled: true }) { 7782 const entityConfig = (0, import_data12.useSelect)( 7783 (select5) => select5(store).getEntityConfig(kind, name), 7784 [kind, name] 7785 ); 7786 const { records: data, ...ret } = useEntityRecords( 7787 kind, 7788 name, 7789 { 7790 ...queryArgs, 7791 // If _fields is provided, we need to include _links in the request for permission caching to work. 7792 ...queryArgs._fields ? { 7793 _fields: [ 7794 .../* @__PURE__ */ new Set([ 7795 ...get_normalized_comma_separable_default( 7796 queryArgs._fields 7797 ) || [], 7798 "_links" 7799 ]) 7800 ].join() 7801 } : {} 7802 }, 7803 options 7804 ); 7805 const ids = (0, import_element4.useMemo)( 7806 () => data?.map( 7807 // @ts-expect-error `data` is `unknown[]`, so the callback signature does not line up. 7808 (record) => record[entityConfig?.key ?? "id"] 7809 ) ?? [], 7810 [data, entityConfig?.key] 7811 ); 7812 const permissions = (0, import_data12.useSelect)( 7813 (select5) => { 7814 const { getEntityRecordsPermissions: getEntityRecordsPermissions2 } = unlock( 7815 select5(store) 7816 ); 7817 return getEntityRecordsPermissions2(kind, name, ids); 7818 }, 7819 [ids, kind, name] 7820 ); 7821 const dataWithPermissions = (0, import_element4.useMemo)( 7822 () => data?.map((record, index) => ({ 7823 // @ts-expect-error `record` is `unknown`, which cannot be spread. 7824 ...record, 7825 permissions: permissions[index] 7826 })) ?? [], 7827 [data, permissions] 7828 ); 7829 return { records: dataWithPermissions, ...ret }; 7830 } 7831 7832 // packages/core-data/build-module/hooks/use-resource-permissions.mjs 7833 var import_deprecated6 = __toESM(require_deprecated(), 1); 7834 var import_warning = __toESM(require_warning(), 1); 7835 7836 // packages/core-data/build-module/hooks/use-query-select.mjs 7837 var import_data13 = __toESM(require_data(), 1); 7838 7839 // node_modules/memize/dist/index.js 7840 function memize(fn, options) { 7841 var size = 0; 7842 var head; 7843 var tail; 7844 options = options || {}; 7845 function memoized() { 7846 var node = head, len = arguments.length, args, i; 7847 searchCache: while (node) { 7848 if (node.args.length !== arguments.length) { 7849 node = node.next; 7850 continue; 7851 } 7852 for (i = 0; i < len; i++) { 7853 if (node.args[i] !== arguments[i]) { 7854 node = node.next; 7855 continue searchCache; 7856 } 7857 } 7858 if (node !== head) { 7859 if (node === tail) { 7860 tail = node.prev; 7861 } 7862 node.prev.next = node.next; 7863 if (node.next) { 7864 node.next.prev = node.prev; 7865 } 7866 node.next = head; 7867 node.prev = null; 7868 head.prev = node; 7869 head = node; 7870 } 7871 return node.val; 7872 } 7873 args = new Array(len); 7874 for (i = 0; i < len; i++) { 7875 args[i] = arguments[i]; 7876 } 7877 node = { 7878 args, 7879 // Generate the result from original function 7880 val: fn.apply(null, args) 7881 }; 7882 if (head) { 7883 head.prev = node; 7884 node.next = head; 7885 } else { 7886 tail = node; 7887 } 7888 if (size === /** @type {MemizeOptions} */ 7889 options.maxSize) { 7890 tail = /** @type {MemizeCacheNode} */ 7891 tail.prev; 7892 tail.next = null; 7893 } else { 7894 size++; 7895 } 7896 head = node; 7897 return node.val; 7898 } 7899 memoized.clear = function() { 7900 head = null; 7901 tail = null; 7902 size = 0; 7903 }; 7904 return memoized; 7905 } 7906 7907 // packages/core-data/build-module/hooks/use-query-select.mjs 7908 var META_SELECTORS = [ 7909 "getIsResolving", 7910 "hasStartedResolution", 7911 "hasFinishedResolution", 7912 "isResolving", 7913 "getCachedResolvers" 7914 ]; 7915 function useQuerySelect(mapQuerySelect, deps) { 7916 return (0, import_data13.useSelect)((select5, registry) => { 7917 const resolve = (store2) => enrichSelectors(select5(store2)); 7918 return mapQuerySelect(resolve, registry); 7919 }, deps); 7920 } 7921 var enrichSelectors = memize(((selectors) => { 7922 const resolvers = {}; 7923 for (const selectorName in selectors) { 7924 if (META_SELECTORS.includes(selectorName)) { 7925 continue; 7926 } 7927 Object.defineProperty(resolvers, selectorName, { 7928 get: () => (...args) => { 7929 const data = selectors[selectorName](...args); 7930 const resolutionStatus = selectors.getResolutionState( 7931 selectorName, 7932 args 7933 )?.status; 7934 return { 7935 data, 7936 ...getResolutionStatus(resolutionStatus) 7937 }; 7938 } 7939 }); 7940 } 7941 return resolvers; 7942 })); 7943 7944 // packages/core-data/build-module/hooks/use-resource-permissions.mjs 7945 function useResourcePermissions(resource, id) { 7946 const isEntity = typeof resource === "object"; 7947 const resourceAsString = isEntity ? JSON.stringify(resource) : resource; 7948 if (isEntity && typeof id !== "undefined") { 7949 (0, import_warning.default)( 7950 `When 'resource' is an entity object, passing 'id' as a separate argument isn't supported.` 7951 ); 7952 } 7953 return useQuerySelect( 7954 (resolve) => { 7955 const hasId = isEntity ? !!resource.id : !!id; 7956 const { canUser: canUser3 } = resolve(store); 7957 const collectionResource = isEntity ? { kind: resource.kind, name: resource.name } : resource; 7958 const create3 = canUser3("create", collectionResource); 7959 if (!hasId) { 7960 const read2 = canUser3("read", collectionResource); 7961 const isResolving2 = create3.isResolving || read2.isResolving; 7962 const hasResolved2 = create3.hasResolved && read2.hasResolved; 7963 let status2 = Status.Idle; 7964 if (isResolving2) { 7965 status2 = Status.Resolving; 7966 } else if (hasResolved2) { 7967 status2 = Status.Success; 7968 } 7969 return { 7970 status: status2, 7971 isResolving: isResolving2, 7972 hasResolved: hasResolved2, 7973 canCreate: create3.hasResolved && create3.data, 7974 canRead: read2.hasResolved && read2.data 7975 }; 7976 } 7977 const read = canUser3("read", resource, id); 7978 const update = canUser3("update", resource, id); 7979 const _delete = canUser3("delete", resource, id); 7980 const isResolving = read.isResolving || create3.isResolving || update.isResolving || _delete.isResolving; 7981 const hasResolved = read.hasResolved && create3.hasResolved && update.hasResolved && _delete.hasResolved; 7982 let status = Status.Idle; 7983 if (isResolving) { 7984 status = Status.Resolving; 7985 } else if (hasResolved) { 7986 status = Status.Success; 7987 } 7988 return { 7989 status, 7990 isResolving, 7991 hasResolved, 7992 canRead: hasResolved && read.data, 7993 canCreate: hasResolved && create3.data, 7994 canUpdate: hasResolved && update.data, 7995 canDelete: hasResolved && _delete.data 7996 }; 7997 }, 7998 [resourceAsString, id] 7999 ); 8000 } 8001 var use_resource_permissions_default = useResourcePermissions; 8002 function useDeprecatedResourcePermissions(resource, id) { 8003 (0, import_deprecated6.default)(`wp.data.__experimentalUseResourcePermissions`, { 8004 alternative: "wp.data.useResourcePermissions", 8005 since: "6.1" 8006 }); 8007 return useResourcePermissions(resource, id); 8008 } 8009 8010 // packages/core-data/build-module/hooks/use-entity-block-editor.mjs 8011 var import_element6 = __toESM(require_element(), 1); 8012 var import_data14 = __toESM(require_data(), 1); 8013 var import_blocks6 = __toESM(require_blocks(), 1); 8014 8015 // packages/core-data/build-module/hooks/use-entity-id.mjs 8016 var import_element5 = __toESM(require_element(), 1); 8017 function useEntityId(kind, name) { 8018 const context = (0, import_element5.useContext)(EntityContext); 8019 return context?.[kind]?.[name]; 8020 } 8021 8022 // packages/core-data/build-module/footnotes/index.mjs 8023 var import_rich_text4 = __toESM(require_rich_text(), 1); 8024 var import_warning2 = __toESM(require_warning(), 1); 8025 8026 // packages/core-data/build-module/footnotes/get-rich-text-values-cached.mjs 8027 var import_block_editor6 = __toESM(require_block_editor(), 1); 8028 var unlockedApis; 8029 var cache = /* @__PURE__ */ new WeakMap(); 8030 function getRichTextValuesCached(block) { 8031 if (!unlockedApis) { 8032 unlockedApis = unlock(import_block_editor6.privateApis); 8033 } 8034 if (!cache.has(block)) { 8035 const values = unlockedApis.getRichTextValues([block]); 8036 cache.set(block, values); 8037 } 8038 return cache.get(block); 8039 } 8040 8041 // packages/core-data/build-module/footnotes/get-footnotes-order.mjs 8042 var cache2 = /* @__PURE__ */ new WeakMap(); 8043 function getBlockFootnotesOrder(block) { 8044 if (!cache2.has(block)) { 8045 const order = []; 8046 for (const value of getRichTextValuesCached(block)) { 8047 if (!value) { 8048 continue; 8049 } 8050 value.replacements.forEach(({ type, attributes }) => { 8051 if (type === "core/footnote") { 8052 order.push(attributes["data-fn"]); 8053 } 8054 }); 8055 } 8056 cache2.set(block, order); 8057 } 8058 return cache2.get(block); 8059 } 8060 function getFootnotesOrder(blocks) { 8061 return blocks.flatMap(getBlockFootnotesOrder); 8062 } 8063 8064 // packages/core-data/build-module/footnotes/index.mjs 8065 var oldFootnotes = {}; 8066 function updateFootnotesFromMeta(blocks, meta) { 8067 const output = { blocks }; 8068 if (!meta) { 8069 return output; 8070 } 8071 if (meta.footnotes === void 0) { 8072 return output; 8073 } 8074 const newOrder = getFootnotesOrder(blocks); 8075 let parsed; 8076 try { 8077 parsed = JSON.parse(meta.footnotes || "[]"); 8078 } catch { 8079 } 8080 let footnotes = []; 8081 if (Array.isArray(parsed)) { 8082 footnotes = parsed; 8083 } else { 8084 (0, import_warning2.default)("Footnotes post meta is not a JSON array; ignoring it."); 8085 } 8086 const currentOrder = footnotes.map((fn) => fn.id); 8087 if (currentOrder.join("") === newOrder.join("")) { 8088 return output; 8089 } 8090 const newFootnotes = newOrder.map( 8091 (fnId) => footnotes.find((fn) => fn.id === fnId) || oldFootnotes[fnId] || { 8092 id: fnId, 8093 content: "" 8094 } 8095 ); 8096 function updateAttributes(attributes) { 8097 if (!attributes || Array.isArray(attributes) || typeof attributes !== "object") { 8098 return attributes; 8099 } 8100 attributes = { ...attributes }; 8101 for (const key in attributes) { 8102 const value = attributes[key]; 8103 if (Array.isArray(value)) { 8104 attributes[key] = value.map(updateAttributes); 8105 continue; 8106 } 8107 if (typeof value !== "string" && !(value instanceof import_rich_text4.RichTextData)) { 8108 continue; 8109 } 8110 const richTextValue = typeof value === "string" ? import_rich_text4.RichTextData.fromHTMLString(value) : new import_rich_text4.RichTextData(value); 8111 let hasFootnotes = false; 8112 richTextValue.replacements.forEach((replacement) => { 8113 if (replacement.type === "core/footnote") { 8114 const id = replacement.attributes["data-fn"]; 8115 const index = newOrder.indexOf(id); 8116 const countValue = (0, import_rich_text4.create)({ 8117 html: replacement.innerHTML 8118 }); 8119 countValue.text = String(index + 1); 8120 countValue.formats = Array.from( 8121 { length: countValue.text.length }, 8122 () => countValue.formats[0] 8123 ); 8124 countValue.replacements = Array.from( 8125 { length: countValue.text.length }, 8126 () => countValue.replacements[0] 8127 ); 8128 replacement.innerHTML = (0, import_rich_text4.toHTMLString)({ 8129 value: countValue 8130 }); 8131 hasFootnotes = true; 8132 } 8133 }); 8134 if (hasFootnotes) { 8135 attributes[key] = typeof value === "string" ? richTextValue.toHTMLString() : richTextValue; 8136 } 8137 } 8138 return attributes; 8139 } 8140 function updateBlocksAttributes(__blocks) { 8141 return __blocks.map((block) => { 8142 return { 8143 ...block, 8144 attributes: updateAttributes(block.attributes), 8145 innerBlocks: updateBlocksAttributes(block.innerBlocks) 8146 }; 8147 }); 8148 } 8149 const newBlocks = updateBlocksAttributes(blocks); 8150 oldFootnotes = { 8151 ...oldFootnotes, 8152 ...footnotes.reduce((acc, fn) => { 8153 if (!newOrder.includes(fn.id)) { 8154 acc[fn.id] = fn; 8155 } 8156 return acc; 8157 }, {}) 8158 }; 8159 return { 8160 meta: { 8161 ...meta, 8162 footnotes: JSON.stringify(newFootnotes) 8163 }, 8164 blocks: newBlocks 8165 }; 8166 } 8167 8168 // packages/core-data/build-module/hooks/use-entity-block-editor.mjs 8169 var EMPTY_ARRAY2 = []; 8170 function useEntityBlockEditor(kind, name, { id: _id } = {}) { 8171 const providerId = useEntityId(kind, name); 8172 const id = _id ?? providerId; 8173 const { content, editedBlocks, meta } = (0, import_data14.useSelect)( 8174 (select5) => { 8175 if (!id) { 8176 return {}; 8177 } 8178 const { getEditedEntityRecord: getEditedEntityRecord3 } = select5(STORE_NAME); 8179 const editedRecord = getEditedEntityRecord3(kind, name, id); 8180 return { 8181 editedBlocks: editedRecord.blocks, 8182 content: editedRecord.content, 8183 meta: editedRecord.meta 8184 }; 8185 }, 8186 [kind, name, id] 8187 ); 8188 const { __unstableCreateUndoLevel: __unstableCreateUndoLevel2, editEntityRecord: editEntityRecord2 } = (0, import_data14.useDispatch)(STORE_NAME); 8189 const blocks = (0, import_element6.useMemo)(() => { 8190 if (!id) { 8191 return void 0; 8192 } 8193 if (editedBlocks) { 8194 return editedBlocks; 8195 } 8196 if (!content || typeof content !== "string") { 8197 return EMPTY_ARRAY2; 8198 } 8199 let _blocks = getCachedBlocks(kind, name, id, content); 8200 if (!_blocks) { 8201 _blocks = (0, import_blocks6.parse)(content); 8202 setCachedBlocks(kind, name, id, content, _blocks); 8203 } 8204 return _blocks; 8205 }, [kind, name, id, editedBlocks, content]); 8206 const onChange = (0, import_element6.useCallback)( 8207 (newBlocks, options) => { 8208 const noChange = blocks === newBlocks; 8209 if (noChange) { 8210 return __unstableCreateUndoLevel2(kind, name, id); 8211 } 8212 const { selection, ...rest } = options; 8213 const edits = { 8214 selection, 8215 content: ({ blocks: blocksForSerialization = [] }) => (0, import_blocks6.__unstableSerializeAndClean)(blocksForSerialization), 8216 ...updateFootnotesFromMeta(newBlocks, meta) 8217 }; 8218 editEntityRecord2(kind, name, id, edits, { 8219 isCached: false, 8220 ...rest 8221 }); 8222 }, 8223 [ 8224 kind, 8225 name, 8226 id, 8227 blocks, 8228 meta, 8229 __unstableCreateUndoLevel2, 8230 editEntityRecord2 8231 ] 8232 ); 8233 const onInput = (0, import_element6.useCallback)( 8234 (newBlocks, options) => { 8235 const { selection, ...rest } = options; 8236 const edits = { 8237 selection, 8238 ...updateFootnotesFromMeta(newBlocks, meta) 8239 }; 8240 editEntityRecord2(kind, name, id, edits, { 8241 isCached: true, 8242 ...rest 8243 }); 8244 }, 8245 [kind, name, id, meta, editEntityRecord2] 8246 ); 8247 return [blocks, onInput, onChange]; 8248 } 8249 8250 // packages/core-data/build-module/hooks/use-entity-prop.mjs 8251 var import_element7 = __toESM(require_element(), 1); 8252 var import_data15 = __toESM(require_data(), 1); 8253 var REVISION_QUERY = { 8254 context: "edit", 8255 _fields: "id,date,author,meta,title,excerpt,content.raw" 8256 }; 8257 function useEntityProp(kind, name, prop, _id) { 8258 const providerId = useEntityId(kind, name); 8259 const id = _id ?? providerId; 8260 const context = (0, import_element7.useContext)(EntityContext); 8261 const revisionId = String(id) === String(providerId) ? context?.revision?.[kind]?.[name] : void 0; 8262 const { value, fullValue } = (0, import_data15.useSelect)( 8263 (select5) => { 8264 if (revisionId) { 8265 const revision = select5(STORE_NAME).getRevision( 8266 kind, 8267 name, 8268 id, 8269 revisionId, 8270 REVISION_QUERY 8271 ); 8272 const propValue = revision?.[prop]; 8273 if (propValue === void 0) { 8274 return {}; 8275 } 8276 const isRawAttribute = propValue !== null && typeof propValue === "object" && "raw" in propValue; 8277 return { 8278 value: isRawAttribute ? propValue.raw : propValue, 8279 fullValue: propValue 8280 }; 8281 } 8282 const { getEntityRecord: getEntityRecord3, getEditedEntityRecord: getEditedEntityRecord3 } = select5(STORE_NAME); 8283 const record = getEntityRecord3(kind, name, id); 8284 const editedRecord = getEditedEntityRecord3(kind, name, id); 8285 return record && editedRecord ? { 8286 value: editedRecord[prop], 8287 fullValue: record[prop] 8288 } : {}; 8289 }, 8290 [kind, name, id, prop, revisionId] 8291 ); 8292 const { editEntityRecord: editEntityRecord2 } = (0, import_data15.useDispatch)(STORE_NAME); 8293 const setValue = (0, import_element7.useCallback)( 8294 (newValue) => { 8295 if (revisionId) { 8296 return; 8297 } 8298 editEntityRecord2(kind, name, id, { 8299 [prop]: newValue 8300 }); 8301 }, 8302 [editEntityRecord2, kind, name, id, prop, revisionId] 8303 ); 8304 return [value, setValue, fullValue]; 8305 } 8306 8307 // packages/core-data/build-module/hooks/use-post-editor-awareness-state.mjs 8308 var import_compose3 = __toESM(require_compose(), 1); 8309 var import_element8 = __toESM(require_element(), 1); 8310 var defaultResolvedSelection = { 8311 richTextOffset: null, 8312 localClientId: null, 8313 attributeKey: null 8314 }; 8315 var defaultState = { 8316 activeCollaborators: [], 8317 resolveSelection: () => defaultResolvedSelection, 8318 getDebugData: () => ({ 8319 doc: {}, 8320 clients: {}, 8321 collaboratorMap: {} 8322 }), 8323 isCurrentCollaboratorDisconnected: false 8324 }; 8325 function getAwarenessState(awareness, newState) { 8326 const activeCollaborators = (newState ?? awareness.getCurrentState()).filter( 8327 (collaborator) => isCollaboratorInfo(collaborator.collaboratorInfo) 8328 ); 8329 return { 8330 activeCollaborators, 8331 resolveSelection: (selection, blocks) => awareness.convertSelectionStateToAbsolute(selection, blocks), 8332 getDebugData: () => awareness.getDebugData(), 8333 isCurrentCollaboratorDisconnected: activeCollaborators.find((collaborator) => collaborator.isMe)?.isConnected === false 8334 }; 8335 } 8336 function usePostEditorAwarenessState(postId, postType) { 8337 const [state, setState] = (0, import_element8.useState)(defaultState); 8338 (0, import_element8.useEffect)(() => { 8339 if (null === postId || null === postType) { 8340 setState(defaultState); 8341 return; 8342 } 8343 const objectType = `postType/$postType}`; 8344 const objectId = postId.toString(); 8345 const awareness = getSyncManager()?.getAwareness( 8346 objectType, 8347 objectId 8348 ); 8349 if (!awareness) { 8350 setState(defaultState); 8351 return; 8352 } 8353 awareness.setUp(); 8354 setState(getAwarenessState(awareness)); 8355 const unsubscribe = awareness?.onStateChange( 8356 (newState) => { 8357 setState(getAwarenessState(awareness, newState)); 8358 } 8359 ); 8360 return unsubscribe; 8361 }, [postId, postType]); 8362 return state; 8363 } 8364 function useActiveCollaborators(postId, postType) { 8365 return usePostEditorAwarenessState(postId, postType).activeCollaborators; 8366 } 8367 function useResolvedSelection(postId, postType) { 8368 const blocks = usePostContentBlocks(); 8369 const awarenessState = usePostEditorAwarenessState(postId, postType); 8370 return (0, import_element8.useCallback)( 8371 (selection) => awarenessState.resolveSelection(selection, blocks), 8372 [blocks, awarenessState] 8373 ); 8374 } 8375 function useLastPostSave(postId, postType) { 8376 const [lastSave, setLastSave] = (0, import_element8.useState)(null); 8377 (0, import_element8.useEffect)(() => { 8378 if (null === postId || null === postType) { 8379 setLastSave(null); 8380 return; 8381 } 8382 const awareness = getSyncManager()?.getAwareness( 8383 `postType/$postType}`, 8384 postId.toString() 8385 ); 8386 if (!awareness) { 8387 setLastSave(null); 8388 return; 8389 } 8390 awareness.setUp(); 8391 const stateMap = awareness.doc.getMap("state"); 8392 const recordMap = awareness.doc.getMap("document"); 8393 const setupTime = Date.now(); 8394 const observer = (event) => { 8395 if (event.keysChanged.has("savedAt")) { 8396 const savedAt = stateMap.get("savedAt"); 8397 const savedByClientId = stateMap.get("savedBy"); 8398 if (typeof savedAt === "number" && typeof savedByClientId === "number" && savedAt > setupTime) { 8399 const postStatus = recordMap.get("status"); 8400 setLastSave({ savedAt, savedByClientId, postStatus }); 8401 } 8402 } 8403 }; 8404 stateMap.observe(observer); 8405 return () => { 8406 stateMap.unobserve(observer); 8407 }; 8408 }, [postId, postType]); 8409 return lastSave; 8410 } 8411 function useOnCollaboratorJoin(postId, postType, callback) { 8412 const { activeCollaborators } = usePostEditorAwarenessState( 8413 postId, 8414 postType 8415 ); 8416 const prevCollaborators = (0, import_compose3.usePrevious)(activeCollaborators); 8417 (0, import_element8.useEffect)(() => { 8418 if (!prevCollaborators || prevCollaborators.length === 0) { 8419 return; 8420 } 8421 const prevMap = new Map( 8422 prevCollaborators.map((collaborator) => [ 8423 collaborator.clientId, 8424 collaborator 8425 ]) 8426 ); 8427 const me = activeCollaborators.find( 8428 (collaborator) => collaborator.isMe 8429 ); 8430 for (const collaborator of activeCollaborators) { 8431 if (!prevMap.has(collaborator.clientId) && !collaborator.isMe) { 8432 callback(collaborator, me); 8433 } 8434 } 8435 }, [activeCollaborators, prevCollaborators, callback]); 8436 } 8437 function useOnCollaboratorLeave(postId, postType, callback) { 8438 const { activeCollaborators } = usePostEditorAwarenessState( 8439 postId, 8440 postType 8441 ); 8442 const prevCollaborators = (0, import_compose3.usePrevious)(activeCollaborators); 8443 (0, import_element8.useEffect)(() => { 8444 if (!prevCollaborators || prevCollaborators.length === 0) { 8445 return; 8446 } 8447 const newMap = new Map( 8448 activeCollaborators.map((collaborator) => [ 8449 collaborator.clientId, 8450 collaborator 8451 ]) 8452 ); 8453 for (const prevCollab of prevCollaborators) { 8454 if (prevCollab.isMe || !prevCollab.isConnected) { 8455 continue; 8456 } 8457 const newCollab = newMap.get(prevCollab.clientId); 8458 if (!newCollab?.isConnected) { 8459 callback(prevCollab); 8460 } 8461 } 8462 }, [activeCollaborators, prevCollaborators, callback]); 8463 } 8464 function useOnPostSave(postId, postType, callback) { 8465 const { activeCollaborators } = usePostEditorAwarenessState( 8466 postId, 8467 postType 8468 ); 8469 const lastPostSave = useLastPostSave(postId, postType); 8470 const prevPostSave = (0, import_compose3.usePrevious)(lastPostSave); 8471 (0, import_element8.useEffect)(() => { 8472 if (!lastPostSave) { 8473 return; 8474 } 8475 if (prevPostSave && lastPostSave.savedAt === prevPostSave.savedAt) { 8476 return; 8477 } 8478 const saver = activeCollaborators.find( 8479 (collaborator) => collaborator.clientId === lastPostSave.savedByClientId && !collaborator.isMe 8480 ); 8481 if (!saver) { 8482 return; 8483 } 8484 callback(lastPostSave, saver, prevPostSave ?? null); 8485 }, [lastPostSave, prevPostSave, activeCollaborators, callback]); 8486 } 8487 8488 // packages/icons/build-module/library/footer.mjs 8489 var import_primitives = __toESM(require_primitives(), 1); 8490 var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1); 8491 var footer_default = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_primitives.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_primitives.Path, { fillRule: "evenodd", d: "M18 5.5h-8v8h8.5V6a.5.5 0 00-.5-.5zm-9.5 8h-3V6a.5.5 0 01.5-.5h2.5v8zM6 4h12a2 2 0 012 2v12a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z" }) }); 8492 8493 // packages/icons/build-module/library/header.mjs 8494 var import_primitives2 = __toESM(require_primitives(), 1); 8495 var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1); 8496 var header_default = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_primitives2.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_primitives2.Path, { d: "M18.5 10.5H10v8h8a.5.5 0 00.5-.5v-7.5zm-10 0h-3V18a.5.5 0 00.5.5h2.5v-8zM6 4h12a2 2 0 012 2v12a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z" }) }); 8497 8498 // packages/icons/build-module/library/layout.mjs 8499 var import_primitives3 = __toESM(require_primitives(), 1); 8500 var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1); 8501 var layout_default = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_primitives3.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_primitives3.Path, { d: "M18 5.5H6a.5.5 0 00-.5.5v3h13V6a.5.5 0 00-.5-.5zm.5 5H10v8h8a.5.5 0 00.5-.5v-7.5zm-10 0h-3V18a.5.5 0 00.5.5h2.5v-8zM6 4h12a2 2 0 012 2v12a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z" }) }); 8502 8503 // packages/icons/build-module/library/navigation-overlay.mjs 8504 var import_primitives4 = __toESM(require_primitives(), 1); 8505 var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1); 8506 var navigation_overlay_default = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_primitives4.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_primitives4.Path, { d: "M18.5 10a1.5 1.5 0 0 1 1.5 1.5v7a1.5 1.5 0 0 1-1.5 1.5h-7a1.5 1.5 0 0 1-1.5-1.5v-7a1.5 1.5 0 0 1 1.5-1.5zM16 4a2 2 0 0 1 2 2v2h-1.5V6a.5.5 0 0 0-.5-.5H6a.5.5 0 0 0-.5.5v3H8v1.5H5.5V16a.5.5 0 0 0 .5.5h2V18H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z" }) }); 8507 8508 // packages/icons/build-module/library/sidebar.mjs 8509 var import_primitives5 = __toESM(require_primitives(), 1); 8510 var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1); 8511 var sidebar_default = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_primitives5.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_primitives5.Path, { d: "M18 5.5H6a.5.5 0 00-.5.5v3h13V6a.5.5 0 00-.5-.5zm.5 5H10v8h8a.5.5 0 00.5-.5v-7.5zM6 4h12a2 2 0 012 2v12a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z" }) }); 8512 8513 // packages/icons/build-module/library/symbol-filled.mjs 8514 var import_primitives6 = __toESM(require_primitives(), 1); 8515 var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1); 8516 var symbol_filled_default = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_primitives6.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_primitives6.Path, { d: "M21.3 10.8l-5.6-5.6c-.7-.7-1.8-.7-2.5 0l-5.6 5.6c-.7.7-.7 1.8 0 2.5l5.6 5.6c.3.3.8.5 1.2.5s.9-.2 1.2-.5l5.6-5.6c.8-.7.8-1.9.1-2.5zm-17.6 1L10 5.5l-1-1-6.3 6.3c-.7.7-.7 1.8 0 2.5L9 19.5l1.1-1.1-6.3-6.3c-.2 0-.2-.2-.1-.3z" }) }); 8517 8518 // packages/core-data/build-module/utils/get-template-part-icon.mjs 8519 function getTemplatePartIcon(areaOrIconName) { 8520 if ("header" === areaOrIconName) { 8521 return header_default; 8522 } else if ("footer" === areaOrIconName) { 8523 return footer_default; 8524 } else if ("sidebar" === areaOrIconName) { 8525 return sidebar_default; 8526 } else if ("navigation-overlay" === areaOrIconName) { 8527 return navigation_overlay_default; 8528 } 8529 return symbol_filled_default; 8530 } 8531 8532 // packages/core-data/build-module/utils/get-template-info.mjs 8533 var EMPTY_OBJECT4 = {}; 8534 var getTemplateInfo = (params) => { 8535 if (!params) { 8536 return EMPTY_OBJECT4; 8537 } 8538 const { templateTypes, templateAreas, template } = params; 8539 const { description, slug, title, area } = template; 8540 const { title: defaultTitle, description: defaultDescription } = Object.values(templateTypes).find((type) => type.slug === slug) ?? EMPTY_OBJECT4; 8541 const templateTitle = typeof title === "string" ? title : title?.rendered; 8542 const templateDescription = typeof description === "string" ? description : description?.raw; 8543 const templateAreasWithIcon = templateAreas?.map((item) => ({ 8544 ...item, 8545 icon: getTemplatePartIcon(item.icon) 8546 })); 8547 const templateIcon = templateAreasWithIcon?.find((item) => area === item.area)?.icon || layout_default; 8548 return { 8549 title: templateTitle && templateTitle !== slug ? templateTitle : defaultTitle || slug, 8550 description: templateDescription || defaultDescription, 8551 icon: templateIcon 8552 }; 8553 }; 8554 8555 // node_modules/clsx/dist/clsx.mjs 8556 function r(e) { 8557 var t, f, n = ""; 8558 if ("string" == typeof e || "number" == typeof e) n += e; 8559 else if ("object" == typeof e) if (Array.isArray(e)) { 8560 var o = e.length; 8561 for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f); 8562 } else for (f in e) e[f] && (n && (n += " "), n += f); 8563 return n; 8564 } 8565 function clsx() { 8566 for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t); 8567 return n; 8568 } 8569 var clsx_default = clsx; 8570 8571 // packages/core-data/build-module/components/entities-saved-states/index.mjs 8572 var import_components3 = __toESM(require_components(), 1); 8573 var import_i18n7 = __toESM(require_i18n(), 1); 8574 var import_element10 = __toESM(require_element(), 1); 8575 var import_compose4 = __toESM(require_compose(), 1); 8576 var import_data19 = __toESM(require_data(), 1); 8577 8578 // packages/core-data/build-module/components/entities-saved-states/entity-type-list.mjs 8579 var import_i18n6 = __toESM(require_i18n(), 1); 8580 var import_data17 = __toESM(require_data(), 1); 8581 var import_components2 = __toESM(require_components(), 1); 8582 8583 // packages/global-styles-engine/build-module/utils/get-global-styles-changes.mjs 8584 var import_i18n4 = __toESM(require_i18n(), 1); 8585 var import_blocks7 = __toESM(require_blocks(), 1); 8586 var globalStylesChangesCache = /* @__PURE__ */ new Map(); 8587 var EMPTY_ARRAY3 = []; 8588 var translationMap = { 8589 caption: (0, import_i18n4.__)("Caption"), 8590 link: (0, import_i18n4.__)("Link"), 8591 button: (0, import_i18n4.__)("Button"), 8592 heading: (0, import_i18n4.__)("Heading"), 8593 h1: (0, import_i18n4.__)("H1"), 8594 h2: (0, import_i18n4.__)("H2"), 8595 h3: (0, import_i18n4.__)("H3"), 8596 h4: (0, import_i18n4.__)("H4"), 8597 h5: (0, import_i18n4.__)("H5"), 8598 h6: (0, import_i18n4.__)("H6"), 8599 "settings.color": (0, import_i18n4.__)("Color"), 8600 "settings.typography": (0, import_i18n4.__)("Typography"), 8601 "settings.shadow": (0, import_i18n4.__)("Shadow"), 8602 "settings.layout": (0, import_i18n4.__)("Layout"), 8603 "styles.color": (0, import_i18n4.__)("Colors"), 8604 "styles.spacing": (0, import_i18n4.__)("Spacing"), 8605 "styles.background": (0, import_i18n4.__)("Background"), 8606 "styles.typography": (0, import_i18n4.__)("Typography"), 8607 "styles.border": (0, import_i18n4.__)("Border"), 8608 "styles.shadow": (0, import_i18n4.__)("Shadow"), 8609 "styles.outline": (0, import_i18n4.__)("Outline"), 8610 "styles.filter": (0, import_i18n4.__)("Filter"), 8611 "styles.dimensions": (0, import_i18n4.__)("Dimensions") 8612 }; 8613 var getBlockNames = memize( 8614 () => (0, import_blocks7.getBlockTypes)().reduce( 8615 (accumulator, { 8616 name, 8617 title 8618 }) => { 8619 accumulator[name] = title; 8620 return accumulator; 8621 }, 8622 {} 8623 ) 8624 ); 8625 var isObject = (obj) => obj !== null && typeof obj === "object"; 8626 function getTranslation(key) { 8627 if (translationMap[key]) { 8628 return translationMap[key]; 8629 } 8630 const keyArray = key.split("."); 8631 if (keyArray?.[0] === "blocks") { 8632 const blockName = getBlockNames()?.[keyArray[1]]; 8633 return blockName || keyArray[1]; 8634 } 8635 if (keyArray?.[0] === "elements") { 8636 return translationMap[keyArray[1]] || keyArray[1]; 8637 } 8638 return void 0; 8639 } 8640 function deepCompare(changedObject, originalObject, parentPath = "") { 8641 if (!isObject(changedObject) && !isObject(originalObject)) { 8642 return changedObject !== originalObject ? parentPath.split(".").slice(0, 2).join(".") : void 0; 8643 } 8644 changedObject = isObject(changedObject) ? changedObject : {}; 8645 originalObject = isObject(originalObject) ? originalObject : {}; 8646 const allKeys = /* @__PURE__ */ new Set([ 8647 ...Object.keys(changedObject), 8648 ...Object.keys(originalObject) 8649 ]); 8650 let diffs = []; 8651 for (const key of allKeys) { 8652 const path = parentPath ? parentPath + "." + key : key; 8653 const changedPath = deepCompare( 8654 changedObject[key], 8655 originalObject[key], 8656 path 8657 ); 8658 if (changedPath) { 8659 diffs = diffs.concat(changedPath); 8660 } 8661 } 8662 return diffs; 8663 } 8664 var COMPARED_STYLE_KEYS = [ 8665 "background", 8666 "color", 8667 "typography", 8668 "spacing", 8669 "border", 8670 "shadow", 8671 "outline", 8672 "filter", 8673 "dimensions" 8674 ]; 8675 function pickComparedStyles(config) { 8676 return Object.fromEntries( 8677 COMPARED_STYLE_KEYS.map((key) => [key, config?.styles?.[key]]) 8678 ); 8679 } 8680 function getGlobalStylesChangelist(next, previous) { 8681 const cacheKey = JSON.stringify({ next, previous }); 8682 if (globalStylesChangesCache.has(cacheKey)) { 8683 return globalStylesChangesCache.get(cacheKey); 8684 } 8685 const changedValueTree = deepCompare( 8686 { 8687 styles: pickComparedStyles(next), 8688 blocks: next?.styles?.blocks, 8689 elements: next?.styles?.elements, 8690 settings: next?.settings 8691 }, 8692 { 8693 styles: pickComparedStyles(previous), 8694 blocks: previous?.styles?.blocks, 8695 elements: previous?.styles?.elements, 8696 settings: previous?.settings 8697 } 8698 ); 8699 if (!changedValueTree || Array.isArray(changedValueTree) && !changedValueTree.length) { 8700 globalStylesChangesCache.set(cacheKey, []); 8701 return []; 8702 } 8703 const changedValueArray = Array.isArray(changedValueTree) ? changedValueTree : [changedValueTree]; 8704 const result = [...new Set(changedValueArray)].reduce((acc, curr) => { 8705 const translation = getTranslation(curr); 8706 if (translation) { 8707 acc.push([curr.split(".")[0], translation]); 8708 } 8709 return acc; 8710 }, []); 8711 globalStylesChangesCache.set(cacheKey, result); 8712 return result; 8713 } 8714 function getGlobalStylesChanges(next, previous, options = {}) { 8715 let changeList = getGlobalStylesChangelist(next, previous); 8716 const changesLength = changeList.length; 8717 const { maxResults } = options; 8718 if (changesLength) { 8719 if (!!maxResults && changesLength > maxResults) { 8720 changeList = changeList.slice(0, maxResults); 8721 } 8722 return Object.entries( 8723 changeList.reduce((acc, curr) => { 8724 const group = acc[curr[0]] || []; 8725 if (!group.includes(curr[1])) { 8726 acc[curr[0]] = [...group, curr[1]]; 8727 } 8728 return acc; 8729 }, {}) 8730 ).map(([key, changeValues]) => { 8731 const changeValuesLength = changeValues.length; 8732 const joinedChangesValue = changeValues.join( 8733 /* translators: Used between list items, there is a space after the comma. */ 8734 (0, import_i18n4.__)(", ") 8735 // eslint-disable-line @wordpress/i18n-no-flanking-whitespace 8736 ); 8737 switch (key) { 8738 case "blocks": { 8739 return (0, import_i18n4.sprintf)( 8740 // translators: %s: a list of block names separated by a comma. 8741 (0, import_i18n4._n)("%s block.", "%s blocks.", changeValuesLength), 8742 joinedChangesValue 8743 ); 8744 } 8745 case "elements": { 8746 return (0, import_i18n4.sprintf)( 8747 // translators: %s: a list of element names separated by a comma. 8748 (0, import_i18n4._n)("%s element.", "%s elements.", changeValuesLength), 8749 joinedChangesValue 8750 ); 8751 } 8752 case "settings": { 8753 return (0, import_i18n4.sprintf)( 8754 // translators: %s: a list of theme.json setting labels separated by a comma. 8755 (0, import_i18n4.__)("%s settings."), 8756 joinedChangesValue 8757 ); 8758 } 8759 case "styles": { 8760 return (0, import_i18n4.sprintf)( 8761 // translators: %s: a list of theme.json top-level styles labels separated by a comma. 8762 (0, import_i18n4.__)("%s styles."), 8763 joinedChangesValue 8764 ); 8765 } 8766 default: { 8767 return (0, import_i18n4.sprintf)( 8768 // translators: %s: a list of global styles changes separated by a comma. 8769 (0, import_i18n4.__)("%s."), 8770 joinedChangesValue 8771 ); 8772 } 8773 } 8774 }); 8775 } 8776 return EMPTY_ARRAY3; 8777 } 8778 8779 // packages/core-data/build-module/components/entities-saved-states/entity-record-item.mjs 8780 var import_components = __toESM(require_components(), 1); 8781 var import_i18n5 = __toESM(require_i18n(), 1); 8782 var import_data16 = __toESM(require_data(), 1); 8783 var import_html_entities4 = __toESM(require_html_entities(), 1); 8784 var import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1); 8785 function EntityRecordItem({ record, checked, onChange }) { 8786 const { name, kind, title, key } = record; 8787 const { entityRecordTitle } = (0, import_data16.useSelect)( 8788 (select5) => { 8789 if ("postType" !== kind || "wp_template" !== name) { 8790 return { 8791 entityRecordTitle: title 8792 }; 8793 } 8794 const template = select5(STORE_NAME).getEditedEntityRecord( 8795 kind, 8796 name, 8797 key 8798 ); 8799 const { default_template_types: templateTypes = [] } = select5(STORE_NAME).getCurrentTheme() ?? {}; 8800 return { 8801 entityRecordTitle: getTemplateInfo({ 8802 template, 8803 templateTypes 8804 }).title 8805 }; 8806 }, 8807 [name, kind, title, key] 8808 ); 8809 return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_components.PanelRow, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)( 8810 import_components.CheckboxControl, 8811 { 8812 label: (0, import_html_entities4.decodeEntities)(entityRecordTitle) || (0, import_i18n5.__)("Untitled"), 8813 checked, 8814 onChange, 8815 className: "entities-saved-states__change-control" 8816 } 8817 ) }) }); 8818 } 8819 8820 // packages/core-data/build-module/components/entities-saved-states/entity-type-list.mjs 8821 var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1); 8822 function getEntityDescription(entity2, count) { 8823 switch (entity2) { 8824 case "site": 8825 return 1 === count ? (0, import_i18n6.__)("This change will affect your whole site.") : (0, import_i18n6.__)("These changes will affect your whole site."); 8826 case "wp_template": 8827 return (0, import_i18n6.__)( 8828 "This change will affect other parts of your site that use this template." 8829 ); 8830 case "page": 8831 case "post": 8832 return (0, import_i18n6.__)("The following has been modified."); 8833 } 8834 } 8835 function GlobalStylesDescription({ record }) { 8836 const { editedRecord, savedRecord } = (0, import_data17.useSelect)( 8837 (select5) => { 8838 const { getEditedEntityRecord: getEditedEntityRecord3, getEntityRecord: getEntityRecord3 } = select5(STORE_NAME); 8839 return { 8840 editedRecord: getEditedEntityRecord3( 8841 record.kind, 8842 record.name, 8843 record.key 8844 ), 8845 savedRecord: getEntityRecord3( 8846 record.kind, 8847 record.name, 8848 record.key 8849 ) 8850 }; 8851 }, 8852 [record.kind, record.name, record.key] 8853 ); 8854 const globalStylesChanges = getGlobalStylesChanges( 8855 editedRecord, 8856 savedRecord, 8857 { 8858 maxResults: 10 8859 } 8860 ); 8861 return globalStylesChanges.length ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { className: "entities-saved-states__changes", children: globalStylesChanges.map((change) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("li", { children: change }, change)) }) : null; 8862 } 8863 function EntityDescription({ record, count }) { 8864 if ("globalStyles" === record?.name) { 8865 return null; 8866 } 8867 const description = getEntityDescription(record?.name, count); 8868 return description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components2.PanelRow, { children: description }) : null; 8869 } 8870 function EntityTypeList({ 8871 list, 8872 unselectedEntities, 8873 setUnselectedEntities 8874 }) { 8875 const count = list.length; 8876 const firstRecord = list[0]; 8877 const entityConfig = (0, import_data17.useSelect)( 8878 (select5) => select5(STORE_NAME).getEntityConfig( 8879 firstRecord.kind, 8880 firstRecord.name 8881 ), 8882 [firstRecord.kind, firstRecord.name] 8883 ); 8884 let entityLabel = entityConfig.label; 8885 if (firstRecord?.name === "wp_template_part") { 8886 entityLabel = 1 === count ? (0, import_i18n6.__)("Template Part") : (0, import_i18n6.__)("Template Parts"); 8887 } 8888 return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)( 8889 import_components2.PanelBody, 8890 { 8891 title: entityLabel, 8892 initialOpen: true, 8893 className: "entities-saved-states__panel-body", 8894 children: [ 8895 /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(EntityDescription, { record: firstRecord, count }), 8896 list.map((record) => { 8897 return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)( 8898 EntityRecordItem, 8899 { 8900 record, 8901 checked: !unselectedEntities.some( 8902 (elt) => elt.kind === record.kind && elt.name === record.name && elt.key === record.key && elt.property === record.property 8903 ), 8904 onChange: (value) => setUnselectedEntities(record, value) 8905 }, 8906 record.key || record.property 8907 ); 8908 }), 8909 "globalStyles" === firstRecord?.name && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(GlobalStylesDescription, { record: firstRecord }) 8910 ] 8911 } 8912 ); 8913 } 8914 8915 // packages/core-data/build-module/components/entities-saved-states/hooks/use-is-dirty.mjs 8916 var import_data18 = __toESM(require_data(), 1); 8917 var import_element9 = __toESM(require_element(), 1); 8918 var useIsDirty = () => { 8919 const { editedEntities, siteEdits, siteEntityConfig } = (0, import_data18.useSelect)( 8920 (select5) => { 8921 const { 8922 __experimentalGetDirtyEntityRecords: __experimentalGetDirtyEntityRecords2, 8923 getEntityRecordEdits: getEntityRecordEdits2, 8924 getEntityConfig: getEntityConfig2 8925 } = select5(STORE_NAME); 8926 return { 8927 editedEntities: __experimentalGetDirtyEntityRecords2(), 8928 siteEdits: getEntityRecordEdits2("root", "site"), 8929 siteEntityConfig: getEntityConfig2("root", "site") 8930 }; 8931 }, 8932 [] 8933 ); 8934 const dirtyEntityRecords = (0, import_element9.useMemo)(() => { 8935 const editedEntitiesWithoutSite = editedEntities.filter( 8936 (record) => !(record.kind === "root" && record.name === "site") 8937 ); 8938 const siteEntityLabels = siteEntityConfig?.meta?.labels ?? {}; 8939 const { 8940 title: siteTitleEdit, 8941 description: siteDescriptionEdit, 8942 site_logo: siteLogoEdit, 8943 site_icon: siteIconEdit, 8944 ...otherSiteEdits 8945 } = siteEdits ?? {}; 8946 const orderedSiteProperties = [ 8947 siteTitleEdit !== void 0 && "title", 8948 siteDescriptionEdit !== void 0 && "description", 8949 siteLogoEdit !== void 0 && "site_logo", 8950 siteIconEdit !== void 0 && "site_icon", 8951 ...Object.keys(otherSiteEdits) 8952 ].filter(Boolean); 8953 const editedSiteEntities = orderedSiteProperties.map( 8954 (property) => ({ 8955 kind: "root", 8956 name: "site", 8957 title: siteEntityLabels[property] || property, 8958 property 8959 }) 8960 ); 8961 return [...editedEntitiesWithoutSite, ...editedSiteEntities]; 8962 }, [editedEntities, siteEdits, siteEntityConfig]); 8963 const [unselectedEntities, _setUnselectedEntities] = (0, import_element9.useState)([]); 8964 const setUnselectedEntities = ({ kind, name, key, property }, checked) => { 8965 if (checked) { 8966 _setUnselectedEntities( 8967 unselectedEntities.filter( 8968 (elt) => elt.kind !== kind || elt.name !== name || elt.key !== key || elt.property !== property 8969 ) 8970 ); 8971 } else { 8972 _setUnselectedEntities([ 8973 ...unselectedEntities, 8974 { kind, name, key, property } 8975 ]); 8976 } 8977 }; 8978 const isDirty = dirtyEntityRecords.length - unselectedEntities.length > 0; 8979 return { 8980 dirtyEntityRecords, 8981 isDirty, 8982 setUnselectedEntities, 8983 unselectedEntities 8984 }; 8985 }; 8986 8987 // packages/core-data/build-module/components/entities-saved-states/index.mjs 8988 var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1); 8989 function EntitiesSavedStates({ 8990 close, 8991 renderDialog, 8992 variant 8993 }) { 8994 const isDirtyProps = useIsDirty(); 8995 return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)( 8996 EntitiesSavedStatesExtensible, 8997 { 8998 close, 8999 renderDialog, 9000 variant, 9001 ...isDirtyProps 9002 } 9003 ); 9004 } 9005 function EntitiesSavedStatesExtensible({ 9006 additionalPrompt = void 0, 9007 close, 9008 onSave = void 0, 9009 saveEnabled: saveEnabledProp = void 0, 9010 saveLabel = (0, import_i18n7.__)("Save"), 9011 renderDialog, 9012 dirtyEntityRecords, 9013 isDirty, 9014 setUnselectedEntities, 9015 unselectedEntities, 9016 variant = "default", 9017 successNoticeContent 9018 }) { 9019 const saveButtonRef = (0, import_element10.useRef)(); 9020 const { saveDirtyEntities: saveDirtyEntities2 } = unlock((0, import_data19.useDispatch)(STORE_NAME)); 9021 const partitionedSavables = dirtyEntityRecords.reduce((acc, record) => { 9022 const { name } = record; 9023 if (!acc[name]) { 9024 acc[name] = []; 9025 } 9026 acc[name].push(record); 9027 return acc; 9028 }, {}); 9029 const { 9030 site: siteSavables, 9031 wp_template: templateSavables, 9032 wp_template_part: templatePartSavables, 9033 ...contentSavables 9034 } = partitionedSavables; 9035 const sortedPartitionedSavables = [ 9036 siteSavables, 9037 templateSavables, 9038 templatePartSavables, 9039 ...Object.values(contentSavables) 9040 ].filter(Array.isArray); 9041 const saveEnabled = saveEnabledProp ?? isDirty; 9042 const dismissPanel = (0, import_element10.useCallback)(() => close(), [close]); 9043 const [saveDialogRef, saveDialogProps] = (0, import_compose4.__experimentalUseDialog)({ 9044 onClose: () => dismissPanel() 9045 }); 9046 const dialogLabelId = (0, import_compose4.useInstanceId)( 9047 EntitiesSavedStatesExtensible, 9048 "entities-saved-states__panel-label" 9049 ); 9050 const dialogDescriptionId = (0, import_compose4.useInstanceId)( 9051 EntitiesSavedStatesExtensible, 9052 "entities-saved-states__panel-description" 9053 ); 9054 const selectItemsToSaveDescription = !!dirtyEntityRecords.length ? (0, import_i18n7.__)("Select the items you want to save.") : void 0; 9055 const isInline = variant === "inline"; 9056 const actionButtons = /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [ 9057 /* @__PURE__ */ (0, import_jsx_runtime10.jsx)( 9058 import_components3.FlexItem, 9059 { 9060 isBlock: isInline ? false : true, 9061 as: import_components3.Button, 9062 variant: isInline ? "tertiary" : "secondary", 9063 size: isInline ? void 0 : "compact", 9064 onClick: dismissPanel, 9065 children: (0, import_i18n7.__)("Cancel") 9066 } 9067 ), 9068 /* @__PURE__ */ (0, import_jsx_runtime10.jsx)( 9069 import_components3.FlexItem, 9070 { 9071 isBlock: isInline ? false : true, 9072 as: import_components3.Button, 9073 ref: saveButtonRef, 9074 variant: "primary", 9075 size: isInline ? void 0 : "compact", 9076 disabled: !saveEnabled, 9077 accessibleWhenDisabled: true, 9078 onClick: () => saveDirtyEntities2({ 9079 onSave, 9080 dirtyEntityRecords, 9081 entitiesToSkip: unselectedEntities, 9082 close, 9083 successNoticeContent 9084 }), 9085 className: "entities-saved-states__save-button", 9086 children: saveLabel 9087 } 9088 ) 9089 ] }); 9090 return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)( 9091 "div", 9092 { 9093 ref: renderDialog ? saveDialogRef : void 0, 9094 ...renderDialog && saveDialogProps, 9095 className: clsx_default("entities-saved-states__panel", { 9096 "is-inline": isInline 9097 }), 9098 role: renderDialog ? "dialog" : void 0, 9099 "aria-labelledby": renderDialog ? dialogLabelId : void 0, 9100 "aria-describedby": renderDialog ? dialogDescriptionId : void 0, 9101 children: [ 9102 !isInline && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_components3.Flex, { className: "entities-saved-states__panel-header", gap: 2, children: actionButtons }), 9103 /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "entities-saved-states__text-prompt", children: [ 9104 /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "entities-saved-states__text-prompt--header-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)( 9105 "strong", 9106 { 9107 id: renderDialog ? dialogLabelId : void 0, 9108 className: "entities-saved-states__text-prompt--header", 9109 children: (0, import_i18n7.__)("Are you ready to save?") 9110 } 9111 ) }), 9112 /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { id: renderDialog ? dialogDescriptionId : void 0, children: [ 9113 additionalPrompt, 9114 /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "entities-saved-states__text-prompt--changes-count", children: isDirty ? (0, import_element10.createInterpolateElement)( 9115 (0, import_i18n7.sprintf)( 9116 /* translators: %d: number of site changes waiting to be saved. */ 9117 (0, import_i18n7._n)( 9118 "There is <strong>%d site change</strong> waiting to be saved.", 9119 "There are <strong>%d site changes</strong> waiting to be saved.", 9120 dirtyEntityRecords.length 9121 ), 9122 dirtyEntityRecords.length 9123 ), 9124 { strong: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", {}) } 9125 ) : selectItemsToSaveDescription }) 9126 ] }) 9127 ] }), 9128 sortedPartitionedSavables.map((list) => { 9129 return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)( 9130 EntityTypeList, 9131 { 9132 list, 9133 unselectedEntities, 9134 setUnselectedEntities 9135 }, 9136 list[0].name 9137 ); 9138 }), 9139 isInline && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)( 9140 import_components3.Flex, 9141 { 9142 direction: "row", 9143 justify: "flex-end", 9144 className: "entities-saved-states__panel-footer", 9145 children: actionButtons 9146 } 9147 ) 9148 ] 9149 } 9150 ); 9151 } 9152 9153 // packages/core-data/build-module/private-apis.mjs 9154 var lockedApis = { 9155 EntitiesSavedStates, 9156 EntitiesSavedStatesExtensible, 9157 getTemplateInfo, 9158 getTemplatePartIcon, 9159 useEntitiesSavedStatesIsDirty: useIsDirty, 9160 useEntityRecordsWithPermissions, 9161 RECEIVE_INTERMEDIATE_RESULTS, 9162 CRDT_AUTOSAVE_SNAPSHOT_KEY, 9163 entityContainsSnapshot, 9164 getEntitySnapshot, 9165 retrySyncConnection, 9166 useActiveCollaborators, 9167 useResolvedSelection, 9168 useOnCollaboratorJoin, 9169 useOnCollaboratorLeave, 9170 useOnPostSave, 9171 SelectionType, 9172 SelectionDirection 9173 }; 9174 var privateApis = {}; 9175 lock(privateApis, lockedApis); 9176 9177 // packages/core-data/build-module/index.mjs 9178 var entitiesConfig2 = [ 9179 ...rootEntitiesConfig, 9180 ...additionalEntityConfigLoaders.filter((config) => !!config.name) 9181 ]; 9182 var entitySelectors = entitiesConfig2.reduce((result, entity2) => { 9183 const { kind, name, plural } = entity2; 9184 const getEntityRecordMethodName = getMethodName(kind, name); 9185 result[getEntityRecordMethodName] = (state, key, query) => { 9186 logEntityDeprecation(kind, name, getEntityRecordMethodName, { 9187 isShorthandSelector: true, 9188 alternativeFunctionName: "getEntityRecord" 9189 }); 9190 return getEntityRecord(state, kind, name, key, query); 9191 }; 9192 if (plural) { 9193 const getEntityRecordsMethodName = getMethodName(kind, plural, "get"); 9194 result[getEntityRecordsMethodName] = (state, query) => { 9195 logEntityDeprecation(kind, name, getEntityRecordsMethodName, { 9196 isShorthandSelector: true, 9197 alternativeFunctionName: "getEntityRecords" 9198 }); 9199 return getEntityRecords(state, kind, name, query); 9200 }; 9201 } 9202 return result; 9203 }, {}); 9204 var entityResolvers = entitiesConfig2.reduce((result, entity2) => { 9205 const { kind, name, plural } = entity2; 9206 const getEntityRecordMethodName = getMethodName(kind, name); 9207 result[getEntityRecordMethodName] = (key, query) => { 9208 logEntityDeprecation(kind, name, getEntityRecordMethodName, { 9209 isShorthandSelector: true, 9210 alternativeFunctionName: "getEntityRecord" 9211 }); 9212 return getEntityRecord2(kind, name, key, query); 9213 }; 9214 if (plural) { 9215 const getEntityRecordsMethodName = getMethodName(kind, plural, "get"); 9216 result[getEntityRecordsMethodName] = (...args) => { 9217 logEntityDeprecation(kind, plural, getEntityRecordsMethodName, { 9218 isShorthandSelector: true, 9219 alternativeFunctionName: "getEntityRecords" 9220 }); 9221 return getEntityRecords2(kind, name, ...args); 9222 }; 9223 result[getEntityRecordsMethodName].shouldInvalidate = (action) => getEntityRecords2.shouldInvalidate(action, kind, name); 9224 } 9225 return result; 9226 }, {}); 9227 var entityActions = entitiesConfig2.reduce((result, entity2) => { 9228 const { kind, name } = entity2; 9229 const saveEntityRecordMethodName = getMethodName(kind, name, "save"); 9230 result[saveEntityRecordMethodName] = (record, options) => { 9231 logEntityDeprecation(kind, name, saveEntityRecordMethodName, { 9232 isShorthandSelector: true, 9233 alternativeFunctionName: "saveEntityRecord" 9234 }); 9235 return saveEntityRecord(kind, name, record, options); 9236 }; 9237 const deleteEntityRecordMethodName = getMethodName(kind, name, "delete"); 9238 result[deleteEntityRecordMethodName] = (key, query, options) => { 9239 logEntityDeprecation(kind, name, deleteEntityRecordMethodName, { 9240 isShorthandSelector: true, 9241 alternativeFunctionName: "deleteEntityRecord" 9242 }); 9243 return deleteEntityRecord(kind, name, key, query, options); 9244 }; 9245 return result; 9246 }, {}); 9247 var storeConfig = () => ({ 9248 reducer: reducer_default2, 9249 actions: { 9250 ...dynamicActions, 9251 ...actions_exports, 9252 ...entityActions, 9253 ...createLocksActions() 9254 }, 9255 selectors: { 9256 ...dynamicSelectors, 9257 ...selectors_exports, 9258 ...entitySelectors 9259 }, 9260 resolvers: { ...resolvers_exports, ...entityResolvers } 9261 }); 9262 var store = (0, import_data20.createReduxStore)(STORE_NAME, storeConfig()); 9263 unlock(store).registerPrivateSelectors(private_selectors_exports); 9264 unlock(store).registerPrivateActions(private_actions_exports); 9265 (0, import_data20.register)(store); 9266 return __toCommonJS(index_exports); 9267 })(); 9268 (window.wp ||= {}).coreData = wp.coreData; 9269 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Sat Sep 12 08:20:32 2026 | Cross-referenced by PHPXref |