| [ 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_max_bit_depth", 3087 "image_sizes", 3088 "image_size_threshold", 3089 "image_strip_meta", 3090 "name", 3091 "site_icon", 3092 "site_icon_url", 3093 "site_logo", 3094 "timezone_string", 3095 "url", 3096 "page_for_posts", 3097 "page_on_front", 3098 "show_on_front" 3099 ].join(",") 3100 }, 3101 // The entity doesn't support selecting multiple records. 3102 // The property is maintained for backward compatibility. 3103 plural: "__unstableBases", 3104 supportsPagination: false 3105 }, 3106 { 3107 label: (0, import_i18n.__)("Post Type"), 3108 name: "postType", 3109 kind: "root", 3110 key: "slug", 3111 baseURL: "/wp/v2/types", 3112 baseURLParams: { context: "edit" }, 3113 plural: "postTypes", 3114 supportsPagination: false 3115 }, 3116 { 3117 name: "media", 3118 kind: "root", 3119 baseURL: "/wp/v2/media", 3120 baseURLParams: { context: "edit" }, 3121 plural: "mediaItems", 3122 label: (0, import_i18n.__)("Media"), 3123 rawAttributes: ["caption", "title", "description"], 3124 supportsPagination: true 3125 }, 3126 { 3127 name: "taxonomy", 3128 kind: "root", 3129 key: "slug", 3130 baseURL: "/wp/v2/taxonomies", 3131 baseURLParams: { context: "edit" }, 3132 plural: "taxonomies", 3133 label: (0, import_i18n.__)("Taxonomy"), 3134 supportsPagination: false 3135 }, 3136 { 3137 name: "sidebar", 3138 kind: "root", 3139 baseURL: "/wp/v2/sidebars", 3140 baseURLParams: { context: "edit" }, 3141 plural: "sidebars", 3142 transientEdits: { blocks: true }, 3143 label: (0, import_i18n.__)("Widget areas"), 3144 supportsPagination: false 3145 }, 3146 { 3147 name: "widget", 3148 kind: "root", 3149 baseURL: "/wp/v2/widgets", 3150 baseURLParams: { context: "edit" }, 3151 plural: "widgets", 3152 transientEdits: { blocks: true }, 3153 label: (0, import_i18n.__)("Widgets"), 3154 supportsPagination: false 3155 }, 3156 { 3157 name: "widgetType", 3158 kind: "root", 3159 baseURL: "/wp/v2/widget-types", 3160 baseURLParams: { context: "edit" }, 3161 plural: "widgetTypes", 3162 label: (0, import_i18n.__)("Widget types"), 3163 supportsPagination: false 3164 }, 3165 { 3166 label: (0, import_i18n.__)("User"), 3167 name: "user", 3168 kind: "root", 3169 baseURL: "/wp/v2/users", 3170 getTitle: (record) => record?.name || record?.slug, 3171 baseURLParams: { context: "edit" }, 3172 plural: "users", 3173 supportsPagination: true 3174 }, 3175 { 3176 name: "comment", 3177 kind: "root", 3178 baseURL: "/wp/v2/comments", 3179 baseURLParams: { context: "edit" }, 3180 plural: "comments", 3181 label: (0, import_i18n.__)("Comment"), 3182 supportsPagination: true, 3183 syncConfig: defaultCollectionSyncConfig 3184 }, 3185 { 3186 name: "menu", 3187 kind: "root", 3188 baseURL: "/wp/v2/menus", 3189 baseURLParams: { context: "edit" }, 3190 plural: "menus", 3191 label: (0, import_i18n.__)("Menu"), 3192 supportsPagination: true 3193 }, 3194 { 3195 name: "menuItem", 3196 kind: "root", 3197 baseURL: "/wp/v2/menu-items", 3198 baseURLParams: { context: "edit" }, 3199 plural: "menuItems", 3200 label: (0, import_i18n.__)("Menu Item"), 3201 rawAttributes: ["title"], 3202 supportsPagination: true 3203 }, 3204 { 3205 name: "menuLocation", 3206 kind: "root", 3207 baseURL: "/wp/v2/menu-locations", 3208 baseURLParams: { context: "edit" }, 3209 plural: "menuLocations", 3210 label: (0, import_i18n.__)("Menu Location"), 3211 key: "name", 3212 supportsPagination: false 3213 }, 3214 { 3215 label: (0, import_i18n.__)("Global Styles"), 3216 name: "globalStyles", 3217 kind: "root", 3218 baseURL: "/wp/v2/global-styles", 3219 baseURLParams: { context: "edit" }, 3220 plural: "globalStylesVariations", 3221 // Should be different from name. 3222 getTitle: () => (0, import_i18n.__)("Custom Styles"), 3223 getRevisionsUrl: (parentId, revisionId) => `/wp/v2/global-styles/$parentId}/revisions$revisionId ? "/" + revisionId : ""}`, 3224 supportsPagination: true 3225 }, 3226 { 3227 label: (0, import_i18n.__)("Themes"), 3228 name: "theme", 3229 kind: "root", 3230 baseURL: "/wp/v2/themes", 3231 baseURLParams: { context: "edit" }, 3232 plural: "themes", 3233 key: "stylesheet", 3234 supportsPagination: false 3235 }, 3236 { 3237 label: (0, import_i18n.__)("Plugins"), 3238 name: "plugin", 3239 kind: "root", 3240 baseURL: "/wp/v2/plugins", 3241 baseURLParams: { context: "edit" }, 3242 plural: "plugins", 3243 key: "plugin", 3244 supportsPagination: false 3245 }, 3246 { 3247 label: (0, import_i18n.__)("Status"), 3248 name: "status", 3249 kind: "root", 3250 baseURL: "/wp/v2/statuses", 3251 baseURLParams: { context: "edit" }, 3252 plural: "statuses", 3253 key: "slug", 3254 supportsPagination: false 3255 }, 3256 { 3257 label: (0, import_i18n.__)("Registered Templates"), 3258 name: "registeredTemplate", 3259 kind: "root", 3260 baseURL: "/wp/v2/registered-templates", 3261 key: "id", 3262 supportsPagination: false 3263 }, 3264 { 3265 label: (0, import_i18n.__)("Font Collections"), 3266 name: "fontCollection", 3267 kind: "root", 3268 baseURL: "/wp/v2/font-collections", 3269 baseURLParams: { context: "view" }, 3270 plural: "fontCollections", 3271 key: "slug", 3272 supportsPagination: true 3273 }, 3274 { 3275 label: (0, import_i18n.__)("Icons"), 3276 name: "icon", 3277 kind: "root", 3278 baseURL: "/wp/v2/icons", 3279 baseURLParams: { context: "view" }, 3280 plural: "icons", 3281 key: "name", 3282 supportsPagination: false 3283 }, 3284 { 3285 label: (0, import_i18n.__)("Icon Collections"), 3286 name: "iconCollection", 3287 kind: "root", 3288 baseURL: "/wp/v2/icon-collections", 3289 baseURLParams: { context: "view" }, 3290 plural: "iconCollections", 3291 key: "slug", 3292 supportsPagination: false 3293 } 3294 ]; 3295 var deprecatedEntities = { 3296 root: { 3297 media: { 3298 since: "6.9", 3299 alternative: { 3300 kind: "postType", 3301 name: "attachment" 3302 } 3303 } 3304 } 3305 }; 3306 var additionalEntityConfigLoaders = [ 3307 { kind: "postType", loadEntities: loadPostTypeEntities }, 3308 { kind: "taxonomy", loadEntities: loadTaxonomyEntities }, 3309 { 3310 kind: "root", 3311 name: "site", 3312 plural: "sites", 3313 loadEntities: loadSiteEntity 3314 } 3315 ]; 3316 var prePersistPostType = async (persistedRecord, edits, name, isTemplate) => { 3317 const newEdits = {}; 3318 if (!isTemplate && persistedRecord?.status === "auto-draft") { 3319 if (!edits.status && !newEdits.status) { 3320 newEdits.status = "draft"; 3321 } 3322 if ((!edits.title || edits.title === "Auto Draft") && !newEdits.title && (!persistedRecord?.title || persistedRecord?.title === "Auto Draft")) { 3323 newEdits.title = ""; 3324 } 3325 } 3326 if (persistedRecord) { 3327 const objectType = `postType/$name}`; 3328 const objectId = persistedRecord.id; 3329 const serializedDoc = await getSyncManager()?.createPersistedCRDTDoc( 3330 objectType, 3331 objectId 3332 ); 3333 if (serializedDoc) { 3334 newEdits.meta = { 3335 ...edits.meta, 3336 [POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE]: serializedDoc 3337 }; 3338 } 3339 } 3340 return newEdits; 3341 }; 3342 async function loadPostTypeEntities() { 3343 const postTypesPromise = (0, import_api_fetch2.default)({ path: "/wp/v2/types?context=view" }); 3344 const taxonomiesPromise = window._wpCollaborationEnabled ? (0, import_api_fetch2.default)({ path: "/wp/v2/taxonomies?context=view" }) : Promise.resolve({}); 3345 const [postTypes, taxonomies] = await Promise.all([ 3346 postTypesPromise, 3347 taxonomiesPromise 3348 ]); 3349 return Object.entries(postTypes ?? {}).map(([name, postType]) => { 3350 const isTemplate = ["wp_template", "wp_template_part"].includes( 3351 name 3352 ); 3353 const namespace = postType?.rest_namespace ?? "wp/v2"; 3354 const syncedProperties = /* @__PURE__ */ new Set([ 3355 "author", 3356 "blocks", 3357 "content", 3358 "comment_status", 3359 "date", 3360 "excerpt", 3361 "featured_media", 3362 "format", 3363 "meta", 3364 "ping_status", 3365 "slug", 3366 "status", 3367 "sticky", 3368 "template", 3369 "title", 3370 ...postType.taxonomies?.map((taxonomy) => taxonomies?.[taxonomy]?.rest_base)?.filter(Boolean) ?? [] 3371 ]); 3372 const entity2 = { 3373 kind: "postType", 3374 baseURL: `/$namespace}/$postType.rest_base}`, 3375 baseURLParams: { context: "edit" }, 3376 name, 3377 label: postType.name, 3378 transientEdits: { 3379 ...blocksTransientEdits, 3380 selection: true 3381 }, 3382 mergedEdits: { meta: true }, 3383 rawAttributes: POST_RAW_ATTRIBUTES, 3384 getTitle: (record) => record?.title?.rendered || record?.title || (isTemplate ? capitalCase(record.slug ?? "") : String(record.id)), 3385 __unstablePrePersist: (persistedRecord, edits) => prePersistPostType(persistedRecord, edits, name, isTemplate), 3386 __unstable_rest_base: postType.rest_base, 3387 supportsPagination: true, 3388 getRevisionsUrl: (parentId, revisionId) => `/$namespace}/$postType.rest_base}/$parentId}/revisions$revisionId ? "/" + revisionId : ""}`, 3389 revisionKey: isTemplate && !window?.__experimentalTemplateActivate ? "wp_id" : DEFAULT_ENTITY_KEY 3390 }; 3391 entity2.syncConfig = { 3392 // Save a CRDT document with this entity 3393 supportsPersistence: true, 3394 /** 3395 * Apply changes from the local editor to the local CRDT document so 3396 * that those changes can be synced to other peers (via the provider). 3397 * 3398 * @param {import('@wordpress/sync').CRDTDoc} crdtDoc 3399 * @param {Partial< import('@wordpress/sync').ObjectData >} changes 3400 * @return {void} 3401 */ 3402 applyChangesToCRDTDoc: (crdtDoc, changes) => applyPostChangesToCRDTDoc(crdtDoc, changes, syncedProperties), 3403 /** 3404 * Create the awareness instance for the entity's CRDT document. 3405 * 3406 * @param {import('@wordpress/sync').CRDTDoc} ydoc 3407 * @param {import('@wordpress/sync').ObjectID} objectId 3408 * @return {import('@wordpress/sync').Awareness} Awareness instance 3409 */ 3410 createAwareness: (ydoc, objectId) => { 3411 const kind = "postType"; 3412 const id = parseInt(objectId, 10); 3413 return new PostEditorAwareness(ydoc, kind, name, id); 3414 }, 3415 /** 3416 * Extract changes from a CRDT document that can be used to update the 3417 * local editor state. 3418 * 3419 * @param {import('@wordpress/sync').CRDTDoc} crdtDoc 3420 * @param {import('@wordpress/sync').ObjectData} editedRecord 3421 * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record 3422 */ 3423 getChangesFromCRDTDoc: (crdtDoc, editedRecord) => getPostChangesFromCRDTDoc( 3424 crdtDoc, 3425 editedRecord, 3426 syncedProperties 3427 ), 3428 /** 3429 * Extract changes from a CRDT document that can be used to update the 3430 * local editor state. 3431 * 3432 * @param {import('@wordpress/sync').ObjectData} record 3433 * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record 3434 */ 3435 getPersistedCRDTDoc: (record) => { 3436 return record?.meta?.[POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE] || null; 3437 }, 3438 shouldSync: () => !(Array.isArray(window._wpCollaborationDisabledPostTypes) && window._wpCollaborationDisabledPostTypes.includes(name)) 3439 }; 3440 return entity2; 3441 }); 3442 } 3443 async function loadTaxonomyEntities() { 3444 const taxonomies = await (0, import_api_fetch2.default)({ 3445 path: "/wp/v2/taxonomies?context=view" 3446 }); 3447 return Object.entries(taxonomies ?? {}).map(([name, taxonomy]) => { 3448 const namespace = taxonomy?.rest_namespace ?? "wp/v2"; 3449 const entity2 = { 3450 kind: "taxonomy", 3451 baseURL: `/$namespace}/$taxonomy.rest_base}`, 3452 baseURLParams: { context: "edit" }, 3453 name, 3454 label: taxonomy.name, 3455 getTitle: (record) => record?.name, 3456 supportsPagination: true 3457 }; 3458 entity2.syncConfig = defaultSyncConfig; 3459 return entity2; 3460 }); 3461 } 3462 async function loadSiteEntity() { 3463 const entity2 = { 3464 label: (0, import_i18n.__)("Site"), 3465 name: "site", 3466 kind: "root", 3467 key: false, 3468 baseURL: "/wp/v2/settings", 3469 supportsPagination: false, 3470 meta: {} 3471 }; 3472 const site = await (0, import_api_fetch2.default)({ 3473 path: entity2.baseURL, 3474 method: "OPTIONS" 3475 }); 3476 const labels = {}; 3477 Object.entries(site?.schema?.properties ?? {}).forEach( 3478 ([key, value]) => { 3479 if (typeof value === "object" && value.title) { 3480 labels[key] = value.title; 3481 } 3482 } 3483 ); 3484 return [{ ...entity2, meta: { labels } }]; 3485 } 3486 var getMethodName = (kind, name, prefix = "get") => { 3487 const kindPrefix = kind === "root" ? "" : pascalCase(kind); 3488 const suffix = pascalCase(name); 3489 return `$prefix}$kindPrefix}$suffix}`; 3490 }; 3491 3492 // packages/core-data/build-module/queried-data/reducer.mjs 3493 function getContextFromAction(action) { 3494 const { query } = action; 3495 if (!query) { 3496 return "default"; 3497 } 3498 const queryParts = get_query_parts_default(query); 3499 return queryParts.context; 3500 } 3501 function getMergedItemIds(itemIds = [], nextItemIds, { page = 1, offset, perPage = 10 } = {}) { 3502 if (perPage === -1) { 3503 return nextItemIds; 3504 } 3505 const nextItemIdsStartIndex = offset ?? (page - 1) * perPage; 3506 const nextItemIdsRange = Math.max(perPage, nextItemIds.length); 3507 const size = Math.max( 3508 itemIds.length, 3509 nextItemIdsStartIndex + nextItemIds.length 3510 ); 3511 const mergedItemIds = new Array(size); 3512 for (let i = 0; i < size; i++) { 3513 const isInNextItemsRange = i >= nextItemIdsStartIndex && i < nextItemIdsStartIndex + nextItemIdsRange; 3514 if (isInNextItemsRange) { 3515 mergedItemIds[i] = nextItemIds[i - nextItemIdsStartIndex]; 3516 } else { 3517 mergedItemIds[i] = itemIds[i]; 3518 } 3519 } 3520 return mergedItemIds; 3521 } 3522 function removeEntitiesById(entities2, ids) { 3523 return Object.fromEntries( 3524 Object.entries(entities2).filter( 3525 ([id]) => !ids.some((itemId) => { 3526 if (Number.isInteger(itemId)) { 3527 return itemId === +id; 3528 } 3529 return itemId === id; 3530 }) 3531 ) 3532 ); 3533 } 3534 function items(state = {}, action) { 3535 switch (action.type) { 3536 case "RECEIVE_ITEMS": { 3537 const context = getContextFromAction(action); 3538 const key = action.key || DEFAULT_ENTITY_KEY; 3539 const itemsList = Array.isArray(action.items) ? action.items : [action.items]; 3540 return { 3541 ...state, 3542 [context]: { 3543 ...state[context], 3544 ...Object.fromEntries( 3545 itemsList.map((item) => [ 3546 item?.[key], 3547 conservativeMapItem( 3548 state?.[context]?.[item?.[key]], 3549 item 3550 ) 3551 ]) 3552 ) 3553 } 3554 }; 3555 } 3556 case "REMOVE_ITEMS": 3557 return Object.fromEntries( 3558 Object.entries(state).map(([itemId, contextState]) => [ 3559 itemId, 3560 removeEntitiesById(contextState, action.itemIds) 3561 ]) 3562 ); 3563 } 3564 return state; 3565 } 3566 function itemIsComplete(state = {}, action) { 3567 switch (action.type) { 3568 case "RECEIVE_ITEMS": { 3569 const context = getContextFromAction(action); 3570 const { query, key = DEFAULT_ENTITY_KEY } = action; 3571 const itemsList = Array.isArray(action.items) ? action.items : [action.items]; 3572 const queryParts = query ? get_query_parts_default(query) : {}; 3573 const isCompleteQuery = !query || !Array.isArray(queryParts.fields); 3574 return { 3575 ...state, 3576 [context]: { 3577 ...state[context], 3578 ...itemsList.reduce((result, item) => { 3579 const itemId = item?.[key]; 3580 result[itemId] = state?.[context]?.[itemId] || isCompleteQuery; 3581 return result; 3582 }, {}) 3583 } 3584 }; 3585 } 3586 case "REMOVE_ITEMS": 3587 return Object.fromEntries( 3588 Object.entries(state).map(([itemId, contextState]) => [ 3589 itemId, 3590 removeEntitiesById(contextState, action.itemIds) 3591 ]) 3592 ); 3593 } 3594 return state; 3595 } 3596 var receiveQueries = (0, import_compose.compose)([ 3597 // Limit to matching action type so we don't attempt to replace action on 3598 // an unhandled action. 3599 if_matching_action_default((action) => "query" in action), 3600 // Inject query parts into action for use both in `keyedReducer` and reducer. 3601 replace_action_default((action) => { 3602 if (action.query) { 3603 return { 3604 ...action, 3605 ...get_query_parts_default(action.query) 3606 }; 3607 } 3608 return action; 3609 }), 3610 (0, import_data6.keyedReducer)("context"), 3611 // Queries shape is shared, but keyed by query `stableKey` part. Original 3612 // reducer tracks only a single query object. 3613 (0, import_data6.keyedReducer)("stableKey") 3614 ])((state = {}, action) => { 3615 if (action.type !== "RECEIVE_ITEMS") { 3616 return state; 3617 } 3618 if (!Array.isArray(action.items)) { 3619 return state; 3620 } 3621 const key = action.key ?? DEFAULT_ENTITY_KEY; 3622 return { 3623 itemIds: getMergedItemIds( 3624 state.itemIds, 3625 action.items.map((item) => item?.[key]).filter(Boolean), 3626 { 3627 page: action.page, 3628 offset: action.offset, 3629 perPage: action.perPage 3630 } 3631 ), 3632 meta: action.meta 3633 }; 3634 }); 3635 var queries = (state = {}, action) => { 3636 switch (action.type) { 3637 case "RECEIVE_ITEMS": 3638 return receiveQueries(state, action); 3639 case "REMOVE_ITEMS": 3640 const removedItems = action.itemIds.reduce((result, itemId) => { 3641 result[itemId] = true; 3642 return result; 3643 }, {}); 3644 return Object.fromEntries( 3645 Object.entries(state).map( 3646 ([queryGroup, contextQueries]) => [ 3647 queryGroup, 3648 Object.fromEntries( 3649 Object.entries(contextQueries).map( 3650 ([query, queryItems]) => [ 3651 query, 3652 { 3653 ...queryItems, 3654 itemIds: queryItems.itemIds.filter( 3655 (queryId) => !removedItems[queryId] 3656 ) 3657 } 3658 ] 3659 ) 3660 ) 3661 ] 3662 ) 3663 ); 3664 default: 3665 return state; 3666 } 3667 }; 3668 var reducer_default = (0, import_data6.combineReducers)({ 3669 items, 3670 itemIsComplete, 3671 queries 3672 }); 3673 3674 // packages/core-data/build-module/reducer.mjs 3675 function users(state = { byId: {}, queries: {} }, action) { 3676 switch (action.type) { 3677 case "RECEIVE_USER_QUERY": 3678 return { 3679 byId: { 3680 ...state.byId, 3681 // Key users by their ID. 3682 ...action.users.reduce( 3683 (newUsers, user) => ({ 3684 ...newUsers, 3685 [user.id]: user 3686 }), 3687 {} 3688 ) 3689 }, 3690 queries: { 3691 ...state.queries, 3692 [action.queryID]: action.users.map((user) => user.id) 3693 } 3694 }; 3695 } 3696 return state; 3697 } 3698 function currentUser(state = {}, action) { 3699 switch (action.type) { 3700 case "RECEIVE_CURRENT_USER": 3701 return action.currentUser; 3702 } 3703 return state; 3704 } 3705 function currentTheme(state = void 0, action) { 3706 switch (action.type) { 3707 case "RECEIVE_CURRENT_THEME": 3708 return action.currentTheme.stylesheet; 3709 } 3710 return state; 3711 } 3712 function currentGlobalStylesId(state = void 0, action) { 3713 switch (action.type) { 3714 case "RECEIVE_CURRENT_GLOBAL_STYLES_ID": 3715 return action.id; 3716 } 3717 return state; 3718 } 3719 function themeBaseGlobalStyles(state = {}, action) { 3720 switch (action.type) { 3721 case "RECEIVE_THEME_GLOBAL_STYLES": 3722 return { 3723 ...state, 3724 [action.stylesheet]: action.globalStyles 3725 }; 3726 } 3727 return state; 3728 } 3729 function themeGlobalStyleVariations(state = {}, action) { 3730 switch (action.type) { 3731 case "RECEIVE_THEME_GLOBAL_STYLE_VARIATIONS": 3732 return { 3733 ...state, 3734 [action.stylesheet]: action.variations 3735 }; 3736 } 3737 return state; 3738 } 3739 var withMultiEntityRecordEdits = (reducer) => (state, action) => { 3740 if (action.type === "UNDO" || action.type === "REDO") { 3741 const { record } = action; 3742 let newState = state; 3743 record.forEach(({ id: { kind, name, recordId }, changes }) => { 3744 const persistedRecord = state?.queriedData?.items?.default?.[recordId]; 3745 const edits = Object.fromEntries( 3746 Object.entries(changes).map(([key, value]) => [ 3747 key, 3748 action.type === "UNDO" ? value.from : value.to 3749 ]) 3750 ); 3751 newState = reducer(newState, { 3752 type: "EDIT_ENTITY_RECORD", 3753 kind, 3754 name, 3755 recordId, 3756 // Clear edits matching the persisted record so the entity is 3757 // no longer dirty after undoing back to its saved state. 3758 edits: clearUnchangedEdits(edits, persistedRecord) 3759 }); 3760 }); 3761 return newState; 3762 } 3763 return reducer(state, action); 3764 }; 3765 function entity(entityConfig) { 3766 return (0, import_compose2.compose)([ 3767 withMultiEntityRecordEdits, 3768 // Limit to matching action type so we don't attempt to replace action on 3769 // an unhandled action. 3770 if_matching_action_default( 3771 (action) => action.name && action.kind && action.name === entityConfig.name && action.kind === entityConfig.kind 3772 ), 3773 // Inject the entity config into the action. 3774 replace_action_default((action) => { 3775 return { 3776 key: entityConfig.key || DEFAULT_ENTITY_KEY, 3777 ...action 3778 }; 3779 }) 3780 ])( 3781 (0, import_data7.combineReducers)({ 3782 queriedData: reducer_default, 3783 edits: (state = {}, action) => { 3784 switch (action.type) { 3785 case "RECEIVE_ITEMS": 3786 const context = action?.query?.context ?? "default"; 3787 if (context !== "default") { 3788 return state; 3789 } 3790 const nextState = { ...state }; 3791 const itemsList = Array.isArray(action.items) ? action.items : [action.items]; 3792 for (const record of itemsList) { 3793 const recordId = record?.[action.key]; 3794 const edits = nextState[recordId]; 3795 if (!edits) { 3796 continue; 3797 } 3798 const nextEdits2 = Object.keys(edits).reduce( 3799 (acc, key) => { 3800 if ( 3801 // Edits are the "raw" attribute values, but records may have 3802 // objects with more properties, so we use `get` here for the 3803 // comparison. 3804 !(0, import_es65.default)( 3805 edits[key], 3806 record[key]?.raw ?? record[key] 3807 ) && // Sometimes the server alters the sent value which means 3808 // we need to also remove the edits before the api request. 3809 (!action.persistedEdits || !(0, import_es65.default)( 3810 edits[key], 3811 action.persistedEdits[key] 3812 )) 3813 ) { 3814 acc[key] = edits[key]; 3815 } 3816 return acc; 3817 }, 3818 {} 3819 ); 3820 if (Object.keys(nextEdits2).length) { 3821 nextState[recordId] = nextEdits2; 3822 } else { 3823 delete nextState[recordId]; 3824 } 3825 } 3826 return nextState; 3827 case "EDIT_ENTITY_RECORD": 3828 const nextEdits = { 3829 ...state[action.recordId], 3830 ...action.edits 3831 }; 3832 Object.keys(nextEdits).forEach((key) => { 3833 if (nextEdits[key] === void 0) { 3834 delete nextEdits[key]; 3835 } 3836 }); 3837 return { 3838 ...state, 3839 [action.recordId]: nextEdits 3840 }; 3841 } 3842 return state; 3843 }, 3844 saving: (state = {}, action) => { 3845 switch (action.type) { 3846 case "SAVE_ENTITY_RECORD_START": 3847 case "SAVE_ENTITY_RECORD_FINISH": 3848 return { 3849 ...state, 3850 [action.recordId]: { 3851 pending: action.type === "SAVE_ENTITY_RECORD_START", 3852 error: action.error, 3853 isAutosave: action.isAutosave 3854 } 3855 }; 3856 } 3857 return state; 3858 }, 3859 deleting: (state = {}, action) => { 3860 switch (action.type) { 3861 case "DELETE_ENTITY_RECORD_START": 3862 case "DELETE_ENTITY_RECORD_FINISH": 3863 return { 3864 ...state, 3865 [action.recordId]: { 3866 pending: action.type === "DELETE_ENTITY_RECORD_START", 3867 error: action.error 3868 } 3869 }; 3870 } 3871 return state; 3872 }, 3873 revisions: (state = {}, action) => { 3874 if (action.type === "RECEIVE_ITEM_REVISIONS") { 3875 const recordKey = action.recordKey; 3876 delete action.recordKey; 3877 const newState = reducer_default(state[recordKey], { 3878 ...action, 3879 type: "RECEIVE_ITEMS" 3880 }); 3881 return { 3882 ...state, 3883 [recordKey]: newState 3884 }; 3885 } 3886 if (action.type === "REMOVE_ITEMS") { 3887 return Object.fromEntries( 3888 Object.entries(state).filter( 3889 ([id]) => !action.itemIds.some((itemId) => { 3890 if (Number.isInteger(itemId)) { 3891 return itemId === +id; 3892 } 3893 return itemId === id; 3894 }) 3895 ) 3896 ); 3897 } 3898 return state; 3899 } 3900 }) 3901 ); 3902 } 3903 function entitiesConfig(state = rootEntitiesConfig, action) { 3904 switch (action.type) { 3905 case "ADD_ENTITIES": 3906 return [...state, ...action.entities]; 3907 } 3908 return state; 3909 } 3910 var entities = (state = {}, action) => { 3911 const newConfig = entitiesConfig(state.config, action); 3912 let entitiesDataReducer = state.reducer; 3913 if (!entitiesDataReducer || newConfig !== state.config) { 3914 const entitiesByKind = newConfig.reduce((acc, record) => { 3915 const { kind } = record; 3916 if (!acc[kind]) { 3917 acc[kind] = []; 3918 } 3919 acc[kind].push(record); 3920 return acc; 3921 }, {}); 3922 entitiesDataReducer = (0, import_data7.combineReducers)( 3923 Object.fromEntries( 3924 Object.entries(entitiesByKind).map( 3925 ([kind, subEntities]) => { 3926 const kindReducer = (0, import_data7.combineReducers)( 3927 Object.fromEntries( 3928 subEntities.map((entityConfig) => [ 3929 entityConfig.name, 3930 entity(entityConfig) 3931 ]) 3932 ) 3933 ); 3934 return [kind, kindReducer]; 3935 } 3936 ) 3937 ) 3938 ); 3939 } 3940 const newData = entitiesDataReducer(state.records, action); 3941 if (newData === state.records && newConfig === state.config && entitiesDataReducer === state.reducer) { 3942 return state; 3943 } 3944 return { 3945 reducer: entitiesDataReducer, 3946 records: newData, 3947 config: newConfig 3948 }; 3949 }; 3950 function undoManager(state = (0, import_undo_manager.createUndoManager)()) { 3951 return state; 3952 } 3953 function syncUndoManagerState(state = { hasRedo: false, hasUndo: false }, action) { 3954 switch (action.type) { 3955 case "SYNC_UNDO_MANAGER_CHANGE": 3956 return { 3957 hasRedo: action.hasRedo, 3958 hasUndo: action.hasUndo 3959 }; 3960 } 3961 return state; 3962 } 3963 function editsReference(state = {}, action) { 3964 switch (action.type) { 3965 case "EDIT_ENTITY_RECORD": 3966 case "UNDO": 3967 case "REDO": 3968 return {}; 3969 } 3970 return state; 3971 } 3972 function embedPreviews(state = {}, action) { 3973 switch (action.type) { 3974 case "RECEIVE_EMBED_PREVIEW": 3975 const { url, preview } = action; 3976 return { 3977 ...state, 3978 [url]: preview 3979 }; 3980 } 3981 return state; 3982 } 3983 function userPermissions(state = {}, action) { 3984 switch (action.type) { 3985 case "RECEIVE_USER_PERMISSION": 3986 return { 3987 ...state, 3988 [action.key]: action.isAllowed 3989 }; 3990 case "RECEIVE_USER_PERMISSIONS": 3991 return { 3992 ...state, 3993 ...action.permissions 3994 }; 3995 } 3996 return state; 3997 } 3998 function autosaves(state = {}, action) { 3999 switch (action.type) { 4000 case "RECEIVE_AUTOSAVES": 4001 const { postId, autosaves: autosavesData } = action; 4002 return { 4003 ...state, 4004 [postId]: autosavesData 4005 }; 4006 } 4007 return state; 4008 } 4009 function blockPatterns(state = [], action) { 4010 switch (action.type) { 4011 case "RECEIVE_BLOCK_PATTERNS": 4012 return action.patterns; 4013 } 4014 return state; 4015 } 4016 function blockPatternCategories(state = [], action) { 4017 switch (action.type) { 4018 case "RECEIVE_BLOCK_PATTERN_CATEGORIES": 4019 return action.categories; 4020 } 4021 return state; 4022 } 4023 function userPatternCategories(state = [], action) { 4024 switch (action.type) { 4025 case "RECEIVE_USER_PATTERN_CATEGORIES": 4026 return action.patternCategories; 4027 } 4028 return state; 4029 } 4030 function navigationFallbackId(state = null, action) { 4031 switch (action.type) { 4032 case "RECEIVE_NAVIGATION_FALLBACK_ID": 4033 return action.fallbackId; 4034 } 4035 return state; 4036 } 4037 function themeGlobalStyleRevisions(state = {}, action) { 4038 switch (action.type) { 4039 case "RECEIVE_THEME_GLOBAL_STYLE_REVISIONS": 4040 return { 4041 ...state, 4042 [action.currentId]: action.revisions 4043 }; 4044 } 4045 return state; 4046 } 4047 function defaultTemplates(state = {}, action) { 4048 switch (action.type) { 4049 case "RECEIVE_DEFAULT_TEMPLATE": 4050 return { 4051 ...state, 4052 [JSON.stringify(action.query)]: action.templateId 4053 }; 4054 } 4055 return state; 4056 } 4057 function registeredPostMeta(state = {}, action) { 4058 switch (action.type) { 4059 case "RECEIVE_REGISTERED_POST_META": 4060 return { 4061 ...state, 4062 [action.postType]: action.registeredPostMeta 4063 }; 4064 } 4065 return state; 4066 } 4067 function editorSettings(state = null, action) { 4068 switch (action.type) { 4069 case "RECEIVE_EDITOR_SETTINGS": 4070 return action.settings; 4071 } 4072 return state; 4073 } 4074 function editorAssets(state = null, action) { 4075 switch (action.type) { 4076 case "RECEIVE_EDITOR_ASSETS": 4077 return action.assets; 4078 } 4079 return state; 4080 } 4081 function syncConnectionStatuses(state = {}, action) { 4082 switch (action.type) { 4083 case "SET_SYNC_CONNECTION_STATUS": { 4084 const key = `$action.kind}/$action.name}:$action.key}`; 4085 return { 4086 ...state, 4087 [key]: action.status 4088 }; 4089 } 4090 case "CLEAR_SYNC_CONNECTION_STATUS": { 4091 const key = `$action.kind}/$action.name}:$action.key}`; 4092 const { [key]: _, ...rest } = state; 4093 return rest; 4094 } 4095 } 4096 return state; 4097 } 4098 function collaborationSupported(state = true, action) { 4099 switch (action.type) { 4100 case "SET_COLLABORATION_SUPPORTED": 4101 return action.supported; 4102 case "SET_SYNC_CONNECTION_STATUS": 4103 if (ConnectionErrorCode.DOCUMENT_SIZE_LIMIT_EXCEEDED === action.status?.error?.code) { 4104 return false; 4105 } 4106 return state; 4107 } 4108 return state; 4109 } 4110 function viewConfigs(state = {}, action) { 4111 switch (action.type) { 4112 case "RECEIVE_VIEW_CONFIG": { 4113 const key = `$action.kind}/$action.name}`; 4114 return { 4115 ...state, 4116 [key]: { 4117 ...state[key], 4118 ...action.config 4119 } 4120 }; 4121 } 4122 } 4123 return state; 4124 } 4125 var reducer_default2 = (0, import_data7.combineReducers)({ 4126 users, 4127 currentTheme, 4128 currentGlobalStylesId, 4129 currentUser, 4130 themeGlobalStyleVariations, 4131 themeBaseGlobalStyles, 4132 themeGlobalStyleRevisions, 4133 entities, 4134 editsReference, 4135 syncUndoManagerState, 4136 undoManager, 4137 embedPreviews, 4138 userPermissions, 4139 autosaves, 4140 blockPatterns, 4141 blockPatternCategories, 4142 userPatternCategories, 4143 navigationFallbackId, 4144 defaultTemplates, 4145 registeredPostMeta, 4146 editorSettings, 4147 editorAssets, 4148 syncConnectionStatuses, 4149 collaborationSupported, 4150 viewConfigs 4151 }); 4152 4153 // packages/core-data/build-module/selectors.mjs 4154 var selectors_exports = {}; 4155 __export(selectors_exports, { 4156 __experimentalGetCurrentGlobalStylesId: () => __experimentalGetCurrentGlobalStylesId, 4157 __experimentalGetCurrentThemeBaseGlobalStyles: () => __experimentalGetCurrentThemeBaseGlobalStyles, 4158 __experimentalGetCurrentThemeGlobalStylesVariations: () => __experimentalGetCurrentThemeGlobalStylesVariations, 4159 __experimentalGetDirtyEntityRecords: () => __experimentalGetDirtyEntityRecords, 4160 __experimentalGetEntitiesBeingSaved: () => __experimentalGetEntitiesBeingSaved, 4161 __experimentalGetEntityRecordNoResolver: () => __experimentalGetEntityRecordNoResolver, 4162 canUser: () => canUser, 4163 canUserEditEntityRecord: () => canUserEditEntityRecord, 4164 getAuthors: () => getAuthors, 4165 getAutosave: () => getAutosave, 4166 getAutosaves: () => getAutosaves, 4167 getBlockPatternCategories: () => getBlockPatternCategories, 4168 getBlockPatterns: () => getBlockPatterns, 4169 getCurrentTheme: () => getCurrentTheme, 4170 getCurrentThemeGlobalStylesRevisions: () => getCurrentThemeGlobalStylesRevisions, 4171 getCurrentUser: () => getCurrentUser, 4172 getDefaultTemplateId: () => getDefaultTemplateId, 4173 getEditedEntityRecord: () => getEditedEntityRecord, 4174 getEmbedPreview: () => getEmbedPreview, 4175 getEntitiesByKind: () => getEntitiesByKind, 4176 getEntitiesConfig: () => getEntitiesConfig, 4177 getEntity: () => getEntity, 4178 getEntityConfig: () => getEntityConfig, 4179 getEntityRecord: () => getEntityRecord, 4180 getEntityRecordEdits: () => getEntityRecordEdits, 4181 getEntityRecordNonTransientEdits: () => getEntityRecordNonTransientEdits, 4182 getEntityRecords: () => getEntityRecords, 4183 getEntityRecordsTotalItems: () => getEntityRecordsTotalItems, 4184 getEntityRecordsTotalPages: () => getEntityRecordsTotalPages, 4185 getLastEntityDeleteError: () => getLastEntityDeleteError, 4186 getLastEntitySaveError: () => getLastEntitySaveError, 4187 getRawEntityRecord: () => getRawEntityRecord, 4188 getRedoEdit: () => getRedoEdit, 4189 getReferenceByDistinctEdits: () => getReferenceByDistinctEdits, 4190 getRevision: () => getRevision, 4191 getRevisions: () => getRevisions, 4192 getThemeSupports: () => getThemeSupports, 4193 getUndoEdit: () => getUndoEdit, 4194 getUserPatternCategories: () => getUserPatternCategories, 4195 getUserQueryResults: () => getUserQueryResults, 4196 hasEditsForEntityRecord: () => hasEditsForEntityRecord, 4197 hasEntityRecord: () => hasEntityRecord, 4198 hasEntityRecords: () => hasEntityRecords, 4199 hasFetchedAutosaves: () => hasFetchedAutosaves, 4200 hasRedo: () => hasRedo, 4201 hasRevision: () => hasRevision, 4202 hasUndo: () => hasUndo, 4203 isAutosavingEntityRecord: () => isAutosavingEntityRecord, 4204 isDeletingEntityRecord: () => isDeletingEntityRecord, 4205 isPreviewEmbedFallback: () => isPreviewEmbedFallback, 4206 isRequestingEmbedPreview: () => isRequestingEmbedPreview, 4207 isSavingEntityRecord: () => isSavingEntityRecord 4208 }); 4209 var import_data9 = __toESM(require_data(), 1); 4210 var import_url2 = __toESM(require_url(), 1); 4211 var import_deprecated2 = __toESM(require_deprecated(), 1); 4212 4213 // packages/core-data/build-module/private-selectors.mjs 4214 var private_selectors_exports = {}; 4215 __export(private_selectors_exports, { 4216 getBlockPatternsForPostType: () => getBlockPatternsForPostType, 4217 getEditorAssets: () => getEditorAssets, 4218 getEditorSettings: () => getEditorSettings, 4219 getEntityRecordPermissions: () => getEntityRecordPermissions, 4220 getEntityRecordsPermissions: () => getEntityRecordsPermissions, 4221 getHomePage: () => getHomePage, 4222 getNavigationFallbackId: () => getNavigationFallbackId, 4223 getPostsPageId: () => getPostsPageId, 4224 getRegisteredPostMeta: () => getRegisteredPostMeta, 4225 getSyncConnectionStatus: () => getSyncConnectionStatus, 4226 getTemplateId: () => getTemplateId, 4227 getUndoManager: () => getUndoManager, 4228 getViewConfig: () => getViewConfig, 4229 isCollaborationSupported: () => isCollaborationSupported 4230 }); 4231 var import_data8 = __toESM(require_data(), 1); 4232 4233 // packages/core-data/build-module/utils/log-entity-deprecation.mjs 4234 var import_deprecated = __toESM(require_deprecated(), 1); 4235 var loggedAlready = false; 4236 function logEntityDeprecation(kind, name, functionName, { 4237 alternativeFunctionName, 4238 isShorthandSelector = false 4239 } = {}) { 4240 const deprecation = deprecatedEntities[kind]?.[name]; 4241 if (!deprecation) { 4242 return; 4243 } 4244 if (!loggedAlready) { 4245 const { alternative } = deprecation; 4246 const message = isShorthandSelector ? `'$functionName}'` : `The '$kind}', '$name}' entity (used via '$functionName}')`; 4247 let alternativeMessage = `the '$alternative.kind}', '$alternative.name}' entity`; 4248 if (alternativeFunctionName) { 4249 alternativeMessage += ` via the '$alternativeFunctionName}' function`; 4250 } 4251 (0, import_deprecated.default)(message, { 4252 ...deprecation, 4253 alternative: alternativeMessage 4254 }); 4255 } 4256 loggedAlready = true; 4257 setTimeout(() => { 4258 loggedAlready = false; 4259 }, 0); 4260 } 4261 4262 // packages/core-data/build-module/private-selectors.mjs 4263 var EMPTY_OBJECT = {}; 4264 function getUndoManager(state) { 4265 return getSyncManager()?.undoManager ?? state.undoManager; 4266 } 4267 function getNavigationFallbackId(state) { 4268 return state.navigationFallbackId; 4269 } 4270 var getBlockPatternsForPostType = (0, import_data8.createRegistrySelector)( 4271 (select4) => (0, import_data8.createSelector)( 4272 (state, postType) => select4(STORE_NAME).getBlockPatterns().filter( 4273 ({ postTypes }) => !postTypes || Array.isArray(postTypes) && postTypes.includes(postType) 4274 ), 4275 () => [select4(STORE_NAME).getBlockPatterns()] 4276 ) 4277 ); 4278 var getEntityRecordsPermissions = (0, import_data8.createRegistrySelector)( 4279 (select4) => (0, import_data8.createSelector)( 4280 (state, kind, name, ids) => { 4281 const normalizedIds = Array.isArray(ids) ? ids : [ids]; 4282 return normalizedIds.map((id) => ({ 4283 delete: select4(STORE_NAME).canUser("delete", { 4284 kind, 4285 name, 4286 id 4287 }), 4288 update: select4(STORE_NAME).canUser("update", { 4289 kind, 4290 name, 4291 id 4292 }) 4293 })); 4294 }, 4295 (state) => [state.userPermissions] 4296 ) 4297 ); 4298 function getEntityRecordPermissions(state, kind, name, id) { 4299 logEntityDeprecation(kind, name, "getEntityRecordPermissions"); 4300 return getEntityRecordsPermissions(state, kind, name, id)[0]; 4301 } 4302 function getRegisteredPostMeta(state, postType) { 4303 return state.registeredPostMeta?.[postType] ?? {}; 4304 } 4305 function normalizePageId(value) { 4306 if (!value || !["number", "string"].includes(typeof value)) { 4307 return null; 4308 } 4309 if (Number(value) === 0) { 4310 return null; 4311 } 4312 return value.toString(); 4313 } 4314 var getHomePage = (0, import_data8.createRegistrySelector)( 4315 (select4) => (0, import_data8.createSelector)( 4316 () => { 4317 const siteData = select4(STORE_NAME).getEntityRecord( 4318 "root", 4319 "__unstableBase" 4320 ); 4321 if (!siteData) { 4322 return null; 4323 } 4324 const homepageId = siteData?.show_on_front === "page" ? normalizePageId(siteData.page_on_front) : null; 4325 if (homepageId) { 4326 return { postType: "page", postId: homepageId }; 4327 } 4328 const frontPageTemplateId = select4( 4329 STORE_NAME 4330 ).getDefaultTemplateId({ 4331 slug: "front-page" 4332 }); 4333 if (frontPageTemplateId) { 4334 return { 4335 postType: "wp_template", 4336 postId: frontPageTemplateId 4337 }; 4338 } 4339 if (frontPageTemplateId === "") { 4340 return EMPTY_OBJECT; 4341 } 4342 return null; 4343 }, 4344 (state) => [ 4345 // Even though getDefaultTemplateId.shouldInvalidate returns true when root/site changes, 4346 // it doesn't seem to invalidate this cache, I'm not sure why. 4347 getEntityRecord(state, "root", "site"), 4348 getEntityRecord(state, "root", "__unstableBase"), 4349 getDefaultTemplateId(state, { 4350 slug: "front-page" 4351 }) 4352 ] 4353 ) 4354 ); 4355 var getPostsPageId = (0, import_data8.createRegistrySelector)((select4) => () => { 4356 const siteData = select4(STORE_NAME).getEntityRecord( 4357 "root", 4358 "__unstableBase" 4359 ); 4360 return siteData?.show_on_front === "page" ? normalizePageId(siteData.page_for_posts) : null; 4361 }); 4362 var getTemplateId = (0, import_data8.createRegistrySelector)( 4363 (select4) => (state, postType, postId) => { 4364 const homepage = unlock(select4(STORE_NAME)).getHomePage(); 4365 if (!homepage) { 4366 return; 4367 } 4368 if (postType === "page" && postType === homepage?.postType && postId.toString() === homepage?.postId) { 4369 const templates = select4(STORE_NAME).getEntityRecords( 4370 "postType", 4371 "wp_template", 4372 { 4373 per_page: -1 4374 } 4375 ); 4376 if (!templates) { 4377 return; 4378 } 4379 const id = templates.find(({ slug }) => slug === "front-page")?.id; 4380 if (id) { 4381 return id; 4382 } 4383 } 4384 const editedEntity = select4(STORE_NAME).getEditedEntityRecord( 4385 "postType", 4386 postType, 4387 postId 4388 ); 4389 if (!editedEntity) { 4390 return; 4391 } 4392 const postsPageId = unlock(select4(STORE_NAME)).getPostsPageId(); 4393 if (postType === "page" && postsPageId === postId.toString()) { 4394 return select4(STORE_NAME).getDefaultTemplateId({ 4395 slug: "home" 4396 }); 4397 } 4398 const currentTemplateSlug = editedEntity.template; 4399 if (currentTemplateSlug) { 4400 const currentTemplate = select4(STORE_NAME).getEntityRecords("postType", "wp_template", { 4401 per_page: -1 4402 })?.find(({ slug }) => slug === currentTemplateSlug); 4403 if (currentTemplate) { 4404 return currentTemplate.id; 4405 } 4406 } 4407 let slugToCheck; 4408 if (editedEntity.slug) { 4409 slugToCheck = postType === "page" ? `$postType}-$editedEntity.slug}` : `single-$postType}-$editedEntity.slug}`; 4410 } else { 4411 slugToCheck = postType === "page" ? "page" : `single-$postType}`; 4412 } 4413 return select4(STORE_NAME).getDefaultTemplateId({ 4414 slug: slugToCheck 4415 }); 4416 } 4417 ); 4418 function getEditorSettings(state) { 4419 return state.editorSettings; 4420 } 4421 function getEditorAssets(state) { 4422 return state.editorAssets; 4423 } 4424 function isCollaborationSupported(state) { 4425 return state.collaborationSupported; 4426 } 4427 function getViewConfig(state, kind, name) { 4428 return state.viewConfigs?.[`$kind}/$name}`] ?? { 4429 default_view: void 0, 4430 default_layouts: void 0, 4431 view_list: void 0, 4432 form: void 0 4433 }; 4434 } 4435 function getSyncConnectionStatus(state) { 4436 if (!state.syncConnectionStatuses) { 4437 return void 0; 4438 } 4439 const PRIORITIZED_STATUSES = ["disconnected", "connecting", "connected"]; 4440 let coalesced; 4441 for (const status of Object.values(state.syncConnectionStatuses)) { 4442 if (!coalesced || PRIORITIZED_STATUSES.indexOf(status.status) < PRIORITIZED_STATUSES.indexOf(coalesced.status)) { 4443 coalesced = status; 4444 } 4445 } 4446 return coalesced; 4447 } 4448 4449 // packages/core-data/build-module/selectors.mjs 4450 var EMPTY_OBJECT2 = {}; 4451 var isRequestingEmbedPreview = (0, import_data9.createRegistrySelector)( 4452 (select4) => (state, url) => { 4453 return select4(STORE_NAME).isResolving("getEmbedPreview", [ 4454 url 4455 ]); 4456 } 4457 ); 4458 function getAuthors(state, query) { 4459 (0, import_deprecated2.default)("select( 'core' ).getAuthors()", { 4460 since: "5.9", 4461 alternative: "select( 'core' ).getUsers({ who: 'authors' })" 4462 }); 4463 const path = (0, import_url2.addQueryArgs)( 4464 "/wp/v2/users/?who=authors&per_page=100", 4465 query 4466 ); 4467 return getUserQueryResults(state, path); 4468 } 4469 function getCurrentUser(state) { 4470 return state.currentUser; 4471 } 4472 var getUserQueryResults = (0, import_data9.createSelector)( 4473 (state, queryID) => { 4474 const queryResults = state.users.queries[queryID] ?? []; 4475 return queryResults.map((id) => state.users.byId[id]); 4476 }, 4477 (state, queryID) => [ 4478 state.users.queries[queryID], 4479 state.users.byId 4480 ] 4481 ); 4482 function getEntitiesByKind(state, kind) { 4483 (0, import_deprecated2.default)("wp.data.select( 'core' ).getEntitiesByKind()", { 4484 since: "6.0", 4485 alternative: "wp.data.select( 'core' ).getEntitiesConfig()" 4486 }); 4487 return getEntitiesConfig(state, kind); 4488 } 4489 var getEntitiesConfig = (0, import_data9.createSelector)( 4490 (state, kind) => state.entities.config.filter((entity2) => entity2.kind === kind), 4491 /* eslint-disable @typescript-eslint/no-unused-vars */ 4492 (state, kind) => state.entities.config 4493 /* eslint-enable @typescript-eslint/no-unused-vars */ 4494 ); 4495 function getEntity(state, kind, name) { 4496 (0, import_deprecated2.default)("wp.data.select( 'core' ).getEntity()", { 4497 since: "6.0", 4498 alternative: "wp.data.select( 'core' ).getEntityConfig()" 4499 }); 4500 return getEntityConfig(state, kind, name); 4501 } 4502 function getEntityConfig(state, kind, name) { 4503 logEntityDeprecation(kind, name, "getEntityConfig"); 4504 return state.entities.config?.find( 4505 (config) => config.kind === kind && config.name === name 4506 ); 4507 } 4508 var getEntityRecord = (0, import_data9.createSelector)( 4509 ((state, kind, name, key, query) => { 4510 logEntityDeprecation(kind, name, "getEntityRecord"); 4511 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 4512 if (!queriedState) { 4513 return void 0; 4514 } 4515 const context = query?.context ?? "default"; 4516 if (!query || !query._fields) { 4517 if (!queriedState.itemIsComplete[context]?.[key]) { 4518 return void 0; 4519 } 4520 return queriedState.items[context][key]; 4521 } 4522 const item = queriedState.items[context]?.[key]; 4523 if (!item) { 4524 return item; 4525 } 4526 const filteredItem = {}; 4527 const fields = get_normalized_comma_separable_default(query._fields) ?? []; 4528 for (let f = 0; f < fields.length; f++) { 4529 const field = fields[f].split("."); 4530 let value = item; 4531 field.forEach((fieldName) => { 4532 value = value?.[fieldName]; 4533 }); 4534 setNestedValue(filteredItem, field, value); 4535 } 4536 return filteredItem; 4537 }), 4538 (state, kind, name, recordId, query) => { 4539 const context = query?.context ?? "default"; 4540 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 4541 return [ 4542 queriedState?.items[context]?.[recordId], 4543 queriedState?.itemIsComplete[context]?.[recordId] 4544 ]; 4545 } 4546 ); 4547 getEntityRecord.__unstableNormalizeArgs = (args) => { 4548 const newArgs = [...args]; 4549 const recordKey = newArgs?.[2]; 4550 newArgs[2] = isNumericID(recordKey) ? Number(recordKey) : recordKey; 4551 return newArgs; 4552 }; 4553 function hasEntityRecord(state, kind, name, key, query) { 4554 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 4555 if (!queriedState) { 4556 return false; 4557 } 4558 const context = query?.context ?? "default"; 4559 if (!query || !query._fields) { 4560 return !!queriedState.itemIsComplete[context]?.[key]; 4561 } 4562 const item = queriedState.items[context]?.[key]; 4563 if (!item) { 4564 return false; 4565 } 4566 const fields = get_normalized_comma_separable_default(query._fields) ?? []; 4567 for (let i = 0; i < fields.length; i++) { 4568 const path = fields[i].split("."); 4569 let value = item; 4570 for (let p = 0; p < path.length; p++) { 4571 const part = path[p]; 4572 if (!value || !Object.hasOwn(value, part)) { 4573 return false; 4574 } 4575 value = value[part]; 4576 } 4577 } 4578 return true; 4579 } 4580 function __experimentalGetEntityRecordNoResolver(state, kind, name, key) { 4581 return getEntityRecord(state, kind, name, key); 4582 } 4583 var getRawEntityRecord = (0, import_data9.createSelector)( 4584 (state, kind, name, key) => { 4585 logEntityDeprecation(kind, name, "getRawEntityRecord"); 4586 const record = getEntityRecord( 4587 state, 4588 kind, 4589 name, 4590 key 4591 ); 4592 const config = getEntityConfig(state, kind, name); 4593 if (!record || !config?.rawAttributes?.length) { 4594 return record; 4595 } 4596 return Object.fromEntries( 4597 Object.keys(record).map((_key) => { 4598 if (config.rawAttributes.includes(_key)) { 4599 const rawValue = record[_key]?.raw; 4600 return [ 4601 _key, 4602 rawValue !== void 0 ? rawValue : record[_key] 4603 ]; 4604 } 4605 return [_key, record[_key]]; 4606 }) 4607 ); 4608 }, 4609 (state, kind, name, recordId, query) => { 4610 const context = query?.context ?? "default"; 4611 return [ 4612 state.entities.config, 4613 state.entities.records?.[kind]?.[name]?.queriedData?.items[context]?.[recordId], 4614 state.entities.records?.[kind]?.[name]?.queriedData?.itemIsComplete[context]?.[recordId] 4615 ]; 4616 } 4617 ); 4618 function hasEntityRecords(state, kind, name, query) { 4619 logEntityDeprecation(kind, name, "hasEntityRecords"); 4620 return Array.isArray(getEntityRecords(state, kind, name, query)); 4621 } 4622 var getEntityRecords = ((state, kind, name, query) => { 4623 logEntityDeprecation(kind, name, "getEntityRecords"); 4624 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 4625 if (!queriedState) { 4626 return null; 4627 } 4628 return getQueriedItems(queriedState, query, { 4629 supportsPagination: !!getEntityConfig(state, kind, name)?.supportsPagination 4630 }); 4631 }); 4632 var getEntityRecordsTotalItems = (state, kind, name, query) => { 4633 logEntityDeprecation(kind, name, "getEntityRecordsTotalItems"); 4634 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 4635 if (!queriedState) { 4636 return null; 4637 } 4638 return getQueriedTotalItems(queriedState, query); 4639 }; 4640 var getEntityRecordsTotalPages = (state, kind, name, query) => { 4641 logEntityDeprecation(kind, name, "getEntityRecordsTotalPages"); 4642 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 4643 if (!queriedState) { 4644 return null; 4645 } 4646 if (!getEntityConfig(state, kind, name)?.supportsPagination || query?.per_page === -1) { 4647 return 1; 4648 } 4649 const totalItems = getQueriedTotalItems(queriedState, query); 4650 if (!totalItems) { 4651 return totalItems; 4652 } 4653 if (!query?.per_page) { 4654 return getQueriedTotalPages(queriedState, query); 4655 } 4656 return Math.ceil(totalItems / query.per_page); 4657 }; 4658 var __experimentalGetDirtyEntityRecords = (0, import_data9.createSelector)( 4659 (state) => { 4660 const { 4661 entities: { records } 4662 } = state; 4663 const dirtyRecords = []; 4664 Object.keys(records).forEach((kind) => { 4665 Object.keys(records[kind]).forEach((name) => { 4666 const primaryKeys = Object.keys(records[kind][name].edits).filter( 4667 (primaryKey) => ( 4668 // The entity record must exist (not be deleted), 4669 // and it must have edits. 4670 getEntityRecord(state, kind, name, primaryKey) && hasEditsForEntityRecord(state, kind, name, primaryKey) 4671 ) 4672 ); 4673 if (primaryKeys.length) { 4674 const entityConfig = getEntityConfig(state, kind, name); 4675 primaryKeys.forEach((primaryKey) => { 4676 const entityRecord = getEditedEntityRecord( 4677 state, 4678 kind, 4679 name, 4680 primaryKey 4681 ); 4682 dirtyRecords.push({ 4683 // We avoid using primaryKey because it's transformed into a string 4684 // when it's used as an object key. 4685 key: entityRecord ? entityRecord[entityConfig.key || DEFAULT_ENTITY_KEY] : void 0, 4686 title: entityConfig?.getTitle?.(entityRecord) || "", 4687 name, 4688 kind 4689 }); 4690 }); 4691 } 4692 }); 4693 }); 4694 return dirtyRecords; 4695 }, 4696 (state) => [state.entities.records] 4697 ); 4698 var __experimentalGetEntitiesBeingSaved = (0, import_data9.createSelector)( 4699 (state) => { 4700 const { 4701 entities: { records } 4702 } = state; 4703 const recordsBeingSaved = []; 4704 Object.keys(records).forEach((kind) => { 4705 Object.keys(records[kind]).forEach((name) => { 4706 const primaryKeys = Object.keys(records[kind][name].saving).filter( 4707 (primaryKey) => isSavingEntityRecord(state, kind, name, primaryKey) 4708 ); 4709 if (primaryKeys.length) { 4710 const entityConfig = getEntityConfig(state, kind, name); 4711 primaryKeys.forEach((primaryKey) => { 4712 const entityRecord = getEditedEntityRecord( 4713 state, 4714 kind, 4715 name, 4716 primaryKey 4717 ); 4718 recordsBeingSaved.push({ 4719 // We avoid using primaryKey because it's transformed into a string 4720 // when it's used as an object key. 4721 key: entityRecord ? entityRecord[entityConfig.key || DEFAULT_ENTITY_KEY] : void 0, 4722 title: entityConfig?.getTitle?.(entityRecord) || "", 4723 name, 4724 kind 4725 }); 4726 }); 4727 } 4728 }); 4729 }); 4730 return recordsBeingSaved; 4731 }, 4732 (state) => [state.entities.records] 4733 ); 4734 function getEntityRecordEdits(state, kind, name, recordId) { 4735 logEntityDeprecation(kind, name, "getEntityRecordEdits"); 4736 return state.entities.records?.[kind]?.[name]?.edits?.[recordId]; 4737 } 4738 var getEntityRecordNonTransientEdits = (0, import_data9.createSelector)( 4739 (state, kind, name, recordId) => { 4740 logEntityDeprecation(kind, name, "getEntityRecordNonTransientEdits"); 4741 const { transientEdits } = getEntityConfig(state, kind, name) || {}; 4742 const edits = getEntityRecordEdits(state, kind, name, recordId) || {}; 4743 if (!transientEdits) { 4744 return edits; 4745 } 4746 return Object.keys(edits).reduce((acc, key) => { 4747 if (!transientEdits[key]) { 4748 acc[key] = edits[key]; 4749 } 4750 return acc; 4751 }, {}); 4752 }, 4753 (state, kind, name, recordId) => [ 4754 state.entities.config, 4755 state.entities.records?.[kind]?.[name]?.edits?.[recordId] 4756 ] 4757 ); 4758 function hasEditsForEntityRecord(state, kind, name, recordId) { 4759 logEntityDeprecation(kind, name, "hasEditsForEntityRecord"); 4760 return isSavingEntityRecord(state, kind, name, recordId) || Object.keys( 4761 getEntityRecordNonTransientEdits(state, kind, name, recordId) 4762 ).length > 0; 4763 } 4764 var getEditedEntityRecord = (0, import_data9.createSelector)( 4765 (state, kind, name, recordId) => { 4766 logEntityDeprecation(kind, name, "getEditedEntityRecord"); 4767 const raw = getRawEntityRecord(state, kind, name, recordId); 4768 const edited = getEntityRecordEdits(state, kind, name, recordId); 4769 if (!raw && !edited) { 4770 return false; 4771 } 4772 return { 4773 ...raw, 4774 ...edited 4775 }; 4776 }, 4777 (state, kind, name, recordId, query) => { 4778 const context = query?.context ?? "default"; 4779 return [ 4780 state.entities.config, 4781 state.entities.records?.[kind]?.[name]?.queriedData.items[context]?.[recordId], 4782 state.entities.records?.[kind]?.[name]?.queriedData.itemIsComplete[context]?.[recordId], 4783 state.entities.records?.[kind]?.[name]?.edits?.[recordId] 4784 ]; 4785 } 4786 ); 4787 function isAutosavingEntityRecord(state, kind, name, recordId) { 4788 logEntityDeprecation(kind, name, "isAutosavingEntityRecord"); 4789 const { pending, isAutosave } = state.entities.records?.[kind]?.[name]?.saving?.[recordId] ?? {}; 4790 return Boolean(pending && isAutosave); 4791 } 4792 function isSavingEntityRecord(state, kind, name, recordId) { 4793 logEntityDeprecation(kind, name, "isSavingEntityRecord"); 4794 return state.entities.records?.[kind]?.[name]?.saving?.[recordId]?.pending ?? false; 4795 } 4796 function isDeletingEntityRecord(state, kind, name, recordId) { 4797 logEntityDeprecation(kind, name, "isDeletingEntityRecord"); 4798 return state.entities.records?.[kind]?.[name]?.deleting?.[recordId]?.pending ?? false; 4799 } 4800 function getLastEntitySaveError(state, kind, name, recordId) { 4801 logEntityDeprecation(kind, name, "getLastEntitySaveError"); 4802 return state.entities.records?.[kind]?.[name]?.saving?.[recordId]?.error; 4803 } 4804 function getLastEntityDeleteError(state, kind, name, recordId) { 4805 logEntityDeprecation(kind, name, "getLastEntityDeleteError"); 4806 return state.entities.records?.[kind]?.[name]?.deleting?.[recordId]?.error; 4807 } 4808 function getUndoEdit(state) { 4809 (0, import_deprecated2.default)("select( 'core' ).getUndoEdit()", { 4810 since: "6.3" 4811 }); 4812 return void 0; 4813 } 4814 function getRedoEdit(state) { 4815 (0, import_deprecated2.default)("select( 'core' ).getRedoEdit()", { 4816 since: "6.3" 4817 }); 4818 return void 0; 4819 } 4820 function hasUndo(state) { 4821 if (getSyncManager()?.undoManager) { 4822 return state.syncUndoManagerState.hasUndo; 4823 } 4824 return getUndoManager(state).hasUndo(); 4825 } 4826 function hasRedo(state) { 4827 if (getSyncManager()?.undoManager) { 4828 return state.syncUndoManagerState.hasRedo; 4829 } 4830 return getUndoManager(state).hasRedo(); 4831 } 4832 function getCurrentTheme(state) { 4833 if (!state.currentTheme) { 4834 return null; 4835 } 4836 return getEntityRecord(state, "root", "theme", state.currentTheme); 4837 } 4838 function __experimentalGetCurrentGlobalStylesId(state) { 4839 return state.currentGlobalStylesId; 4840 } 4841 function getThemeSupports(state) { 4842 return getCurrentTheme(state)?.theme_supports ?? EMPTY_OBJECT2; 4843 } 4844 function getEmbedPreview(state, url) { 4845 return state.embedPreviews[url]; 4846 } 4847 function isPreviewEmbedFallback(state, url) { 4848 const preview = state.embedPreviews[url]; 4849 const oEmbedLinkCheck = '<a href="' + url + '">' + url + "</a>"; 4850 if (!preview) { 4851 return false; 4852 } 4853 return preview.html === oEmbedLinkCheck; 4854 } 4855 function canUser(state, action, resource, id) { 4856 const isEntity = typeof resource === "object"; 4857 if (isEntity && (!resource.kind || !resource.name)) { 4858 return false; 4859 } 4860 if (isEntity) { 4861 logEntityDeprecation(resource.kind, resource.name, "canUser"); 4862 } 4863 const key = getUserPermissionCacheKey(action, resource, id); 4864 return state.userPermissions[key]; 4865 } 4866 function canUserEditEntityRecord(state, kind, name, recordId) { 4867 (0, import_deprecated2.default)(`wp.data.select( 'core' ).canUserEditEntityRecord()`, { 4868 since: "6.7", 4869 alternative: `wp.data.select( 'core' ).canUser( 'update', { kind, name, id } )` 4870 }); 4871 return canUser(state, "update", { kind, name, id: recordId }); 4872 } 4873 function getAutosaves(state, postType, postId) { 4874 return state.autosaves[postId]; 4875 } 4876 function getAutosave(state, postType, postId, authorId) { 4877 if (authorId === void 0) { 4878 return; 4879 } 4880 const autosaves2 = state.autosaves[postId]; 4881 return autosaves2?.find( 4882 (autosave) => autosave.author === authorId 4883 ); 4884 } 4885 var hasFetchedAutosaves = (0, import_data9.createRegistrySelector)( 4886 (select4) => (state, postType, postId) => { 4887 return select4(STORE_NAME).hasFinishedResolution("getAutosaves", [ 4888 postType, 4889 postId 4890 ]); 4891 } 4892 ); 4893 function getReferenceByDistinctEdits(state) { 4894 return state.editsReference; 4895 } 4896 function __experimentalGetCurrentThemeBaseGlobalStyles(state) { 4897 const currentTheme2 = getCurrentTheme(state); 4898 if (!currentTheme2) { 4899 return null; 4900 } 4901 return state.themeBaseGlobalStyles[currentTheme2.stylesheet]; 4902 } 4903 function __experimentalGetCurrentThemeGlobalStylesVariations(state) { 4904 const currentTheme2 = getCurrentTheme(state); 4905 if (!currentTheme2) { 4906 return null; 4907 } 4908 return state.themeGlobalStyleVariations[currentTheme2.stylesheet]; 4909 } 4910 function getBlockPatterns(state) { 4911 return state.blockPatterns; 4912 } 4913 function getBlockPatternCategories(state) { 4914 return state.blockPatternCategories; 4915 } 4916 function getUserPatternCategories(state) { 4917 return state.userPatternCategories; 4918 } 4919 function getCurrentThemeGlobalStylesRevisions(state) { 4920 (0, import_deprecated2.default)("select( 'core' ).getCurrentThemeGlobalStylesRevisions()", { 4921 since: "6.5.0", 4922 alternative: "select( 'core' ).getRevisions( 'root', 'globalStyles', ${ recordKey } )" 4923 }); 4924 const currentGlobalStylesId2 = __experimentalGetCurrentGlobalStylesId(state); 4925 if (!currentGlobalStylesId2) { 4926 return null; 4927 } 4928 return state.themeGlobalStyleRevisions[currentGlobalStylesId2]; 4929 } 4930 function getDefaultTemplateId(state, query) { 4931 return state.defaultTemplates[JSON.stringify(query)]; 4932 } 4933 var getRevisions = (state, kind, name, recordKey, query) => { 4934 logEntityDeprecation(kind, name, "getRevisions"); 4935 const queriedStateRevisions = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey]; 4936 if (!queriedStateRevisions) { 4937 return null; 4938 } 4939 return getQueriedItems(queriedStateRevisions, query); 4940 }; 4941 function hasRevision(state, kind, name, recordKey, revisionKey, query) { 4942 const queriedState = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey]; 4943 if (!queriedState) { 4944 return false; 4945 } 4946 const context = query?.context ?? "default"; 4947 if (!query || !query._fields) { 4948 return !!queriedState.itemIsComplete[context]?.[revisionKey]; 4949 } 4950 const item = queriedState.items[context]?.[revisionKey]; 4951 if (!item) { 4952 return false; 4953 } 4954 const fields = get_normalized_comma_separable_default(query._fields) ?? []; 4955 for (let i = 0; i < fields.length; i++) { 4956 const path = fields[i].split("."); 4957 let value = item; 4958 for (let p = 0; p < path.length; p++) { 4959 const part = path[p]; 4960 if (!value || !Object.hasOwn(value, part)) { 4961 return false; 4962 } 4963 value = value[part]; 4964 } 4965 } 4966 return true; 4967 } 4968 var getRevision = (0, import_data9.createSelector)( 4969 (state, kind, name, recordKey, revisionKey, query) => { 4970 logEntityDeprecation(kind, name, "getRevision"); 4971 const queriedState = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey]; 4972 if (!queriedState) { 4973 return void 0; 4974 } 4975 const context = query?.context ?? "default"; 4976 if (!query || !query._fields) { 4977 if (!queriedState.itemIsComplete[context]?.[revisionKey]) { 4978 return void 0; 4979 } 4980 return queriedState.items[context][revisionKey]; 4981 } 4982 const item = queriedState.items[context]?.[revisionKey]; 4983 if (!item) { 4984 return item; 4985 } 4986 const filteredItem = {}; 4987 const fields = get_normalized_comma_separable_default(query._fields) ?? []; 4988 for (let f = 0; f < fields.length; f++) { 4989 const field = fields[f].split("."); 4990 let value = item; 4991 field.forEach((fieldName) => { 4992 value = value?.[fieldName]; 4993 }); 4994 setNestedValue(filteredItem, field, value); 4995 } 4996 return filteredItem; 4997 }, 4998 (state, kind, name, recordKey, revisionKey, query) => { 4999 const context = query?.context ?? "default"; 5000 const queriedState = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey]; 5001 return [ 5002 queriedState?.items?.[context]?.[revisionKey], 5003 queriedState?.itemIsComplete?.[context]?.[revisionKey] 5004 ]; 5005 } 5006 ); 5007 5008 // packages/core-data/build-module/actions.mjs 5009 var actions_exports = {}; 5010 __export(actions_exports, { 5011 __experimentalBatch: () => __experimentalBatch, 5012 __experimentalReceiveCurrentGlobalStylesId: () => __experimentalReceiveCurrentGlobalStylesId, 5013 __experimentalReceiveThemeBaseGlobalStyles: () => __experimentalReceiveThemeBaseGlobalStyles, 5014 __experimentalReceiveThemeGlobalStyleVariations: () => __experimentalReceiveThemeGlobalStyleVariations, 5015 __experimentalSaveSpecifiedEntityEdits: () => __experimentalSaveSpecifiedEntityEdits, 5016 __unstableCreateUndoLevel: () => __unstableCreateUndoLevel, 5017 addEntities: () => addEntities, 5018 clearEntityRecordEdits: () => clearEntityRecordEdits, 5019 deleteEntityRecord: () => deleteEntityRecord, 5020 editEntityRecord: () => editEntityRecord, 5021 receiveAutosaves: () => receiveAutosaves, 5022 receiveCurrentTheme: () => receiveCurrentTheme, 5023 receiveCurrentUser: () => receiveCurrentUser, 5024 receiveDefaultTemplateId: () => receiveDefaultTemplateId, 5025 receiveEmbedPreview: () => receiveEmbedPreview, 5026 receiveEntityRecords: () => receiveEntityRecords, 5027 receiveNavigationFallbackId: () => receiveNavigationFallbackId, 5028 receiveRevisions: () => receiveRevisions, 5029 receiveThemeGlobalStyleRevisions: () => receiveThemeGlobalStyleRevisions, 5030 receiveThemeSupports: () => receiveThemeSupports, 5031 receiveUploadPermissions: () => receiveUploadPermissions, 5032 receiveUserPermission: () => receiveUserPermission, 5033 receiveUserPermissions: () => receiveUserPermissions, 5034 receiveUserQuery: () => receiveUserQuery, 5035 redo: () => redo, 5036 saveEditedEntityRecord: () => saveEditedEntityRecord, 5037 saveEntityRecord: () => saveEntityRecord, 5038 undo: () => undo 5039 }); 5040 var import_api_fetch4 = __toESM(require_api_fetch(), 1); 5041 var import_url3 = __toESM(require_url(), 1); 5042 var import_deprecated3 = __toESM(require_deprecated(), 1); 5043 5044 // packages/core-data/build-module/batch/default-processor.mjs 5045 var import_api_fetch3 = __toESM(require_api_fetch(), 1); 5046 var maxItems = null; 5047 function chunk(arr, chunkSize) { 5048 const tmp = [...arr]; 5049 const cache3 = []; 5050 while (tmp.length) { 5051 cache3.push(tmp.splice(0, chunkSize)); 5052 } 5053 return cache3; 5054 } 5055 async function defaultProcessor(requests) { 5056 if (maxItems === null) { 5057 const preflightResponse = await (0, import_api_fetch3.default)({ 5058 path: "/batch/v1", 5059 method: "OPTIONS" 5060 }); 5061 maxItems = preflightResponse.endpoints[0].args.requests.maxItems; 5062 } 5063 const results = []; 5064 for (const batchRequests of chunk(requests, maxItems)) { 5065 const batchResponse = await (0, import_api_fetch3.default)({ 5066 path: "/batch/v1", 5067 method: "POST", 5068 data: { 5069 validation: "require-all-validate", 5070 requests: batchRequests.map((request) => ({ 5071 path: request.path, 5072 body: request.data, 5073 // Rename 'data' to 'body'. 5074 method: request.method, 5075 headers: request.headers 5076 })) 5077 } 5078 }); 5079 let batchResults; 5080 if (batchResponse.failed) { 5081 batchResults = batchResponse.responses.map((response) => ({ 5082 error: response?.body 5083 })); 5084 } else { 5085 batchResults = batchResponse.responses.map((response) => { 5086 const result = {}; 5087 if (response.status >= 200 && response.status < 300) { 5088 result.output = response.body; 5089 } else { 5090 result.error = response.body; 5091 } 5092 return result; 5093 }); 5094 } 5095 results.push(...batchResults); 5096 } 5097 return results; 5098 } 5099 5100 // packages/core-data/build-module/batch/create-batch.mjs 5101 function createBatch(processor = defaultProcessor) { 5102 let lastId = 0; 5103 let queue = []; 5104 const pending = new ObservableSet(); 5105 return { 5106 /** 5107 * Adds an input to the batch and returns a promise that is resolved or 5108 * rejected when the input is processed by `batch.run()`. 5109 * 5110 * You may also pass a thunk which allows inputs to be added 5111 * asynchronously. 5112 * 5113 * ``` 5114 * // Both are allowed: 5115 * batch.add( { path: '/v1/books', ... } ); 5116 * batch.add( ( add ) => add( { path: '/v1/books', ... } ) ); 5117 * ``` 5118 * 5119 * If a thunk is passed, `batch.run()` will pause until either: 5120 * 5121 * - The thunk calls its `add` argument, or; 5122 * - The thunk returns a promise and that promise resolves, or; 5123 * - The thunk returns a non-promise. 5124 * 5125 * @param {any|Function} inputOrThunk Input to add or thunk to execute. 5126 * 5127 * @return {Promise|any} If given an input, returns a promise that 5128 * is resolved or rejected when the batch is 5129 * processed. If given a thunk, returns the return 5130 * value of that thunk. 5131 */ 5132 add(inputOrThunk) { 5133 const id = ++lastId; 5134 pending.add(id); 5135 const add = (input) => new Promise((resolve, reject) => { 5136 queue.push({ 5137 input, 5138 resolve, 5139 reject 5140 }); 5141 pending.delete(id); 5142 }); 5143 if (typeof inputOrThunk === "function") { 5144 return Promise.resolve(inputOrThunk(add)).finally(() => { 5145 pending.delete(id); 5146 }); 5147 } 5148 return add(inputOrThunk); 5149 }, 5150 /** 5151 * Runs the batch. This calls `batchProcessor` and resolves or rejects 5152 * all promises returned by `add()`. 5153 * 5154 * @return {Promise<boolean>} A promise that resolves to a boolean that is true 5155 * if the processor returned no errors. 5156 */ 5157 async run() { 5158 if (pending.size) { 5159 await new Promise((resolve) => { 5160 const unsubscribe = pending.subscribe(() => { 5161 if (!pending.size) { 5162 unsubscribe(); 5163 resolve(void 0); 5164 } 5165 }); 5166 }); 5167 } 5168 let results; 5169 try { 5170 results = await processor( 5171 queue.map(({ input }) => input) 5172 ); 5173 if (results.length !== queue.length) { 5174 throw new Error( 5175 "run: Array returned by processor must be same size as input array." 5176 ); 5177 } 5178 } catch (error) { 5179 for (const { reject } of queue) { 5180 reject(error); 5181 } 5182 throw error; 5183 } 5184 let isSuccess = true; 5185 results.forEach((result, key) => { 5186 const queueItem = queue[key]; 5187 if (result?.error) { 5188 queueItem?.reject(result.error); 5189 isSuccess = false; 5190 } else { 5191 queueItem?.resolve(result?.output ?? result); 5192 } 5193 }); 5194 queue = []; 5195 return isSuccess; 5196 } 5197 }; 5198 } 5199 var ObservableSet = class { 5200 constructor(...args) { 5201 this.set = new Set(...args); 5202 this.subscribers = /* @__PURE__ */ new Set(); 5203 } 5204 get size() { 5205 return this.set.size; 5206 } 5207 add(value) { 5208 this.set.add(value); 5209 this.subscribers.forEach((subscriber) => subscriber()); 5210 return this; 5211 } 5212 delete(value) { 5213 const isSuccess = this.set.delete(value); 5214 this.subscribers.forEach((subscriber) => subscriber()); 5215 return isSuccess; 5216 } 5217 subscribe(subscriber) { 5218 this.subscribers.add(subscriber); 5219 return () => { 5220 this.subscribers.delete(subscriber); 5221 }; 5222 } 5223 }; 5224 5225 // packages/core-data/build-module/actions.mjs 5226 function addTitleToAutoDraft(record) { 5227 return record.status === "auto-draft" ? { ...record, title: "" } : record; 5228 } 5229 function receiveUserQuery(queryID, users2) { 5230 return { 5231 type: "RECEIVE_USER_QUERY", 5232 users: Array.isArray(users2) ? users2 : [users2], 5233 queryID 5234 }; 5235 } 5236 function receiveCurrentUser(currentUser2) { 5237 return { 5238 type: "RECEIVE_CURRENT_USER", 5239 currentUser: currentUser2 5240 }; 5241 } 5242 function addEntities(entities2) { 5243 return { 5244 type: "ADD_ENTITIES", 5245 entities: entities2 5246 }; 5247 } 5248 function receiveEntityRecords(kind, name, records, query = void 0, invalidateCache = false, edits = void 0, meta = void 0) { 5249 if (kind === "postType") { 5250 records = Array.isArray(records) ? records.map(addTitleToAutoDraft) : addTitleToAutoDraft(records); 5251 } 5252 let action; 5253 if (query) { 5254 action = receiveQueriedItems(records, query, edits, meta); 5255 } else { 5256 action = receiveItems(records, edits, meta); 5257 } 5258 return { 5259 ...action, 5260 kind, 5261 name, 5262 invalidateCache 5263 }; 5264 } 5265 function receiveCurrentTheme(currentTheme2) { 5266 return { 5267 type: "RECEIVE_CURRENT_THEME", 5268 currentTheme: currentTheme2 5269 }; 5270 } 5271 function __experimentalReceiveCurrentGlobalStylesId(currentGlobalStylesId2) { 5272 return { 5273 type: "RECEIVE_CURRENT_GLOBAL_STYLES_ID", 5274 id: currentGlobalStylesId2 5275 }; 5276 } 5277 function __experimentalReceiveThemeBaseGlobalStyles(stylesheet, globalStyles) { 5278 return { 5279 type: "RECEIVE_THEME_GLOBAL_STYLES", 5280 stylesheet, 5281 globalStyles 5282 }; 5283 } 5284 function __experimentalReceiveThemeGlobalStyleVariations(stylesheet, variations) { 5285 return { 5286 type: "RECEIVE_THEME_GLOBAL_STYLE_VARIATIONS", 5287 stylesheet, 5288 variations 5289 }; 5290 } 5291 function receiveThemeSupports() { 5292 (0, import_deprecated3.default)("wp.data.dispatch( 'core' ).receiveThemeSupports", { 5293 since: "5.9" 5294 }); 5295 return { 5296 type: "DO_NOTHING" 5297 }; 5298 } 5299 function receiveThemeGlobalStyleRevisions(currentId, revisions) { 5300 (0, import_deprecated3.default)( 5301 "wp.data.dispatch( 'core' ).receiveThemeGlobalStyleRevisions()", 5302 { 5303 since: "6.5.0", 5304 alternative: "wp.data.dispatch( 'core' ).receiveRevisions" 5305 } 5306 ); 5307 return { 5308 type: "RECEIVE_THEME_GLOBAL_STYLE_REVISIONS", 5309 currentId, 5310 revisions 5311 }; 5312 } 5313 function receiveEmbedPreview(url, preview) { 5314 return { 5315 type: "RECEIVE_EMBED_PREVIEW", 5316 url, 5317 preview 5318 }; 5319 } 5320 var deleteEntityRecord = (kind, name, recordId, query, { __unstableFetch = import_api_fetch4.default, throwOnError = false } = {}) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 5321 logEntityDeprecation(kind, name, "deleteEntityRecord"); 5322 const configs = await resolveSelect2.getEntitiesConfig(kind); 5323 const entityConfig = configs.find( 5324 (config) => config.kind === kind && config.name === name 5325 ); 5326 let error; 5327 let deletedRecord = false; 5328 if (!entityConfig) { 5329 return; 5330 } 5331 const lock2 = await dispatch3.__unstableAcquireStoreLock( 5332 STORE_NAME, 5333 ["entities", "records", kind, name, recordId], 5334 { exclusive: true } 5335 ); 5336 try { 5337 dispatch3({ 5338 type: "DELETE_ENTITY_RECORD_START", 5339 kind, 5340 name, 5341 recordId 5342 }); 5343 let hasError = false; 5344 let { baseURL } = entityConfig; 5345 if (kind === "postType" && name === "wp_template" && (recordId && typeof recordId === "string" && !/^\d+$/.test(recordId) || !window?.__experimentalTemplateActivate)) { 5346 baseURL = baseURL.slice(0, baseURL.lastIndexOf("/")) + "/templates"; 5347 } 5348 try { 5349 let path = `$baseURL}/$recordId}`; 5350 if (query) { 5351 path = (0, import_url3.addQueryArgs)(path, query); 5352 } 5353 deletedRecord = await __unstableFetch({ 5354 path, 5355 method: "DELETE" 5356 }); 5357 await dispatch3(removeItems(kind, name, recordId, true)); 5358 if (entityConfig.syncConfig) { 5359 const objectType = `$kind}/$name}`; 5360 const objectId = recordId; 5361 getSyncManager()?.unload(objectType, objectId); 5362 } 5363 } catch (_error) { 5364 hasError = true; 5365 error = _error; 5366 } 5367 dispatch3({ 5368 type: "DELETE_ENTITY_RECORD_FINISH", 5369 kind, 5370 name, 5371 recordId, 5372 error 5373 }); 5374 if (hasError && throwOnError) { 5375 throw error; 5376 } 5377 return deletedRecord; 5378 } finally { 5379 dispatch3.__unstableReleaseStoreLock(lock2); 5380 } 5381 }; 5382 var editEntityRecord = (kind, name, recordId, edits, options = {}) => ({ select: select4, dispatch: dispatch3 }) => { 5383 logEntityDeprecation(kind, name, "editEntityRecord"); 5384 const entityConfig = select4.getEntityConfig(kind, name); 5385 if (!entityConfig) { 5386 throw new Error( 5387 `The entity being edited ($kind}, $name}) does not have a loaded config.` 5388 ); 5389 } 5390 const { mergedEdits = {} } = entityConfig; 5391 const record = select4.getRawEntityRecord(kind, name, recordId); 5392 const editedRecord = select4.getEditedEntityRecord( 5393 kind, 5394 name, 5395 recordId 5396 ); 5397 const editsWithMerges = Object.keys(edits).reduce((acc, key) => { 5398 acc[key] = mergedEdits[key] ? { ...editedRecord[key], ...edits[key] } : edits[key]; 5399 return acc; 5400 }, {}); 5401 const edit = { 5402 kind, 5403 name, 5404 recordId, 5405 // Clear edits when they are equal to their persisted counterparts 5406 // so that the property is not considered dirty. 5407 edits: clearUnchangedEdits(editsWithMerges, record) 5408 }; 5409 if (entityConfig.syncConfig) { 5410 const objectType = `$kind}/$name}`; 5411 const objectId = recordId; 5412 const isNewUndoLevel = options.undoIgnore ? false : !options.isCached; 5413 const origin = options.undoIgnore ? LOCAL_UNDO_IGNORED_ORIGIN : LOCAL_EDITOR_ORIGIN; 5414 getSyncManager()?.update( 5415 objectType, 5416 objectId, 5417 editsWithMerges, 5418 origin, 5419 { isNewUndoLevel } 5420 ); 5421 } 5422 if (!options.undoIgnore) { 5423 select4.getUndoManager().addRecord( 5424 [ 5425 { 5426 id: { kind, name, recordId }, 5427 changes: Object.keys(edits).reduce((acc, key) => { 5428 acc[key] = { 5429 from: editedRecord[key], 5430 to: edits[key] 5431 }; 5432 return acc; 5433 }, {}) 5434 } 5435 ], 5436 options.isCached 5437 ); 5438 } 5439 dispatch3({ 5440 type: "EDIT_ENTITY_RECORD", 5441 ...edit 5442 }); 5443 }; 5444 var clearEntityRecordEdits = (kind, name, recordId) => ({ select: select4, dispatch: dispatch3 }) => { 5445 const entityConfig = select4.getEntityConfig(kind, name); 5446 logEntityDeprecation(kind, name, "clearEntityRecordEdits"); 5447 if (!entityConfig) { 5448 throw new Error( 5449 `The entity being edited ($kind}, $name}) does not have a loaded config.` 5450 ); 5451 } 5452 const currentEdits = select4.getEntityRecordEdits( 5453 kind, 5454 name, 5455 recordId 5456 ); 5457 if (!currentEdits) { 5458 return; 5459 } 5460 const clearedEdits = Object.keys(currentEdits).reduce( 5461 (acc, key) => { 5462 acc[key] = void 0; 5463 return acc; 5464 }, 5465 {} 5466 ); 5467 dispatch3({ 5468 type: "EDIT_ENTITY_RECORD", 5469 kind, 5470 name, 5471 recordId, 5472 edits: clearedEdits 5473 }); 5474 }; 5475 var undo = () => ({ select: select4, dispatch: dispatch3 }) => { 5476 const undoRecord = select4.getUndoManager().undo(); 5477 if (!undoRecord) { 5478 return; 5479 } 5480 dispatch3({ 5481 type: "UNDO", 5482 record: undoRecord 5483 }); 5484 }; 5485 var redo = () => ({ select: select4, dispatch: dispatch3 }) => { 5486 const redoRecord = select4.getUndoManager().redo(); 5487 if (!redoRecord) { 5488 return; 5489 } 5490 dispatch3({ 5491 type: "REDO", 5492 record: redoRecord 5493 }); 5494 }; 5495 var __unstableCreateUndoLevel = () => ({ select: select4 }) => { 5496 select4.getUndoManager().addRecord(); 5497 }; 5498 var saveEntityRecord = (kind, name, record, options = {}) => async ({ select: select4, resolveSelect: resolveSelect2, dispatch: dispatch3 }) => { 5499 const { 5500 isAutosave = false, 5501 __unstableFetch = import_api_fetch4.default, 5502 __unstableSkipSyncUpdate = false, 5503 throwOnError = false 5504 } = options; 5505 logEntityDeprecation(kind, name, "saveEntityRecord"); 5506 const configs = await resolveSelect2.getEntitiesConfig(kind); 5507 const entityConfig = configs.find( 5508 (config) => config.kind === kind && config.name === name 5509 ); 5510 if (!entityConfig) { 5511 return; 5512 } 5513 const entityIdKey = entityConfig.key ?? DEFAULT_ENTITY_KEY; 5514 const recordId = record[entityIdKey]; 5515 const isNewRecord = !!entityIdKey && !recordId; 5516 const lock2 = await dispatch3.__unstableAcquireStoreLock( 5517 STORE_NAME, 5518 ["entities", "records", kind, name, recordId || v4_default()], 5519 { exclusive: true } 5520 ); 5521 try { 5522 for (const [key, value] of Object.entries(record)) { 5523 if (typeof value === "function") { 5524 const evaluatedValue = value( 5525 select4.getEditedEntityRecord(kind, name, recordId) 5526 ); 5527 dispatch3.editEntityRecord( 5528 kind, 5529 name, 5530 recordId, 5531 { 5532 [key]: evaluatedValue 5533 }, 5534 { undoIgnore: true } 5535 ); 5536 record[key] = evaluatedValue; 5537 } 5538 } 5539 dispatch3({ 5540 type: "SAVE_ENTITY_RECORD_START", 5541 kind, 5542 name, 5543 recordId, 5544 isAutosave 5545 }); 5546 let updatedRecord; 5547 let error; 5548 let hasError = false; 5549 let { baseURL } = entityConfig; 5550 if (kind === "postType" && name === "wp_template" && (recordId && typeof recordId === "string" && !/^\d+$/.test(recordId) || !window?.__experimentalTemplateActivate)) { 5551 baseURL = baseURL.slice(0, baseURL.lastIndexOf("/")) + "/templates"; 5552 } 5553 try { 5554 const path = `$baseURL}$recordId ? "/" + recordId : ""}`; 5555 const persistedRecord = !isNewRecord ? select4.getRawEntityRecord(kind, name, recordId) : {}; 5556 if (isAutosave) { 5557 const merged = { ...persistedRecord, ...record }; 5558 const data = [ 5559 "title", 5560 "excerpt", 5561 "content", 5562 "meta" 5563 ].reduce( 5564 (acc, key) => { 5565 if (key in merged) { 5566 acc[key] = merged[key]; 5567 } 5568 return acc; 5569 }, 5570 { 5571 // Do not update the `status` if we have edited it when auto saving. 5572 // It's very important to let the user explicitly save this change, 5573 // because it can lead to unexpected results. An example would be to 5574 // have a draft post and change the status to publish. 5575 status: merged.status === "auto-draft" ? "draft" : void 0 5576 } 5577 ); 5578 updatedRecord = await __unstableFetch({ 5579 path: `$path}/autosaves`, 5580 method: "POST", 5581 data 5582 }); 5583 if (persistedRecord.id === updatedRecord.id) { 5584 let newRecord = { 5585 ...persistedRecord, 5586 ...data, 5587 ...updatedRecord 5588 }; 5589 newRecord = Object.keys(newRecord).reduce( 5590 (acc, key) => { 5591 if ([ 5592 "title", 5593 "excerpt", 5594 "content", 5595 "meta" 5596 ].includes(key)) { 5597 acc[key] = newRecord[key]; 5598 } else if (key === "status") { 5599 acc[key] = persistedRecord.status === "auto-draft" && newRecord.status === "draft" ? newRecord.status : persistedRecord.status; 5600 } else { 5601 acc[key] = persistedRecord[key]; 5602 } 5603 return acc; 5604 }, 5605 {} 5606 ); 5607 dispatch3.receiveEntityRecords( 5608 kind, 5609 name, 5610 newRecord, 5611 void 0, 5612 true 5613 ); 5614 } else { 5615 dispatch3.receiveAutosaves( 5616 persistedRecord.id, 5617 updatedRecord 5618 ); 5619 } 5620 } else { 5621 let edits = record; 5622 if (entityConfig.__unstablePrePersist) { 5623 edits = { 5624 ...edits, 5625 ...await entityConfig.__unstablePrePersist( 5626 persistedRecord, 5627 edits 5628 ) 5629 }; 5630 } 5631 updatedRecord = await __unstableFetch({ 5632 path, 5633 method: recordId ? "PUT" : "POST", 5634 data: edits 5635 }); 5636 dispatch3.receiveEntityRecords( 5637 kind, 5638 name, 5639 updatedRecord, 5640 void 0, 5641 true, 5642 edits 5643 ); 5644 if (entityConfig.syncConfig) { 5645 getSyncManager()?.update( 5646 `$kind}/$name}`, 5647 recordId, 5648 __unstableSkipSyncUpdate ? {} : updatedRecord, 5649 LOCAL_UNDO_IGNORED_ORIGIN, 5650 { isSave: true } 5651 ); 5652 } 5653 } 5654 } catch (_error) { 5655 hasError = true; 5656 error = _error; 5657 } 5658 dispatch3({ 5659 type: "SAVE_ENTITY_RECORD_FINISH", 5660 kind, 5661 name, 5662 recordId, 5663 error, 5664 isAutosave 5665 }); 5666 if (hasError && throwOnError) { 5667 throw error; 5668 } 5669 return updatedRecord; 5670 } finally { 5671 dispatch3.__unstableReleaseStoreLock(lock2); 5672 } 5673 }; 5674 var __experimentalBatch = (requests) => async ({ dispatch: dispatch3 }) => { 5675 const batch = createBatch(); 5676 const api = { 5677 saveEntityRecord(kind, name, record, options) { 5678 return batch.add( 5679 (add) => dispatch3.saveEntityRecord(kind, name, record, { 5680 ...options, 5681 __unstableFetch: add 5682 }) 5683 ); 5684 }, 5685 saveEditedEntityRecord(kind, name, recordId, options) { 5686 return batch.add( 5687 (add) => dispatch3.saveEditedEntityRecord(kind, name, recordId, { 5688 ...options, 5689 __unstableFetch: add 5690 }) 5691 ); 5692 }, 5693 deleteEntityRecord(kind, name, recordId, query, options) { 5694 return batch.add( 5695 (add) => dispatch3.deleteEntityRecord(kind, name, recordId, query, { 5696 ...options, 5697 __unstableFetch: add 5698 }) 5699 ); 5700 } 5701 }; 5702 const resultPromises = requests.map((request) => request(api)); 5703 const [, ...results] = await Promise.all([ 5704 batch.run(), 5705 ...resultPromises 5706 ]); 5707 return results; 5708 }; 5709 var saveEditedEntityRecord = (kind, name, recordId, options) => async ({ select: select4, dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 5710 logEntityDeprecation(kind, name, "saveEditedEntityRecord"); 5711 if (!select4.hasEditsForEntityRecord(kind, name, recordId)) { 5712 return; 5713 } 5714 const configs = await resolveSelect2.getEntitiesConfig(kind); 5715 const entityConfig = configs.find( 5716 (config) => config.kind === kind && config.name === name 5717 ); 5718 if (!entityConfig) { 5719 return; 5720 } 5721 const entityIdKey = entityConfig.key || DEFAULT_ENTITY_KEY; 5722 const edits = select4.getEntityRecordNonTransientEdits( 5723 kind, 5724 name, 5725 recordId 5726 ); 5727 const record = { [entityIdKey]: recordId, ...edits }; 5728 return await dispatch3.saveEntityRecord(kind, name, record, options); 5729 }; 5730 var __experimentalSaveSpecifiedEntityEdits = (kind, name, recordId, itemsToSave, options) => async ({ select: select4, dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 5731 logEntityDeprecation( 5732 kind, 5733 name, 5734 "__experimentalSaveSpecifiedEntityEdits" 5735 ); 5736 if (!select4.hasEditsForEntityRecord(kind, name, recordId)) { 5737 return; 5738 } 5739 const edits = select4.getEntityRecordNonTransientEdits( 5740 kind, 5741 name, 5742 recordId 5743 ); 5744 const editsToSave = {}; 5745 for (const item of itemsToSave) { 5746 setNestedValue(editsToSave, item, getNestedValue(edits, item)); 5747 } 5748 const configs = await resolveSelect2.getEntitiesConfig(kind); 5749 const entityConfig = configs.find( 5750 (config) => config.kind === kind && config.name === name 5751 ); 5752 const entityIdKey = entityConfig?.key || DEFAULT_ENTITY_KEY; 5753 if (recordId) { 5754 editsToSave[entityIdKey] = recordId; 5755 } 5756 return await dispatch3.saveEntityRecord( 5757 kind, 5758 name, 5759 editsToSave, 5760 options 5761 ); 5762 }; 5763 function receiveUploadPermissions(hasUploadPermissions) { 5764 (0, import_deprecated3.default)("wp.data.dispatch( 'core' ).receiveUploadPermissions", { 5765 since: "5.9", 5766 alternative: "receiveUserPermission" 5767 }); 5768 return receiveUserPermission("create/media", hasUploadPermissions); 5769 } 5770 function receiveUserPermission(key, isAllowed) { 5771 return { 5772 type: "RECEIVE_USER_PERMISSION", 5773 key, 5774 isAllowed 5775 }; 5776 } 5777 function receiveUserPermissions(permissions) { 5778 return { 5779 type: "RECEIVE_USER_PERMISSIONS", 5780 permissions 5781 }; 5782 } 5783 function receiveAutosaves(postId, autosaves2) { 5784 return { 5785 type: "RECEIVE_AUTOSAVES", 5786 postId, 5787 autosaves: Array.isArray(autosaves2) ? autosaves2 : [autosaves2] 5788 }; 5789 } 5790 function receiveNavigationFallbackId(fallbackId) { 5791 return { 5792 type: "RECEIVE_NAVIGATION_FALLBACK_ID", 5793 fallbackId 5794 }; 5795 } 5796 function receiveDefaultTemplateId(query, templateId) { 5797 return { 5798 type: "RECEIVE_DEFAULT_TEMPLATE", 5799 query, 5800 templateId 5801 }; 5802 } 5803 var receiveRevisions = (kind, name, recordKey, records, query, invalidateCache = false, meta) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 5804 logEntityDeprecation(kind, name, "receiveRevisions"); 5805 const configs = await resolveSelect2.getEntitiesConfig(kind); 5806 const entityConfig = configs.find( 5807 (config) => config.kind === kind && config.name === name 5808 ); 5809 const key = entityConfig?.revisionKey ?? DEFAULT_ENTITY_KEY; 5810 dispatch3({ 5811 type: "RECEIVE_ITEM_REVISIONS", 5812 key, 5813 items: records, 5814 recordKey, 5815 meta, 5816 query, 5817 kind, 5818 name, 5819 invalidateCache 5820 }); 5821 }; 5822 5823 // packages/core-data/build-module/private-actions.mjs 5824 var private_actions_exports = {}; 5825 __export(private_actions_exports, { 5826 __unstableNotifySyncUndoManagerChange: () => __unstableNotifySyncUndoManagerChange, 5827 editMediaEntity: () => editMediaEntity, 5828 receiveEditorAssets: () => receiveEditorAssets, 5829 receiveEditorSettings: () => receiveEditorSettings, 5830 receiveRegisteredPostMeta: () => receiveRegisteredPostMeta, 5831 receiveViewConfig: () => receiveViewConfig, 5832 setCollaborationSupported: () => setCollaborationSupported, 5833 setSyncConnectionStatus: () => setSyncConnectionStatus 5834 }); 5835 var import_api_fetch5 = __toESM(require_api_fetch(), 1); 5836 function receiveRegisteredPostMeta(postType, registeredPostMeta2) { 5837 return { 5838 type: "RECEIVE_REGISTERED_POST_META", 5839 postType, 5840 registeredPostMeta: registeredPostMeta2 5841 }; 5842 } 5843 var editMediaEntity = (recordId, edits = {}, { __unstableFetch = import_api_fetch5.default, throwOnError = false } = {}) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 5844 if (!recordId) { 5845 return; 5846 } 5847 const kind = "postType"; 5848 const name = "attachment"; 5849 const configs = await resolveSelect2.getEntitiesConfig(kind); 5850 const entityConfig = configs.find( 5851 (config) => config.kind === kind && config.name === name 5852 ); 5853 if (!entityConfig) { 5854 return; 5855 } 5856 const lock2 = await dispatch3.__unstableAcquireStoreLock( 5857 STORE_NAME, 5858 ["entities", "records", kind, name, recordId], 5859 { exclusive: true } 5860 ); 5861 let updatedRecord; 5862 let error; 5863 let hasError = false; 5864 try { 5865 dispatch3({ 5866 type: "SAVE_ENTITY_RECORD_START", 5867 kind, 5868 name, 5869 recordId 5870 }); 5871 try { 5872 const path = `$entityConfig.baseURL}/$recordId}/edit`; 5873 const newRecord = await __unstableFetch({ 5874 path, 5875 method: "POST", 5876 data: { 5877 ...edits 5878 } 5879 }); 5880 if (newRecord) { 5881 dispatch3.receiveEntityRecords( 5882 kind, 5883 name, 5884 newRecord, 5885 void 0, 5886 true, 5887 void 0, 5888 void 0 5889 ); 5890 updatedRecord = newRecord; 5891 } 5892 } catch (e) { 5893 error = e; 5894 hasError = true; 5895 } 5896 dispatch3({ 5897 type: "SAVE_ENTITY_RECORD_FINISH", 5898 kind, 5899 name, 5900 recordId, 5901 error 5902 }); 5903 if (hasError && throwOnError) { 5904 throw error; 5905 } 5906 return updatedRecord; 5907 } finally { 5908 dispatch3.__unstableReleaseStoreLock(lock2); 5909 } 5910 }; 5911 function receiveEditorSettings(settings) { 5912 return { 5913 type: "RECEIVE_EDITOR_SETTINGS", 5914 settings 5915 }; 5916 } 5917 function receiveEditorAssets(assets) { 5918 return { 5919 type: "RECEIVE_EDITOR_ASSETS", 5920 assets 5921 }; 5922 } 5923 var setCollaborationSupported = (supported) => ({ dispatch: dispatch3 }) => { 5924 dispatch3({ type: "SET_COLLABORATION_SUPPORTED", supported }); 5925 if (!supported && hasSyncManager()) { 5926 getSyncManager().unloadAll(); 5927 dispatch3.__unstableNotifySyncUndoManagerChange({ 5928 hasUndo: false, 5929 hasRedo: false 5930 }); 5931 } 5932 }; 5933 function receiveViewConfig(kind, name, config) { 5934 return { 5935 type: "RECEIVE_VIEW_CONFIG", 5936 kind, 5937 name, 5938 config 5939 }; 5940 } 5941 function __unstableNotifySyncUndoManagerChange(state) { 5942 return { 5943 type: "SYNC_UNDO_MANAGER_CHANGE", 5944 ...state 5945 }; 5946 } 5947 function setSyncConnectionStatus(kind, name, key, status) { 5948 if (!status) { 5949 return { 5950 type: "CLEAR_SYNC_CONNECTION_STATUS", 5951 kind, 5952 name, 5953 key 5954 }; 5955 } 5956 return { 5957 type: "SET_SYNC_CONNECTION_STATUS", 5958 kind, 5959 name, 5960 key, 5961 status 5962 }; 5963 } 5964 5965 // packages/core-data/build-module/resolvers.mjs 5966 var resolvers_exports = {}; 5967 __export(resolvers_exports, { 5968 __experimentalGetCurrentGlobalStylesId: () => __experimentalGetCurrentGlobalStylesId2, 5969 __experimentalGetCurrentThemeBaseGlobalStyles: () => __experimentalGetCurrentThemeBaseGlobalStyles2, 5970 __experimentalGetCurrentThemeGlobalStylesVariations: () => __experimentalGetCurrentThemeGlobalStylesVariations2, 5971 canUser: () => canUser2, 5972 canUserEditEntityRecord: () => canUserEditEntityRecord2, 5973 getAuthors: () => getAuthors2, 5974 getAutosave: () => getAutosave2, 5975 getAutosaves: () => getAutosaves2, 5976 getBlockPatternCategories: () => getBlockPatternCategories2, 5977 getBlockPatterns: () => getBlockPatterns2, 5978 getCurrentTheme: () => getCurrentTheme2, 5979 getCurrentThemeGlobalStylesRevisions: () => getCurrentThemeGlobalStylesRevisions2, 5980 getCurrentUser: () => getCurrentUser2, 5981 getDefaultTemplateId: () => getDefaultTemplateId2, 5982 getEditedEntityRecord: () => getEditedEntityRecord2, 5983 getEditorAssets: () => getEditorAssets2, 5984 getEditorSettings: () => getEditorSettings2, 5985 getEmbedPreview: () => getEmbedPreview2, 5986 getEntitiesConfig: () => getEntitiesConfig2, 5987 getEntityRecord: () => getEntityRecord2, 5988 getEntityRecords: () => getEntityRecords2, 5989 getEntityRecordsTotalItems: () => getEntityRecordsTotalItems2, 5990 getEntityRecordsTotalPages: () => getEntityRecordsTotalPages2, 5991 getNavigationFallbackId: () => getNavigationFallbackId2, 5992 getRawEntityRecord: () => getRawEntityRecord2, 5993 getRegisteredPostMeta: () => getRegisteredPostMeta2, 5994 getRevision: () => getRevision2, 5995 getRevisions: () => getRevisions2, 5996 getThemeSupports: () => getThemeSupports2, 5997 getUserPatternCategories: () => getUserPatternCategories2, 5998 getViewConfig: () => getViewConfig2 5999 }); 6000 var import_url6 = __toESM(require_url(), 1); 6001 var import_html_entities2 = __toESM(require_html_entities(), 1); 6002 var import_api_fetch9 = __toESM(require_api_fetch(), 1); 6003 6004 // packages/core-data/build-module/fetch/index.mjs 6005 var import_api_fetch8 = __toESM(require_api_fetch(), 1); 6006 6007 // packages/core-data/build-module/fetch/__experimental-fetch-link-suggestions.mjs 6008 var import_api_fetch6 = __toESM(require_api_fetch(), 1); 6009 var import_url4 = __toESM(require_url(), 1); 6010 var import_html_entities = __toESM(require_html_entities(), 1); 6011 var import_i18n2 = __toESM(require_i18n(), 1); 6012 async function fetchLinkSuggestions(search, searchOptions = {}, editorSettings2 = {}) { 6013 const searchOptionsToUse = searchOptions.isInitialSuggestions && searchOptions.initialSuggestionsSearchOptions ? { 6014 ...searchOptions, 6015 ...searchOptions.initialSuggestionsSearchOptions 6016 } : searchOptions; 6017 const { 6018 type, 6019 subtype, 6020 page, 6021 perPage = searchOptions.isInitialSuggestions ? 3 : 20 6022 } = searchOptionsToUse; 6023 const { disablePostFormats = false } = editorSettings2; 6024 const queries2 = []; 6025 if (!type || type === "post") { 6026 queries2.push( 6027 (0, import_api_fetch6.default)({ 6028 path: (0, import_url4.addQueryArgs)("/wp/v2/search", { 6029 search, 6030 page, 6031 per_page: perPage, 6032 type: "post", 6033 subtype 6034 }) 6035 }).then((results2) => { 6036 return results2.map((result) => { 6037 return { 6038 id: result.id, 6039 url: result.url, 6040 title: (0, import_html_entities.decodeEntities)(result.title || "") || (0, import_i18n2.__)("(no title)"), 6041 type: result.subtype || result.type, 6042 kind: "post-type" 6043 }; 6044 }); 6045 }).catch(() => []) 6046 // Fail by returning no results. 6047 ); 6048 } 6049 if (!type || type === "term") { 6050 queries2.push( 6051 (0, import_api_fetch6.default)({ 6052 path: (0, import_url4.addQueryArgs)("/wp/v2/search", { 6053 search, 6054 page, 6055 per_page: perPage, 6056 type: "term", 6057 subtype 6058 }) 6059 }).then((results2) => { 6060 return results2.map((result) => { 6061 return { 6062 id: result.id, 6063 url: result.url, 6064 title: (0, import_html_entities.decodeEntities)(result.title || "") || (0, import_i18n2.__)("(no title)"), 6065 type: result.subtype || result.type, 6066 kind: "taxonomy" 6067 }; 6068 }); 6069 }).catch(() => []) 6070 // Fail by returning no results. 6071 ); 6072 } 6073 if (!disablePostFormats && (!type || type === "post-format")) { 6074 queries2.push( 6075 (0, import_api_fetch6.default)({ 6076 path: (0, import_url4.addQueryArgs)("/wp/v2/search", { 6077 search, 6078 page, 6079 per_page: perPage, 6080 type: "post-format", 6081 subtype 6082 }) 6083 }).then((results2) => { 6084 return results2.map((result) => { 6085 return { 6086 id: result.id, 6087 url: result.url, 6088 title: (0, import_html_entities.decodeEntities)(result.title || "") || (0, import_i18n2.__)("(no title)"), 6089 type: result.subtype || result.type, 6090 kind: "taxonomy" 6091 }; 6092 }); 6093 }).catch(() => []) 6094 // Fail by returning no results. 6095 ); 6096 } 6097 if (!type || type === "attachment") { 6098 queries2.push( 6099 (0, import_api_fetch6.default)({ 6100 path: (0, import_url4.addQueryArgs)("/wp/v2/media", { 6101 search, 6102 page, 6103 per_page: perPage 6104 }) 6105 }).then((results2) => { 6106 return results2.map((result) => { 6107 return { 6108 id: result.id, 6109 url: result.source_url, 6110 title: (0, import_html_entities.decodeEntities)(result.title.rendered || "") || (0, import_i18n2.__)("(no title)"), 6111 type: result.type, 6112 kind: "media" 6113 }; 6114 }); 6115 }).catch(() => []) 6116 // Fail by returning no results. 6117 ); 6118 } 6119 const responses = await Promise.all(queries2); 6120 let results = responses.flat(); 6121 results = results.filter((result) => !!result.id); 6122 results = sortResults(results, search); 6123 results = results.slice(0, perPage); 6124 return results; 6125 } 6126 function sortResults(results, search) { 6127 const searchTokens = tokenize(search); 6128 const scores = {}; 6129 for (const result of results) { 6130 if (result.title) { 6131 const titleTokens = tokenize(result.title); 6132 const exactMatchingTokens = titleTokens.filter( 6133 (titleToken) => searchTokens.some( 6134 (searchToken) => titleToken === searchToken 6135 ) 6136 ); 6137 const subMatchingTokens = titleTokens.filter( 6138 (titleToken) => searchTokens.some( 6139 (searchToken) => titleToken !== searchToken && titleToken.includes(searchToken) 6140 ) 6141 ); 6142 const exactMatchScore = exactMatchingTokens.length / titleTokens.length * 10; 6143 const subMatchScore = subMatchingTokens.length / titleTokens.length; 6144 scores[result.id] = exactMatchScore + subMatchScore; 6145 } else { 6146 scores[result.id] = 0; 6147 } 6148 } 6149 return results.sort((a, b) => scores[b.id] - scores[a.id]); 6150 } 6151 function tokenize(text) { 6152 return text.toLowerCase().match(/[\p{L}\p{N}]+/gu) || []; 6153 } 6154 6155 // packages/core-data/build-module/fetch/__experimental-fetch-url-data.mjs 6156 var import_api_fetch7 = __toESM(require_api_fetch(), 1); 6157 var import_url5 = __toESM(require_url(), 1); 6158 var CACHE = /* @__PURE__ */ new Map(); 6159 var fetchUrlData = async (url, options = {}) => { 6160 const endpoint = "/wp-block-editor/v1/url-details"; 6161 const args = { 6162 url: (0, import_url5.prependHTTP)(url) 6163 }; 6164 if (!(0, import_url5.isURL)(url)) { 6165 return Promise.reject(`$url} is not a valid URL.`); 6166 } 6167 const protocol = (0, import_url5.getProtocol)(url); 6168 if (!protocol || !(0, import_url5.isValidProtocol)(protocol) || !protocol.startsWith("http") || !/^https?:\/\/[^\/\s]/i.test(url)) { 6169 return Promise.reject( 6170 `$url} does not have a valid protocol. URLs must be "http" based` 6171 ); 6172 } 6173 if (CACHE.has(url)) { 6174 return CACHE.get(url); 6175 } 6176 return (0, import_api_fetch7.default)({ 6177 path: (0, import_url5.addQueryArgs)(endpoint, args), 6178 ...options 6179 }).then((res) => { 6180 CACHE.set(url, res); 6181 return res; 6182 }); 6183 }; 6184 var experimental_fetch_url_data_default = fetchUrlData; 6185 6186 // packages/core-data/build-module/fetch/index.mjs 6187 async function fetchBlockPatterns() { 6188 const restPatterns = await (0, import_api_fetch8.default)({ 6189 path: "/wp/v2/block-patterns/patterns" 6190 }); 6191 if (!restPatterns) { 6192 return []; 6193 } 6194 return restPatterns.map( 6195 (pattern) => Object.fromEntries( 6196 Object.entries(pattern).map(([key, value]) => [ 6197 camelCase(key), 6198 value 6199 ]) 6200 ) 6201 ); 6202 } 6203 6204 // packages/core-data/build-module/parsed-blocks-cache.mjs 6205 var parsedBlocksCache = /* @__PURE__ */ new Map(); 6206 function getCacheKey(kind, name, id) { 6207 return `$kind}:$name}:$id}`; 6208 } 6209 6210 // packages/core-data/build-module/resolvers.mjs 6211 var getAuthors2 = (query) => async ({ dispatch: dispatch3 }) => { 6212 const path = (0, import_url6.addQueryArgs)( 6213 "/wp/v2/users/?who=authors&per_page=100", 6214 query 6215 ); 6216 const users2 = await (0, import_api_fetch9.default)({ path }); 6217 dispatch3.receiveUserQuery(path, users2); 6218 }; 6219 var getCurrentUser2 = () => async ({ dispatch: dispatch3 }) => { 6220 const currentUser2 = await (0, import_api_fetch9.default)({ path: "/wp/v2/users/me" }); 6221 dispatch3.receiveCurrentUser(currentUser2); 6222 }; 6223 var getEntityRecord2 = (kind, name, key = "", query) => async ({ select: select4, dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => { 6224 const configs = await resolveSelect2.getEntitiesConfig(kind); 6225 const entityConfig = configs.find( 6226 (config) => config.name === name && config.kind === kind 6227 ); 6228 if (!entityConfig) { 6229 return; 6230 } 6231 const lock2 = await dispatch3.__unstableAcquireStoreLock( 6232 STORE_NAME, 6233 ["entities", "records", kind, name, key], 6234 { exclusive: false } 6235 ); 6236 try { 6237 if (query !== void 0 && query._fields) { 6238 query = { 6239 ...query, 6240 _fields: [ 6241 .../* @__PURE__ */ new Set([ 6242 ...get_normalized_comma_separable_default(query._fields) || [], 6243 entityConfig.key || DEFAULT_ENTITY_KEY 6244 ]) 6245 ].join() 6246 }; 6247 } 6248 if (query !== void 0 && query._fields) { 6249 const hasRecord = select4.hasEntityRecord( 6250 kind, 6251 name, 6252 key, 6253 query 6254 ); 6255 if (hasRecord) { 6256 return; 6257 } 6258 } 6259 let { baseURL } = entityConfig; 6260 if (kind === "postType" && name === "wp_template" && (key && typeof key === "string" && !/^\d+$/.test(key) || !window?.__experimentalTemplateActivate)) { 6261 baseURL = baseURL.slice(0, baseURL.lastIndexOf("/")) + "/templates"; 6262 } 6263 const path = (0, import_url6.addQueryArgs)(baseURL + (key ? "/" + key : ""), { 6264 ...entityConfig.baseURLParams, 6265 ...query 6266 }); 6267 const response = await (0, import_api_fetch9.default)({ path, parse: false }); 6268 const record = await response.json(); 6269 const permissions = getUserPermissionsFromAllowHeader( 6270 response.headers?.get("allow") 6271 ); 6272 const canUserResolutionsArgs = []; 6273 const receiveUserPermissionArgs = {}; 6274 for (const action of ALLOWED_RESOURCE_ACTIONS) { 6275 receiveUserPermissionArgs[getUserPermissionCacheKey(action, { 6276 kind, 6277 name, 6278 id: key 6279 })] = permissions[action]; 6280 canUserResolutionsArgs.push([ 6281 action, 6282 { kind, name, id: key } 6283 ]); 6284 } 6285 if (entityConfig.syncConfig && isNumericID(key) && !query) { 6286 const objectType = `$kind}/$name}`; 6287 const objectId = key; 6288 const recordWithTransients = { ...record }; 6289 Object.entries(entityConfig.transientEdits ?? {}).filter( 6290 ([propName, transientConfig]) => void 0 === recordWithTransients[propName] && transientConfig && "object" === typeof transientConfig && "read" in transientConfig && "function" === typeof transientConfig.read 6291 ).forEach(([propName, transientConfig]) => { 6292 recordWithTransients[propName] = transientConfig.read(recordWithTransients); 6293 }); 6294 if (recordWithTransients.blocks && typeof recordWithTransients.content?.raw === "string") { 6295 parsedBlocksCache.set(getCacheKey(kind, name, key), { 6296 content: recordWithTransients.content.raw, 6297 blocks: recordWithTransients.blocks 6298 }); 6299 } 6300 const syncManager2 = select4?.isCollaborationSupported?.() === false ? void 0 : getSyncManager(); 6301 void syncManager2?.load( 6302 entityConfig.syncConfig, 6303 objectType, 6304 objectId, 6305 recordWithTransients, 6306 { 6307 // Handle edits sourced from the sync manager. 6308 editRecord: (edits, options = {}) => { 6309 if (!Object.keys(edits).length) { 6310 return; 6311 } 6312 dispatch3({ 6313 type: "EDIT_ENTITY_RECORD", 6314 kind, 6315 name, 6316 recordId: key, 6317 edits, 6318 meta: { 6319 undo: void 0 6320 }, 6321 options 6322 }); 6323 }, 6324 // Get the current entity record (with edits) 6325 getEditedRecord: async () => await resolveSelect2.getEditedEntityRecord( 6326 kind, 6327 name, 6328 key 6329 ), 6330 // Handle sync connection status changes. 6331 onStatusChange: (status) => { 6332 dispatch3.setSyncConnectionStatus( 6333 kind, 6334 name, 6335 key, 6336 status 6337 ); 6338 }, 6339 // Refetch the current entity record from the database. 6340 refetchRecord: async () => { 6341 dispatch3.receiveEntityRecords( 6342 kind, 6343 name, 6344 await (0, import_api_fetch9.default)({ path, parse: true }), 6345 query 6346 ); 6347 }, 6348 // Persist the CRDT document. 6349 // 6350 // TODO: Currently, persisted CRDT documents are stored in post meta. 6351 // This effectively means that only post entities support CRDT 6352 // persistence. As we add support for syncing additional entity, 6353 // we'll need to revisit where persisted CRDT documents are stored. 6354 persistCRDTDoc: () => { 6355 if (!entityConfig.syncConfig?.supportsPersistence) { 6356 return; 6357 } 6358 return resolveSelect2.getEditedEntityRecord(kind, name, key).then(async (editedRecord) => { 6359 const { meta, status } = editedRecord; 6360 if ("auto-draft" === status || !meta) { 6361 return; 6362 } 6363 const entityIdKey = entityConfig.key || DEFAULT_ENTITY_KEY; 6364 const entityId = editedRecord[entityIdKey]; 6365 await saveCRDTDoc( 6366 `$kind}/$name}`, 6367 entityId 6368 ); 6369 }); 6370 }, 6371 addUndoMeta: (ydoc, meta) => { 6372 const selectionHistory = getSelectionHistory(ydoc); 6373 if (selectionHistory) { 6374 meta.set( 6375 "selectionHistory", 6376 selectionHistory 6377 ); 6378 } 6379 }, 6380 onUndoStackChange: (undoState) => { 6381 dispatch3.__unstableNotifySyncUndoManagerChange( 6382 undoState 6383 ); 6384 }, 6385 restoreUndoMeta: (ydoc, meta) => { 6386 const selectionHistory = meta.get("selectionHistory"); 6387 if (selectionHistory) { 6388 setTimeout(() => { 6389 restoreSelection(selectionHistory, ydoc); 6390 }, 0); 6391 } 6392 } 6393 } 6394 ); 6395 } 6396 registry.batch(() => { 6397 dispatch3.receiveEntityRecords(kind, name, record, query); 6398 dispatch3.receiveUserPermissions(receiveUserPermissionArgs); 6399 dispatch3.finishResolutions("canUser", canUserResolutionsArgs); 6400 }); 6401 } finally { 6402 dispatch3.__unstableReleaseStoreLock(lock2); 6403 } 6404 }; 6405 getEntityRecord2.shouldInvalidate = (action, kind, name) => { 6406 return kind === "root" && name === "site" && (action.type === "RECEIVE_ITEMS" && // Making sure persistedEdits is set seems to be the only way of 6407 // knowing whether it's an update or fetch. Only an update would 6408 // have persistedEdits. 6409 action.persistedEdits && action.persistedEdits.status !== "auto-draft" || action.type === "REMOVE_ITEMS") && action.kind === "postType" && action.name === "wp_template"; 6410 }; 6411 var getRawEntityRecord2 = forward_resolver_default("getEntityRecord"); 6412 var getEditedEntityRecord2 = forward_resolver_default("getEntityRecord"); 6413 var getEntityRecords2 = (kind, name, query = {}) => async ({ dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => { 6414 const configs = await resolveSelect2.getEntitiesConfig(kind); 6415 const entityConfig = configs.find( 6416 (config) => config.name === name && config.kind === kind 6417 ); 6418 if (!entityConfig) { 6419 return; 6420 } 6421 const lock2 = await dispatch3.__unstableAcquireStoreLock( 6422 STORE_NAME, 6423 ["entities", "records", kind, name], 6424 { exclusive: false } 6425 ); 6426 const rawQuery = { ...query }; 6427 const key = entityConfig.key || DEFAULT_ENTITY_KEY; 6428 function getResolutionsArgs(records, recordsQuery) { 6429 const normalizedQuery = normalizeQueryForResolution(recordsQuery); 6430 return records.filter((record) => record?.[key]).map((record) => [ 6431 kind, 6432 name, 6433 record[key], 6434 normalizedQuery 6435 ]); 6436 } 6437 try { 6438 if (query._fields) { 6439 query = { 6440 ...query, 6441 _fields: [ 6442 .../* @__PURE__ */ new Set([ 6443 ...get_normalized_comma_separable_default(query._fields) || [], 6444 key 6445 ]) 6446 ].join() 6447 }; 6448 } 6449 let { baseURL } = entityConfig; 6450 const { combinedTemplates = true } = query; 6451 if (kind === "postType" && name === "wp_template" && combinedTemplates) { 6452 baseURL = baseURL.slice(0, baseURL.lastIndexOf("/")) + "/templates"; 6453 } 6454 const path = (0, import_url6.addQueryArgs)(baseURL, { 6455 ...entityConfig.baseURLParams, 6456 ...query 6457 }); 6458 let records = [], meta; 6459 if (entityConfig.supportsPagination && query.per_page !== -1) { 6460 const response = await (0, import_api_fetch9.default)({ path, parse: false }); 6461 records = Object.values(await response.json()); 6462 meta = { 6463 totalItems: parseInt( 6464 response.headers.get("X-WP-Total") 6465 ), 6466 totalPages: parseInt( 6467 response.headers.get("X-WP-TotalPages") 6468 ) 6469 }; 6470 } else if (query.per_page === -1 && query[RECEIVE_INTERMEDIATE_RESULTS] === true) { 6471 let page = 1; 6472 let totalPages; 6473 do { 6474 const response = await (0, import_api_fetch9.default)({ 6475 path: (0, import_url6.addQueryArgs)(path, { page, per_page: 100 }), 6476 parse: false 6477 }); 6478 const pageRecords = Object.values(await response.json()); 6479 totalPages = parseInt( 6480 response.headers.get("X-WP-TotalPages") 6481 ); 6482 if (!meta) { 6483 meta = { 6484 totalItems: parseInt( 6485 response.headers.get("X-WP-Total") 6486 ), 6487 totalPages: 1 6488 }; 6489 } 6490 records.push(...pageRecords); 6491 registry.batch(() => { 6492 dispatch3.receiveEntityRecords( 6493 kind, 6494 name, 6495 records, 6496 query, 6497 false, 6498 void 0, 6499 meta 6500 ); 6501 dispatch3.finishResolutions( 6502 "getEntityRecord", 6503 getResolutionsArgs(pageRecords, rawQuery) 6504 ); 6505 }); 6506 page++; 6507 } while (page <= totalPages); 6508 } else { 6509 records = Object.values(await (0, import_api_fetch9.default)({ path })); 6510 meta = { 6511 totalItems: records.length, 6512 totalPages: 1 6513 }; 6514 } 6515 if (entityConfig.syncConfig && -1 === query.per_page) { 6516 const objectType = `$kind}/$name}`; 6517 getSyncManager()?.loadCollection( 6518 entityConfig.syncConfig, 6519 objectType, 6520 { 6521 onStatusChange: (status) => { 6522 dispatch3.setSyncConnectionStatus( 6523 kind, 6524 name, 6525 null, 6526 status 6527 ); 6528 }, 6529 refetchRecords: async () => { 6530 dispatch3.receiveEntityRecords( 6531 kind, 6532 name, 6533 await (0, import_api_fetch9.default)({ path, parse: true }), 6534 query 6535 ); 6536 } 6537 } 6538 ); 6539 } 6540 if (query._fields) { 6541 records = records.map((record) => { 6542 query._fields.split(",").forEach((field) => { 6543 if (!record.hasOwnProperty(field)) { 6544 record[field] = void 0; 6545 } 6546 }); 6547 return record; 6548 }); 6549 } 6550 registry.batch(() => { 6551 dispatch3.receiveEntityRecords( 6552 kind, 6553 name, 6554 records, 6555 query, 6556 false, 6557 void 0, 6558 meta 6559 ); 6560 const targetHints = records.filter( 6561 (record) => !!record?.[key] && !!record?._links?.self?.[0]?.targetHints?.allow 6562 ).map((record) => ({ 6563 id: record[key], 6564 permissions: getUserPermissionsFromAllowHeader( 6565 record._links.self[0].targetHints.allow 6566 ) 6567 })); 6568 const canUserResolutionsArgs = []; 6569 const receiveUserPermissionArgs = {}; 6570 for (const targetHint of targetHints) { 6571 for (const action of ALLOWED_RESOURCE_ACTIONS) { 6572 canUserResolutionsArgs.push([ 6573 action, 6574 { kind, name, id: targetHint.id } 6575 ]); 6576 receiveUserPermissionArgs[getUserPermissionCacheKey(action, { 6577 kind, 6578 name, 6579 id: targetHint.id 6580 })] = targetHint.permissions[action]; 6581 } 6582 } 6583 if (targetHints.length > 0) { 6584 dispatch3.receiveUserPermissions( 6585 receiveUserPermissionArgs 6586 ); 6587 dispatch3.finishResolutions( 6588 "canUser", 6589 canUserResolutionsArgs 6590 ); 6591 } 6592 dispatch3.finishResolutions( 6593 "getEntityRecord", 6594 getResolutionsArgs(records, rawQuery) 6595 ); 6596 dispatch3.__unstableReleaseStoreLock(lock2); 6597 }); 6598 } catch { 6599 dispatch3.__unstableReleaseStoreLock(lock2); 6600 } 6601 }; 6602 getEntityRecords2.shouldInvalidate = (action, kind, name) => { 6603 return (action.type === "RECEIVE_ITEMS" || action.type === "REMOVE_ITEMS") && action.invalidateCache && kind === action.kind && name === action.name; 6604 }; 6605 var getEntityRecordsTotalItems2 = forward_resolver_default("getEntityRecords"); 6606 var getEntityRecordsTotalPages2 = forward_resolver_default("getEntityRecords"); 6607 var getCurrentTheme2 = () => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 6608 const activeThemes = await resolveSelect2.getEntityRecords( 6609 "root", 6610 "theme", 6611 { status: "active" } 6612 ); 6613 dispatch3.receiveCurrentTheme(activeThemes[0]); 6614 }; 6615 var getThemeSupports2 = forward_resolver_default("getCurrentTheme"); 6616 var getEmbedPreview2 = (url) => async ({ dispatch: dispatch3 }) => { 6617 try { 6618 const embedProxyResponse = await (0, import_api_fetch9.default)({ 6619 path: (0, import_url6.addQueryArgs)("/oembed/1.0/proxy", { url }) 6620 }); 6621 dispatch3.receiveEmbedPreview(url, embedProxyResponse); 6622 } catch { 6623 dispatch3.receiveEmbedPreview(url, false); 6624 } 6625 }; 6626 var canUser2 = (requestedAction, resource, id) => async ({ dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => { 6627 if (!ALLOWED_RESOURCE_ACTIONS.includes(requestedAction)) { 6628 throw new Error(`'$requestedAction}' is not a valid action.`); 6629 } 6630 const { hasStartedResolution } = registry.select(STORE_NAME); 6631 for (const relatedAction of ALLOWED_RESOURCE_ACTIONS) { 6632 if (relatedAction === requestedAction) { 6633 continue; 6634 } 6635 const isAlreadyResolving = hasStartedResolution("canUser", [ 6636 relatedAction, 6637 resource, 6638 id 6639 ]); 6640 if (isAlreadyResolving) { 6641 return; 6642 } 6643 } 6644 let resourcePath = null; 6645 if (typeof resource === "object") { 6646 if (!resource.kind || !resource.name) { 6647 throw new Error("The entity resource object is not valid."); 6648 } 6649 const configs = await resolveSelect2.getEntitiesConfig( 6650 resource.kind 6651 ); 6652 const entityConfig = configs.find( 6653 (config) => config.name === resource.name && config.kind === resource.kind 6654 ); 6655 if (!entityConfig) { 6656 return; 6657 } 6658 resourcePath = entityConfig.baseURL + (resource.id ? "/" + resource.id : ""); 6659 } else { 6660 resourcePath = `/wp/v2/$resource}` + (id ? "/" + id : ""); 6661 } 6662 let response; 6663 try { 6664 response = await (0, import_api_fetch9.default)({ 6665 path: resourcePath, 6666 method: "OPTIONS", 6667 parse: false 6668 }); 6669 } catch { 6670 return; 6671 } 6672 const permissions = getUserPermissionsFromAllowHeader( 6673 response.headers?.get("allow") 6674 ); 6675 const receiveUserPermissionArgs = {}; 6676 const canUserResolutionsArgs = []; 6677 for (const action of ALLOWED_RESOURCE_ACTIONS) { 6678 receiveUserPermissionArgs[getUserPermissionCacheKey(action, resource, id)] = permissions[action]; 6679 if (action !== requestedAction) { 6680 canUserResolutionsArgs.push([action, resource, id]); 6681 } 6682 } 6683 registry.batch(() => { 6684 dispatch3.receiveUserPermissions(receiveUserPermissionArgs); 6685 dispatch3.finishResolutions("canUser", canUserResolutionsArgs); 6686 }); 6687 }; 6688 var canUserEditEntityRecord2 = (kind, name, recordId) => async ({ dispatch: dispatch3 }) => { 6689 await dispatch3(canUser2("update", { kind, name, id: recordId })); 6690 }; 6691 var getAutosaves2 = (postType, postId) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 6692 const { 6693 rest_base: restBase, 6694 rest_namespace: restNamespace = "wp/v2", 6695 supports 6696 } = await resolveSelect2.getPostType(postType); 6697 if (!supports?.autosave) { 6698 return; 6699 } 6700 const autosaves2 = await (0, import_api_fetch9.default)({ 6701 path: `/$restNamespace}/$restBase}/$postId}/autosaves?context=edit` 6702 }); 6703 if (autosaves2 && autosaves2.length) { 6704 dispatch3.receiveAutosaves(postId, autosaves2); 6705 } 6706 }; 6707 var getAutosave2 = (postType, postId) => async ({ resolveSelect: resolveSelect2 }) => { 6708 await resolveSelect2.getAutosaves(postType, postId); 6709 }; 6710 var __experimentalGetCurrentGlobalStylesId2 = () => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 6711 const activeThemes = await resolveSelect2.getEntityRecords( 6712 "root", 6713 "theme", 6714 { status: "active" } 6715 ); 6716 const globalStylesURL = activeThemes?.[0]?._links?.["wp:user-global-styles"]?.[0]?.href; 6717 if (!globalStylesURL) { 6718 return; 6719 } 6720 const matches = globalStylesURL.match(/\/(\d+)(?:\?|$)/); 6721 const id = matches ? Number(matches[1]) : null; 6722 if (id) { 6723 dispatch3.__experimentalReceiveCurrentGlobalStylesId(id); 6724 } 6725 }; 6726 var __experimentalGetCurrentThemeBaseGlobalStyles2 = () => async ({ resolveSelect: resolveSelect2, dispatch: dispatch3 }) => { 6727 const currentTheme2 = await resolveSelect2.getCurrentTheme(); 6728 const themeGlobalStyles = await (0, import_api_fetch9.default)({ 6729 path: `/wp/v2/global-styles/themes/$currentTheme2.stylesheet}?context=view` 6730 }); 6731 dispatch3.__experimentalReceiveThemeBaseGlobalStyles( 6732 currentTheme2.stylesheet, 6733 themeGlobalStyles 6734 ); 6735 }; 6736 var __experimentalGetCurrentThemeGlobalStylesVariations2 = () => async ({ resolveSelect: resolveSelect2, dispatch: dispatch3 }) => { 6737 const currentTheme2 = await resolveSelect2.getCurrentTheme(); 6738 const variations = await (0, import_api_fetch9.default)({ 6739 path: `/wp/v2/global-styles/themes/$currentTheme2.stylesheet}/variations?context=view` 6740 }); 6741 dispatch3.__experimentalReceiveThemeGlobalStyleVariations( 6742 currentTheme2.stylesheet, 6743 variations 6744 ); 6745 }; 6746 var getCurrentThemeGlobalStylesRevisions2 = () => async ({ resolveSelect: resolveSelect2, dispatch: dispatch3 }) => { 6747 const globalStylesId = await resolveSelect2.__experimentalGetCurrentGlobalStylesId(); 6748 const record = globalStylesId ? await resolveSelect2.getEntityRecord( 6749 "root", 6750 "globalStyles", 6751 globalStylesId 6752 ) : void 0; 6753 const revisionsURL = record?._links?.["version-history"]?.[0]?.href; 6754 if (revisionsURL) { 6755 const resetRevisions = await (0, import_api_fetch9.default)({ 6756 url: revisionsURL 6757 }); 6758 const revisions = resetRevisions?.map( 6759 (revision) => Object.fromEntries( 6760 Object.entries(revision).map(([key, value]) => [ 6761 camelCase(key), 6762 value 6763 ]) 6764 ) 6765 ); 6766 dispatch3.receiveThemeGlobalStyleRevisions( 6767 globalStylesId, 6768 revisions 6769 ); 6770 } 6771 }; 6772 getCurrentThemeGlobalStylesRevisions2.shouldInvalidate = (action) => { 6773 return action.type === "SAVE_ENTITY_RECORD_FINISH" && action.kind === "root" && !action.error && action.name === "globalStyles"; 6774 }; 6775 var getBlockPatterns2 = () => async ({ dispatch: dispatch3 }) => { 6776 const patterns = await fetchBlockPatterns(); 6777 dispatch3({ type: "RECEIVE_BLOCK_PATTERNS", patterns }); 6778 }; 6779 var getBlockPatternCategories2 = () => async ({ dispatch: dispatch3 }) => { 6780 const categories = await (0, import_api_fetch9.default)({ 6781 path: "/wp/v2/block-patterns/categories" 6782 }); 6783 dispatch3({ type: "RECEIVE_BLOCK_PATTERN_CATEGORIES", categories }); 6784 }; 6785 var getUserPatternCategories2 = () => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 6786 const patternCategories = await resolveSelect2.getEntityRecords( 6787 "taxonomy", 6788 "wp_pattern_category", 6789 { 6790 per_page: -1, 6791 _fields: "id,name,description,slug", 6792 context: "view" 6793 } 6794 ); 6795 const mappedPatternCategories = patternCategories?.map((userCategory) => ({ 6796 ...userCategory, 6797 label: (0, import_html_entities2.decodeEntities)(userCategory.name), 6798 name: userCategory.slug 6799 })) || []; 6800 dispatch3({ 6801 type: "RECEIVE_USER_PATTERN_CATEGORIES", 6802 patternCategories: mappedPatternCategories 6803 }); 6804 }; 6805 var getNavigationFallbackId2 = () => async ({ dispatch: dispatch3, select: select4, registry }) => { 6806 const fallback = await (0, import_api_fetch9.default)({ 6807 path: (0, import_url6.addQueryArgs)("/wp-block-editor/v1/navigation-fallback", { 6808 _embed: true 6809 }) 6810 }); 6811 const record = fallback?._embedded?.self; 6812 registry.batch(() => { 6813 dispatch3.receiveNavigationFallbackId(fallback?.id); 6814 if (!record) { 6815 return; 6816 } 6817 const existingFallbackEntityRecord = select4.getEntityRecord( 6818 "postType", 6819 "wp_navigation", 6820 fallback.id 6821 ); 6822 const invalidateNavigationQueries = !existingFallbackEntityRecord; 6823 dispatch3.receiveEntityRecords( 6824 "postType", 6825 "wp_navigation", 6826 record, 6827 void 0, 6828 invalidateNavigationQueries 6829 ); 6830 dispatch3.finishResolution("getEntityRecord", [ 6831 "postType", 6832 "wp_navigation", 6833 fallback.id 6834 ]); 6835 }); 6836 }; 6837 var getDefaultTemplateId2 = (query) => async ({ dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => { 6838 const template = await (0, import_api_fetch9.default)({ 6839 path: (0, import_url6.addQueryArgs)("/wp/v2/templates/lookup", query) 6840 }); 6841 await resolveSelect2.getEntitiesConfig("postType"); 6842 const id = window?.__experimentalTemplateActivate ? template?.wp_id || template?.id : template?.id; 6843 registry.batch(() => { 6844 dispatch3.receiveDefaultTemplateId(query, id || ""); 6845 if (id) { 6846 template.id = id; 6847 dispatch3.receiveEntityRecords( 6848 "postType", 6849 template.type, 6850 template 6851 ); 6852 dispatch3.finishResolution("getEntityRecord", [ 6853 "postType", 6854 template.type, 6855 id 6856 ]); 6857 } 6858 }); 6859 }; 6860 getDefaultTemplateId2.shouldInvalidate = (action) => { 6861 return action.type === "RECEIVE_ITEMS" && action.kind === "root" && action.name === "site" && !!action.persistedEdits; 6862 }; 6863 var getRevisions2 = (kind, name, recordKey, query = {}) => async ({ dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => { 6864 const configs = await resolveSelect2.getEntitiesConfig(kind); 6865 const entityConfig = configs.find( 6866 (config) => config.name === name && config.kind === kind 6867 ); 6868 if (!entityConfig) { 6869 return; 6870 } 6871 const rawQuery = { ...query }; 6872 const lock2 = await dispatch3.__unstableAcquireStoreLock( 6873 STORE_NAME, 6874 ["entities", "records", kind, name, recordKey, "revisions"], 6875 { exclusive: false } 6876 ); 6877 try { 6878 if (query._fields) { 6879 query = { 6880 ...query, 6881 _fields: [ 6882 .../* @__PURE__ */ new Set([ 6883 ...get_normalized_comma_separable_default(query._fields) || [], 6884 entityConfig.revisionKey || DEFAULT_ENTITY_KEY 6885 ]) 6886 ].join() 6887 }; 6888 } 6889 const path = (0, import_url6.addQueryArgs)( 6890 entityConfig.getRevisionsUrl(recordKey), 6891 query 6892 ); 6893 let records, response; 6894 const meta = {}; 6895 const isPaginated = entityConfig.supportsPagination && query.per_page !== -1; 6896 try { 6897 response = await (0, import_api_fetch9.default)({ path, parse: !isPaginated }); 6898 } catch { 6899 return; 6900 } 6901 if (response) { 6902 if (isPaginated) { 6903 records = Object.values(await response.json()); 6904 meta.totalItems = parseInt( 6905 response.headers.get("X-WP-Total") 6906 ); 6907 } else { 6908 records = Object.values(response); 6909 } 6910 if (query._fields) { 6911 records = records.map((record) => { 6912 query._fields.split(",").forEach((field) => { 6913 if (!record.hasOwnProperty(field)) { 6914 record[field] = void 0; 6915 } 6916 }); 6917 return record; 6918 }); 6919 } 6920 registry.batch(() => { 6921 dispatch3.receiveRevisions( 6922 kind, 6923 name, 6924 recordKey, 6925 records, 6926 query, 6927 false, 6928 meta 6929 ); 6930 const key = entityConfig.revisionKey || DEFAULT_ENTITY_KEY; 6931 const normalizedQuery = normalizeQueryForResolution(rawQuery); 6932 const resolutionsArgs = records.filter((record) => record[key]).map((record) => [ 6933 kind, 6934 name, 6935 recordKey, 6936 record[key], 6937 normalizedQuery 6938 ]); 6939 dispatch3.finishResolutions( 6940 "getRevision", 6941 resolutionsArgs 6942 ); 6943 }); 6944 } 6945 } finally { 6946 dispatch3.__unstableReleaseStoreLock(lock2); 6947 } 6948 }; 6949 getRevisions2.shouldInvalidate = (action, kind, name, recordKey) => action.type === "SAVE_ENTITY_RECORD_FINISH" && name === action.name && kind === action.kind && !action.error && recordKey === action.recordId; 6950 var getRevision2 = (kind, name, recordKey, revisionKey, query) => async ({ select: select4, dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 6951 const configs = await resolveSelect2.getEntitiesConfig(kind); 6952 const entityConfig = configs.find( 6953 (config) => config.name === name && config.kind === kind 6954 ); 6955 if (!entityConfig) { 6956 return; 6957 } 6958 if (query !== void 0 && query._fields) { 6959 query = { 6960 ...query, 6961 _fields: [ 6962 .../* @__PURE__ */ new Set([ 6963 ...get_normalized_comma_separable_default(query._fields) || [], 6964 entityConfig.revisionKey || DEFAULT_ENTITY_KEY 6965 ]) 6966 ].join() 6967 }; 6968 } 6969 const lock2 = await dispatch3.__unstableAcquireStoreLock( 6970 STORE_NAME, 6971 [ 6972 "entities", 6973 "records", 6974 kind, 6975 name, 6976 recordKey, 6977 "revisions", 6978 revisionKey 6979 ], 6980 { exclusive: false } 6981 ); 6982 try { 6983 if (select4.hasRevision(kind, name, recordKey, revisionKey, query)) { 6984 return; 6985 } 6986 const path = (0, import_url6.addQueryArgs)( 6987 entityConfig.getRevisionsUrl(recordKey, revisionKey), 6988 query 6989 ); 6990 let record; 6991 try { 6992 record = await (0, import_api_fetch9.default)({ path }); 6993 } catch { 6994 return; 6995 } 6996 if (record) { 6997 dispatch3.receiveRevisions( 6998 kind, 6999 name, 7000 recordKey, 7001 record, 7002 query 7003 ); 7004 } 7005 } finally { 7006 dispatch3.__unstableReleaseStoreLock(lock2); 7007 } 7008 }; 7009 var getRegisteredPostMeta2 = (postType) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 7010 let options; 7011 try { 7012 const { 7013 rest_namespace: restNamespace = "wp/v2", 7014 rest_base: restBase 7015 } = await resolveSelect2.getPostType(postType) || {}; 7016 options = await (0, import_api_fetch9.default)({ 7017 path: `$restNamespace}/$restBase}/?context=edit`, 7018 method: "OPTIONS" 7019 }); 7020 } catch { 7021 return; 7022 } 7023 if (options) { 7024 dispatch3.receiveRegisteredPostMeta( 7025 postType, 7026 options?.schema?.properties?.meta?.properties 7027 ); 7028 } 7029 }; 7030 var getEntitiesConfig2 = (kind) => async ({ dispatch: dispatch3 }) => { 7031 const loader = additionalEntityConfigLoaders.find( 7032 (l) => l.kind === kind 7033 ); 7034 if (!loader) { 7035 return; 7036 } 7037 try { 7038 const configs = await loader.loadEntities(); 7039 if (!configs.length) { 7040 return; 7041 } 7042 dispatch3.addEntities(configs); 7043 } catch { 7044 } 7045 }; 7046 var getEditorSettings2 = () => async ({ dispatch: dispatch3 }) => { 7047 const settings = await (0, import_api_fetch9.default)({ 7048 path: "/wp-block-editor/v1/settings" 7049 }); 7050 dispatch3.receiveEditorSettings(settings); 7051 }; 7052 var getEditorAssets2 = () => async ({ dispatch: dispatch3 }) => { 7053 const assets = await (0, import_api_fetch9.default)({ 7054 path: "/wp-block-editor/v1/assets" 7055 }); 7056 dispatch3.receiveEditorAssets(assets); 7057 }; 7058 var getViewConfig2 = (kind, name, options = {}) => async ({ dispatch: dispatch3 }) => { 7059 const query = { kind, name }; 7060 const fields = get_normalized_comma_separable_default(options.fields); 7061 if (fields?.length) { 7062 query._fields = fields.join(","); 7063 } 7064 const config = await (0, import_api_fetch9.default)({ 7065 path: (0, import_url6.addQueryArgs)("/wp/v2/view-config", query) 7066 }); 7067 dispatch3.receiveViewConfig(kind, name, config); 7068 }; 7069 7070 // packages/core-data/build-module/locks/utils.mjs 7071 function deepCopyLocksTreePath(tree, path) { 7072 const newTree = { ...tree }; 7073 let currentNode = newTree; 7074 for (const branchName of path) { 7075 currentNode.children = { 7076 ...currentNode.children, 7077 [branchName]: { 7078 locks: [], 7079 children: {}, 7080 ...currentNode.children[branchName] 7081 } 7082 }; 7083 currentNode = currentNode.children[branchName]; 7084 } 7085 return newTree; 7086 } 7087 function getNode(tree, path) { 7088 let currentNode = tree; 7089 for (const branchName of path) { 7090 const nextNode = currentNode.children[branchName]; 7091 if (!nextNode) { 7092 return null; 7093 } 7094 currentNode = nextNode; 7095 } 7096 return currentNode; 7097 } 7098 function* iteratePath(tree, path) { 7099 let currentNode = tree; 7100 yield currentNode; 7101 for (const branchName of path) { 7102 const nextNode = currentNode.children[branchName]; 7103 if (!nextNode) { 7104 break; 7105 } 7106 yield nextNode; 7107 currentNode = nextNode; 7108 } 7109 } 7110 function* iterateDescendants(node) { 7111 const stack = Object.values(node.children); 7112 while (stack.length) { 7113 const childNode = stack.pop(); 7114 yield childNode; 7115 stack.push(...Object.values(childNode.children)); 7116 } 7117 } 7118 function hasConflictingLock({ exclusive }, locks2) { 7119 if (exclusive && locks2.length) { 7120 return true; 7121 } 7122 if (!exclusive && locks2.filter((lock2) => lock2.exclusive).length) { 7123 return true; 7124 } 7125 return false; 7126 } 7127 7128 // packages/core-data/build-module/locks/reducer.mjs 7129 var DEFAULT_STATE = { 7130 requests: [], 7131 tree: { 7132 locks: [], 7133 children: {} 7134 } 7135 }; 7136 function locks(state = DEFAULT_STATE, action) { 7137 switch (action.type) { 7138 case "ENQUEUE_LOCK_REQUEST": { 7139 const { request } = action; 7140 return { 7141 ...state, 7142 requests: [request, ...state.requests] 7143 }; 7144 } 7145 case "GRANT_LOCK_REQUEST": { 7146 const { lock: lock2, request } = action; 7147 const { store: store2, path } = request; 7148 const storePath = [store2, ...path]; 7149 const newTree = deepCopyLocksTreePath(state.tree, storePath); 7150 const node = getNode(newTree, storePath); 7151 node.locks = [...node.locks, lock2]; 7152 return { 7153 ...state, 7154 requests: state.requests.filter((r) => r !== request), 7155 tree: newTree 7156 }; 7157 } 7158 case "RELEASE_LOCK": { 7159 const { lock: lock2 } = action; 7160 const storePath = [lock2.store, ...lock2.path]; 7161 const newTree = deepCopyLocksTreePath(state.tree, storePath); 7162 const node = getNode(newTree, storePath); 7163 node.locks = node.locks.filter((l) => l !== lock2); 7164 return { 7165 ...state, 7166 tree: newTree 7167 }; 7168 } 7169 } 7170 return state; 7171 } 7172 7173 // packages/core-data/build-module/locks/selectors.mjs 7174 function getPendingLockRequests(state) { 7175 return state.requests; 7176 } 7177 function isLockAvailable(state, store2, path, { exclusive }) { 7178 const storePath = [store2, ...path]; 7179 const locks2 = state.tree; 7180 for (const node2 of iteratePath(locks2, storePath)) { 7181 if (hasConflictingLock({ exclusive }, node2.locks)) { 7182 return false; 7183 } 7184 } 7185 const node = getNode(locks2, storePath); 7186 if (!node) { 7187 return true; 7188 } 7189 for (const descendant of iterateDescendants(node)) { 7190 if (hasConflictingLock({ exclusive }, descendant.locks)) { 7191 return false; 7192 } 7193 } 7194 return true; 7195 } 7196 7197 // packages/core-data/build-module/locks/engine.mjs 7198 function createLocks() { 7199 let state = locks(void 0, { type: "@@INIT" }); 7200 function processPendingLockRequests() { 7201 for (const request of getPendingLockRequests(state)) { 7202 const { store: store2, path, exclusive, notifyAcquired } = request; 7203 if (isLockAvailable(state, store2, path, { exclusive })) { 7204 const lock2 = { store: store2, path, exclusive }; 7205 state = locks(state, { 7206 type: "GRANT_LOCK_REQUEST", 7207 lock: lock2, 7208 request 7209 }); 7210 notifyAcquired(lock2); 7211 } 7212 } 7213 } 7214 function acquire(store2, path, exclusive) { 7215 return new Promise((resolve) => { 7216 state = locks(state, { 7217 type: "ENQUEUE_LOCK_REQUEST", 7218 request: { store: store2, path, exclusive, notifyAcquired: resolve } 7219 }); 7220 processPendingLockRequests(); 7221 }); 7222 } 7223 function release(lock2) { 7224 state = locks(state, { 7225 type: "RELEASE_LOCK", 7226 lock: lock2 7227 }); 7228 processPendingLockRequests(); 7229 } 7230 return { acquire, release }; 7231 } 7232 7233 // packages/core-data/build-module/locks/actions.mjs 7234 function createLocksActions() { 7235 const locks2 = createLocks(); 7236 function __unstableAcquireStoreLock(store2, path, { exclusive }) { 7237 return () => locks2.acquire(store2, path, exclusive); 7238 } 7239 function __unstableReleaseStoreLock(lock2) { 7240 return () => locks2.release(lock2); 7241 } 7242 return { __unstableAcquireStoreLock, __unstableReleaseStoreLock }; 7243 } 7244 7245 // packages/core-data/build-module/dynamic-entities.mjs 7246 var dynamicActions; 7247 var dynamicSelectors; 7248 7249 // packages/core-data/build-module/entity-provider.mjs 7250 var import_element2 = __toESM(require_element(), 1); 7251 7252 // packages/core-data/build-module/entity-context.mjs 7253 var import_element = __toESM(require_element(), 1); 7254 var EntityContext = (0, import_element.createContext)({}); 7255 EntityContext.displayName = "EntityContext"; 7256 7257 // packages/core-data/build-module/entity-provider.mjs 7258 var import_jsx_runtime = __toESM(require_jsx_runtime(), 1); 7259 function EntityProvider({ 7260 kind, 7261 type: name, 7262 id, 7263 revisionId, 7264 children 7265 }) { 7266 const parent = (0, import_element2.useContext)(EntityContext); 7267 const childContext = (0, import_element2.useMemo)( 7268 () => ({ 7269 ...parent, 7270 ...kind && { 7271 [kind]: { 7272 ...parent?.[kind], 7273 [name]: id 7274 } 7275 }, 7276 ...revisionId !== void 0 && { revisionId } 7277 }), 7278 [parent, kind, name, id, revisionId] 7279 ); 7280 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EntityContext.Provider, { value: childContext, children }); 7281 } 7282 7283 // packages/core-data/build-module/hooks/use-entity-record.mjs 7284 var import_data10 = __toESM(require_data(), 1); 7285 var import_deprecated4 = __toESM(require_deprecated(), 1); 7286 var import_element3 = __toESM(require_element(), 1); 7287 7288 // packages/core-data/build-module/hooks/constants.mjs 7289 var Status = /* @__PURE__ */ ((Status2) => { 7290 Status2["Idle"] = "IDLE"; 7291 Status2["Resolving"] = "RESOLVING"; 7292 Status2["Error"] = "ERROR"; 7293 Status2["Success"] = "SUCCESS"; 7294 return Status2; 7295 })(Status || {}); 7296 7297 // packages/core-data/build-module/hooks/utils.mjs 7298 function getResolutionStatus(resolutionStatus) { 7299 let status; 7300 switch (resolutionStatus) { 7301 case "resolving": 7302 status = Status.Resolving; 7303 break; 7304 case "finished": 7305 status = Status.Success; 7306 break; 7307 case "error": 7308 status = Status.Error; 7309 break; 7310 default: 7311 status = Status.Idle; 7312 } 7313 return { 7314 status, 7315 isResolving: status === Status.Resolving, 7316 hasStarted: status !== Status.Idle, 7317 hasResolved: status === Status.Success || status === Status.Error 7318 }; 7319 } 7320 7321 // packages/core-data/build-module/hooks/use-entity-record.mjs 7322 var EMPTY_OBJECT3 = {}; 7323 function useEntityRecord(kind, name, recordId, options = { enabled: true }) { 7324 const { editEntityRecord: editEntityRecord2, saveEditedEntityRecord: saveEditedEntityRecord2 } = (0, import_data10.useDispatch)(store); 7325 const mutations = (0, import_element3.useMemo)( 7326 () => ({ 7327 edit: (record2, editOptions = {}) => editEntityRecord2(kind, name, recordId, record2, editOptions), 7328 save: (saveOptions = {}) => saveEditedEntityRecord2(kind, name, recordId, { 7329 throwOnError: true, 7330 ...saveOptions 7331 }) 7332 }), 7333 [editEntityRecord2, kind, name, recordId, saveEditedEntityRecord2] 7334 ); 7335 const { record, editedRecord, hasEdits, edits, ...resolution } = (0, import_data10.useSelect)( 7336 (select4) => { 7337 if (!options.enabled) { 7338 return { 7339 record: null, 7340 editedRecord: EMPTY_OBJECT3, 7341 hasEdits: false, 7342 edits: EMPTY_OBJECT3, 7343 ...getResolutionStatus() 7344 }; 7345 } 7346 const storeSelectors = select4(store); 7347 const resolutionStatus = storeSelectors.getResolutionState( 7348 "getEntityRecord", 7349 [kind, name, recordId] 7350 )?.status; 7351 return { 7352 record: storeSelectors.getEntityRecord( 7353 kind, 7354 name, 7355 recordId 7356 ) ?? null, 7357 editedRecord: storeSelectors.getEditedEntityRecord( 7358 kind, 7359 name, 7360 recordId 7361 ), 7362 hasEdits: storeSelectors.hasEditsForEntityRecord( 7363 kind, 7364 name, 7365 recordId 7366 ), 7367 edits: storeSelectors.getEntityRecordNonTransientEdits( 7368 kind, 7369 name, 7370 recordId 7371 ), 7372 ...getResolutionStatus(resolutionStatus) 7373 }; 7374 }, 7375 [kind, name, recordId, options.enabled] 7376 ); 7377 return { 7378 record, 7379 editedRecord, 7380 hasEdits, 7381 edits, 7382 ...resolution, 7383 ...mutations 7384 }; 7385 } 7386 function useDeprecatedEntityRecord(kind, name, recordId, options) { 7387 (0, import_deprecated4.default)(`wp.data.__experimentalUseEntityRecord`, { 7388 alternative: "wp.data.useEntityRecord", 7389 since: "6.1" 7390 }); 7391 return useEntityRecord(kind, name, recordId, options); 7392 } 7393 7394 // packages/core-data/build-module/hooks/use-entity-records.mjs 7395 var import_url7 = __toESM(require_url(), 1); 7396 var import_deprecated5 = __toESM(require_deprecated(), 1); 7397 var import_data11 = __toESM(require_data(), 1); 7398 var import_element4 = __toESM(require_element(), 1); 7399 var EMPTY_ARRAY = []; 7400 function useEntityRecords(kind, name, queryArgs = {}, options = { enabled: true }) { 7401 const queryAsString = (0, import_url7.addQueryArgs)("", queryArgs); 7402 const { records, totalItems, totalPages, ...rest } = (0, import_data11.useSelect)( 7403 (select4) => { 7404 if (!options.enabled) { 7405 return { 7406 // Avoiding returning a new reference on every execution. 7407 records: EMPTY_ARRAY, 7408 totalItems: null, 7409 totalPages: null, 7410 ...getResolutionStatus() 7411 }; 7412 } 7413 const storeSelectors = select4(store); 7414 const resolutionStatus = storeSelectors.getResolutionState( 7415 "getEntityRecords", 7416 [kind, name, queryArgs] 7417 )?.status; 7418 return { 7419 records: storeSelectors.getEntityRecords( 7420 kind, 7421 name, 7422 queryArgs 7423 ), 7424 totalItems: storeSelectors.getEntityRecordsTotalItems( 7425 kind, 7426 name, 7427 queryArgs 7428 ), 7429 totalPages: storeSelectors.getEntityRecordsTotalPages( 7430 kind, 7431 name, 7432 queryArgs 7433 ), 7434 ...getResolutionStatus(resolutionStatus) 7435 }; 7436 }, 7437 [kind, name, queryAsString, options.enabled] 7438 ); 7439 return { 7440 records, 7441 totalItems, 7442 totalPages, 7443 ...rest 7444 }; 7445 } 7446 function useDeprecatedEntityRecords(kind, name, queryArgs, options) { 7447 (0, import_deprecated5.default)(`wp.data.__experimentalUseEntityRecords`, { 7448 alternative: "wp.data.useEntityRecords", 7449 since: "6.1" 7450 }); 7451 return useEntityRecords(kind, name, queryArgs, options); 7452 } 7453 function useEntityRecordsWithPermissions(kind, name, queryArgs = {}, options = { enabled: true }) { 7454 const entityConfig = (0, import_data11.useSelect)( 7455 (select4) => select4(store).getEntityConfig(kind, name), 7456 [kind, name] 7457 ); 7458 const { records: data, ...ret } = useEntityRecords( 7459 kind, 7460 name, 7461 { 7462 ...queryArgs, 7463 // If _fields is provided, we need to include _links in the request for permission caching to work. 7464 ...queryArgs._fields ? { 7465 _fields: [ 7466 .../* @__PURE__ */ new Set([ 7467 ...get_normalized_comma_separable_default( 7468 queryArgs._fields 7469 ) || [], 7470 "_links" 7471 ]) 7472 ].join() 7473 } : {} 7474 }, 7475 options 7476 ); 7477 const ids = (0, import_element4.useMemo)( 7478 () => data?.map( 7479 // @ts-ignore 7480 (record) => record[entityConfig?.key ?? "id"] 7481 ) ?? [], 7482 [data, entityConfig?.key] 7483 ); 7484 const permissions = (0, import_data11.useSelect)( 7485 (select4) => { 7486 const { getEntityRecordsPermissions: getEntityRecordsPermissions2 } = unlock( 7487 select4(store) 7488 ); 7489 return getEntityRecordsPermissions2(kind, name, ids); 7490 }, 7491 [ids, kind, name] 7492 ); 7493 const dataWithPermissions = (0, import_element4.useMemo)( 7494 () => data?.map((record, index) => ({ 7495 // @ts-ignore 7496 ...record, 7497 permissions: permissions[index] 7498 })) ?? [], 7499 [data, permissions] 7500 ); 7501 return { records: dataWithPermissions, ...ret }; 7502 } 7503 7504 // packages/core-data/build-module/hooks/use-resource-permissions.mjs 7505 var import_deprecated6 = __toESM(require_deprecated(), 1); 7506 var import_warning = __toESM(require_warning(), 1); 7507 7508 // packages/core-data/build-module/hooks/use-query-select.mjs 7509 var import_data12 = __toESM(require_data(), 1); 7510 7511 // node_modules/memize/dist/index.js 7512 function memize(fn, options) { 7513 var size = 0; 7514 var head; 7515 var tail; 7516 options = options || {}; 7517 function memoized() { 7518 var node = head, len = arguments.length, args, i; 7519 searchCache: while (node) { 7520 if (node.args.length !== arguments.length) { 7521 node = node.next; 7522 continue; 7523 } 7524 for (i = 0; i < len; i++) { 7525 if (node.args[i] !== arguments[i]) { 7526 node = node.next; 7527 continue searchCache; 7528 } 7529 } 7530 if (node !== head) { 7531 if (node === tail) { 7532 tail = node.prev; 7533 } 7534 node.prev.next = node.next; 7535 if (node.next) { 7536 node.next.prev = node.prev; 7537 } 7538 node.next = head; 7539 node.prev = null; 7540 head.prev = node; 7541 head = node; 7542 } 7543 return node.val; 7544 } 7545 args = new Array(len); 7546 for (i = 0; i < len; i++) { 7547 args[i] = arguments[i]; 7548 } 7549 node = { 7550 args, 7551 // Generate the result from original function 7552 val: fn.apply(null, args) 7553 }; 7554 if (head) { 7555 head.prev = node; 7556 node.next = head; 7557 } else { 7558 tail = node; 7559 } 7560 if (size === /** @type {MemizeOptions} */ 7561 options.maxSize) { 7562 tail = /** @type {MemizeCacheNode} */ 7563 tail.prev; 7564 tail.next = null; 7565 } else { 7566 size++; 7567 } 7568 head = node; 7569 return node.val; 7570 } 7571 memoized.clear = function() { 7572 head = null; 7573 tail = null; 7574 size = 0; 7575 }; 7576 return memoized; 7577 } 7578 7579 // packages/core-data/build-module/hooks/use-query-select.mjs 7580 var META_SELECTORS = [ 7581 "getIsResolving", 7582 "hasStartedResolution", 7583 "hasFinishedResolution", 7584 "isResolving", 7585 "getCachedResolvers" 7586 ]; 7587 function useQuerySelect(mapQuerySelect, deps) { 7588 return (0, import_data12.useSelect)((select4, registry) => { 7589 const resolve = (store2) => enrichSelectors(select4(store2)); 7590 return mapQuerySelect(resolve, registry); 7591 }, deps); 7592 } 7593 var enrichSelectors = memize(((selectors) => { 7594 const resolvers = {}; 7595 for (const selectorName in selectors) { 7596 if (META_SELECTORS.includes(selectorName)) { 7597 continue; 7598 } 7599 Object.defineProperty(resolvers, selectorName, { 7600 get: () => (...args) => { 7601 const data = selectors[selectorName](...args); 7602 const resolutionStatus = selectors.getResolutionState( 7603 selectorName, 7604 args 7605 )?.status; 7606 return { 7607 data, 7608 ...getResolutionStatus(resolutionStatus) 7609 }; 7610 } 7611 }); 7612 } 7613 return resolvers; 7614 })); 7615 7616 // packages/core-data/build-module/hooks/use-resource-permissions.mjs 7617 function useResourcePermissions(resource, id) { 7618 const isEntity = typeof resource === "object"; 7619 const resourceAsString = isEntity ? JSON.stringify(resource) : resource; 7620 if (isEntity && typeof id !== "undefined") { 7621 (0, import_warning.default)( 7622 `When 'resource' is an entity object, passing 'id' as a separate argument isn't supported.` 7623 ); 7624 } 7625 return useQuerySelect( 7626 (resolve) => { 7627 const hasId = isEntity ? !!resource.id : !!id; 7628 const { canUser: canUser3 } = resolve(store); 7629 const collectionResource = isEntity ? { kind: resource.kind, name: resource.name } : resource; 7630 const create3 = canUser3("create", collectionResource); 7631 if (!hasId) { 7632 const read2 = canUser3("read", collectionResource); 7633 const isResolving2 = create3.isResolving || read2.isResolving; 7634 const hasResolved2 = create3.hasResolved && read2.hasResolved; 7635 let status2 = Status.Idle; 7636 if (isResolving2) { 7637 status2 = Status.Resolving; 7638 } else if (hasResolved2) { 7639 status2 = Status.Success; 7640 } 7641 return { 7642 status: status2, 7643 isResolving: isResolving2, 7644 hasResolved: hasResolved2, 7645 canCreate: create3.hasResolved && create3.data, 7646 canRead: read2.hasResolved && read2.data 7647 }; 7648 } 7649 const read = canUser3("read", resource, id); 7650 const update = canUser3("update", resource, id); 7651 const _delete = canUser3("delete", resource, id); 7652 const isResolving = read.isResolving || create3.isResolving || update.isResolving || _delete.isResolving; 7653 const hasResolved = read.hasResolved && create3.hasResolved && update.hasResolved && _delete.hasResolved; 7654 let status = Status.Idle; 7655 if (isResolving) { 7656 status = Status.Resolving; 7657 } else if (hasResolved) { 7658 status = Status.Success; 7659 } 7660 return { 7661 status, 7662 isResolving, 7663 hasResolved, 7664 canRead: hasResolved && read.data, 7665 canCreate: hasResolved && create3.data, 7666 canUpdate: hasResolved && update.data, 7667 canDelete: hasResolved && _delete.data 7668 }; 7669 }, 7670 [resourceAsString, id] 7671 ); 7672 } 7673 var use_resource_permissions_default = useResourcePermissions; 7674 function useDeprecatedResourcePermissions(resource, id) { 7675 (0, import_deprecated6.default)(`wp.data.__experimentalUseResourcePermissions`, { 7676 alternative: "wp.data.useResourcePermissions", 7677 since: "6.1" 7678 }); 7679 return useResourcePermissions(resource, id); 7680 } 7681 7682 // packages/core-data/build-module/hooks/use-entity-block-editor.mjs 7683 var import_element6 = __toESM(require_element(), 1); 7684 var import_data13 = __toESM(require_data(), 1); 7685 var import_blocks5 = __toESM(require_blocks(), 1); 7686 7687 // packages/core-data/build-module/hooks/use-entity-id.mjs 7688 var import_element5 = __toESM(require_element(), 1); 7689 function useEntityId(kind, name) { 7690 const context = (0, import_element5.useContext)(EntityContext); 7691 return context?.[kind]?.[name]; 7692 } 7693 7694 // packages/core-data/build-module/footnotes/index.mjs 7695 var import_rich_text4 = __toESM(require_rich_text(), 1); 7696 7697 // packages/core-data/build-module/footnotes/get-rich-text-values-cached.mjs 7698 var import_block_editor5 = __toESM(require_block_editor(), 1); 7699 var unlockedApis; 7700 var cache = /* @__PURE__ */ new WeakMap(); 7701 function getRichTextValuesCached(block) { 7702 if (!unlockedApis) { 7703 unlockedApis = unlock(import_block_editor5.privateApis); 7704 } 7705 if (!cache.has(block)) { 7706 const values = unlockedApis.getRichTextValues([block]); 7707 cache.set(block, values); 7708 } 7709 return cache.get(block); 7710 } 7711 7712 // packages/core-data/build-module/footnotes/get-footnotes-order.mjs 7713 var cache2 = /* @__PURE__ */ new WeakMap(); 7714 function getBlockFootnotesOrder(block) { 7715 if (!cache2.has(block)) { 7716 const order = []; 7717 for (const value of getRichTextValuesCached(block)) { 7718 if (!value) { 7719 continue; 7720 } 7721 value.replacements.forEach(({ type, attributes }) => { 7722 if (type === "core/footnote") { 7723 order.push(attributes["data-fn"]); 7724 } 7725 }); 7726 } 7727 cache2.set(block, order); 7728 } 7729 return cache2.get(block); 7730 } 7731 function getFootnotesOrder(blocks) { 7732 return blocks.flatMap(getBlockFootnotesOrder); 7733 } 7734 7735 // packages/core-data/build-module/footnotes/index.mjs 7736 var oldFootnotes = {}; 7737 function updateFootnotesFromMeta(blocks, meta) { 7738 const output = { blocks }; 7739 if (!meta) { 7740 return output; 7741 } 7742 if (meta.footnotes === void 0) { 7743 return output; 7744 } 7745 const newOrder = getFootnotesOrder(blocks); 7746 const footnotes = meta.footnotes ? JSON.parse(meta.footnotes) : []; 7747 const currentOrder = footnotes.map((fn) => fn.id); 7748 if (currentOrder.join("") === newOrder.join("")) { 7749 return output; 7750 } 7751 const newFootnotes = newOrder.map( 7752 (fnId) => footnotes.find((fn) => fn.id === fnId) || oldFootnotes[fnId] || { 7753 id: fnId, 7754 content: "" 7755 } 7756 ); 7757 function updateAttributes(attributes) { 7758 if (!attributes || Array.isArray(attributes) || typeof attributes !== "object") { 7759 return attributes; 7760 } 7761 attributes = { ...attributes }; 7762 for (const key in attributes) { 7763 const value = attributes[key]; 7764 if (Array.isArray(value)) { 7765 attributes[key] = value.map(updateAttributes); 7766 continue; 7767 } 7768 if (typeof value !== "string" && !(value instanceof import_rich_text4.RichTextData)) { 7769 continue; 7770 } 7771 const richTextValue = typeof value === "string" ? import_rich_text4.RichTextData.fromHTMLString(value) : new import_rich_text4.RichTextData(value); 7772 let hasFootnotes = false; 7773 richTextValue.replacements.forEach((replacement) => { 7774 if (replacement.type === "core/footnote") { 7775 const id = replacement.attributes["data-fn"]; 7776 const index = newOrder.indexOf(id); 7777 const countValue = (0, import_rich_text4.create)({ 7778 html: replacement.innerHTML 7779 }); 7780 countValue.text = String(index + 1); 7781 countValue.formats = Array.from( 7782 { length: countValue.text.length }, 7783 () => countValue.formats[0] 7784 ); 7785 countValue.replacements = Array.from( 7786 { length: countValue.text.length }, 7787 () => countValue.replacements[0] 7788 ); 7789 replacement.innerHTML = (0, import_rich_text4.toHTMLString)({ 7790 value: countValue 7791 }); 7792 hasFootnotes = true; 7793 } 7794 }); 7795 if (hasFootnotes) { 7796 attributes[key] = typeof value === "string" ? richTextValue.toHTMLString() : richTextValue; 7797 } 7798 } 7799 return attributes; 7800 } 7801 function updateBlocksAttributes(__blocks) { 7802 return __blocks.map((block) => { 7803 return { 7804 ...block, 7805 attributes: updateAttributes(block.attributes), 7806 innerBlocks: updateBlocksAttributes(block.innerBlocks) 7807 }; 7808 }); 7809 } 7810 const newBlocks = updateBlocksAttributes(blocks); 7811 oldFootnotes = { 7812 ...oldFootnotes, 7813 ...footnotes.reduce((acc, fn) => { 7814 if (!newOrder.includes(fn.id)) { 7815 acc[fn.id] = fn; 7816 } 7817 return acc; 7818 }, {}) 7819 }; 7820 return { 7821 meta: { 7822 ...meta, 7823 footnotes: JSON.stringify(newFootnotes) 7824 }, 7825 blocks: newBlocks 7826 }; 7827 } 7828 7829 // packages/core-data/build-module/hooks/use-entity-block-editor.mjs 7830 var EMPTY_ARRAY2 = []; 7831 function useEntityBlockEditor(kind, name, { id: _id } = {}) { 7832 const providerId = useEntityId(kind, name); 7833 const id = _id ?? providerId; 7834 const { content, editedBlocks, meta } = (0, import_data13.useSelect)( 7835 (select4) => { 7836 if (!id) { 7837 return {}; 7838 } 7839 const { getEditedEntityRecord: getEditedEntityRecord3 } = select4(STORE_NAME); 7840 const editedRecord = getEditedEntityRecord3(kind, name, id); 7841 return { 7842 editedBlocks: editedRecord.blocks, 7843 content: editedRecord.content, 7844 meta: editedRecord.meta 7845 }; 7846 }, 7847 [kind, name, id] 7848 ); 7849 const { __unstableCreateUndoLevel: __unstableCreateUndoLevel2, editEntityRecord: editEntityRecord2 } = (0, import_data13.useDispatch)(STORE_NAME); 7850 const blocks = (0, import_element6.useMemo)(() => { 7851 if (!id) { 7852 return void 0; 7853 } 7854 if (editedBlocks) { 7855 return editedBlocks; 7856 } 7857 if (!content || typeof content !== "string") { 7858 return EMPTY_ARRAY2; 7859 } 7860 const cacheKey = getCacheKey(kind, name, id); 7861 const cached = parsedBlocksCache.get(cacheKey); 7862 let _blocks; 7863 if (cached && cached.content === content) { 7864 _blocks = cached.blocks; 7865 } else { 7866 _blocks = (0, import_blocks5.parse)(content); 7867 parsedBlocksCache.set(cacheKey, { content, blocks: _blocks }); 7868 } 7869 return _blocks; 7870 }, [kind, name, id, editedBlocks, content]); 7871 const onChange = (0, import_element6.useCallback)( 7872 (newBlocks, options) => { 7873 const noChange = blocks === newBlocks; 7874 if (noChange) { 7875 return __unstableCreateUndoLevel2(kind, name, id); 7876 } 7877 const { selection, ...rest } = options; 7878 const edits = { 7879 selection, 7880 content: ({ blocks: blocksForSerialization = [] }) => (0, import_blocks5.__unstableSerializeAndClean)(blocksForSerialization), 7881 ...updateFootnotesFromMeta(newBlocks, meta) 7882 }; 7883 editEntityRecord2(kind, name, id, edits, { 7884 isCached: false, 7885 ...rest 7886 }); 7887 }, 7888 [ 7889 kind, 7890 name, 7891 id, 7892 blocks, 7893 meta, 7894 __unstableCreateUndoLevel2, 7895 editEntityRecord2 7896 ] 7897 ); 7898 const onInput = (0, import_element6.useCallback)( 7899 (newBlocks, options) => { 7900 const { selection, ...rest } = options; 7901 const edits = { 7902 selection, 7903 ...updateFootnotesFromMeta(newBlocks, meta) 7904 }; 7905 editEntityRecord2(kind, name, id, edits, { 7906 isCached: true, 7907 ...rest 7908 }); 7909 }, 7910 [kind, name, id, meta, editEntityRecord2] 7911 ); 7912 return [blocks, onInput, onChange]; 7913 } 7914 7915 // packages/core-data/build-module/hooks/use-entity-prop.mjs 7916 var import_element7 = __toESM(require_element(), 1); 7917 var import_data14 = __toESM(require_data(), 1); 7918 function useEntityProp(kind, name, prop, _id) { 7919 const providerId = useEntityId(kind, name); 7920 const id = _id ?? providerId; 7921 const context = (0, import_element7.useContext)(EntityContext); 7922 const revisionId = context?.revisionId; 7923 const { value, fullValue } = (0, import_data14.useSelect)( 7924 (select4) => { 7925 if (revisionId) { 7926 const revisions = select4(STORE_NAME).getRevisions( 7927 kind, 7928 name, 7929 id, 7930 { 7931 per_page: -1, 7932 context: "edit", 7933 _fields: "id,date,author,meta,title.raw,excerpt.raw,content.raw" 7934 } 7935 ); 7936 const entityConfig = select4(STORE_NAME).getEntityConfig( 7937 kind, 7938 name 7939 ); 7940 const revKey = entityConfig?.revisionKey || DEFAULT_ENTITY_KEY; 7941 const revision = revisions?.find( 7942 (r) => r[revKey] === revisionId 7943 ); 7944 return revision ? { 7945 value: revision[prop]?.raw ?? revision[prop], 7946 fullValue: revision[prop] 7947 } : {}; 7948 } 7949 const { getEntityRecord: getEntityRecord3, getEditedEntityRecord: getEditedEntityRecord3 } = select4(STORE_NAME); 7950 const record = getEntityRecord3(kind, name, id); 7951 const editedRecord = getEditedEntityRecord3(kind, name, id); 7952 return record && editedRecord ? { 7953 value: editedRecord[prop], 7954 fullValue: record[prop] 7955 } : {}; 7956 }, 7957 [kind, name, id, prop, revisionId] 7958 ); 7959 const { editEntityRecord: editEntityRecord2 } = (0, import_data14.useDispatch)(STORE_NAME); 7960 const setValue = (0, import_element7.useCallback)( 7961 (newValue) => { 7962 if (revisionId) { 7963 return; 7964 } 7965 editEntityRecord2(kind, name, id, { 7966 [prop]: newValue 7967 }); 7968 }, 7969 [editEntityRecord2, kind, name, id, prop, revisionId] 7970 ); 7971 return [value, setValue, fullValue]; 7972 } 7973 7974 // packages/core-data/build-module/hooks/use-post-editor-awareness-state.mjs 7975 var import_compose3 = __toESM(require_compose(), 1); 7976 var import_element8 = __toESM(require_element(), 1); 7977 var defaultResolvedSelection = { 7978 richTextOffset: null, 7979 localClientId: null, 7980 attributeKey: null 7981 }; 7982 var defaultState = { 7983 activeCollaborators: [], 7984 resolveSelection: () => defaultResolvedSelection, 7985 getDebugData: () => ({ 7986 doc: {}, 7987 clients: {}, 7988 collaboratorMap: {} 7989 }), 7990 isCurrentCollaboratorDisconnected: false 7991 }; 7992 function getAwarenessState(awareness, newState) { 7993 const activeCollaborators = newState ?? awareness.getCurrentState(); 7994 return { 7995 activeCollaborators, 7996 resolveSelection: (selection, blocks) => awareness.convertSelectionStateToAbsolute(selection, blocks), 7997 getDebugData: () => awareness.getDebugData(), 7998 isCurrentCollaboratorDisconnected: activeCollaborators.find((collaborator) => collaborator.isMe)?.isConnected === false 7999 }; 8000 } 8001 function usePostEditorAwarenessState(postId, postType) { 8002 const [state, setState] = (0, import_element8.useState)(defaultState); 8003 (0, import_element8.useEffect)(() => { 8004 if (null === postId || null === postType) { 8005 setState(defaultState); 8006 return; 8007 } 8008 const objectType = `postType/$postType}`; 8009 const objectId = postId.toString(); 8010 const awareness = getSyncManager()?.getAwareness( 8011 objectType, 8012 objectId 8013 ); 8014 if (!awareness) { 8015 setState(defaultState); 8016 return; 8017 } 8018 awareness.setUp(); 8019 setState(getAwarenessState(awareness)); 8020 const unsubscribe = awareness?.onStateChange( 8021 (newState) => { 8022 setState(getAwarenessState(awareness, newState)); 8023 } 8024 ); 8025 return unsubscribe; 8026 }, [postId, postType]); 8027 return state; 8028 } 8029 function useActiveCollaborators(postId, postType) { 8030 return usePostEditorAwarenessState(postId, postType).activeCollaborators; 8031 } 8032 function useResolvedSelection(postId, postType) { 8033 const blocks = usePostContentBlocks(); 8034 const awarenessState = usePostEditorAwarenessState(postId, postType); 8035 return (0, import_element8.useCallback)( 8036 (selection) => awarenessState.resolveSelection(selection, blocks), 8037 [blocks, awarenessState] 8038 ); 8039 } 8040 function useLastPostSave(postId, postType) { 8041 const [lastSave, setLastSave] = (0, import_element8.useState)(null); 8042 (0, import_element8.useEffect)(() => { 8043 if (null === postId || null === postType) { 8044 setLastSave(null); 8045 return; 8046 } 8047 const awareness = getSyncManager()?.getAwareness( 8048 `postType/$postType}`, 8049 postId.toString() 8050 ); 8051 if (!awareness) { 8052 setLastSave(null); 8053 return; 8054 } 8055 awareness.setUp(); 8056 const stateMap = awareness.doc.getMap("state"); 8057 const recordMap = awareness.doc.getMap("document"); 8058 const setupTime = Date.now(); 8059 const observer = (event) => { 8060 if (event.keysChanged.has("savedAt")) { 8061 const savedAt = stateMap.get("savedAt"); 8062 const savedByClientId = stateMap.get("savedBy"); 8063 if (typeof savedAt === "number" && typeof savedByClientId === "number" && savedAt > setupTime) { 8064 const postStatus = recordMap.get("status"); 8065 setLastSave({ savedAt, savedByClientId, postStatus }); 8066 } 8067 } 8068 }; 8069 stateMap.observe(observer); 8070 return () => { 8071 stateMap.unobserve(observer); 8072 }; 8073 }, [postId, postType]); 8074 return lastSave; 8075 } 8076 function useOnCollaboratorJoin(postId, postType, callback) { 8077 const { activeCollaborators } = usePostEditorAwarenessState( 8078 postId, 8079 postType 8080 ); 8081 const prevCollaborators = (0, import_compose3.usePrevious)(activeCollaborators); 8082 (0, import_element8.useEffect)(() => { 8083 if (!prevCollaborators || prevCollaborators.length === 0) { 8084 return; 8085 } 8086 const prevMap = new Map( 8087 prevCollaborators.map((collaborator) => [ 8088 collaborator.clientId, 8089 collaborator 8090 ]) 8091 ); 8092 const me = activeCollaborators.find( 8093 (collaborator) => collaborator.isMe 8094 ); 8095 for (const collaborator of activeCollaborators) { 8096 if (!prevMap.has(collaborator.clientId) && !collaborator.isMe) { 8097 callback(collaborator, me); 8098 } 8099 } 8100 }, [activeCollaborators, prevCollaborators, callback]); 8101 } 8102 function useOnCollaboratorLeave(postId, postType, callback) { 8103 const { activeCollaborators } = usePostEditorAwarenessState( 8104 postId, 8105 postType 8106 ); 8107 const prevCollaborators = (0, import_compose3.usePrevious)(activeCollaborators); 8108 (0, import_element8.useEffect)(() => { 8109 if (!prevCollaborators || prevCollaborators.length === 0) { 8110 return; 8111 } 8112 const newMap = new Map( 8113 activeCollaborators.map((collaborator) => [ 8114 collaborator.clientId, 8115 collaborator 8116 ]) 8117 ); 8118 for (const prevCollab of prevCollaborators) { 8119 if (prevCollab.isMe || !prevCollab.isConnected) { 8120 continue; 8121 } 8122 const newCollab = newMap.get(prevCollab.clientId); 8123 if (!newCollab?.isConnected) { 8124 callback(prevCollab); 8125 } 8126 } 8127 }, [activeCollaborators, prevCollaborators, callback]); 8128 } 8129 function useOnPostSave(postId, postType, callback) { 8130 const { activeCollaborators } = usePostEditorAwarenessState( 8131 postId, 8132 postType 8133 ); 8134 const lastPostSave = useLastPostSave(postId, postType); 8135 const prevPostSave = (0, import_compose3.usePrevious)(lastPostSave); 8136 (0, import_element8.useEffect)(() => { 8137 if (!lastPostSave) { 8138 return; 8139 } 8140 if (prevPostSave && lastPostSave.savedAt === prevPostSave.savedAt) { 8141 return; 8142 } 8143 const saver = activeCollaborators.find( 8144 (collaborator) => collaborator.clientId === lastPostSave.savedByClientId && !collaborator.isMe 8145 ); 8146 if (!saver) { 8147 return; 8148 } 8149 callback(lastPostSave, saver, prevPostSave ?? null); 8150 }, [lastPostSave, prevPostSave, activeCollaborators, callback]); 8151 } 8152 8153 // packages/core-data/build-module/private-apis.mjs 8154 var lockedApis = { 8155 useEntityRecordsWithPermissions, 8156 RECEIVE_INTERMEDIATE_RESULTS, 8157 retrySyncConnection, 8158 useActiveCollaborators, 8159 useResolvedSelection, 8160 useOnCollaboratorJoin, 8161 useOnCollaboratorLeave, 8162 useOnPostSave, 8163 SelectionType, 8164 SelectionDirection 8165 }; 8166 var privateApis = {}; 8167 lock(privateApis, lockedApis); 8168 8169 // packages/core-data/build-module/index.mjs 8170 var entitiesConfig2 = [ 8171 ...rootEntitiesConfig, 8172 ...additionalEntityConfigLoaders.filter((config) => !!config.name) 8173 ]; 8174 var entitySelectors = entitiesConfig2.reduce((result, entity2) => { 8175 const { kind, name, plural } = entity2; 8176 const getEntityRecordMethodName = getMethodName(kind, name); 8177 result[getEntityRecordMethodName] = (state, key, query) => { 8178 logEntityDeprecation(kind, name, getEntityRecordMethodName, { 8179 isShorthandSelector: true, 8180 alternativeFunctionName: "getEntityRecord" 8181 }); 8182 return getEntityRecord(state, kind, name, key, query); 8183 }; 8184 if (plural) { 8185 const getEntityRecordsMethodName = getMethodName(kind, plural, "get"); 8186 result[getEntityRecordsMethodName] = (state, query) => { 8187 logEntityDeprecation(kind, name, getEntityRecordsMethodName, { 8188 isShorthandSelector: true, 8189 alternativeFunctionName: "getEntityRecords" 8190 }); 8191 return getEntityRecords(state, kind, name, query); 8192 }; 8193 } 8194 return result; 8195 }, {}); 8196 var entityResolvers = entitiesConfig2.reduce((result, entity2) => { 8197 const { kind, name, plural } = entity2; 8198 const getEntityRecordMethodName = getMethodName(kind, name); 8199 result[getEntityRecordMethodName] = (key, query) => { 8200 logEntityDeprecation(kind, name, getEntityRecordMethodName, { 8201 isShorthandSelector: true, 8202 alternativeFunctionName: "getEntityRecord" 8203 }); 8204 return getEntityRecord2(kind, name, key, query); 8205 }; 8206 if (plural) { 8207 const getEntityRecordsMethodName = getMethodName(kind, plural, "get"); 8208 result[getEntityRecordsMethodName] = (...args) => { 8209 logEntityDeprecation(kind, plural, getEntityRecordsMethodName, { 8210 isShorthandSelector: true, 8211 alternativeFunctionName: "getEntityRecords" 8212 }); 8213 return getEntityRecords2(kind, name, ...args); 8214 }; 8215 result[getEntityRecordsMethodName].shouldInvalidate = (action) => getEntityRecords2.shouldInvalidate(action, kind, name); 8216 } 8217 return result; 8218 }, {}); 8219 var entityActions = entitiesConfig2.reduce((result, entity2) => { 8220 const { kind, name } = entity2; 8221 const saveEntityRecordMethodName = getMethodName(kind, name, "save"); 8222 result[saveEntityRecordMethodName] = (record, options) => { 8223 logEntityDeprecation(kind, name, saveEntityRecordMethodName, { 8224 isShorthandSelector: true, 8225 alternativeFunctionName: "saveEntityRecord" 8226 }); 8227 return saveEntityRecord(kind, name, record, options); 8228 }; 8229 const deleteEntityRecordMethodName = getMethodName(kind, name, "delete"); 8230 result[deleteEntityRecordMethodName] = (key, query, options) => { 8231 logEntityDeprecation(kind, name, deleteEntityRecordMethodName, { 8232 isShorthandSelector: true, 8233 alternativeFunctionName: "deleteEntityRecord" 8234 }); 8235 return deleteEntityRecord(kind, name, key, query, options); 8236 }; 8237 return result; 8238 }, {}); 8239 var storeConfig = () => ({ 8240 reducer: reducer_default2, 8241 actions: { 8242 ...dynamicActions, 8243 ...actions_exports, 8244 ...entityActions, 8245 ...createLocksActions() 8246 }, 8247 selectors: { 8248 ...dynamicSelectors, 8249 ...selectors_exports, 8250 ...entitySelectors 8251 }, 8252 resolvers: { ...resolvers_exports, ...entityResolvers } 8253 }); 8254 var store = (0, import_data15.createReduxStore)(STORE_NAME, storeConfig()); 8255 unlock(store).registerPrivateSelectors(private_selectors_exports); 8256 unlock(store).registerPrivateActions(private_actions_exports); 8257 (0, import_data15.register)(store); 8258 return __toCommonJS(index_exports); 8259 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Sun Aug 2 08:20:19 2026 | Cross-referenced by PHPXref |