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