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

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