PluginProbe
Gutenberg / 23.3.1
Gutenberg v23.3.1
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.3.1, at build/scripts/core-data/index.js

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