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

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

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