PluginProbe
Gutenberg / 23.7.2
Gutenberg v23.7.2
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / build / scripts / core-data / index.js

index.js in Gutenberg 23.7.2, at build/scripts/core-data/index.js

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