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