PluginProbe
Gutenberg / 24.1.0
Gutenberg v24.1.0
24.1.0 24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 All 404 releases
← All changes | build/scripts/core-data/index.js +2211 -898 23.1.0 → 24.1.0 View file →
@@ -1,4 +1,5 @@
1 +(function() {
1 2 "use strict";
2 3 var wp;
3 4 (wp ||= {}).coreData = (() => {
4 5 var __create = Object.create;
@@ -108,8 +109,29 @@
108 109 module.exports = window.wp.undoManager;
109 110 }
110 111 });
111 112
113 + // package-external:@wordpress/api-fetch
114 + var require_api_fetch = __commonJS({
115 + "package-external:@wordpress/api-fetch"(exports, module) {
116 + module.exports = window.wp.apiFetch;
117 + }
118 + });
119 +
120 + // package-external:@wordpress/sync
121 + var require_sync = __commonJS({
122 + "package-external:@wordpress/sync"(exports, module) {
123 + module.exports = window.wp.sync;
124 + }
125 + });
126 +
127 + // package-external:@wordpress/private-apis
128 + var require_private_apis = __commonJS({
129 + "package-external:@wordpress/private-apis"(exports, module) {
130 + module.exports = window.wp.privateApis;
131 + }
132 + });
133 +
112 134 // node_modules/equivalent-key-map/equivalent-key-map.js
113 135 var require_equivalent_key_map = __commonJS({
114 136 "node_modules/equivalent-key-map/equivalent-key-map.js"(exports, module) {
115 137 "use strict";
@@ -328,15 +350,8 @@
328 350 module.exports = window.wp.url;
329 351 }
330 352 });
331 353
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 354 // package-external:@wordpress/blocks
340 355 var require_blocks = __commonJS({
341 356 "package-external:@wordpress/blocks"(exports, module) {
342 357 module.exports = window.wp.blocks;
@@ -349,15 +364,8 @@
349 364 module.exports = window.wp.i18n;
350 365 }
351 366 });
352 367
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 368 // package-external:@wordpress/block-editor
361 369 var require_block_editor = __commonJS({
362 370 "package-external:@wordpress/block-editor"(exports, module) {
363 371 module.exports = window.wp.blockEditor;
@@ -370,15 +378,8 @@
370 378 module.exports = window.wp.richText;
371 379 }
372 380 });
373 381
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 382 // package-external:@wordpress/deprecated
382 383 var require_deprecated = __commonJS({
383 384 "package-external:@wordpress/deprecated"(exports, module) {
384 385 module.exports = window.wp.deprecated;
@@ -384,8 +385,15 @@
384 385 module.exports = window.wp.deprecated;
385 386 }
386 387 });
387 388
389 + // package-external:@wordpress/notices
390 + var require_notices = __commonJS({
391 + "package-external:@wordpress/notices"(exports, module) {
392 + module.exports = window.wp.notices;
393 + }
394 + });
395 +
388 396 // package-external:@wordpress/html-entities
389 397 var require_html_entities = __commonJS({
390 398 "package-external:@wordpress/html-entities"(exports, module) {
391 399 module.exports = window.wp.htmlEntities;
@@ -412,14 +420,26 @@
412 420 module.exports = window.wp.warning;
413 421 }
414 422 });
415 423
424 + // package-external:@wordpress/primitives
425 + var require_primitives = __commonJS({
426 + "package-external:@wordpress/primitives"(exports, module) {
427 + module.exports = window.wp.primitives;
428 + }
429 + });
430 +
431 + // package-external:@wordpress/components
432 + var require_components = __commonJS({
433 + "package-external:@wordpress/components"(exports, module) {
434 + module.exports = window.wp.components;
435 + }
436 + });
437 +
416 438 // packages/core-data/build-module/index.mjs
417 439 var index_exports = {};
418 440 __export(index_exports, {
419 441 EntityProvider: () => EntityProvider,
420 - SelectionDirection: () => SelectionDirection,
421 - SelectionType: () => SelectionType,
422 442 __experimentalFetchLinkSuggestions: () => fetchLinkSuggestions,
423 443 __experimentalFetchUrlData: () => experimental_fetch_url_data_default,
424 444 __experimentalUseEntityRecord: () => useDeprecatedEntityRecord,
425 445 __experimentalUseEntityRecords: () => useDeprecatedEntityRecords,
@@ -433,18 +453,35 @@
433 453 useEntityRecord: () => useEntityRecord,
434 454 useEntityRecords: () => useEntityRecords,
435 455 useResourcePermissions: () => use_resource_permissions_default
436 456 });
437 - var import_data15 = __toESM(require_data(), 1);
457 + var import_data20 = __toESM(require_data(), 1);
438 458
439 459 // packages/core-data/build-module/reducer.mjs
440 - var import_es64 = __toESM(require_es6(), 1);
460 + var import_es65 = __toESM(require_es6(), 1);
441 461 var import_compose2 = __toESM(require_compose(), 1);
442 462 var import_data7 = __toESM(require_data(), 1);
443 463 var import_undo_manager = __toESM(require_undo_manager(), 1);
444 464
465 + // packages/core-data/build-module/utils/clear-unchanged-edits.mjs
466 + var import_es6 = __toESM(require_es6(), 1);
467 + function clearUnchangedEdits(edits, persistedRecord) {
468 + if (!persistedRecord) {
469 + return edits;
470 + }
471 + return Object.fromEntries(
472 + Object.entries(edits).map(([key, value]) => {
473 + const persisted = persistedRecord[key]?.raw ?? persistedRecord[key];
474 + return [
475 + key,
476 + (0, import_es6.default)(value, persisted) ? void 0 : value
477 + ];
478 + })
479 + );
480 + }
481 +
445 482 // packages/core-data/build-module/utils/conservative-map-item.mjs
446 - var import_es6 = __toESM(require_es6(), 1);
483 + var import_es62 = __toESM(require_es6(), 1);
447 484 function conservativeMapItem(item, nextItem) {
448 485 if (!item) {
449 486 return nextItem;
450 487 }
@@ -450,9 +487,9 @@
450 487 }
451 488 let hasChanges = false;
452 489 const result = {};
453 490 for (const key in nextItem) {
454 - if ((0, import_es6.default)(item[key], nextItem[key])) {
491 + if ((0, import_es62.default)(item[key], nextItem[key])) {
455 492 result[key] = item[key];
456 493 } else {
457 494 hasChanges = true;
458 495 result[key] = nextItem[key];
@@ -479,8 +516,58 @@
479 516 return null;
480 517 }
481 518 var get_normalized_comma_separable_default = getNormalizedCommaSeparable;
482 519
520 + // packages/core-data/build-module/utils/set-nested-value.mjs
521 + function setNestedValue(object, path, value) {
522 + if (!object || typeof object !== "object") {
523 + return object;
524 + }
525 + const normalizedPath = Array.isArray(path) ? path : path.split(".");
526 + normalizedPath.reduce((acc, key, idx) => {
527 + if (acc[key] === void 0) {
528 + if (Number.isInteger(normalizedPath[idx + 1])) {
529 + acc[key] = [];
530 + } else {
531 + acc[key] = {};
532 + }
533 + }
534 + if (idx === normalizedPath.length - 1) {
535 + acc[key] = value;
536 + }
537 + return acc[key];
538 + }, object);
539 + return object;
540 + }
541 +
542 + // packages/core-data/build-module/utils/get-filtered-item.mjs
543 + var filteredItemCache = /* @__PURE__ */ new WeakMap();
544 + function getFilteredItem(item, _fields) {
545 + const fields = get_normalized_comma_separable_default(_fields) ?? [];
546 + const fieldsKey = fields.join(",");
547 + let itemCache = filteredItemCache.get(item);
548 + if (itemCache) {
549 + const filtered = itemCache.get(fieldsKey);
550 + if (filtered !== void 0) {
551 + return filtered;
552 + }
553 + } else if (item !== null && typeof item === "object") {
554 + itemCache = /* @__PURE__ */ new Map();
555 + filteredItemCache.set(item, itemCache);
556 + }
557 + const filteredItem = {};
558 + for (let f = 0; f < fields.length; f++) {
559 + const field = fields[f].split(".");
560 + let value = item;
561 + field.forEach((fieldName) => {
562 + value = value?.[fieldName];
563 + });
564 + setNestedValue(filteredItem, field, value);
565 + }
566 + itemCache?.set(fieldsKey, filteredItem);
567 + return filteredItem;
568 + }
569 +
483 570 // packages/core-data/build-module/utils/if-matching-action.mjs
484 571 var ifMatchingAction = (isMatch) => (reducer) => (state, action) => {
485 572 if (state === void 0 || isMatch(action)) {
486 573 return reducer(state, action);
@@ -518,30 +605,8 @@
518 605 };
519 606 }
520 607 var with_weak_map_cache_default = withWeakMapCache;
521 608
522 - // packages/core-data/build-module/utils/set-nested-value.mjs
523 - function setNestedValue(object, path, value) {
524 - if (!object || typeof object !== "object") {
525 - return object;
526 - }
527 - const normalizedPath = Array.isArray(path) ? path : path.split(".");
528 - normalizedPath.reduce((acc, key, idx) => {
529 - if (acc[key] === void 0) {
530 - if (Number.isInteger(normalizedPath[idx + 1])) {
531 - acc[key] = [];
532 - } else {
533 - acc[key] = {};
534 - }
535 - }
536 - if (idx === normalizedPath.length - 1) {
537 - acc[key] = value;
538 - }
539 - return acc[key];
540 - }, object);
541 - return object;
542 - }
543 -
544 609 // packages/core-data/build-module/utils/get-nested-value.mjs
545 610 function getNestedValue(object, path, defaultValue) {
546 611 if (!object || typeof object !== "object" || typeof path !== "string" && !Array.isArray(path)) {
547 612 return object;
@@ -599,8 +664,112 @@
599 664 );
600 665 return entries.length > 0 ? Object.fromEntries(entries) : void 0;
601 666 }
602 667
668 + // packages/core-data/build-module/utils/save-crdt-doc.mjs
669 + var import_api_fetch = __toESM(require_api_fetch(), 1);
670 +
671 + // packages/core-data/build-module/sync.mjs
672 + var import_sync = __toESM(require_sync(), 1);
673 +
674 + // packages/core-data/build-module/lock-unlock.mjs
675 + var import_private_apis = __toESM(require_private_apis(), 1);
676 + var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)(
677 + "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.",
678 + "@wordpress/core-data"
679 + );
680 +
681 + // packages/core-data/build-module/sync.mjs
682 + var {
683 + ConnectionErrorCode,
684 + createSyncManager,
685 + Delta,
686 + CRDT_DOC_META_PERSISTENCE_KEY,
687 + CRDT_RECORD_MAP_KEY,
688 + LOCAL_EDITOR_ORIGIN,
689 + LOCAL_UNDO_IGNORED_ORIGIN,
690 + retrySyncConnection
691 + } = unlock(import_sync.privateApis);
692 + var CRDT_AUTOSAVE_SNAPSHOT_KEY = "crdt_snapshot";
693 + var syncManager;
694 + function getSyncManager() {
695 + if (syncManager) {
696 + return syncManager;
697 + }
698 + if (!globalThis.window?.__experimentalEnableRealTimeCollaboration) {
699 + return void 0;
700 + }
701 + syncManager = createSyncManager();
702 + return syncManager;
703 + }
704 + function hasSyncManager() {
705 + return Boolean(syncManager);
706 + }
707 + function getEntitySnapshot(kind, name, recordId) {
708 + if (!hasSyncManager()) {
709 + return void 0;
710 + }
711 + return getSyncManager()?.getEntitySnapshot(
712 + `${kind}/${name}`,
713 + `${recordId}`
714 + );
715 + }
716 + function entityContainsSnapshot(kind, name, recordId, encodedSnapshot) {
717 + if (!hasSyncManager()) {
718 + return false;
719 + }
720 + return getSyncManager()?.entityContainsSnapshot(
721 + `${kind}/${name}`,
722 + `${recordId}`,
723 + encodedSnapshot
724 + ) ?? false;
725 + }
726 +
727 + // packages/core-data/build-module/utils/save-crdt-doc.mjs
728 + var SYNC_SAVE_API_PATH = "/wp-sync/v1/save";
729 + var saveCRDTDocQueues = /* @__PURE__ */ new Map();
730 + async function serializeAndSaveCRDTDoc(objectType, objectId, room) {
731 + const serializedDoc = await getSyncManager()?.createPersistedCRDTDoc(
732 + objectType,
733 + objectId
734 + );
735 + if (!serializedDoc) {
736 + return;
737 + }
738 + await (0, import_api_fetch.default)({
739 + path: SYNC_SAVE_API_PATH,
740 + method: "POST",
741 + data: {
742 + room,
743 + doc: serializedDoc
744 + }
745 + });
746 + }
747 + async function saveCRDTDoc(objectType, objectId) {
748 + const room = `${objectType}:${objectId}`;
749 + const previousSave = saveCRDTDocQueues.get(room) || Promise.resolve();
750 + const currentSave = previousSave.catch(() => {
751 + }).then(() => serializeAndSaveCRDTDoc(objectType, objectId, room));
752 + saveCRDTDocQueues.set(room, currentSave);
753 + try {
754 + await currentSave;
755 + } finally {
756 + if (saveCRDTDocQueues.get(room) === currentSave) {
757 + saveCRDTDocQueues.delete(room);
758 + }
759 + }
760 + }
761 +
762 + // packages/core-data/build-module/utils/get-pagination-meta.mjs
763 + function getPaginationMeta(headers) {
764 + const totalItems = parseInt(headers.get("X-WP-Total") ?? "");
765 + const totalPages = parseInt(headers.get("X-WP-TotalPages") ?? "");
766 + return {
767 + totalItems: Number.isFinite(totalItems) ? totalItems : null,
768 + totalPages: Number.isFinite(totalPages) ? totalPages : null
769 + };
770 + }
771 +
603 772 // packages/core-data/build-module/queried-data/actions.mjs
604 773 function receiveItems(items2, edits, meta) {
605 774 return {
606 775 type: "RECEIVE_ITEMS",
@@ -855,15 +1024,15 @@
855 1024 return noCase(input, __assign({ delimiter: " ", transform: capitalCaseTransform }, options));
856 1025 }
857 1026
858 1027 // packages/core-data/build-module/entities.mjs
859 - var import_api_fetch = __toESM(require_api_fetch(), 1);
1028 + var import_api_fetch2 = __toESM(require_api_fetch(), 1);
860 1029 var import_blocks4 = __toESM(require_blocks(), 1);
861 1030 var import_i18n = __toESM(require_i18n(), 1);
862 1031
863 1032 // packages/core-data/build-module/awareness/post-editor-awareness.mjs
864 1033 var import_data4 = __toESM(require_data(), 1);
865 - var import_sync8 = __toESM(require_sync(), 1);
1034 + var import_sync9 = __toESM(require_sync(), 1);
866 1035 var import_block_editor3 = __toESM(require_block_editor(), 1);
867 1036
868 1037 // packages/core-data/build-module/awareness/base-awareness.mjs
869 1038 var import_data = __toESM(require_data(), 1);
@@ -873,9 +1042,9 @@
873 1042 var LOCAL_CURSOR_UPDATE_DEBOUNCE_IN_MS = 5;
874 1043 var REMOVAL_DELAY_IN_MS = 5e3;
875 1044
876 1045 // packages/core-data/build-module/awareness/typed-awareness.mjs
877 - var import_sync = __toESM(require_sync(), 1);
1046 + var import_sync3 = __toESM(require_sync(), 1);
878 1047
879 1048 // packages/core-data/build-module/awareness/utils.mjs
880 1049 function getBrowserName() {
881 1050 const userAgent = window.navigator.userAgent;
@@ -919,18 +1088,49 @@
919 1088 return Object.entries(collaboratorInfo1).every(([key, value]) => {
920 1089 return value === collaboratorInfo2[key];
921 1090 });
922 1091 }
923 - function generateCollaboratorInfo(currentCollaborator) {
924 - const { avatar_urls, id, name, slug } = currentCollaborator;
1092 + function hasValidAvatarUrls(value) {
1093 + if ("object" !== typeof value || null === value || Array.isArray(value)) {
1094 + return false;
1095 + }
1096 + return ["24", "48", "96"].every(
1097 + (size) => !(size in value) || "string" === typeof value[size]
1098 + );
1099 + }
1100 + function isCollaboratorInfo(value) {
1101 + if ("object" !== typeof value || null === value) {
1102 + return false;
1103 + }
1104 + return "id" in value && "name" in value && "slug" in value && "browserType" in value && "enteredAt" in value && (null === value.id || "number" === typeof value.id && Number.isInteger(value.id) && value.id > 0) && "string" === typeof value.name && "" !== value.name.trim() && "string" === typeof value.slug && (!("avatar_urls" in value) || hasValidAvatarUrls(value.avatar_urls)) && "string" === typeof value.browserType && "number" === typeof value.enteredAt && Number.isFinite(value.enteredAt);
1105 + }
1106 + function generateCollaboratorInfo(currentCollaborator, clientId) {
1107 + const presentationInfo = {
1108 + browserType: getBrowserName(),
1109 + enteredAt: Date.now()
1110 + };
1111 + if ("object" === typeof currentCollaborator && currentCollaborator) {
1112 + const user = currentCollaborator;
1113 + if ("id" in user && "name" in user) {
1114 + const collaboratorInfo = {
1115 + ...presentationInfo,
1116 + ..."avatar_urls" in user && hasValidAvatarUrls(user.avatar_urls) ? { avatar_urls: user.avatar_urls } : {},
1117 + id: user.id,
1118 + name: user.name,
1119 + slug: "slug" in user && "string" === typeof user.slug ? user.slug : ""
1120 + };
1121 + if (isCollaboratorInfo(collaboratorInfo) && null !== collaboratorInfo.id) {
1122 + return collaboratorInfo;
1123 + }
1124 + }
1125 + }
925 1126 return {
926 - avatar_urls,
927 - // eslint-disable-line camelcase
928 - browserType: getBrowserName(),
929 - enteredAt: Date.now(),
930 - id,
931 - name,
932 - slug
1127 + ...presentationInfo,
1128 + id: null,
1129 + // Keep shared awareness data language-neutral. The editor localizes this
1130 + // fallback name for the viewer when it is displayed.
1131 + name: "Anonymous User",
1132 + slug: `anonymous-${clientId}`
933 1133 };
934 1134 }
935 1135 function getRecordValue(obj, key) {
936 1136 if ("object" === typeof obj && null !== obj && key in obj) {
@@ -942,9 +1142,9 @@
942 1142 return Object.keys(obj);
943 1143 }
944 1144
945 1145 // packages/core-data/build-module/awareness/typed-awareness.mjs
946 - var TypedAwareness = class extends import_sync.Awareness {
1146 + var TypedAwareness = class extends import_sync3.Awareness {
947 1147 /**
948 1148 * Get the states from an awareness document.
949 1149 */
950 1150 getStates() {
@@ -1215,11 +1415,17 @@
1215 1415 /**
1216 1416 * Set the current collaborator info in the local state.
1217 1417 */
1218 1418 async setCurrentCollaboratorInfo() {
1219 - const currentUser2 = await (0, import_data.resolveSelect)(STORE_NAME).getCurrentUser();
1220 - const collaboratorInfo = generateCollaboratorInfo(currentUser2);
1221 - this.setLocalStateField("collaboratorInfo", collaboratorInfo);
1419 + let currentUser2;
1420 + try {
1421 + currentUser2 = await (0, import_data.resolveSelect)(STORE_NAME).getCurrentUser();
1422 + } catch {
1423 + }
1424 + this.setLocalStateField(
1425 + "collaboratorInfo",
1426 + generateCollaboratorInfo(currentUser2, this.clientID)
1427 + );
1222 1428 }
1223 1429 };
1224 1430 var baseEqualityFieldChecks = {
1225 1431 collaboratorInfo: areCollaboratorInfosEqual
@@ -1229,16 +1435,27 @@
1229 1435 };
1230 1436
1231 1437 // packages/core-data/build-module/awareness/block-lookup.mjs
1232 1438 var import_data2 = __toESM(require_data(), 1);
1233 - var import_sync2 = __toESM(require_sync(), 1);
1439 + var import_sync4 = __toESM(require_sync(), 1);
1234 1440 var import_block_editor = __toESM(require_block_editor(), 1);
1441 + function getContainingBlockYMap(yType) {
1442 + let current = yType;
1443 + while (current) {
1444 + const parent = current.parent;
1445 + if (parent instanceof import_sync4.Y.Map && parent.parent instanceof import_sync4.Y.Array && parent.get("clientId") !== void 0 && parent.get("innerBlocks") instanceof import_sync4.Y.Array) {
1446 + return parent;
1447 + }
1448 + current = parent instanceof import_sync4.Y.AbstractType ? parent : null;
1449 + }
1450 + return null;
1451 + }
1235 1452 function getBlockPathInYdoc(yType) {
1236 1453 const path = [];
1237 1454 let current = yType;
1238 1455 while (current) {
1239 1456 const parentArray = current.parent;
1240 - if (!parentArray || !(parentArray instanceof import_sync2.Y.Array)) {
1457 + if (!parentArray || !(parentArray instanceof import_sync4.Y.Array)) {
1241 1458 return null;
1242 1459 }
1243 1460 let index = -1;
1244 1461 for (let i = 0; i < parentArray.length; i++) {
@@ -1251,9 +1468,9 @@
1251 1468 return null;
1252 1469 }
1253 1470 path.unshift(index);
1254 1471 const grandparent = parentArray.parent;
1255 - if (grandparent instanceof import_sync2.Y.Map && grandparent.get("clientId") !== void 0) {
1472 + if (grandparent instanceof import_sync4.Y.Map && grandparent.get("clientId") !== void 0) {
1256 1473 current = grandparent;
1257 1474 } else {
1258 1475 break;
1259 1476 }
@@ -1259,15 +1476,12 @@
1259 1476 }
1260 1477 }
1261 1478 return path;
1262 1479 }
1263 - function resolveBlockClientIdByPath(path) {
1480 + function resolveBlockClientIdByPath(path, blocks) {
1264 1481 if (path.length === 0) {
1265 1482 return null;
1266 1483 }
1267 - const { getBlocks } = (0, import_data2.select)(import_block_editor.store);
1268 - const postContentBlocks = getPostContentBlocks(getBlocks(), getBlocks);
1269 - let blocks = postContentBlocks;
1270 1484 for (let i = 0; i < path.length; i++) {
1271 1485 const block = blocks[path[i]];
1272 1486 if (!block) {
1273 1487 return null;
@@ -1278,78 +1492,61 @@
1278 1492 blocks = block.innerBlocks;
1279 1493 }
1280 1494 return null;
1281 1495 }
1282 - function getPostContentBlocks(rootBlocks, getBlocks) {
1283 - const postContentBlock = findBlockByName(rootBlocks, "core/post-content");
1284 - if (postContentBlock) {
1285 - return getBlocks(postContentBlock.clientId);
1286 - }
1287 - return rootBlocks;
1496 + function usePostContentBlocks() {
1497 + return (0, import_data2.useSelect)((select5) => {
1498 + const { getBlocksByName, getClientIdsTree } = unlock(
1499 + select5(import_block_editor.store)
1500 + );
1501 + const [postContentClientId] = getBlocksByName("core/post-content");
1502 + return getClientIdsTree(postContentClientId ?? "");
1503 + }, []);
1288 1504 }
1289 - function findBlockByName(blocks, name) {
1290 - for (const block of blocks) {
1291 - if (block.name === name) {
1292 - return block;
1293 - }
1294 - if (block.innerBlocks?.length) {
1295 - const found = findBlockByName(block.innerBlocks, name);
1296 - if (found) {
1297 - return found;
1298 - }
1299 - }
1300 - }
1301 - return null;
1302 - }
1303 1505
1304 1506 // packages/core-data/build-module/utils/crdt-utils.mjs
1305 - var import_sync4 = __toESM(require_sync(), 1);
1507 + var import_sync5 = __toESM(require_sync(), 1);
1306 1508 var import_rich_text = __toESM(require_rich_text(), 1);
1307 -
1308 - // packages/core-data/build-module/sync.mjs
1309 - var import_sync3 = __toESM(require_sync(), 1);
1310 -
1311 - // packages/core-data/build-module/lock-unlock.mjs
1312 - var import_private_apis = __toESM(require_private_apis(), 1);
1313 - var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)(
1314 - "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.",
1315 - "@wordpress/core-data"
1316 - );
1317 -
1318 - // packages/core-data/build-module/sync.mjs
1319 - var {
1320 - ConnectionErrorCode,
1321 - createSyncManager,
1322 - Delta,
1323 - CRDT_DOC_META_PERSISTENCE_KEY,
1324 - CRDT_RECORD_MAP_KEY,
1325 - LOCAL_EDITOR_ORIGIN,
1326 - LOCAL_UNDO_IGNORED_ORIGIN,
1327 - retrySyncConnection
1328 - } = unlock(import_sync3.privateApis);
1329 - var syncManager;
1330 - function getSyncManager() {
1331 - if (syncManager) {
1332 - return syncManager;
1333 - }
1334 - syncManager = createSyncManager();
1335 - return syncManager;
1336 - }
1337 -
1338 - // packages/core-data/build-module/utils/crdt-utils.mjs
1339 1509 function getRootMap(doc, key) {
1340 1510 return doc.getMap(key);
1341 1511 }
1342 1512 function createYMap(partial = {}) {
1343 - return new import_sync4.Y.Map(Object.entries(partial));
1513 + return new import_sync5.Y.Map(Object.entries(partial));
1344 1514 }
1345 1515 function isYMap(value) {
1346 - return value instanceof import_sync4.Y.Map;
1516 + return value instanceof import_sync5.Y.Map;
1347 1517 }
1518 + function asRichTextOffset(offset) {
1519 + return offset;
1520 + }
1521 + function asHtmlStringIndex(index) {
1522 + return index;
1523 + }
1524 + function getYTextByAttributeKey(attributes, attributeKey) {
1525 + const directValue = attributes.get(attributeKey);
1526 + if (directValue instanceof import_sync5.Y.Text) {
1527 + return directValue;
1528 + }
1529 + let value = attributes;
1530 + for (const pathPart of attributeKey.split(".")) {
1531 + if (value instanceof import_sync5.Y.Map) {
1532 + value = value.get(pathPart);
1533 + } else if (value instanceof import_sync5.Y.Array) {
1534 + const index = Number.parseInt(pathPart, 10);
1535 + if (!Number.isSafeInteger(index) || index < 0 || index.toString() !== pathPart) {
1536 + return null;
1537 + }
1538 + value = value.get(index);
1539 + } else {
1540 + return null;
1541 + }
1542 + }
1543 + return value instanceof import_sync5.Y.Text ? value : null;
1544 + }
1348 1545 function findBlockByClientIdInDoc(blockId, ydoc) {
1349 1546 const ymap = getRootMap(ydoc, CRDT_RECORD_MAP_KEY);
1350 1547 const blocks = ymap.get("blocks");
1351 - if (!(blocks instanceof import_sync4.Y.Array)) {
1548 + if (!(blocks instanceof import_sync5.Y.Array)) {
1352 1549 return null;
1353 1550 }
1354 1551 return findBlockByClientIdInBlocks(blockId, blocks);
1355 1552 }
@@ -1365,26 +1562,26 @@
1365 1562 return null;
1366 1563 }
1367 1564 function htmlIndexToRichTextOffset(html, htmlIndex) {
1368 1565 if (!html.includes("<") && !html.includes("&")) {
1369 - return htmlIndex;
1566 + return asRichTextOffset(htmlIndex);
1370 1567 }
1371 1568 const marker = pickMarker(html);
1372 1569 if (!marker) {
1373 - return htmlIndex;
1570 + return asRichTextOffset(htmlIndex);
1374 1571 }
1375 1572 const withMarker = html.slice(0, htmlIndex) + marker + html.slice(htmlIndex);
1376 1573 const value = (0, import_rich_text.create)({ html: withMarker });
1377 1574 const markerPos = value.text.indexOf(marker);
1378 - return markerPos === -1 ? htmlIndex : markerPos;
1575 + return asRichTextOffset(markerPos === -1 ? htmlIndex : markerPos);
1379 1576 }
1380 1577 function richTextOffsetToHtmlIndex(html, richTextOffset) {
1381 1578 if (!html.includes("<") && !html.includes("&")) {
1382 - return richTextOffset;
1579 + return asHtmlStringIndex(richTextOffset);
1383 1580 }
1384 1581 const marker = pickMarker(html);
1385 1582 if (!marker) {
1386 - return richTextOffset;
1583 + return asHtmlStringIndex(richTextOffset);
1387 1584 }
1388 1585 const value = (0, import_rich_text.create)({ html });
1389 1586 const markerValue = (0, import_rich_text.create)({ text: marker });
1390 1587 if (value.formats[richTextOffset]) {
@@ -1397,9 +1594,11 @@
1397 1594 richTextOffset
1398 1595 );
1399 1596 const htmlWithMarker = (0, import_rich_text.toHTMLString)({ value: withMarker });
1400 1597 const markerIndex = htmlWithMarker.indexOf(marker);
1401 - return markerIndex === -1 ? richTextOffset : markerIndex;
1598 + return asHtmlStringIndex(
1599 + markerIndex === -1 ? richTextOffset : markerIndex
1600 + );
1402 1601 }
1403 1602 function findBlockByClientIdInBlocks(blockId, blocks) {
1404 1603 for (const block of blocks) {
1405 1604 if (block.get("clientId") === blockId) {
@@ -1420,9 +1619,9 @@
1420 1619 }
1421 1620
1422 1621 // packages/core-data/build-module/utils/crdt-user-selections.mjs
1423 1622 var import_data3 = __toESM(require_data(), 1);
1424 - var import_sync6 = __toESM(require_sync(), 1);
1623 + var import_sync7 = __toESM(require_sync(), 1);
1425 1624 var import_block_editor2 = __toESM(require_block_editor(), 1);
1426 1625 var SelectionType = /* @__PURE__ */ ((SelectionType2) => {
1427 1626 SelectionType2["None"] = "none";
1428 1627 SelectionType2["Cursor"] = "cursor";
@@ -1430,8 +1629,13 @@
1430 1629 SelectionType2["SelectionInMultipleBlocks"] = "selection-in-multiple-blocks";
1431 1630 SelectionType2["WholeBlock"] = "whole-block";
1432 1631 return SelectionType2;
1433 1632 })(SelectionType || {});
1633 + var SelectionDirection = /* @__PURE__ */ ((SelectionDirection2) => {
1634 + SelectionDirection2["Forward"] = "f";
1635 + SelectionDirection2["Backward"] = "b";
1636 + return SelectionDirection2;
1637 + })(SelectionDirection || {});
1434 1638 function getSelectionState(selectionStart, selectionEnd, yDoc, options) {
1435 1639 const { selectionDirection } = options ?? {};
1436 1640 const ymap = getRootMap(yDoc, CRDT_RECORD_MAP_KEY);
1437 1641 const yBlocks = ymap.get("blocks");
@@ -1465,32 +1669,32 @@
1465 1669 type: "cursor",
1466 1670 cursorPosition
1467 1671 };
1468 1672 } else if (isSelectionInOneBlock) {
1469 - const cursorStartPosition2 = getCursorPosition(
1673 + const cursorStartPosition = getCursorPosition(
1470 1674 selectionStart,
1471 1675 yBlocks
1472 1676 );
1473 - const cursorEndPosition2 = getCursorPosition(selectionEnd, yBlocks);
1474 - if (!cursorStartPosition2 || !cursorEndPosition2) {
1677 + const cursorEndPosition = getCursorPosition(selectionEnd, yBlocks);
1678 + if (!cursorStartPosition || !cursorEndPosition) {
1475 1679 return noSelection;
1476 1680 }
1477 1681 return {
1478 1682 type: "selection-in-one-block",
1479 - cursorStartPosition: cursorStartPosition2,
1480 - cursorEndPosition: cursorEndPosition2,
1683 + cursorStartPosition,
1684 + cursorEndPosition,
1481 1685 selectionDirection
1482 1686 };
1483 1687 }
1484 - const cursorStartPosition = getCursorPosition(selectionStart, yBlocks);
1485 - const cursorEndPosition = getCursorPosition(selectionEnd, yBlocks);
1486 - if (!cursorStartPosition || !cursorEndPosition) {
1688 + const startEndpoint = getSelectionEndpoint(selectionStart, yBlocks);
1689 + const endEndpoint = getSelectionEndpoint(selectionEnd, yBlocks);
1690 + if (!startEndpoint || !endEndpoint) {
1487 1691 return noSelection;
1488 1692 }
1489 1693 return {
1490 1694 type: "selection-in-multiple-blocks",
1491 - cursorStartPosition,
1492 - cursorEndPosition,
1695 + startEndpoint,
1696 + endEndpoint,
1493 1697 selectionDirection
1494 1698 };
1495 1699 }
1496 1700 function getCursorPosition(selection, blocks) {
@@ -1499,21 +1703,37 @@
1499 1703 if (!block || !selection.attributeKey || void 0 === selection.offset) {
1500 1704 return null;
1501 1705 }
1502 1706 const attributes = block.get("attributes");
1503 - const currentYText = attributes?.get(selection.attributeKey);
1504 - if (!(currentYText instanceof import_sync6.Y.Text)) {
1707 + const currentYText = attributes ? getYTextByAttributeKey(attributes, selection.attributeKey) : null;
1708 + if (!(currentYText instanceof import_sync7.Y.Text)) {
1505 1709 return null;
1506 1710 }
1507 - const relativePosition = import_sync6.Y.createRelativePositionFromTypeIndex(
1711 + const relativePosition = import_sync7.Y.createRelativePositionFromTypeIndex(
1508 1712 currentYText,
1509 - richTextOffsetToHtmlIndex(currentYText.toString(), selection.offset)
1713 + richTextOffsetToHtmlIndex(
1714 + currentYText.toString(),
1715 + asRichTextOffset(selection.offset)
1716 + )
1510 1717 );
1511 1718 return {
1512 1719 relativePosition,
1513 - absoluteOffset: selection.offset
1720 + absoluteOffset: selection.offset,
1721 + attributeKey: selection.attributeKey
1514 1722 };
1515 1723 }
1724 + function getSelectionEndpoint(selection, blocks) {
1725 + const cursorPosition = getCursorPosition(selection, blocks);
1726 + if (cursorPosition) {
1727 + return { type: "cursor", cursorPosition };
1728 + }
1729 + const path = getBlockPathForLocalClientId(selection.clientId);
1730 + const blockPosition = path ? createRelativePositionForBlockPath(path, blocks) : null;
1731 + if (blockPosition) {
1732 + return { type: "whole-block", blockPosition };
1733 + }
1734 + return null;
1735 + }
1516 1736 function getBlockPathForLocalClientId(clientId) {
1517 1737 const { getBlockIndex, getBlockRootClientId, getBlockName } = (0, import_data3.select)(import_block_editor2.store);
1518 1738 const path = [];
1519 1739 let current = clientId;
@@ -1547,9 +1767,9 @@
1547 1767 }
1548 1768 if (i === path.length - 1) {
1549 1769 return block;
1550 1770 }
1551 - currentBlocks = block.get("innerBlocks") ?? new import_sync6.Y.Array();
1771 + currentBlocks = block.get("innerBlocks") ?? new import_sync7.Y.Array();
1552 1772 }
1553 1773 return null;
1554 1774 }
1555 1775 function createRelativePositionForBlockPath(path, blocks) {
@@ -1558,15 +1778,15 @@
1558 1778 if (path[i] >= currentBlocks.length) {
1559 1779 return null;
1560 1780 }
1561 1781 if (i === path.length - 1) {
1562 - return import_sync6.Y.createRelativePositionFromTypeIndex(
1782 + return import_sync7.Y.createRelativePositionFromTypeIndex(
1563 1783 currentBlocks,
1564 1784 path[i]
1565 1785 );
1566 1786 }
1567 1787 const block = currentBlocks.get(path[i]);
1568 - currentBlocks = block?.get("innerBlocks") ?? new import_sync6.Y.Array();
1788 + currentBlocks = block?.get("innerBlocks") ?? new import_sync7.Y.Array();
1569 1789 }
1570 1790 return null;
1571 1791 }
1572 1792 function areSelectionsStatesEqual(selection1, selection2) {
@@ -1589,17 +1809,17 @@
1589 1809 selection1.cursorEndPosition,
1590 1810 selection2.cursorEndPosition
1591 1811 ) && selection1.selectionDirection === selection2.selectionDirection;
1592 1812 case "selection-in-multiple-blocks":
1593 - return areCursorPositionsEqual(
1594 - selection1.cursorStartPosition,
1595 - selection2.cursorStartPosition
1596 - ) && areCursorPositionsEqual(
1597 - selection1.cursorEndPosition,
1598 - selection2.cursorEndPosition
1813 + return areEndpointsEqual(
1814 + selection1.startEndpoint,
1815 + selection2.startEndpoint
1816 + ) && areEndpointsEqual(
1817 + selection1.endEndpoint,
1818 + selection2.endEndpoint
1599 1819 ) && selection1.selectionDirection === selection2.selectionDirection;
1600 1820 case "whole-block":
1601 - return import_sync6.Y.compareRelativePositions(
1821 + return import_sync7.Y.compareRelativePositions(
1602 1822 selection1.blockPosition,
1603 1823 selection2.blockPosition
1604 1824 );
1605 1825 default:
@@ -1605,10 +1825,25 @@
1605 1825 default:
1606 1826 return false;
1607 1827 }
1608 1828 }
1829 + function areEndpointsEqual(ep1, ep2) {
1830 + if (ep1.type !== ep2.type) {
1831 + return false;
1832 + }
1833 + if (ep1.type === "cursor" && ep2.type === "cursor") {
1834 + return areCursorPositionsEqual(
1835 + ep1.cursorPosition,
1836 + ep2.cursorPosition
1837 + );
1838 + }
1839 + return import_sync7.Y.compareRelativePositions(
1840 + ep1.blockPosition,
1841 + ep2.blockPosition
1842 + );
1843 + }
1609 1844 function areCursorPositionsEqual(cursorPosition1, cursorPosition2) {
1610 - const isRelativePositionEqual = import_sync6.Y.compareRelativePositions(
1845 + const isRelativePositionEqual = import_sync7.Y.compareRelativePositions(
1611 1846 cursorPosition1.relativePosition,
1612 1847 cursorPosition2.relativePosition
1613 1848 );
1614 1849 const isAbsoluteOffsetEqual = cursorPosition1.absoluteOffset === cursorPosition2.absoluteOffset;
@@ -1614,15 +1849,8 @@
1614 1849 const isAbsoluteOffsetEqual = cursorPosition1.absoluteOffset === cursorPosition2.absoluteOffset;
1615 1850 return isRelativePositionEqual && isAbsoluteOffsetEqual;
1616 1851 }
1617 1852
1618 - // packages/core-data/build-module/types.mjs
1619 - var SelectionDirection = /* @__PURE__ */ ((SelectionDirection2) => {
1620 - SelectionDirection2["Forward"] = "f";
1621 - SelectionDirection2["Backward"] = "b";
1622 - return SelectionDirection2;
1623 - })(SelectionDirection || {});
1624 -
1625 1853 // packages/core-data/build-module/awareness/post-editor-awareness.mjs
1626 1854 var PostEditorAwareness = class extends BaseAwarenessState {
1627 1855 constructor(doc, kind, name, postId) {
1628 1856 super(doc);
@@ -1750,47 +1978,68 @@
1750 1978 * from the Yjs block because the local block-editor store may use different
1751 1979 * clientIds (e.g. in "Show Template" mode where blocks are cloned).
1752 1980 *
1753 1981 * @param selection - The selection state.
1982 + * @param blocks - The tree of block-editor store post content blocks.
1754 1983 * @return The rich-text offset and block client ID, or nulls if not resolvable.
1755 1984 */
1756 - convertSelectionStateToAbsolute(selection) {
1985 + convertSelectionStateToAbsolute(selection, blocks) {
1757 1986 if (selection.type === SelectionType.None) {
1758 - return { richTextOffset: null, localClientId: null };
1987 + return {
1988 + richTextOffset: null,
1989 + localClientId: null,
1990 + attributeKey: null
1991 + };
1759 1992 }
1760 1993 if (selection.type === SelectionType.WholeBlock) {
1761 - const absolutePos = import_sync8.Y.createAbsolutePositionFromRelativePosition(
1994 + const absolutePos = import_sync9.Y.createAbsolutePositionFromRelativePosition(
1762 1995 selection.blockPosition,
1763 1996 this.doc
1764 1997 );
1765 1998 let localClientId2 = null;
1766 - if (absolutePos && absolutePos.type instanceof import_sync8.Y.Array) {
1999 + if (absolutePos && absolutePos.type instanceof import_sync9.Y.Array) {
1767 2000 const parentArray = absolutePos.type;
1768 2001 const block = parentArray.get(absolutePos.index);
1769 - if (block instanceof import_sync8.Y.Map) {
2002 + if (block instanceof import_sync9.Y.Map) {
1770 2003 const path2 = getBlockPathInYdoc(block);
1771 - localClientId2 = path2 ? resolveBlockClientIdByPath(path2) : null;
2004 + localClientId2 = path2 ? resolveBlockClientIdByPath(path2, blocks) : null;
1772 2005 }
1773 2006 }
1774 - return { richTextOffset: null, localClientId: localClientId2 };
2007 + return {
2008 + richTextOffset: null,
2009 + localClientId: localClientId2,
2010 + attributeKey: null
2011 + };
1775 2012 }
2013 + if (selection.type === SelectionType.SelectionInMultipleBlocks) {
2014 + return {
2015 + richTextOffset: null,
2016 + localClientId: null,
2017 + attributeKey: null
2018 + };
2019 + }
1776 2020 const cursorPos = "cursorPosition" in selection ? selection.cursorPosition : selection.cursorStartPosition;
1777 - const absolutePosition = import_sync8.Y.createAbsolutePositionFromRelativePosition(
2021 + const absolutePosition = import_sync9.Y.createAbsolutePositionFromRelativePosition(
1778 2022 cursorPos.relativePosition,
1779 2023 this.doc
1780 2024 );
1781 2025 if (!absolutePosition) {
1782 - return { richTextOffset: null, localClientId: null };
2026 + return {
2027 + richTextOffset: null,
2028 + localClientId: null,
2029 + attributeKey: null
2030 + };
1783 2031 }
1784 - const yType = absolutePosition.type.parent?.parent;
1785 - const path = yType instanceof import_sync8.Y.Map ? getBlockPathInYdoc(yType) : null;
1786 - const localClientId = path ? resolveBlockClientIdByPath(path) : null;
2032 + const yType = getContainingBlockYMap(absolutePosition.type);
2033 + const path = yType ? getBlockPathInYdoc(yType) : null;
2034 + const localClientId = path ? resolveBlockClientIdByPath(path, blocks) : null;
1787 2035 return {
1788 2036 richTextOffset: htmlIndexToRichTextOffset(
1789 2037 absolutePosition.type.toString(),
1790 - absolutePosition.index
2038 + asHtmlStringIndex(absolutePosition.index)
1791 2039 ),
1792 - localClientId
2040 + localClientId,
2041 + attributeKey: cursorPos.attributeKey ?? null
1793 2042 };
1794 2043 }
1795 2044 /**
1796 2045 * Type guard to check if a struct is a Y.Item (not Y.GC)
@@ -1813,17 +2062,17 @@
1813 2062 value.toJSON()
1814 2063 ])
1815 2064 );
1816 2065 const collaboratorMapData = new Map(
1817 - Array.from(this.getSeenStates().entries()).map(
1818 - ([clientId, collaboratorState]) => [
1819 - String(clientId),
1820 - {
1821 - name: collaboratorState.collaboratorInfo.name,
1822 - wpUserId: collaboratorState.collaboratorInfo.id
1823 - }
1824 - ]
1825 - )
2066 + Array.from(this.getSeenStates().entries()).filter(
2067 + ([, collaboratorState]) => isCollaboratorInfo(collaboratorState.collaboratorInfo)
2068 + ).map(([clientId, collaboratorState]) => [
2069 + String(clientId),
2070 + {
2071 + name: collaboratorState.collaboratorInfo.name,
2072 + wpUserId: collaboratorState.collaboratorInfo.id
2073 + }
2074 + ])
1826 2075 );
1827 2076 const serializableClientItems = {};
1828 2077 ydoc.store.clients.forEach((structs, clientId) => {
1829 2078 const items2 = structs.filter(this.isYItem);
@@ -1865,51 +2114,47 @@
1865 2114 return a.clientId === b.clientId && a.attributeKey === b.attributeKey && a.offset === b.offset;
1866 2115 }
1867 2116
1868 2117 // packages/core-data/build-module/utils/crdt.mjs
1869 - var import_es63 = __toESM(require_es6(), 1);
2118 + var import_es64 = __toESM(require_es6(), 1);
1870 2119 var import_blocks3 = __toESM(require_blocks(), 1);
1871 - var import_sync13 = __toESM(require_sync(), 1);
2120 + var import_sync14 = __toESM(require_sync(), 1);
1872 2121
1873 - // node_modules/uuid/dist/esm-browser/rng.js
1874 - var getRandomValues;
1875 - var rnds8 = new Uint8Array(16);
1876 - function rng() {
1877 - if (!getRandomValues) {
1878 - getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
1879 - if (!getRandomValues) {
1880 - throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
1881 - }
1882 - }
1883 - return getRandomValues(rnds8);
1884 - }
1885 -
1886 - // node_modules/uuid/dist/esm-browser/stringify.js
2122 + // node_modules/uuid/dist/stringify.js
1887 2123 var byteToHex = [];
1888 2124 for (let i = 0; i < 256; ++i) {
1889 2125 byteToHex.push((i + 256).toString(16).slice(1));
1890 2126 }
1891 2127 function unsafeStringify(arr, offset = 0) {
1892 - return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
2128 + return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
1893 2129 }
1894 2130
1895 - // node_modules/uuid/dist/esm-browser/native.js
1896 - var randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
1897 - var native_default = {
1898 - randomUUID
1899 - };
2131 + // node_modules/uuid/dist/rng.js
2132 + var rnds8 = new Uint8Array(16);
2133 + function rng() {
2134 + return crypto.getRandomValues(rnds8);
2135 + }
1900 2136
1901 - // node_modules/uuid/dist/esm-browser/v4.js
2137 + // node_modules/uuid/dist/v4.js
1902 2138 function v4(options, buf, offset) {
1903 - if (native_default.randomUUID && !buf && !options) {
1904 - return native_default.randomUUID();
2139 + if (!buf && !options && crypto.randomUUID) {
2140 + return crypto.randomUUID();
1905 2141 }
2142 + return _v4(options, buf, offset);
2143 + }
2144 + function _v4(options, buf, offset) {
1906 2145 options = options || {};
1907 - const rnds = options.random || (options.rng || rng)();
2146 + const rnds = options.random ?? options.rng?.() ?? rng();
2147 + if (rnds.length < 16) {
2148 + throw new Error("Random bytes length must be >= 16");
2149 + }
1908 2150 rnds[6] = rnds[6] & 15 | 64;
1909 2151 rnds[8] = rnds[8] & 63 | 128;
1910 2152 if (buf) {
1911 2153 offset = offset || 0;
2154 + if (offset < 0 || offset + 16 > buf.length) {
2155 + throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
2156 + }
1912 2157 for (let i = 0; i < 16; ++i) {
1913 2158 buf[offset + i] = rnds[i];
1914 2159 }
1915 2160 return buf;
@@ -1918,12 +2163,12 @@
1918 2163 }
1919 2164 var v4_default = v4;
1920 2165
1921 2166 // packages/core-data/build-module/utils/crdt-blocks.mjs
1922 - var import_es62 = __toESM(require_es6(), 1);
2167 + var import_es63 = __toESM(require_es6(), 1);
1923 2168 var import_blocks = __toESM(require_blocks(), 1);
1924 2169 var import_rich_text3 = __toESM(require_rich_text(), 1);
1925 - var import_sync9 = __toESM(require_sync(), 1);
2170 + var import_sync10 = __toESM(require_sync(), 1);
1926 2171
1927 2172 // packages/core-data/build-module/utils/crdt-text.mjs
1928 2173 var import_rich_text2 = __toESM(require_rich_text(), 1);
1929 2174 var RICH_TEXT_CACHE_MAX_SIZE = 500;
@@ -1976,10 +2221,21 @@
1976 2221 return newAttributes;
1977 2222 }
1978 2223 function makeBlocksSerializable(blocks) {
1979 2224 return blocks.map((block) => {
1980 - const { name, innerBlocks, attributes, ...rest } = block;
1981 - delete rest.validationIssues;
2225 + const {
2226 + name,
2227 + innerBlocks,
2228 + attributes,
2229 + /*
2230 + * Any validation issues discovered when loading a block are appended
2231 + * to the block node with a logging function, which cannot be serialized.
2232 + *
2233 + * @see import("@wordpress/blocks/src/api/parser").parseRawBlock()
2234 + */
2235 + validationIssues,
2236 + ...rest
2237 + } = block;
1982 2238 return {
1983 2239 ...rest,
1984 2240 name,
1985 2241 attributes: makeBlockAttributesSerializable(name, attributes),
@@ -2036,9 +2292,9 @@
2036 2292 const overwrites = {
2037 2293 innerBlocks: null,
2038 2294 clientId: null
2039 2295 };
2040 - const res = (0, import_es62.default)(
2296 + const res = (0, import_es63.default)(
2041 2297 Object.assign({}, gblock, overwrites),
2042 2298 Object.assign({}, yblockAsJson, overwrites)
2043 2299 );
2044 2300 const inners = gblock.innerBlocks || [];
@@ -2047,9 +2303,9 @@
2047 2303 (block, i) => areBlocksEqual(block, yinners.get(i))
2048 2304 );
2049 2305 }
2050 2306 function createNewYAttributeMap(blockName, attributes) {
2051 - return new import_sync9.Y.Map(
2307 + return new import_sync10.Y.Map(
2052 2308 Object.entries(attributes).map(
2053 2309 ([attributeName, attributeValue]) => {
2054 2310 return [
2055 2311 attributeName,
@@ -2071,13 +2327,13 @@
2071 2327 if (!schema) {
2072 2328 return value;
2073 2329 }
2074 2330 if (schema.type === "rich-text") {
2075 - return new import_sync9.Y.Text(value?.toString() ?? "");
2331 + return new import_sync10.Y.Text(value?.toString() ?? "");
2076 2332 }
2077 2333 if (schema.type === "array" && schema.query && Array.isArray(value)) {
2078 2334 const query = schema.query;
2079 - const yArray = new import_sync9.Y.Array();
2335 + const yArray = new import_sync10.Y.Array();
2080 2336 yArray.insert(
2081 2337 0,
2082 2338 value.map((item) => createYMapFromQuery(query, item))
2083 2339 );
@@ -2092,9 +2348,9 @@
2092 2348 return !!value && typeof value === "object" && !Array.isArray(value);
2093 2349 }
2094 2350 function createYMapFromQuery(query, obj) {
2095 2351 if (!isRecord(obj)) {
2096 - return new import_sync9.Y.Map();
2352 + return new import_sync10.Y.Map();
2097 2353 }
2098 2354 const entries = Object.entries(obj).map(
2099 2355 ([key, val]) => {
2100 2356 const subSchema = query[key];
@@ -2100,9 +2356,9 @@
2100 2356 const subSchema = query[key];
2101 2357 return [key, createYValueFromSchema(subSchema, val)];
2102 2358 }
2103 2359 );
2104 - return new import_sync9.Y.Map(entries);
2360 + return new import_sync10.Y.Map(entries);
2105 2361 }
2106 2362 function createNewYBlock(block) {
2107 2363 return createYMap(
2108 2364 Object.fromEntries(
@@ -2114,9 +2370,9 @@
2114 2370 createNewYAttributeMap(block.name, value)
2115 2371 ];
2116 2372 }
2117 2373 case "innerBlocks": {
2118 - const innerBlocks = new import_sync9.Y.Array();
2374 + const innerBlocks = new import_sync10.Y.Array();
2119 2375 if (!Array.isArray(value)) {
2120 2376 return [key, innerBlocks];
2121 2377 }
2122 2378 innerBlocks.insert(
@@ -2133,9 +2389,9 @@
2133 2389 })
2134 2390 )
2135 2391 );
2136 2392 }
2137 - function mergeCrdtBlocks(yblocks, incomingBlocks, cursorPosition) {
2393 + function mergeCrdtBlocks(yblocks, incomingBlocks, attributeCursor, options = {}) {
2138 2394 if (!serializableBlocksCache.has(incomingBlocks)) {
2139 2395 serializableBlocksCache.set(
2140 2396 incomingBlocks,
2141 2397 makeBlocksSerializable(incomingBlocks)
@@ -2140,19 +2396,19 @@
2140 2396 incomingBlocks,
2141 2397 makeBlocksSerializable(incomingBlocks)
2142 2398 );
2143 2399 }
2144 - const blocksToSync = serializableBlocksCache.get(incomingBlocks) ?? [];
2400 + const incomingBlocksToSync = serializableBlocksCache.get(incomingBlocks) ?? [];
2145 2401 const numOfCommonEntries = Math.min(
2146 - blocksToSync.length ?? 0,
2402 + incomingBlocksToSync.length ?? 0,
2147 2403 yblocks.length
2148 2404 );
2149 2405 let left = 0;
2150 2406 let right = 0;
2151 - for (; left < numOfCommonEntries && areBlocksEqual(blocksToSync[left], yblocks.get(left)); left++) {
2407 + for (; left < numOfCommonEntries && areBlocksEqual(incomingBlocksToSync[left], yblocks.get(left)); left++) {
2152 2408 }
2153 2409 for (; right < numOfCommonEntries - left && areBlocksEqual(
2154 - blocksToSync[blocksToSync.length - right - 1],
2410 + incomingBlocksToSync[incomingBlocksToSync.length - right - 1],
2155 2411 yblocks.get(yblocks.length - right - 1)
2156 2412 ); right++) {
2157 2413 }
2158 2414 const numOfUpdatesNeeded = numOfCommonEntries - left - right;
@@ -2157,89 +2413,129 @@
2157 2413 }
2158 2414 const numOfUpdatesNeeded = numOfCommonEntries - left - right;
2159 2415 const numOfInsertionsNeeded = Math.max(
2160 2416 0,
2161 - blocksToSync.length - yblocks.length
2417 + incomingBlocksToSync.length - yblocks.length
2162 2418 );
2163 2419 const numOfDeletionsNeeded = Math.max(
2164 2420 0,
2165 - yblocks.length - blocksToSync.length
2421 + yblocks.length - incomingBlocksToSync.length
2166 2422 );
2167 2423 for (let i = 0; i < numOfUpdatesNeeded; i++, left++) {
2168 - const block = blocksToSync[left];
2169 - const yblock = yblocks.get(left);
2170 - Object.entries(block).forEach(([key, value]) => {
2171 - switch (key) {
2172 - case "attributes": {
2173 - const currentAttributes = yblock.get(key);
2174 - if (!currentAttributes) {
2175 - yblock.set(
2176 - key,
2177 - createNewYAttributeMap(block.name, value)
2424 + const incomingYBlock = incomingBlocksToSync[left];
2425 + const localYBlock = yblocks.get(left);
2426 + Object.entries(incomingYBlock).forEach(
2427 + ([incomingBlockProperty, incomingBlockPropertyValue]) => {
2428 + switch (incomingBlockProperty) {
2429 + case "attributes": {
2430 + const localAttributes = localYBlock.get(
2431 + incomingBlockProperty
2178 2432 );
2433 + const incomingAttributes = incomingBlockPropertyValue;
2434 + if (!localAttributes) {
2435 + localYBlock.set(
2436 + incomingBlockProperty,
2437 + createNewYAttributeMap(
2438 + incomingYBlock.name,
2439 + incomingAttributes
2440 + )
2441 + );
2442 + break;
2443 + }
2444 + Object.entries(incomingAttributes).forEach(
2445 + ([
2446 + incomingAttributeName,
2447 + incomingAttributeValue
2448 + ]) => {
2449 + const currentAttribute = localAttributes?.get(
2450 + incomingAttributeName
2451 + );
2452 + const isExpectedType = isExpectedAttributeType(
2453 + incomingYBlock.name,
2454 + incomingAttributeName,
2455 + currentAttribute
2456 + );
2457 + const isYType = currentAttribute instanceof import_sync10.Y.AbstractType;
2458 + const isAttributeChanged = !isExpectedType || isYType || !(0, import_es63.default)(
2459 + currentAttribute,
2460 + incomingAttributeValue
2461 + );
2462 + if (isAttributeChanged) {
2463 + updateYBlockAttribute(
2464 + incomingYBlock.name,
2465 + incomingYBlock.clientId,
2466 + incomingAttributeName,
2467 + incomingAttributeValue,
2468 + localAttributes,
2469 + attributeCursor
2470 + );
2471 + }
2472 + }
2473 + );
2474 + localAttributes.forEach(
2475 + (_attrValue, attrName) => {
2476 + if (!incomingBlockPropertyValue.hasOwnProperty(
2477 + attrName
2478 + )) {
2479 + localAttributes.delete(attrName);
2480 + }
2481 + }
2482 + );
2179 2483 break;
2180 2484 }
2181 - Object.entries(value).forEach(
2182 - ([attributeName, attributeValue]) => {
2183 - const currentAttribute = currentAttributes?.get(attributeName);
2184 - const isExpectedType = isExpectedAttributeType(
2185 - block.name,
2186 - attributeName,
2187 - currentAttribute
2485 + case "innerBlocks": {
2486 + let yInnerBlocks = localYBlock.get(
2487 + incomingBlockProperty
2488 + );
2489 + if (!(yInnerBlocks instanceof import_sync10.Y.Array)) {
2490 + yInnerBlocks = new import_sync10.Y.Array();
2491 + localYBlock.set(
2492 + incomingBlockProperty,
2493 + yInnerBlocks
2188 2494 );
2189 - const isYType = currentAttribute instanceof import_sync9.Y.AbstractType;
2190 - const isAttributeChanged = !isExpectedType || isYType || !(0, import_es62.default)(
2191 - currentAttribute,
2192 - attributeValue
2495 + }
2496 + mergeCrdtBlocks(
2497 + yInnerBlocks,
2498 + incomingBlockPropertyValue ?? [],
2499 + attributeCursor,
2500 + options
2501 + );
2502 + break;
2503 + }
2504 + case "clientId": {
2505 + if (options.preserveClientIds) {
2506 + break;
2507 + }
2508 + if (incomingBlockPropertyValue !== localYBlock.get(incomingBlockProperty)) {
2509 + localYBlock.set(
2510 + incomingBlockProperty,
2511 + incomingBlockPropertyValue
2193 2512 );
2194 - if (isAttributeChanged) {
2195 - updateYBlockAttribute(
2196 - block.name,
2197 - attributeName,
2198 - attributeValue,
2199 - currentAttributes,
2200 - cursorPosition
2201 - );
2202 - }
2203 2513 }
2204 - );
2205 - currentAttributes.forEach(
2206 - (_attrValue, attrName) => {
2207 - if (!value.hasOwnProperty(attrName)) {
2208 - currentAttributes.delete(attrName);
2209 - }
2514 + break;
2515 + }
2516 + default:
2517 + if (!(0, import_es63.default)(
2518 + incomingYBlock[incomingBlockProperty],
2519 + localYBlock.get(incomingBlockProperty)
2520 + )) {
2521 + localYBlock.set(
2522 + incomingBlockProperty,
2523 + incomingBlockPropertyValue
2524 + );
2210 2525 }
2211 - );
2212 - break;
2213 2526 }
2214 - case "innerBlocks": {
2215 - let yInnerBlocks = yblock.get(key);
2216 - if (!(yInnerBlocks instanceof import_sync9.Y.Array)) {
2217 - yInnerBlocks = new import_sync9.Y.Array();
2218 - yblock.set(key, yInnerBlocks);
2219 - }
2220 - mergeCrdtBlocks(
2221 - yInnerBlocks,
2222 - value ?? [],
2223 - cursorPosition
2224 - );
2225 - break;
2226 - }
2227 - default:
2228 - if (!(0, import_es62.default)(block[key], yblock.get(key))) {
2229 - yblock.set(key, value);
2230 - }
2231 2527 }
2232 - });
2233 - yblock.forEach((_v, k) => {
2234 - if (!block.hasOwnProperty(k)) {
2235 - yblock.delete(k);
2528 + );
2529 + localYBlock.forEach((_v, k) => {
2530 + if (!incomingYBlock.hasOwnProperty(k)) {
2531 + localYBlock.delete(k);
2236 2532 }
2237 2533 });
2238 2534 }
2239 2535 yblocks.delete(left, numOfDeletionsNeeded);
2240 2536 for (let i = 0; i < numOfInsertionsNeeded; i++, left++) {
2241 - const newBlock = [createNewYBlock(blocksToSync[left])];
2537 + const newBlock = [createNewYBlock(incomingBlocksToSync[left])];
2242 2538 yblocks.insert(left, newBlock);
2243 2539 }
2244 2540 const knownClientIds = /* @__PURE__ */ new Set();
2245 2541 for (let j = 0; j < yblocks.length; j++) {
@@ -2255,14 +2551,14 @@
2255 2551 knownClientIds.add(clientId);
2256 2552 }
2257 2553 }
2258 2554 function areArrayElementsEqual(newElement, yElement) {
2259 - if (yElement instanceof import_sync9.Y.Map && isRecord(newElement)) {
2260 - return (0, import_es62.default)(newElement, yElement.toJSON());
2555 + if (yElement instanceof import_sync10.Y.Map && isRecord(newElement)) {
2556 + return (0, import_es63.default)(newElement, yElement.toJSON());
2261 2557 }
2262 - return (0, import_es62.default)(newElement, yElement);
2558 + return (0, import_es63.default)(newElement, yElement);
2263 2559 }
2264 - function mergeYArray(yArray, newValue, schema, cursorPosition) {
2560 + function mergeYArray(yArray, newValue, schema, cursorPosition, cursorScope) {
2265 2561 if (!schema.query) {
2266 2562 return;
2267 2563 }
2268 2564 const query = schema.query;
@@ -2279,14 +2575,15 @@
2279 2575 const numOfUpdatesNeeded = numOfCommonEntries - left - right;
2280 2576 for (let i = 0; i < numOfUpdatesNeeded; i++) {
2281 2577 const currentElement = yArray.get(left + i);
2282 2578 const newElement = newValue[left + i];
2283 - if (currentElement instanceof import_sync9.Y.Map && isRecord(newElement)) {
2579 + if (currentElement instanceof import_sync10.Y.Map && isRecord(newElement)) {
2284 2580 mergeYMapValues(
2285 2581 currentElement,
2286 2582 newElement,
2287 2583 query,
2288 - cursorPosition
2584 + cursorPosition,
2585 + cursorScope
2289 2586 );
2290 2587 } else {
2291 2588 yArray.delete(0, yArray.length);
2292 2589 yArray.insert(
@@ -2317,26 +2614,43 @@
2317 2614 }
2318 2615 yArray.insert(insertAt, itemsToInsert);
2319 2616 }
2320 2617 }
2321 - function mergeYValue(schema, newVal, yMap, key, cursorPosition) {
2618 + function mergeYValue(schema, newVal, yMap, key, cursorPosition, cursorScope) {
2322 2619 const currentVal = yMap.get(key);
2323 - if (schema?.type === "rich-text" && typeof newVal === "string" && currentVal instanceof import_sync9.Y.Text) {
2324 - mergeRichTextUpdate(currentVal, newVal, cursorPosition);
2325 - } else if (schema?.type === "array" && schema.query && Array.isArray(newVal) && currentVal instanceof import_sync9.Y.Array) {
2326 - mergeYArray(currentVal, newVal, schema, cursorPosition);
2327 - } else if (schema?.type === "object" && schema.query && isRecord(newVal) && currentVal instanceof import_sync9.Y.Map) {
2328 - mergeYMapValues(currentVal, newVal, schema.query, cursorPosition);
2620 + if (schema?.type === "rich-text" && typeof newVal === "string" && currentVal instanceof import_sync10.Y.Text) {
2621 + mergeRichTextUpdate(
2622 + currentVal,
2623 + newVal,
2624 + resolveRichTextCursorPosition(cursorPosition, cursorScope, newVal)
2625 + );
2626 + } else if (schema?.type === "array" && schema.query && Array.isArray(newVal) && currentVal instanceof import_sync10.Y.Array) {
2627 + mergeYArray(currentVal, newVal, schema, cursorPosition, cursorScope);
2628 + } else if (schema?.type === "object" && schema.query && isRecord(newVal) && currentVal instanceof import_sync10.Y.Map) {
2629 + mergeYMapValues(
2630 + currentVal,
2631 + newVal,
2632 + schema.query,
2633 + cursorPosition,
2634 + cursorScope
2635 + );
2329 2636 } else {
2330 2637 const newYValue = createYValueFromSchema(schema, newVal);
2331 - if (newYValue !== newVal || !(0, import_es62.default)(currentVal, newVal)) {
2638 + if (newYValue !== newVal || !(0, import_es63.default)(currentVal, newVal)) {
2332 2639 yMap.set(key, newYValue);
2333 2640 }
2334 2641 }
2335 2642 }
2336 - function mergeYMapValues(yMap, newObj, query, cursorPosition) {
2643 + function mergeYMapValues(yMap, newObj, query, cursorPosition, cursorScope) {
2337 2644 for (const [key, newVal] of Object.entries(newObj)) {
2338 - mergeYValue(query[key], newVal, yMap, key, cursorPosition);
2645 + mergeYValue(
2646 + query[key],
2647 + newVal,
2648 + yMap,
2649 + key,
2650 + cursorPosition,
2651 + cursorScope
2652 + );
2339 2653 }
2340 2654 for (const key of yMap.keys()) {
2341 2655 if (!Object.hasOwn(newObj, key)) {
2342 2656 yMap.delete(key);
@@ -2342,9 +2656,9 @@
2342 2656 yMap.delete(key);
2343 2657 }
2344 2658 }
2345 2659 }
2346 - function updateYBlockAttribute(blockName, attributeName, attributeValue, currentAttributes, cursorPosition) {
2660 + function updateYBlockAttribute(blockName, clientId, attributeName, attributeValue, currentAttributes, newCursorPosition) {
2347 2661 const schema = getBlockAttributeSchema(blockName, attributeName);
2348 2662 mergeYValue(
2349 2663 schema,
2350 2664 attributeValue,
@@ -2349,11 +2663,18 @@
2349 2663 schema,
2350 2664 attributeValue,
2351 2665 currentAttributes,
2352 2666 attributeName,
2353 - cursorPosition
2667 + newCursorPosition,
2668 + { attributeKey: attributeName, clientId }
2354 2669 );
2355 2670 }
2671 + function resolveRichTextCursorPosition(cursorPosition, cursorScope, updatedValue) {
2672 + return cursorPosition && cursorPosition.clientId === cursorScope.clientId && cursorPosition.attributeKey === cursorScope.attributeKey && "number" === typeof cursorPosition.offset && Number.isInteger(cursorPosition.offset) ? richTextOffsetToHtmlIndex(
2673 + updatedValue,
2674 + asRichTextOffset(cursorPosition.offset)
2675 + ) : null;
2676 + }
2356 2677 var cachedBlockAttributeSchemas;
2357 2678 function getBlockAttributeSchema(blockName, attributeName) {
2358 2679 if (!cachedBlockAttributeSchemas) {
2359 2680 cachedBlockAttributeSchemas = /* @__PURE__ */ new Map();
@@ -2375,18 +2696,18 @@
2375 2696 }
2376 2697 function isExpectedAttributeType(blockName, attributeName, attributeValue) {
2377 2698 const schema = getBlockAttributeSchema(blockName, attributeName);
2378 2699 if (schema?.type === "rich-text") {
2379 - return attributeValue instanceof import_sync9.Y.Text;
2700 + return attributeValue instanceof import_sync10.Y.Text;
2380 2701 }
2381 2702 if (schema?.type === "string") {
2382 2703 return typeof attributeValue === "string";
2383 2704 }
2384 2705 if (schema?.type === "array" && schema.query) {
2385 - return attributeValue instanceof import_sync9.Y.Array;
2706 + return attributeValue instanceof import_sync10.Y.Array;
2386 2707 }
2387 2708 if (schema?.type === "object" && schema.query) {
2388 - return attributeValue instanceof import_sync9.Y.Map;
2709 + return attributeValue instanceof import_sync10.Y.Map;
2389 2710 }
2390 2711 return true;
2391 2712 }
2392 2713 function isLocalAttribute(blockName, attributeName) {
@@ -2392,32 +2713,37 @@
2392 2713 function isLocalAttribute(blockName, attributeName) {
2393 2714 return "local" === getBlockAttributeSchema(blockName, attributeName)?.role;
2394 2715 }
2395 2716 var localDoc;
2396 - function mergeRichTextUpdate(blockYText, updatedValue, cursorPosition = null) {
2397 - if (!localDoc) {
2398 - localDoc = new import_sync9.Y.Doc();
2399 - }
2400 - const localYText = localDoc.getText("temporary-text");
2401 - localYText.delete(0, localYText.length);
2402 - localYText.insert(0, updatedValue);
2717 + function mergeRichTextUpdate(blockYText, updatedValue, htmlCursorIndex = null) {
2403 2718 const currentValueAsDelta = new Delta(blockYText.toDelta());
2404 - const updatedValueAsDelta = new Delta(localYText.toDelta());
2719 + const updatedValueAsDelta = new Delta([{ insert: updatedValue }]);
2405 2720 const deltaDiff = currentValueAsDelta.diffWithCursor(
2406 2721 updatedValueAsDelta,
2407 - cursorPosition
2722 + htmlCursorIndex
2408 2723 );
2409 - blockYText.applyDelta(deltaDiff.ops);
2724 + const safeDiff = htmlCursorIndex === null || isDeltaVerificationMatch(blockYText, deltaDiff, updatedValue) ? deltaDiff : currentValueAsDelta.diff(updatedValueAsDelta);
2725 + blockYText.applyDelta(safeDiff.ops);
2410 2726 }
2727 + function isDeltaVerificationMatch(blockYText, delta, expectedValue) {
2728 + if (!localDoc) {
2729 + localDoc = new import_sync10.Y.Doc();
2730 + }
2731 + const verificationYText = localDoc.getText("verification-text");
2732 + verificationYText.delete(0, verificationYText.length);
2733 + verificationYText.insert(0, blockYText.toString());
2734 + verificationYText.applyDelta(delta.ops);
2735 + return verificationYText.toString() === expectedValue;
2736 + }
2411 2737
2412 2738 // packages/core-data/build-module/utils/crdt-selection.mjs
2413 2739 var import_data5 = __toESM(require_data(), 1);
2414 2740 var import_block_editor4 = __toESM(require_block_editor(), 1);
2415 2741 var import_blocks2 = __toESM(require_blocks(), 1);
2416 - var import_sync12 = __toESM(require_sync(), 1);
2742 + var import_sync13 = __toESM(require_sync(), 1);
2417 2743
2418 2744 // packages/core-data/build-module/utils/block-selection-history.mjs
2419 - var import_sync11 = __toESM(require_sync(), 1);
2745 + var import_sync12 = __toESM(require_sync(), 1);
2420 2746 var SELECTION_HISTORY_DEFAULT_SIZE = 5;
2421 2747 var YSelectionType = /* @__PURE__ */ ((YSelectionType2) => {
2422 2748 YSelectionType2["RelativeSelection"] = "RelativeSelection";
2423 2749 YSelectionType2["BlockSelection"] = "BlockSelection";
@@ -2461,12 +2787,13 @@
2461 2787 const clientId = selection.clientId;
2462 2788 const block = findBlockByClientIdInDoc(clientId, ydoc);
2463 2789 const attributes = block?.get("attributes");
2464 2790 const attributeKey = selection.attributeKey;
2465 - const changedYText = attributeKey ? attributes?.get(attributeKey) : void 0;
2466 - const isYText = changedYText instanceof import_sync11.Y.Text;
2467 - const isFullyDefinedSelection = attributeKey && clientId;
2468 - if (!isYText || !isFullyDefinedSelection) {
2791 + let changedYText = null;
2792 + if (attributeKey && attributes) {
2793 + changedYText = getYTextByAttributeKey(attributes, attributeKey);
2794 + }
2795 + if (!(changedYText instanceof import_sync12.Y.Text) || !attributeKey || !clientId) {
2469 2796 return {
2470 2797 type: "BlockSelection",
2471 2798 clientId
2472 2799 };
@@ -2471,11 +2798,14 @@
2471 2798 clientId
2472 2799 };
2473 2800 }
2474 2801 const offset = selection.offset ?? 0;
2475 - const relativePosition = import_sync11.Y.createRelativePositionFromTypeIndex(
2802 + const relativePosition = import_sync12.Y.createRelativePositionFromTypeIndex(
2476 2803 changedYText,
2477 - richTextOffsetToHtmlIndex(changedYText.toString(), offset)
2804 + richTextOffsetToHtmlIndex(
2805 + changedYText.toString(),
2806 + asRichTextOffset(offset)
2807 + )
2478 2808 );
2479 2809 return {
2480 2810 type: "RelativeSelection",
2481 2811 attributeKey,
@@ -2503,9 +2833,9 @@
2503 2833 }
2504 2834 function convertYSelectionToBlockSelection(ySelection, ydoc) {
2505 2835 if (ySelection.type === YSelectionType.RelativeSelection) {
2506 2836 const { relativePosition, attributeKey, clientId } = ySelection;
2507 - const absolutePosition = import_sync12.Y.createAbsolutePositionFromRelativePosition(
2837 + const absolutePosition = import_sync13.Y.createAbsolutePositionFromRelativePosition(
2508 2838 relativePosition,
2509 2839 ydoc
2510 2840 );
2511 2841 if (absolutePosition) {
@@ -2513,9 +2843,9 @@
2513 2843 clientId,
2514 2844 attributeKey,
2515 2845 offset: htmlIndexToRichTextOffset(
2516 2846 absolutePosition.type.toString(),
2517 - absolutePosition.index
2847 + asHtmlStringIndex(absolutePosition.index)
2518 2848 )
2519 2849 };
2520 2850 }
2521 2851 } else if (ySelection.type === YSelectionType.BlockSelection) {
@@ -2646,19 +2976,29 @@
2646 2976 return;
2647 2977 }
2648 2978 switch (key) {
2649 2979 case "blocks": {
2650 - if (!newValue) {
2980 + const newCursorPosition = parseCursorSelection(
2981 + changes.selection
2982 + );
2983 + const rawContent = getRawValue(changes.content);
2984 + if (!newValue && typeof rawContent === "string") {
2985 + mergeContentWithoutBlocks(
2986 + ymap,
2987 + rawContent,
2988 + newCursorPosition
2989 + );
2990 + break;
2991 + } else if (!newValue) {
2651 2992 ymap.set(key, void 0);
2652 2993 break;
2653 2994 }
2654 2995 let currentBlocks = ymap.get(key);
2655 - if (!(currentBlocks instanceof import_sync13.Y.Array)) {
2656 - currentBlocks = new import_sync13.Y.Array();
2996 + if (!(currentBlocks instanceof import_sync14.Y.Array)) {
2997 + currentBlocks = new import_sync14.Y.Array();
2657 2998 ymap.set(key, currentBlocks);
2658 2999 }
2659 - const cursorPosition = changes.selection?.selectionStart?.offset ?? null;
2660 - mergeCrdtBlocks(currentBlocks, newValue, cursorPosition);
3000 + mergeCrdtBlocks(currentBlocks, newValue, newCursorPosition);
2661 3001 break;
2662 3002 }
2663 3003 case "content":
2664 3004 case "excerpt":
@@ -2667,12 +3007,12 @@
2667 3007 let rawValue = getRawValue(newValue);
2668 3008 if (key === "title" && !currentValue?.toString() && "Auto Draft" === rawValue) {
2669 3009 rawValue = "";
2670 3010 }
2671 - if (currentValue instanceof import_sync13.Y.Text) {
3011 + if (currentValue instanceof import_sync14.Y.Text) {
2672 3012 mergeRichTextUpdate(currentValue, rawValue ?? "");
2673 3013 } else {
2674 - const newYText = new import_sync13.Y.Text(rawValue ?? "");
3014 + const newYText = new import_sync14.Y.Text(rawValue ?? "");
2675 3015 ymap.set(key, newYText);
2676 3016 }
2677 3017 break;
2678 3018 }
@@ -2721,11 +3061,37 @@
2721 3061 updateSelectionHistory(ydoc, selection);
2722 3062 }, 0);
2723 3063 }
2724 3064 }
2725 - function defaultGetChangesFromCRDTDoc(crdtDoc) {
2726 - return getRootMap(crdtDoc, CRDT_RECORD_MAP_KEY).toJSON();
3065 + function mergeContentWithoutBlocks(ymap, rawContent, cursorPosition) {
3066 + let currentBlocks = ymap.get("blocks");
3067 + if (!(currentBlocks instanceof import_sync14.Y.Array)) {
3068 + currentBlocks = new import_sync14.Y.Array();
3069 + ymap.set("blocks", currentBlocks);
3070 + }
3071 + mergeCrdtBlocks(
3072 + currentBlocks,
3073 + (0, import_blocks3.parse)(rawContent),
3074 + cursorPosition,
3075 + { preserveClientIds: true }
3076 + );
2727 3077 }
3078 + function parseCursorSelection(selection) {
3079 + const selectionStart = selection?.selectionStart;
3080 + return selectionStart?.clientId && selectionStart.attributeKey && "number" === typeof selectionStart.offset && Number.isInteger(selectionStart.offset) ? {
3081 + attributeKey: selectionStart.attributeKey,
3082 + clientId: selectionStart.clientId,
3083 + offset: asRichTextOffset(selectionStart.offset)
3084 + } : null;
3085 + }
3086 + function defaultGetChangesFromCRDTDoc(crdtDoc, editedRecord) {
3087 + const docRecord = getRootMap(crdtDoc, CRDT_RECORD_MAP_KEY).toJSON();
3088 + return Object.fromEntries(
3089 + Object.entries(docRecord).filter(
3090 + ([key, newValue]) => haveValuesChanged(editedRecord?.[key], newValue)
3091 + )
3092 + );
3093 + }
2728 3094 function getPostChangesFromCRDTDoc(ydoc, editedRecord, syncedProperties) {
2729 3095 const ymap = getRootMap(ydoc, CRDT_RECORD_MAP_KEY);
2730 3096 let allowedMetaChanges = {};
2731 3097 const changes = Object.fromEntries(
@@ -2792,8 +3158,12 @@
2792 3158 changes.blocks = deserializeBlockAttributes(
2793 3159 changes.blocks
2794 3160 );
2795 3161 }
3162 + if (changes.blocks && !changes.content) {
3163 + const capturedBlocks = changes.blocks;
3164 + changes.content = () => (0, import_blocks3.__unstableSerializeAndClean)(capturedBlocks);
3165 + }
2796 3166 if ("object" === typeof changes.meta) {
2797 3167 changes.meta = {
2798 3168 ...editedRecord.meta,
2799 3169 ...allowedMetaChanges
@@ -2829,9 +3199,9 @@
2829 3199 }
2830 3200 return void 0;
2831 3201 }
2832 3202 function haveValuesChanged(currentValue, newValue) {
2833 - return !(0, import_es63.default)(currentValue, newValue);
3203 + return !(0, import_es64.default)(currentValue, newValue);
2834 3204 }
2835 3205 function updateMapValue(map, key, currentValue, newValue) {
2836 3206 if (void 0 === newValue) {
2837 3207 map.delete(key);
@@ -2861,15 +3231,17 @@
2861 3231 name: "__unstableBase",
2862 3232 baseURL: "/",
2863 3233 baseURLParams: {
2864 3234 // Please also change the preload path when changing this.
2865 - // @see lib/compat/wordpress-7.0/preload.php
3235 + // @see lib/compat/wordpress-7.1/preload.php
2866 3236 _fields: [
2867 3237 "description",
2868 3238 "gmt_offset",
2869 3239 "home",
3240 + "image_max_bit_depth",
2870 3241 "image_sizes",
2871 3242 "image_size_threshold",
3243 + "image_strip_meta",
2872 3244 "name",
2873 3245 "site_icon",
2874 3246 "site_icon_url",
2875 3247 "site_logo",
@@ -2961,9 +3333,9 @@
2961 3333 baseURLParams: { context: "edit" },
2962 3334 plural: "comments",
2963 3335 label: (0, import_i18n.__)("Comment"),
2964 3336 supportsPagination: true,
2965 - syncConfig: defaultCollectionSyncConfig
3337 + ...globalThis.window?.__experimentalEnableRealTimeCollaboration ? { syncConfig: defaultCollectionSyncConfig } : {}
2966 3338 },
2967 3339 {
2968 3340 name: "menu",
2969 3341 kind: "root",
@@ -3035,16 +3407,8 @@
3035 3407 key: "slug",
3036 3408 supportsPagination: false
3037 3409 },
3038 3410 {
3039 - label: (0, import_i18n.__)("Registered Templates"),
3040 - name: "registeredTemplate",
3041 - kind: "root",
3042 - baseURL: "/wp/v2/registered-templates",
3043 - key: "id",
3044 - supportsPagination: false
3045 - },
3046 - {
3047 3411 label: (0, import_i18n.__)("Font Collections"),
3048 3412 name: "fontCollection",
3049 3413 kind: "root",
3050 3414 baseURL: "/wp/v2/font-collections",
@@ -3061,8 +3425,18 @@
3061 3425 baseURLParams: { context: "view" },
3062 3426 plural: "icons",
3063 3427 key: "name",
3064 3428 supportsPagination: false
3429 + },
3430 + {
3431 + label: (0, import_i18n.__)("Icon Collections"),
3432 + name: "iconCollection",
3433 + kind: "root",
3434 + baseURL: "/wp/v2/icon-collections",
3435 + baseURLParams: { context: "view" },
3436 + plural: "iconCollections",
3437 + key: "slug",
3438 + supportsPagination: false
3065 3439 }
3066 3440 ];
3067 3441 var deprecatedEntities = {
3068 3442 root: {
@@ -3094,9 +3468,9 @@
3094 3468 if ((!edits.title || edits.title === "Auto Draft") && !newEdits.title && (!persistedRecord?.title || persistedRecord?.title === "Auto Draft")) {
3095 3469 newEdits.title = "";
3096 3470 }
3097 3471 }
3098 - if (persistedRecord) {
3472 + if (window.__experimentalEnableRealTimeCollaboration && persistedRecord) {
3099 3473 const objectType = `postType/${name}`;
3100 3474 const objectId = persistedRecord.id;
3101 3475 const serializedDoc = await getSyncManager()?.createPersistedCRDTDoc(
3102 3476 objectType,
@@ -3111,10 +3485,10 @@
3111 3485 }
3112 3486 return newEdits;
3113 3487 };
3114 3488 async function loadPostTypeEntities() {
3115 - const postTypesPromise = (0, import_api_fetch.default)({ path: "/wp/v2/types?context=view" });
3116 - const taxonomiesPromise = window._wpCollaborationEnabled ? (0, import_api_fetch.default)({ path: "/wp/v2/taxonomies?context=view" }) : Promise.resolve({});
3489 + const postTypesPromise = (0, import_api_fetch2.default)({ path: "/wp/v2/types?context=view" });
3490 + const taxonomiesPromise = window.__experimentalEnableRealTimeCollaboration ? (0, import_api_fetch2.default)({ path: "/wp/v2/taxonomies?context=view" }) : Promise.resolve({});
3117 3491 const [postTypes, taxonomies] = await Promise.all([
3118 3492 postTypesPromise,
3119 3493 taxonomiesPromise
3120 3494 ]);
@@ -3155,13 +3529,20 @@
3155 3529 rawAttributes: POST_RAW_ATTRIBUTES,
3156 3530 getTitle: (record) => record?.title?.rendered || record?.title || (isTemplate ? capitalCase(record.slug ?? "") : String(record.id)),
3157 3531 __unstablePrePersist: (persistedRecord, edits) => prePersistPostType(persistedRecord, edits, name, isTemplate),
3158 3532 __unstable_rest_base: postType.rest_base,
3159 - supportsPagination: true,
3533 + // The templates controller returns the whole collection and never
3534 + // paginates.
3535 + supportsPagination: !isTemplate,
3160 3536 getRevisionsUrl: (parentId, revisionId) => `/${namespace}/${postType.rest_base}/${parentId}/revisions${revisionId ? "/" + revisionId : ""}`,
3161 - revisionKey: isTemplate && !window?.__experimentalTemplateActivate ? "wp_id" : DEFAULT_ENTITY_KEY
3537 + revisionKey: isTemplate ? "wp_id" : DEFAULT_ENTITY_KEY
3162 3538 };
3539 + if (!window.__experimentalEnableRealTimeCollaboration) {
3540 + return entity2;
3541 + }
3163 3542 entity2.syncConfig = {
3543 + // Save a CRDT document with this entity
3544 + supportsPersistence: true,
3164 3545 /**
3165 3546 * Apply changes from the local editor to the local CRDT document so
3166 3547 * that those changes can be synced to other peers (via the provider).
3167 3548 *
@@ -3203,15 +3584,16 @@
3203 3584 * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record
3204 3585 */
3205 3586 getPersistedCRDTDoc: (record) => {
3206 3587 return record?.meta?.[POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE] || null;
3207 - }
3588 + },
3589 + shouldSync: () => !(Array.isArray(window._wpCollaborationDisabledPostTypes) && window._wpCollaborationDisabledPostTypes.includes(name))
3208 3590 };
3209 3591 return entity2;
3210 3592 });
3211 3593 }
3212 3594 async function loadTaxonomyEntities() {
3213 - const taxonomies = await (0, import_api_fetch.default)({
3595 + const taxonomies = await (0, import_api_fetch2.default)({
3214 3596 path: "/wp/v2/taxonomies?context=view"
3215 3597 });
3216 3598 return Object.entries(taxonomies ?? {}).map(([name, taxonomy]) => {
3217 3599 const namespace = taxonomy?.rest_namespace ?? "wp/v2";
@@ -3223,9 +3605,11 @@
3223 3605 label: taxonomy.name,
3224 3606 getTitle: (record) => record?.name,
3225 3607 supportsPagination: true
3226 3608 };
3227 - entity2.syncConfig = defaultSyncConfig;
3609 + if (window.__experimentalEnableRealTimeCollaboration) {
3610 + entity2.syncConfig = defaultSyncConfig;
3611 + }
3228 3612 return entity2;
3229 3613 });
3230 3614 }
3231 3615 async function loadSiteEntity() {
@@ -3237,9 +3621,9 @@
3237 3621 baseURL: "/wp/v2/settings",
3238 3622 supportsPagination: false,
3239 3623 meta: {}
3240 3624 };
3241 - const site = await (0, import_api_fetch.default)({
3625 + const site = await (0, import_api_fetch2.default)({
3242 3626 path: entity2.baseURL,
3243 3627 method: "OPTIONS"
3244 3628 });
3245 3629 const labels = {};
@@ -3400,8 +3784,29 @@
3400 3784 ),
3401 3785 meta: action.meta
3402 3786 };
3403 3787 });
3788 + function removeQueryItems(queryItems, removedItems) {
3789 + const itemIds = queryItems.itemIds.filter(
3790 + (itemId) => !removedItems[itemId]
3791 + );
3792 + const removedCount = queryItems.itemIds.length - itemIds.length;
3793 + if (removedCount === 0) {
3794 + return queryItems;
3795 + }
3796 + const nextQueryItems = { ...queryItems, itemIds };
3797 + if (Number.isFinite(queryItems.meta?.totalItems)) {
3798 + nextQueryItems.meta = {
3799 + ...queryItems.meta,
3800 + totalItems: Math.max(
3801 + 0,
3802 + queryItems.meta.totalItems - removedCount
3803 + ),
3804 + totalPages: null
3805 + };
3806 + }
3807 + return nextQueryItems;
3808 + }
3404 3809 var queries = (state = {}, action) => {
3405 3810 switch (action.type) {
3406 3811 case "RECEIVE_ITEMS":
3407 3812 return receiveQueries(state, action);
@@ -3417,14 +3822,12 @@
3417 3822 Object.fromEntries(
3418 3823 Object.entries(contextQueries).map(
3419 3824 ([query, queryItems]) => [
3420 3825 query,
3421 - {
3422 - ...queryItems,
3423 - itemIds: queryItems.itemIds.filter(
3424 - (queryId) => !removedItems[queryId]
3425 - )
3426 - }
3826 + removeQueryItems(
3827 + queryItems,
3828 + removedItems
3829 + )
3427 3830 ]
3428 3831 )
3429 3832 )
3430 3833 ]
@@ -3509,20 +3912,23 @@
3509 3912 if (action.type === "UNDO" || action.type === "REDO") {
3510 3913 const { record } = action;
3511 3914 let newState = state;
3512 3915 record.forEach(({ id: { kind, name, recordId }, changes }) => {
3916 + const persistedRecord = state?.queriedData?.items?.default?.[recordId];
3917 + const edits = Object.fromEntries(
3918 + Object.entries(changes).map(([key, value]) => [
3919 + key,
3920 + action.type === "UNDO" ? value.from : value.to
3921 + ])
3922 + );
3513 3923 newState = reducer(newState, {
3514 3924 type: "EDIT_ENTITY_RECORD",
3515 3925 kind,
3516 3926 name,
3517 3927 recordId,
3518 - edits: Object.entries(changes).reduce(
3519 - (acc, [key, value]) => {
3520 - acc[key] = action.type === "UNDO" ? value.from : value.to;
3521 - return acc;
3522 - },
3523 - {}
3524 - )
3928 + // Clear edits matching the persisted record so the entity is
3929 + // no longer dirty after undoing back to its saved state.
3930 + edits: clearUnchangedEdits(edits, persistedRecord)
3525 3931 });
3526 3932 });
3527 3933 return newState;
3528 3934 }
@@ -3566,14 +3972,14 @@
3566 3972 if (
3567 3973 // Edits are the "raw" attribute values, but records may have
3568 3974 // objects with more properties, so we use `get` here for the
3569 3975 // comparison.
3570 - !(0, import_es64.default)(
3976 + !(0, import_es65.default)(
3571 3977 edits[key],
3572 3978 record[key]?.raw ?? record[key]
3573 3979 ) && // Sometimes the server alters the sent value which means
3574 3980 // we need to also remove the edits before the api request.
3575 - (!action.persistedEdits || !(0, import_es64.default)(
3981 + (!action.persistedEdits || !(0, import_es65.default)(
3576 3982 edits[key],
3577 3983 action.persistedEdits[key]
3578 3984 ))
3579 3985 ) {
@@ -3715,8 +4121,18 @@
3715 4121 };
3716 4122 function undoManager(state = (0, import_undo_manager.createUndoManager)()) {
3717 4123 return state;
3718 4124 }
4125 + function syncUndoManagerState(state = { hasRedo: false, hasUndo: false }, action) {
4126 + switch (action.type) {
4127 + case "SYNC_UNDO_MANAGER_CHANGE":
4128 + return {
4129 + hasRedo: action.hasRedo,
4130 + hasUndo: action.hasUndo
4131 + };
4132 + }
4133 + return state;
4134 + }
3719 4135 function editsReference(state = {}, action) {
3720 4136 switch (action.type) {
3721 4137 case "EDIT_ENTITY_RECORD":
3722 4138 case "UNDO":
@@ -3864,13 +4280,18 @@
3864 4280 return state;
3865 4281 }
3866 4282 function viewConfigs(state = {}, action) {
3867 4283 switch (action.type) {
3868 - case "RECEIVE_VIEW_CONFIG":
4284 + case "RECEIVE_VIEW_CONFIG": {
4285 + const key = `${action.kind}/${action.name}`;
3869 4286 return {
3870 4287 ...state,
3871 - [`${action.kind}/${action.name}`]: action.config
4288 + [key]: {
4289 + ...state[key],
4290 + ...action.config
4291 + }
3872 4292 };
4293 + }
3873 4294 }
3874 4295 return state;
3875 4296 }
3876 4297 var reducer_default2 = (0, import_data7.combineReducers)({
@@ -3882,8 +4303,9 @@
3882 4303 themeBaseGlobalStyles,
3883 4304 themeGlobalStyleRevisions,
3884 4305 entities,
3885 4306 editsReference,
4307 + syncUndoManagerState,
3886 4308 undoManager,
3887 4309 embedPreviews,
3888 4310 userPermissions,
3889 4311 autosaves,
@@ -3938,9 +4360,8 @@
3938 4360 getRedoEdit: () => getRedoEdit,
3939 4361 getReferenceByDistinctEdits: () => getReferenceByDistinctEdits,
3940 4362 getRevision: () => getRevision,
3941 4363 getRevisions: () => getRevisions,
3942 - getSyncConnectionStatus: () => getSyncConnectionStatus,
3943 4364 getThemeSupports: () => getThemeSupports,
3944 4365 getUndoEdit: () => getUndoEdit,
3945 4366 getUserPatternCategories: () => getUserPatternCategories,
3946 4367 getUserQueryResults: () => getUserQueryResults,
@@ -3968,12 +4389,14 @@
3968 4389 getEditorAssets: () => getEditorAssets,
3969 4390 getEditorSettings: () => getEditorSettings,
3970 4391 getEntityRecordPermissions: () => getEntityRecordPermissions,
3971 4392 getEntityRecordsPermissions: () => getEntityRecordsPermissions,
4393 + getEntitySyncConnectionStatus: () => getEntitySyncConnectionStatus,
3972 4394 getHomePage: () => getHomePage,
3973 4395 getNavigationFallbackId: () => getNavigationFallbackId,
3974 4396 getPostsPageId: () => getPostsPageId,
3975 4397 getRegisteredPostMeta: () => getRegisteredPostMeta,
4398 + getSyncConnectionStatus: () => getSyncConnectionStatus,
3976 4399 getTemplateId: () => getTemplateId,
3977 4400 getUndoManager: () => getUndoManager,
3978 4401 getViewConfig: () => getViewConfig,
3979 4402 isCollaborationSupported: () => isCollaborationSupported
@@ -4125,9 +4548,11 @@
4125 4548 );
4126 4549 if (!templates) {
4127 4550 return;
4128 4551 }
4129 - const id = templates.find(({ slug }) => slug === "front-page")?.id;
4552 + const id = templates.find(
4553 + ({ slug }) => slug === "front-page"
4554 + )?.id;
4130 4555 if (id) {
4131 4556 return id;
4132 4557 }
4133 4558 }
@@ -4181,8 +4606,24 @@
4181 4606 view_list: void 0,
4182 4607 form: void 0
4183 4608 };
4184 4609 }
4610 + function getSyncConnectionStatus(state) {
4611 + if (!state.syncConnectionStatuses) {
4612 + return void 0;
4613 + }
4614 + const PRIORITIZED_STATUSES = ["disconnected", "connecting", "connected"];
4615 + let coalesced;
4616 + for (const status of Object.values(state.syncConnectionStatuses)) {
4617 + if (!coalesced || PRIORITIZED_STATUSES.indexOf(status.status) < PRIORITIZED_STATUSES.indexOf(coalesced.status)) {
4618 + coalesced = status;
4619 + }
4620 + }
4621 + return coalesced;
4622 + }
4623 + function getEntitySyncConnectionStatus(state, kind, name, recordId) {
4624 + return state.syncConnectionStatuses?.[`${kind}/${name}:${recordId}`];
4625 + }
4185 4626
4186 4627 // packages/core-data/build-module/selectors.mjs
4187 4628 var EMPTY_OBJECT2 = {};
4188 4629 var isRequestingEmbedPreview = (0, import_data9.createRegistrySelector)(
@@ -4241,54 +4682,34 @@
4241 4682 return state.entities.config?.find(
4242 4683 (config) => config.kind === kind && config.name === name
4243 4684 );
4244 4685 }
4245 - var getEntityRecord = (0, import_data9.createSelector)(
4246 - ((state, kind, name, key, query) => {
4247 - logEntityDeprecation(kind, name, "getEntityRecord");
4248 - const queriedState = state.entities.records?.[kind]?.[name]?.queriedData;
4249 - if (!queriedState) {
4686 + var getEntityRecord = ((state, kind, name, recordId, query) => {
4687 + logEntityDeprecation(kind, name, "getEntityRecord");
4688 + const queriedState = state.entities.records?.[kind]?.[name]?.queriedData;
4689 + if (!queriedState) {
4690 + return void 0;
4691 + }
4692 + const context = query?.context ?? "default";
4693 + if (!query || !query._fields) {
4694 + if (!queriedState.itemIsComplete[context]?.[recordId]) {
4250 4695 return void 0;
4251 4696 }
4252 - const context = query?.context ?? "default";
4253 - if (!query || !query._fields) {
4254 - if (!queriedState.itemIsComplete[context]?.[key]) {
4255 - return void 0;
4256 - }
4257 - return queriedState.items[context][key];
4258 - }
4259 - const item = queriedState.items[context]?.[key];
4260 - if (!item) {
4261 - return item;
4262 - }
4263 - const filteredItem = {};
4264 - const fields = get_normalized_comma_separable_default(query._fields) ?? [];
4265 - for (let f = 0; f < fields.length; f++) {
4266 - const field = fields[f].split(".");
4267 - let value = item;
4268 - field.forEach((fieldName) => {
4269 - value = value?.[fieldName];
4270 - });
4271 - setNestedValue(filteredItem, field, value);
4272 - }
4273 - return filteredItem;
4274 - }),
4275 - (state, kind, name, recordId, query) => {
4276 - const context = query?.context ?? "default";
4277 - const queriedState = state.entities.records?.[kind]?.[name]?.queriedData;
4278 - return [
4279 - queriedState?.items[context]?.[recordId],
4280 - queriedState?.itemIsComplete[context]?.[recordId]
4281 - ];
4697 + return queriedState.items[context][recordId];
4282 4698 }
4283 - );
4284 - getEntityRecord.__unstableNormalizeArgs = (args) => {
4699 + const item = queriedState.items[context]?.[recordId];
4700 + if (!item) {
4701 + return item;
4702 + }
4703 + return getFilteredItem(item, query._fields);
4704 + });
4705 + getEntityRecord.normalizeArgs = (args) => {
4285 4706 const newArgs = [...args];
4286 4707 const recordKey = newArgs?.[2];
4287 4708 newArgs[2] = isNumericID(recordKey) ? Number(recordKey) : recordKey;
4288 4709 return newArgs;
4289 4710 };
4290 - function hasEntityRecord(state, kind, name, key, query) {
4711 + function hasEntityRecord(state, kind, name, recordId, query) {
4291 4712 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData;
4292 4713 if (!queriedState) {
4293 4714 return false;
4294 4715 }
@@ -4293,11 +4714,11 @@
4293 4714 return false;
4294 4715 }
4295 4716 const context = query?.context ?? "default";
4296 4717 if (!query || !query._fields) {
4297 - return !!queriedState.itemIsComplete[context]?.[key];
4718 + return !!queriedState.itemIsComplete[context]?.[recordId];
4298 4719 }
4299 - const item = queriedState.items[context]?.[key];
4720 + const item = queriedState.items[context]?.[recordId];
4300 4721 if (!item) {
4301 4722 return false;
4302 4723 }
4303 4724 const fields = get_normalized_comma_separable_default(query._fields) ?? [];
@@ -4313,19 +4734,19 @@
4313 4734 }
4314 4735 }
4315 4736 return true;
4316 4737 }
4317 - function __experimentalGetEntityRecordNoResolver(state, kind, name, key) {
4318 - return getEntityRecord(state, kind, name, key);
4738 + function __experimentalGetEntityRecordNoResolver(state, kind, name, recordId) {
4739 + return getEntityRecord(state, kind, name, recordId);
4319 4740 }
4320 4741 var getRawEntityRecord = (0, import_data9.createSelector)(
4321 - (state, kind, name, key) => {
4742 + (state, kind, name, recordId) => {
4322 4743 logEntityDeprecation(kind, name, "getRawEntityRecord");
4323 4744 const record = getEntityRecord(
4324 4745 state,
4325 4746 kind,
4326 4747 name,
4327 - key
4748 + recordId
4328 4749 );
4329 4750 const config = getEntityConfig(state, kind, name);
4330 4751 if (!record || !config?.rawAttributes?.length) {
4331 4752 return record;
@@ -4330,17 +4751,17 @@
4330 4751 if (!record || !config?.rawAttributes?.length) {
4331 4752 return record;
4332 4753 }
4333 4754 return Object.fromEntries(
4334 - Object.keys(record).map((_key) => {
4335 - if (config.rawAttributes.includes(_key)) {
4336 - const rawValue = record[_key]?.raw;
4755 + Object.keys(record).map((key) => {
4756 + if (config.rawAttributes.includes(key)) {
4757 + const rawValue = record[key]?.raw;
4337 4758 return [
4338 - _key,
4339 - rawValue !== void 0 ? rawValue : record[_key]
4759 + key,
4760 + rawValue !== void 0 ? rawValue : record[key]
4340 4761 ];
4341 4762 }
4342 - return [_key, record[_key]];
4763 + return [key, record[key]];
4343 4764 })
4344 4765 );
4345 4766 },
4346 4767 (state, kind, name, recordId, query) => {
@@ -4469,9 +4890,9 @@
4469 4890 (state) => [state.entities.records]
4470 4891 );
4471 4892 function getEntityRecordEdits(state, kind, name, recordId) {
4472 4893 logEntityDeprecation(kind, name, "getEntityRecordEdits");
4473 - return state.entities.records?.[kind]?.[name]?.edits?.[recordId];
4894 + return state.entities.records?.[kind]?.[name]?.edits?.[String(recordId)];
4474 4895 }
4475 4896 var getEntityRecordNonTransientEdits = (0, import_data9.createSelector)(
4476 4897 (state, kind, name, recordId) => {
4477 4898 logEntityDeprecation(kind, name, "getEntityRecordNonTransientEdits");
@@ -4488,9 +4909,9 @@
4488 4909 }, {});
4489 4910 },
4490 4911 (state, kind, name, recordId) => [
4491 4912 state.entities.config,
4492 - state.entities.records?.[kind]?.[name]?.edits?.[recordId]
4913 + state.entities.records?.[kind]?.[name]?.edits?.[String(recordId)]
4493 4914 ]
4494 4915 );
4495 4916 function hasEditsForEntityRecord(state, kind, name, recordId) {
4496 4917 logEntityDeprecation(kind, name, "hasEditsForEntityRecord");
@@ -4516,9 +4937,9 @@
4516 4937 return [
4517 4938 state.entities.config,
4518 4939 state.entities.records?.[kind]?.[name]?.queriedData.items[context]?.[recordId],
4519 4940 state.entities.records?.[kind]?.[name]?.queriedData.itemIsComplete[context]?.[recordId],
4520 - state.entities.records?.[kind]?.[name]?.edits?.[recordId]
4941 + state.entities.records?.[kind]?.[name]?.edits?.[String(recordId)]
4521 4942 ];
4522 4943 }
4523 4944 );
4524 4945 function isAutosavingEntityRecord(state, kind, name, recordId) {
@@ -4527,17 +4948,17 @@
4527 4948 return Boolean(pending && isAutosave);
4528 4949 }
4529 4950 function isSavingEntityRecord(state, kind, name, recordId) {
4530 4951 logEntityDeprecation(kind, name, "isSavingEntityRecord");
4531 - return state.entities.records?.[kind]?.[name]?.saving?.[recordId]?.pending ?? false;
4952 + return state.entities.records?.[kind]?.[name]?.saving?.[String(recordId)]?.pending ?? false;
4532 4953 }
4533 4954 function isDeletingEntityRecord(state, kind, name, recordId) {
4534 4955 logEntityDeprecation(kind, name, "isDeletingEntityRecord");
4535 - return state.entities.records?.[kind]?.[name]?.deleting?.[recordId]?.pending ?? false;
4956 + return state.entities.records?.[kind]?.[name]?.deleting?.[String(recordId)]?.pending ?? false;
4536 4957 }
4537 4958 function getLastEntitySaveError(state, kind, name, recordId) {
4538 4959 logEntityDeprecation(kind, name, "getLastEntitySaveError");
4539 - return state.entities.records?.[kind]?.[name]?.saving?.[recordId]?.error;
4960 + return state.entities.records?.[kind]?.[name]?.saving?.[String(recordId)]?.error;
4540 4961 }
4541 4962 function getLastEntityDeleteError(state, kind, name, recordId) {
4542 4963 logEntityDeprecation(kind, name, "getLastEntityDeleteError");
4543 4964 return state.entities.records?.[kind]?.[name]?.deleting?.[recordId]?.error;
@@ -4554,11 +4975,17 @@
4554 4975 });
4555 4976 return void 0;
4556 4977 }
4557 4978 function hasUndo(state) {
4979 + if (getSyncManager()?.undoManager) {
4980 + return state.syncUndoManagerState.hasUndo;
4981 + }
4558 4982 return getUndoManager(state).hasUndo();
4559 4983 }
4560 4984 function hasRedo(state) {
4985 + if (getSyncManager()?.undoManager) {
4986 + return state.syncUndoManagerState.hasRedo;
4987 + }
4561 4988 return getUndoManager(state).hasRedo();
4562 4989 }
4563 4990 function getCurrentTheme(state) {
4564 4991 if (!state.currentTheme) {
@@ -4695,60 +5122,27 @@
4695 5122 }
4696 5123 }
4697 5124 return true;
4698 5125 }
4699 - var getRevision = (0, import_data9.createSelector)(
4700 - (state, kind, name, recordKey, revisionKey, query) => {
4701 - logEntityDeprecation(kind, name, "getRevision");
4702 - const queriedState = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey];
4703 - if (!queriedState) {
5126 + var getRevision = (state, kind, name, recordKey, revisionKey, query) => {
5127 + logEntityDeprecation(kind, name, "getRevision");
5128 + const queriedState = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey];
5129 + if (!queriedState) {
5130 + return void 0;
5131 + }
5132 + const context = query?.context ?? "default";
5133 + if (!query || !query._fields) {
5134 + if (!queriedState.itemIsComplete[context]?.[revisionKey]) {
4704 5135 return void 0;
4705 5136 }
4706 - const context = query?.context ?? "default";
4707 - if (!query || !query._fields) {
4708 - if (!queriedState.itemIsComplete[context]?.[revisionKey]) {
4709 - return void 0;
4710 - }
4711 - return queriedState.items[context][revisionKey];
4712 - }
4713 - const item = queriedState.items[context]?.[revisionKey];
4714 - if (!item) {
4715 - return item;
4716 - }
4717 - const filteredItem = {};
4718 - const fields = get_normalized_comma_separable_default(query._fields) ?? [];
4719 - for (let f = 0; f < fields.length; f++) {
4720 - const field = fields[f].split(".");
4721 - let value = item;
4722 - field.forEach((fieldName) => {
4723 - value = value?.[fieldName];
4724 - });
4725 - setNestedValue(filteredItem, field, value);
4726 - }
4727 - return filteredItem;
4728 - },
4729 - (state, kind, name, recordKey, revisionKey, query) => {
4730 - const context = query?.context ?? "default";
4731 - const queriedState = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey];
4732 - return [
4733 - queriedState?.items?.[context]?.[revisionKey],
4734 - queriedState?.itemIsComplete?.[context]?.[revisionKey]
4735 - ];
5137 + return queriedState.items[context][revisionKey];
4736 5138 }
4737 - );
4738 - function getSyncConnectionStatus(state) {
4739 - if (!state.syncConnectionStatuses) {
4740 - return void 0;
5139 + const item = queriedState.items[context]?.[revisionKey];
5140 + if (!item) {
5141 + return item;
4741 5142 }
4742 - const PRIORITIZED_STATUSES = ["disconnected", "connecting", "connected"];
4743 - let coalesced;
4744 - for (const status of Object.values(state.syncConnectionStatuses)) {
4745 - if (!coalesced || PRIORITIZED_STATUSES.indexOf(status.status) < PRIORITIZED_STATUSES.indexOf(coalesced.status)) {
4746 - coalesced = status;
4747 - }
4748 - }
4749 - return coalesced;
4750 - }
5143 + return getFilteredItem(item, query._fields);
5144 + };
4751 5145
4752 5146 // packages/core-data/build-module/actions.mjs
4753 5147 var actions_exports = {};
4754 5148 __export(actions_exports, {
@@ -4778,18 +5172,17 @@
4778 5172 receiveUserQuery: () => receiveUserQuery,
4779 5173 redo: () => redo,
4780 5174 saveEditedEntityRecord: () => saveEditedEntityRecord,
4781 5175 saveEntityRecord: () => saveEntityRecord,
4782 - setSyncConnectionStatus: () => setSyncConnectionStatus,
4783 5176 undo: () => undo
4784 5177 });
4785 - var import_es65 = __toESM(require_es6(), 1);
4786 - var import_api_fetch3 = __toESM(require_api_fetch(), 1);
5178 + var import_es66 = __toESM(require_es6(), 1);
5179 + var import_api_fetch4 = __toESM(require_api_fetch(), 1);
4787 5180 var import_url3 = __toESM(require_url(), 1);
4788 5181 var import_deprecated3 = __toESM(require_deprecated(), 1);
4789 5182
4790 5183 // packages/core-data/build-module/batch/default-processor.mjs
4791 - var import_api_fetch2 = __toESM(require_api_fetch(), 1);
5184 + var import_api_fetch3 = __toESM(require_api_fetch(), 1);
4792 5185 var maxItems = null;
4793 5186 function chunk(arr, chunkSize) {
4794 5187 const tmp = [...arr];
4795 5188 const cache3 = [];
@@ -4799,9 +5192,9 @@
4799 5192 return cache3;
4800 5193 }
4801 5194 async function defaultProcessor(requests) {
4802 5195 if (maxItems === null) {
4803 - const preflightResponse = await (0, import_api_fetch2.default)({
5196 + const preflightResponse = await (0, import_api_fetch3.default)({
4804 5197 path: "/batch/v1",
4805 5198 method: "OPTIONS"
4806 5199 });
4807 5200 maxItems = preflightResponse.endpoints[0].args.requests.maxItems;
@@ -4807,9 +5200,9 @@
4807 5200 maxItems = preflightResponse.endpoints[0].args.requests.maxItems;
4808 5201 }
4809 5202 const results = [];
4810 5203 for (const batchRequests of chunk(requests, maxItems)) {
4811 - const batchResponse = await (0, import_api_fetch2.default)({
5204 + const batchResponse = await (0, import_api_fetch3.default)({
4812 5205 path: "/batch/v1",
4813 5206 method: "POST",
4814 5207 data: {
4815 5208 validation: "require-all-validate",
@@ -4971,8 +5364,39 @@
4971 5364 // packages/core-data/build-module/actions.mjs
4972 5365 function addTitleToAutoDraft(record) {
4973 5366 return record.status === "auto-draft" ? { ...record, title: "" } : record;
4974 5367 }
5368 + function getServerMutatedMetaFields(updatedMeta, persistedMeta, syncedMeta) {
5369 + const baseline = { ...persistedMeta, ...syncedMeta };
5370 + return Object.fromEntries(
5371 + Object.entries(updatedMeta ?? {}).filter(([key, value]) => {
5372 + if (key === POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE) {
5373 + return false;
5374 + }
5375 + return !(0, import_es66.default)(value, baseline[key]);
5376 + })
5377 + );
5378 + }
5379 + function getServerMutatedFields(updatedRecord, persistedRecord, syncedChanges) {
5380 + return Object.fromEntries(
5381 + Object.entries(updatedRecord).flatMap(([key, value]) => {
5382 + if (key === "meta") {
5383 + const serverMutatedMeta = getServerMutatedMetaFields(
5384 + value,
5385 + persistedRecord.meta,
5386 + syncedChanges.meta
5387 + );
5388 + return Object.keys(serverMutatedMeta).length ? [[key, serverMutatedMeta]] : [];
5389 + }
5390 + const baseline = key in syncedChanges ? syncedChanges[key] : persistedRecord[key];
5391 + const wasServerMutated = !(0, import_es66.default)(
5392 + getRawValue(value) ?? value,
5393 + getRawValue(baseline) ?? baseline
5394 + );
5395 + return wasServerMutated ? [[key, value]] : [];
5396 + })
5397 + );
5398 + }
4975 5399 function receiveUserQuery(queryID, users2) {
4976 5400 return {
4977 5401 type: "RECEIVE_USER_QUERY",
4978 5402 users: Array.isArray(users2) ? users2 : [users2],
@@ -5062,9 +5486,9 @@
5062 5486 url,
5063 5487 preview
5064 5488 };
5065 5489 }
5066 - var deleteEntityRecord = (kind, name, recordId, query, { __unstableFetch = import_api_fetch3.default, throwOnError = false } = {}) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => {
5490 + var deleteEntityRecord = (kind, name, recordId, query, { __unstableFetch = import_api_fetch4.default, throwOnError = false } = {}) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => {
5067 5491 logEntityDeprecation(kind, name, "deleteEntityRecord");
5068 5492 const configs = await resolveSelect2.getEntitiesConfig(kind);
5069 5493 const entityConfig = configs.find(
5070 5494 (config) => config.kind === kind && config.name === name
@@ -5086,12 +5510,9 @@
5086 5510 name,
5087 5511 recordId
5088 5512 });
5089 5513 let hasError = false;
5090 - let { baseURL } = entityConfig;
5091 - if (kind === "postType" && name === "wp_template" && (recordId && typeof recordId === "string" && !/^\d+$/.test(recordId) || !window?.__experimentalTemplateActivate)) {
5092 - baseURL = baseURL.slice(0, baseURL.lastIndexOf("/")) + "/templates";
5093 - }
5514 + const { baseURL } = entityConfig;
5094 5515 try {
5095 5516 let path = `${baseURL}/${recordId}`;
5096 5517 if (query) {
5097 5518 path = (0, import_url3.addQueryArgs)(path, query);
@@ -5149,14 +5570,9 @@
5149 5570 name,
5150 5571 recordId,
5151 5572 // Clear edits when they are equal to their persisted counterparts
5152 5573 // so that the property is not considered dirty.
5153 - edits: Object.keys(edits).reduce((acc, key) => {
5154 - const recordValue = record[key];
5155 - const value = editsWithMerges[key];
5156 - acc[key] = (0, import_es65.default)(recordValue, value) ? void 0 : value;
5157 - return acc;
5158 - }, {})
5574 + edits: clearUnchangedEdits(editsWithMerges, record)
5159 5575 };
5160 5576 if (entityConfig.syncConfig) {
5161 5577 const objectType = `${kind}/${name}`;
5162 5578 const objectId = recordId;
@@ -5245,13 +5661,15 @@
5245 5661 };
5246 5662 var __unstableCreateUndoLevel = () => ({ select: select5 }) => {
5247 5663 select5.getUndoManager().addRecord();
5248 5664 };
5249 - var saveEntityRecord = (kind, name, record, {
5250 - isAutosave = false,
5251 - __unstableFetch = import_api_fetch3.default,
5252 - throwOnError = false
5253 - } = {}) => async ({ select: select5, resolveSelect: resolveSelect2, dispatch: dispatch3 }) => {
5665 + var saveEntityRecord = (kind, name, record, options = {}) => async ({ select: select5, resolveSelect: resolveSelect2, dispatch: dispatch3 }) => {
5666 + const {
5667 + isAutosave = false,
5668 + __unstableFetch = import_api_fetch4.default,
5669 + __unstableSkipSyncUpdate = false,
5670 + throwOnError = false
5671 + } = options;
5254 5672 logEntityDeprecation(kind, name, "saveEntityRecord");
5255 5673 const configs = await resolveSelect2.getEntitiesConfig(kind);
5256 5674 const entityConfig = configs.find(
5257 5675 (config) => config.kind === kind && config.name === name
@@ -5294,15 +5712,20 @@
5294 5712 });
5295 5713 let updatedRecord;
5296 5714 let error;
5297 5715 let hasError = false;
5298 - let { baseURL } = entityConfig;
5299 - if (kind === "postType" && name === "wp_template" && (recordId && typeof recordId === "string" && !/^\d+$/.test(recordId) || !window?.__experimentalTemplateActivate)) {
5300 - baseURL = baseURL.slice(0, baseURL.lastIndexOf("/")) + "/templates";
5301 - }
5716 + const { baseURL } = entityConfig;
5302 5717 try {
5303 5718 const path = `${baseURL}${recordId ? "/" + recordId : ""}`;
5304 5719 const persistedRecord = !isNewRecord ? select5.getRawEntityRecord(kind, name, recordId) : {};
5720 + if (entityConfig.syncConfig && !__unstableSkipSyncUpdate && !isNewRecord && persistedRecord) {
5721 + getSyncManager()?.update(
5722 + `${kind}/${name}`,
5723 + recordId,
5724 + record,
5725 + LOCAL_UNDO_IGNORED_ORIGIN
5726 + );
5727 + }
5305 5728 if (isAutosave) {
5306 5729 const merged = { ...persistedRecord, ...record };
5307 5730 const data = [
5308 5731 "title",
@@ -5323,8 +5746,17 @@
5323 5746 // have a draft post and change the status to publish.
5324 5747 status: merged.status === "auto-draft" ? "draft" : void 0
5325 5748 }
5326 5749 );
5750 + if (entityConfig.syncConfig) {
5751 + const crdtSnapshot = getSyncManager()?.getEntitySnapshot(
5752 + `${kind}/${name}`,
5753 + recordId
5754 + );
5755 + if (crdtSnapshot) {
5756 + data[CRDT_AUTOSAVE_SNAPSHOT_KEY] = crdtSnapshot;
5757 + }
5758 + }
5327 5759 updatedRecord = await __unstableFetch({
5328 5760 path: `${path}/autosaves`,
5329 5761 method: "POST",
5330 5762 data
@@ -5387,15 +5819,27 @@
5387 5819 name,
5388 5820 updatedRecord,
5389 5821 void 0,
5390 5822 true,
5391 - edits
5823 + record
5392 5824 );
5393 5825 if (entityConfig.syncConfig) {
5826 + let syncChanges;
5827 + if (__unstableSkipSyncUpdate) {
5828 + syncChanges = {};
5829 + } else if (isNewRecord || !persistedRecord) {
5830 + syncChanges = updatedRecord;
5831 + } else {
5832 + syncChanges = getServerMutatedFields(
5833 + updatedRecord,
5834 + persistedRecord,
5835 + record
5836 + );
5837 + }
5394 5838 getSyncManager()?.update(
5395 5839 `${kind}/${name}`,
5396 5840 recordId,
5397 - updatedRecord,
5841 + syncChanges,
5398 5842 LOCAL_UNDO_IGNORED_ORIGIN,
5399 5843 { isSave: true }
5400 5844 );
5401 5845 }
@@ -5567,37 +6011,27 @@
5567 6011 name,
5568 6012 invalidateCache
5569 6013 });
5570 6014 };
5571 - function setSyncConnectionStatus(kind, name, key, status) {
5572 - if (!status) {
5573 - return {
5574 - type: "CLEAR_SYNC_CONNECTION_STATUS",
5575 - kind,
5576 - name,
5577 - key
5578 - };
5579 - }
5580 - return {
5581 - type: "SET_SYNC_CONNECTION_STATUS",
5582 - kind,
5583 - name,
5584 - key,
5585 - status
5586 - };
5587 - }
5588 6015
5589 6016 // packages/core-data/build-module/private-actions.mjs
5590 6017 var private_actions_exports = {};
5591 6018 __export(private_actions_exports, {
6019 + __unstableNotifySyncUndoManagerChange: () => __unstableNotifySyncUndoManagerChange,
5592 6020 editMediaEntity: () => editMediaEntity,
5593 6021 receiveEditorAssets: () => receiveEditorAssets,
5594 6022 receiveEditorSettings: () => receiveEditorSettings,
5595 6023 receiveRegisteredPostMeta: () => receiveRegisteredPostMeta,
5596 6024 receiveViewConfig: () => receiveViewConfig,
5597 - setCollaborationSupported: () => setCollaborationSupported
6025 + saveDirtyEntities: () => saveDirtyEntities,
6026 + setCollaborationSupported: () => setCollaborationSupported,
6027 + setSyncConnectionStatus: () => setSyncConnectionStatus
5598 6028 });
5599 - var import_api_fetch4 = __toESM(require_api_fetch(), 1);
6029 + var import_api_fetch5 = __toESM(require_api_fetch(), 1);
6030 + var import_notices = __toESM(require_notices(), 1);
6031 + var import_block_editor5 = __toESM(require_block_editor(), 1);
6032 + var import_html_entities = __toESM(require_html_entities(), 1);
6033 + var import_i18n2 = __toESM(require_i18n(), 1);
5600 6034 function receiveRegisteredPostMeta(postType, registeredPostMeta2) {
5601 6035 return {
5602 6036 type: "RECEIVE_REGISTERED_POST_META",
5603 6037 postType,
@@ -5603,9 +6037,9 @@
5603 6037 postType,
5604 6038 registeredPostMeta: registeredPostMeta2
5605 6039 };
5606 6040 }
5607 - var editMediaEntity = (recordId, edits = {}, { __unstableFetch = import_api_fetch4.default, throwOnError = false } = {}) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => {
6041 + var editMediaEntity = (recordId, edits = {}, { __unstableFetch = import_api_fetch5.default, throwOnError = false } = {}) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => {
5608 6042 if (!recordId) {
5609 6043 return;
5610 6044 }
5611 6045 const kind = "postType";
@@ -5685,8 +6119,15 @@
5685 6119 };
5686 6120 }
5687 6121 var setCollaborationSupported = (supported) => ({ dispatch: dispatch3 }) => {
5688 6122 dispatch3({ type: "SET_COLLABORATION_SUPPORTED", supported });
6123 + if (!supported && hasSyncManager()) {
6124 + getSyncManager().unloadAll();
6125 + dispatch3.__unstableNotifySyncUndoManagerChange({
6126 + hasUndo: false,
6127 + hasRedo: false
6128 + });
6129 + }
5689 6130 };
5690 6131 function receiveViewConfig(kind, name, config) {
5691 6132 return {
5692 6133 type: "RECEIVE_VIEW_CONFIG",
@@ -5694,8 +6135,157 @@
5694 6135 name,
5695 6136 config
5696 6137 };
5697 6138 }
6139 + function __unstableNotifySyncUndoManagerChange(state) {
6140 + return {
6141 + type: "SYNC_UNDO_MANAGER_CHANGE",
6142 + ...state
6143 + };
6144 + }
6145 + function setSyncConnectionStatus(kind, name, key, status) {
6146 + if (!status) {
6147 + return {
6148 + type: "CLEAR_SYNC_CONNECTION_STATUS",
6149 + kind,
6150 + name,
6151 + key
6152 + };
6153 + }
6154 + return {
6155 + type: "SET_SYNC_CONNECTION_STATUS",
6156 + kind,
6157 + name,
6158 + key,
6159 + status
6160 + };
6161 + }
6162 + var saveDirtyEntities = ({
6163 + onSave,
6164 + dirtyEntityRecords = [],
6165 + entitiesToSkip = [],
6166 + close,
6167 + successNoticeContent
6168 + } = {}) => ({ registry }) => {
6169 + const PUBLISH_ON_SAVE_ENTITIES = [
6170 + { kind: "postType", name: "wp_navigation" }
6171 + ];
6172 + const saveNoticeId = "site-editor-save-success";
6173 + const homeUrl = registry.select(STORE_NAME).getEntityRecord("root", "__unstableBase")?.home;
6174 + registry.dispatch(import_notices.store).removeNotice(saveNoticeId);
6175 + const entitiesToSave = dirtyEntityRecords.filter(
6176 + ({ kind, name, key, property }) => {
6177 + return !entitiesToSkip.some(
6178 + (elt) => elt.kind === kind && elt.name === name && elt.key === key && elt.property === property
6179 + );
6180 + }
6181 + );
6182 + close?.(entitiesToSave);
6183 + const siteItemsToSave = [];
6184 + const pendingSavedRecords = [];
6185 + entitiesToSave.forEach(({ kind, name, key, property }) => {
6186 + if ("root" === kind && "site" === name) {
6187 + siteItemsToSave.push(property);
6188 + } else {
6189 + if (PUBLISH_ON_SAVE_ENTITIES.some(
6190 + (typeToPublish) => typeToPublish.kind === kind && typeToPublish.name === name
6191 + )) {
6192 + registry.dispatch(STORE_NAME).editEntityRecord(kind, name, key, {
6193 + status: "publish"
6194 + });
6195 + }
6196 + pendingSavedRecords.push(
6197 + registry.dispatch(STORE_NAME).saveEditedEntityRecord(kind, name, key, {
6198 + throwOnError: true
6199 + }).catch(ensureError)
6200 + );
6201 + }
6202 + });
6203 + if (siteItemsToSave.length) {
6204 + pendingSavedRecords.push(
6205 + registry.dispatch(STORE_NAME).__experimentalSaveSpecifiedEntityEdits(
6206 + "root",
6207 + "site",
6208 + void 0,
6209 + siteItemsToSave,
6210 + {
6211 + throwOnError: true
6212 + }
6213 + ).catch(ensureError)
6214 + );
6215 + }
6216 + registry.dispatch(import_block_editor5.store).__unstableMarkLastChangeAsPersistent();
6217 + return Promise.all(pendingSavedRecords).then(async (values) => {
6218 + if (onSave) {
6219 + await onSave();
6220 + }
6221 + return values;
6222 + }).then((values) => {
6223 + const errors = values.filter((v) => v instanceof Error);
6224 + if (errors.length) {
6225 + const firstMessage = errors.find(
6226 + (e) => e.message
6227 + )?.message;
6228 + registry.dispatch(import_notices.store).createErrorNotice(
6229 + (0, import_html_entities.decodeEntities)(
6230 + firstMessage || (0, import_i18n2.__)("Saving failed.")
6231 + ),
6232 + {
6233 + type: "snackbar",
6234 + id: saveNoticeId
6235 + }
6236 + );
6237 + } else {
6238 + registry.dispatch(import_notices.store).createSuccessNotice(
6239 + successNoticeContent || (0, import_i18n2.__)("Site updated."),
6240 + {
6241 + type: "snackbar",
6242 + id: saveNoticeId,
6243 + actions: [
6244 + {
6245 + label: (0, import_i18n2.__)("View site"),
6246 + url: homeUrl,
6247 + openInNewTab: true
6248 + }
6249 + ]
6250 + }
6251 + );
6252 + }
6253 + }).catch(
6254 + (error) => registry.dispatch(import_notices.store).createErrorNotice(
6255 + (0, import_html_entities.decodeEntities)(
6256 + error?.message || (0, import_i18n2.__)("Saving failed.")
6257 + ),
6258 + {
6259 + type: "snackbar",
6260 + id: saveNoticeId
6261 + }
6262 + )
6263 + );
6264 + function ensureError(error) {
6265 + if (error instanceof Error) {
6266 + return error;
6267 + }
6268 + let message;
6269 + if (!error) {
6270 + } else if (typeof error.message === "string") {
6271 + message = error.message;
6272 + } else if (typeof error === "string") {
6273 + message = error;
6274 + } else if (
6275 + // Only consider own method, lest we erroneously end up calling
6276 + // `Object#toString` at the end of the prototype chain, thereby
6277 + // returning `"[object Object]"`.
6278 + Object.hasOwn(error, "toString") && typeof error.toString === "function"
6279 + ) {
6280 + const result = error.toString();
6281 + if (typeof result === "string") {
6282 + message = result;
6283 + }
6284 + }
6285 + return new Error(message, { cause: error });
6286 + }
6287 + };
5698 6288
5699 6289 // packages/core-data/build-module/resolvers.mjs
5700 6290 var resolvers_exports = {};
5701 6291 __export(resolvers_exports, {
@@ -5731,19 +6321,19 @@
5731 6321 getUserPatternCategories: () => getUserPatternCategories2,
5732 6322 getViewConfig: () => getViewConfig2
5733 6323 });
5734 6324 var import_url6 = __toESM(require_url(), 1);
5735 - var import_html_entities2 = __toESM(require_html_entities(), 1);
5736 - var import_api_fetch8 = __toESM(require_api_fetch(), 1);
6325 + var import_html_entities3 = __toESM(require_html_entities(), 1);
6326 + var import_api_fetch9 = __toESM(require_api_fetch(), 1);
5737 6327
5738 6328 // packages/core-data/build-module/fetch/index.mjs
5739 - var import_api_fetch7 = __toESM(require_api_fetch(), 1);
6329 + var import_api_fetch8 = __toESM(require_api_fetch(), 1);
5740 6330
5741 6331 // packages/core-data/build-module/fetch/__experimental-fetch-link-suggestions.mjs
5742 - var import_api_fetch5 = __toESM(require_api_fetch(), 1);
6332 + var import_api_fetch6 = __toESM(require_api_fetch(), 1);
5743 6333 var import_url4 = __toESM(require_url(), 1);
5744 - var import_html_entities = __toESM(require_html_entities(), 1);
5745 - var import_i18n2 = __toESM(require_i18n(), 1);
6334 + var import_html_entities2 = __toESM(require_html_entities(), 1);
6335 + var import_i18n3 = __toESM(require_i18n(), 1);
5746 6336 async function fetchLinkSuggestions(search, searchOptions = {}, editorSettings2 = {}) {
5747 6337 const searchOptionsToUse = searchOptions.isInitialSuggestions && searchOptions.initialSuggestionsSearchOptions ? {
5748 6338 ...searchOptions,
5749 6339 ...searchOptions.initialSuggestionsSearchOptions
@@ -5757,9 +6347,9 @@
5757 6347 const { disablePostFormats = false } = editorSettings2;
5758 6348 const queries2 = [];
5759 6349 if (!type || type === "post") {
5760 6350 queries2.push(
5761 - (0, import_api_fetch5.default)({
6351 + (0, import_api_fetch6.default)({
5762 6352 path: (0, import_url4.addQueryArgs)("/wp/v2/search", {
5763 6353 search,
5764 6354 page,
5765 6355 per_page: perPage,
@@ -5770,9 +6360,9 @@
5770 6360 return results2.map((result) => {
5771 6361 return {
5772 6362 id: result.id,
5773 6363 url: result.url,
5774 - title: (0, import_html_entities.decodeEntities)(result.title || "") || (0, import_i18n2.__)("(no title)"),
6364 + title: (0, import_html_entities2.decodeEntities)(result.title || "") || (0, import_i18n3.__)("(no title)"),
5775 6365 type: result.subtype || result.type,
5776 6366 kind: "post-type"
5777 6367 };
5778 6368 });
@@ -5781,9 +6371,9 @@
5781 6371 );
5782 6372 }
5783 6373 if (!type || type === "term") {
5784 6374 queries2.push(
5785 - (0, import_api_fetch5.default)({
6375 + (0, import_api_fetch6.default)({
5786 6376 path: (0, import_url4.addQueryArgs)("/wp/v2/search", {
5787 6377 search,
5788 6378 page,
5789 6379 per_page: perPage,
@@ -5794,9 +6384,9 @@
5794 6384 return results2.map((result) => {
5795 6385 return {
5796 6386 id: result.id,
5797 6387 url: result.url,
5798 - title: (0, import_html_entities.decodeEntities)(result.title || "") || (0, import_i18n2.__)("(no title)"),
6388 + title: (0, import_html_entities2.decodeEntities)(result.title || "") || (0, import_i18n3.__)("(no title)"),
5799 6389 type: result.subtype || result.type,
5800 6390 kind: "taxonomy"
5801 6391 };
5802 6392 });
@@ -5805,9 +6395,9 @@
5805 6395 );
5806 6396 }
5807 6397 if (!disablePostFormats && (!type || type === "post-format")) {
5808 6398 queries2.push(
5809 - (0, import_api_fetch5.default)({
6399 + (0, import_api_fetch6.default)({
5810 6400 path: (0, import_url4.addQueryArgs)("/wp/v2/search", {
5811 6401 search,
5812 6402 page,
5813 6403 per_page: perPage,
@@ -5818,9 +6408,9 @@
5818 6408 return results2.map((result) => {
5819 6409 return {
5820 6410 id: result.id,
5821 6411 url: result.url,
5822 - title: (0, import_html_entities.decodeEntities)(result.title || "") || (0, import_i18n2.__)("(no title)"),
6412 + title: (0, import_html_entities2.decodeEntities)(result.title || "") || (0, import_i18n3.__)("(no title)"),
5823 6413 type: result.subtype || result.type,
5824 6414 kind: "taxonomy"
5825 6415 };
5826 6416 });
@@ -5829,9 +6419,9 @@
5829 6419 );
5830 6420 }
5831 6421 if (!type || type === "attachment") {
5832 6422 queries2.push(
5833 - (0, import_api_fetch5.default)({
6423 + (0, import_api_fetch6.default)({
5834 6424 path: (0, import_url4.addQueryArgs)("/wp/v2/media", {
5835 6425 search,
5836 6426 page,
5837 6427 per_page: perPage
@@ -5840,9 +6430,9 @@
5840 6430 return results2.map((result) => {
5841 6431 return {
5842 6432 id: result.id,
5843 6433 url: result.source_url,
5844 - title: (0, import_html_entities.decodeEntities)(result.title.rendered || "") || (0, import_i18n2.__)("(no title)"),
6434 + title: (0, import_html_entities2.decodeEntities)(result.title.rendered || "") || (0, import_i18n3.__)("(no title)"),
5845 6435 type: result.type,
5846 6436 kind: "media"
5847 6437 };
5848 6438 });
@@ -5858,8 +6448,9 @@
5858 6448 return results;
5859 6449 }
5860 6450 function sortResults(results, search) {
5861 6451 const searchTokens = tokenize(search);
6452 + const scoreKey = (result) => `${result.kind}:${result.type}:${result.id}`;
5862 6453 const scores = {};
5863 6454 for (const result of results) {
5864 6455 if (result.title) {
5865 6456 const titleTokens = tokenize(result.title);
@@ -5874,14 +6465,16 @@
5874 6465 )
5875 6466 );
5876 6467 const exactMatchScore = exactMatchingTokens.length / titleTokens.length * 10;
5877 6468 const subMatchScore = subMatchingTokens.length / titleTokens.length;
5878 - scores[result.id] = exactMatchScore + subMatchScore;
6469 + scores[scoreKey(result)] = exactMatchScore + subMatchScore;
5879 6470 } else {
5880 - scores[result.id] = 0;
6471 + scores[scoreKey(result)] = 0;
5881 6472 }
5882 6473 }
5883 - return results.sort((a, b) => scores[b.id] - scores[a.id]);
6474 + return results.sort(
6475 + (a, b) => scores[scoreKey(b)] - scores[scoreKey(a)]
6476 + );
5884 6477 }
5885 6478 function tokenize(text) {
5886 6479 return text.toLowerCase().match(/[\p{L}\p{N}]+/gu) || [];
5887 6480 }
@@ -5886,9 +6479,9 @@
5886 6479 return text.toLowerCase().match(/[\p{L}\p{N}]+/gu) || [];
5887 6480 }
5888 6481
5889 6482 // packages/core-data/build-module/fetch/__experimental-fetch-url-data.mjs
5890 - var import_api_fetch6 = __toESM(require_api_fetch(), 1);
6483 + var import_api_fetch7 = __toESM(require_api_fetch(), 1);
5891 6484 var import_url5 = __toESM(require_url(), 1);
5892 6485 var CACHE = /* @__PURE__ */ new Map();
5893 6486 var fetchUrlData = async (url, options = {}) => {
5894 6487 const endpoint = "/wp-block-editor/v1/url-details";
@@ -5906,9 +6499,9 @@
5906 6499 }
5907 6500 if (CACHE.has(url)) {
5908 6501 return CACHE.get(url);
5909 6502 }
5910 - return (0, import_api_fetch6.default)({
6503 + return (0, import_api_fetch7.default)({
5911 6504 path: (0, import_url5.addQueryArgs)(endpoint, args),
5912 6505 ...options
5913 6506 }).then((res) => {
5914 6507 CACHE.set(url, res);
@@ -5918,9 +6511,9 @@
5918 6511 var experimental_fetch_url_data_default = fetchUrlData;
5919 6512
5920 6513 // packages/core-data/build-module/fetch/index.mjs
5921 6514 async function fetchBlockPatterns() {
5922 - const restPatterns = await (0, import_api_fetch7.default)({
6515 + const restPatterns = await (0, import_api_fetch8.default)({
5923 6516 path: "/wp/v2/block-patterns/patterns"
5924 6517 });
5925 6518 if (!restPatterns) {
5926 6519 return [];
@@ -5934,8 +6527,34 @@
5934 6527 )
5935 6528 );
5936 6529 }
5937 6530
6531 + // packages/core-data/build-module/parsed-blocks-cache.mjs
6532 + var import_data10 = __toESM(require_data(), 1);
6533 + var import_blocks5 = __toESM(require_blocks(), 1);
6534 + var caches = /* @__PURE__ */ new WeakMap();
6535 + function getCacheKey(kind, name, id) {
6536 + return `${kind}:${name}:${id}`;
6537 + }
6538 + function getBlockTypes2() {
6539 + return (0, import_data10.select)(import_blocks5.store).getBlockTypes();
6540 + }
6541 + function getCachedBlocks(kind, name, id, content) {
6542 + const cached = caches.get(getBlockTypes2())?.get(getCacheKey(kind, name, id));
6543 + if (cached && cached.content === content) {
6544 + return cached.blocks;
6545 + }
6546 + }
6547 + function setCachedBlocks(kind, name, id, content, blocks) {
6548 + const blockTypes = getBlockTypes2();
6549 + let cache3 = caches.get(blockTypes);
6550 + if (!cache3) {
6551 + cache3 = /* @__PURE__ */ new Map();
6552 + caches.set(blockTypes, cache3);
6553 + }
6554 + cache3.set(getCacheKey(kind, name, id), { content, blocks });
6555 + }
6556 +
5938 6557 // packages/core-data/build-module/resolvers.mjs
5939 6558 var getAuthors2 = (query) => async ({ dispatch: dispatch3 }) => {
5940 6559 const path = (0, import_url6.addQueryArgs)(
5941 6560 "/wp/v2/users/?who=authors&per_page=100",
@@ -5940,13 +6559,13 @@
5940 6559 const path = (0, import_url6.addQueryArgs)(
5941 6560 "/wp/v2/users/?who=authors&per_page=100",
5942 6561 query
5943 6562 );
5944 - const users2 = await (0, import_api_fetch8.default)({ path });
6563 + const users2 = await (0, import_api_fetch9.default)({ path });
5945 6564 dispatch3.receiveUserQuery(path, users2);
5946 6565 };
5947 6566 var getCurrentUser2 = () => async ({ dispatch: dispatch3 }) => {
5948 - const currentUser2 = await (0, import_api_fetch8.default)({ path: "/wp/v2/users/me" });
6567 + const currentUser2 = await (0, import_api_fetch9.default)({ path: "/wp/v2/users/me" });
5949 6568 dispatch3.receiveCurrentUser(currentUser2);
5950 6569 };
5951 6570 var getEntityRecord2 = (kind, name, key = "", query) => async ({ select: select5, dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => {
5952 6571 const configs = await resolveSelect2.getEntitiesConfig(kind);
@@ -5983,22 +6602,18 @@
5983 6602 if (hasRecord) {
5984 6603 return;
5985 6604 }
5986 6605 }
5987 - let { baseURL } = entityConfig;
5988 - if (kind === "postType" && name === "wp_template" && (key && typeof key === "string" && !/^\d+$/.test(key) || !window?.__experimentalTemplateActivate)) {
5989 - baseURL = baseURL.slice(0, baseURL.lastIndexOf("/")) + "/templates";
5990 - }
6606 + const { baseURL } = entityConfig;
5991 6607 const path = (0, import_url6.addQueryArgs)(baseURL + (key ? "/" + key : ""), {
5992 6608 ...entityConfig.baseURLParams,
5993 6609 ...query
5994 6610 });
5995 - const response = await (0, import_api_fetch8.default)({ path, parse: false });
6611 + const response = await (0, import_api_fetch9.default)({ path, parse: false });
5996 6612 const record = await response.json();
5997 6613 const permissions = getUserPermissionsFromAllowHeader(
5998 6614 response.headers?.get("allow")
5999 6615 );
6000 - const canUserResolutionsArgs = [];
6001 6616 const receiveUserPermissionArgs = {};
6002 6617 for (const action of ALLOWED_RESOURCE_ACTIONS) {
6003 6618 receiveUserPermissionArgs[getUserPermissionCacheKey(action, {
6004 6619 kind,
@@ -6004,13 +6619,10 @@
6004 6619 kind,
6005 6620 name,
6006 6621 id: key
6007 6622 })] = permissions[action];
6008 - canUserResolutionsArgs.push([
6009 - action,
6010 - { kind, name, id: key }
6011 - ]);
6012 6623 }
6624 + const canUserResolutionsArgs = [[{ kind, name, id: key }]];
6013 6625 if (entityConfig.syncConfig && isNumericID(key) && !query) {
6014 6626 const objectType = `${kind}/${name}`;
6015 6627 const objectId = key;
6016 6628 const recordWithTransients = { ...record };
@@ -6018,9 +6630,19 @@
6018 6630 ([propName, transientConfig]) => void 0 === recordWithTransients[propName] && transientConfig && "object" === typeof transientConfig && "read" in transientConfig && "function" === typeof transientConfig.read
6019 6631 ).forEach(([propName, transientConfig]) => {
6020 6632 recordWithTransients[propName] = transientConfig.read(recordWithTransients);
6021 6633 });
6022 - void getSyncManager()?.load(
6634 + if (recordWithTransients.blocks && typeof recordWithTransients.content?.raw === "string") {
6635 + setCachedBlocks(
6636 + kind,
6637 + name,
6638 + key,
6639 + recordWithTransients.content.raw,
6640 + recordWithTransients.blocks
6641 + );
6642 + }
6643 + const syncManager2 = select5?.isCollaborationSupported?.() === false ? void 0 : getSyncManager();
6644 + void syncManager2?.load(
6023 6645 entityConfig.syncConfig,
6024 6646 objectType,
6025 6647 objectId,
6026 6648 recordWithTransients,
@@ -6061,9 +6683,9 @@
6061 6683 refetchRecord: async () => {
6062 6684 dispatch3.receiveEntityRecords(
6063 6685 kind,
6064 6686 name,
6065 - await (0, import_api_fetch8.default)({ path, parse: true }),
6687 + await (0, import_api_fetch9.default)({ path, parse: true }),
6066 6688 query
6067 6689 );
6068 6690 },
6069 6691 // Persist the CRDT document.
@@ -6072,17 +6694,21 @@
6072 6694 // This effectively means that only post entities support CRDT
6073 6695 // persistence. As we add support for syncing additional entity,
6074 6696 // we'll need to revisit where persisted CRDT documents are stored.
6075 6697 persistCRDTDoc: () => {
6076 - resolveSelect2.getEditedEntityRecord(kind, name, key).then((editedRecord) => {
6698 + if (!entityConfig.syncConfig?.supportsPersistence) {
6699 + return;
6700 + }
6701 + return resolveSelect2.getEditedEntityRecord(kind, name, key).then(async (editedRecord) => {
6077 6702 const { meta, status } = editedRecord;
6078 6703 if ("auto-draft" === status || !meta) {
6079 6704 return;
6080 6705 }
6081 - dispatch3.saveEntityRecord(
6082 - kind,
6083 - name,
6084 - editedRecord
6706 + const entityIdKey = entityConfig.key || DEFAULT_ENTITY_KEY;
6707 + const entityId = editedRecord[entityIdKey];
6708 + await saveCRDTDoc(
6709 + `${kind}/${name}`,
6710 + entityId
6085 6711 );
6086 6712 });
6087 6713 },
6088 6714 addUndoMeta: (ydoc, meta) => {
@@ -6093,8 +6719,13 @@
6093 6719 selectionHistory
6094 6720 );
6095 6721 }
6096 6722 },
6723 + onUndoStackChange: (undoState) => {
6724 + dispatch3.__unstableNotifySyncUndoManagerChange(
6725 + undoState
6726 + );
6727 + },
6097 6728 restoreUndoMeta: (ydoc, meta) => {
6098 6729 const selectionHistory = meta.get("selectionHistory");
6099 6730 if (selectionHistory) {
6100 6731 setTimeout(() => {
@@ -6157,13 +6788,9 @@
6157 6788 ])
6158 6789 ].join()
6159 6790 };
6160 6791 }
6161 - let { baseURL } = entityConfig;
6162 - const { combinedTemplates = true } = query;
6163 - if (kind === "postType" && name === "wp_template" && combinedTemplates) {
6164 - baseURL = baseURL.slice(0, baseURL.lastIndexOf("/")) + "/templates";
6165 - }
6792 + const { baseURL } = entityConfig;
6166 6793 const path = (0, import_url6.addQueryArgs)(baseURL, {
6167 6794 ...entityConfig.baseURLParams,
6168 6795 ...query
6169 6796 });
@@ -6168,35 +6795,25 @@
6168 6795 ...query
6169 6796 });
6170 6797 let records = [], meta;
6171 6798 if (entityConfig.supportsPagination && query.per_page !== -1) {
6172 - const response = await (0, import_api_fetch8.default)({ path, parse: false });
6799 + const response = await (0, import_api_fetch9.default)({ path, parse: false });
6173 6800 records = Object.values(await response.json());
6174 - meta = {
6175 - totalItems: parseInt(
6176 - response.headers.get("X-WP-Total")
6177 - ),
6178 - totalPages: parseInt(
6179 - response.headers.get("X-WP-TotalPages")
6180 - )
6181 - };
6801 + meta = getPaginationMeta(response.headers);
6182 6802 } else if (query.per_page === -1 && query[RECEIVE_INTERMEDIATE_RESULTS] === true) {
6183 6803 let page = 1;
6184 6804 let totalPages;
6185 6805 do {
6186 - const response = await (0, import_api_fetch8.default)({
6806 + const response = await (0, import_api_fetch9.default)({
6187 6807 path: (0, import_url6.addQueryArgs)(path, { page, per_page: 100 }),
6188 6808 parse: false
6189 6809 });
6190 6810 const pageRecords = Object.values(await response.json());
6191 - totalPages = parseInt(
6192 - response.headers.get("X-WP-TotalPages")
6193 - );
6811 + const pageMeta = getPaginationMeta(response.headers);
6812 + totalPages = pageMeta.totalPages ?? 1;
6194 6813 if (!meta) {
6195 6814 meta = {
6196 - totalItems: parseInt(
6197 - response.headers.get("X-WP-Total")
6198 - ),
6815 + totalItems: pageMeta.totalItems,
6199 6816 totalPages: 1
6200 6817 };
6201 6818 }
6202 6819 records.push(...pageRecords);
@@ -6217,9 +6834,9 @@
6217 6834 });
6218 6835 page++;
6219 6836 } while (page <= totalPages);
6220 6837 } else {
6221 - records = Object.values(await (0, import_api_fetch8.default)({ path }));
6838 + records = Object.values(await (0, import_api_fetch9.default)({ path }));
6222 6839 meta = {
6223 6840 totalItems: records.length,
6224 6841 totalPages: 1
6225 6842 };
@@ -6241,9 +6858,9 @@
6241 6858 refetchRecords: async () => {
6242 6859 dispatch3.receiveEntityRecords(
6243 6860 kind,
6244 6861 name,
6245 - await (0, import_api_fetch8.default)({ path, parse: true }),
6862 + await (0, import_api_fetch9.default)({ path, parse: true }),
6246 6863 query
6247 6864 );
6248 6865 }
6249 6866 }
@@ -6279,13 +6896,12 @@
6279 6896 }));
6280 6897 const canUserResolutionsArgs = [];
6281 6898 const receiveUserPermissionArgs = {};
6282 6899 for (const targetHint of targetHints) {
6900 + canUserResolutionsArgs.push([
6901 + { kind, name, id: targetHint.id }
6902 + ]);
6283 6903 for (const action of ALLOWED_RESOURCE_ACTIONS) {
6284 - canUserResolutionsArgs.push([
6285 - action,
6286 - { kind, name, id: targetHint.id }
6287 - ]);
6288 6904 receiveUserPermissionArgs[getUserPermissionCacheKey(action, {
6289 6905 kind,
6290 6906 name,
6291 6907 id: targetHint.id
@@ -6326,9 +6942,9 @@
6326 6942 };
6327 6943 var getThemeSupports2 = forward_resolver_default("getCurrentTheme");
6328 6944 var getEmbedPreview2 = (url) => async ({ dispatch: dispatch3 }) => {
6329 6945 try {
6330 - const embedProxyResponse = await (0, import_api_fetch8.default)({
6946 + const embedProxyResponse = await (0, import_api_fetch9.default)({
6331 6947 path: (0, import_url6.addQueryArgs)("/oembed/1.0/proxy", { url })
6332 6948 });
6333 6949 dispatch3.receiveEmbedPreview(url, embedProxyResponse);
6334 6950 } catch {
@@ -6334,26 +6950,9 @@
6334 6950 } catch {
6335 6951 dispatch3.receiveEmbedPreview(url, false);
6336 6952 }
6337 6953 };
6338 - var canUser2 = (requestedAction, resource, id) => async ({ dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => {
6339 - if (!ALLOWED_RESOURCE_ACTIONS.includes(requestedAction)) {
6340 - throw new Error(`'${requestedAction}' is not a valid action.`);
6341 - }
6342 - const { hasStartedResolution } = registry.select(STORE_NAME);
6343 - for (const relatedAction of ALLOWED_RESOURCE_ACTIONS) {
6344 - if (relatedAction === requestedAction) {
6345 - continue;
6346 - }
6347 - const isAlreadyResolving = hasStartedResolution("canUser", [
6348 - relatedAction,
6349 - resource,
6350 - id
6351 - ]);
6352 - if (isAlreadyResolving) {
6353 - return;
6354 - }
6355 - }
6954 + var canUser2 = (resource, id) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => {
6356 6955 let resourcePath = null;
6357 6956 if (typeof resource === "object") {
6358 6957 if (!resource.kind || !resource.name) {
6359 6958 throw new Error("The entity resource object is not valid.");
@@ -6372,9 +6971,9 @@
6372 6971 resourcePath = `/wp/v2/${resource}` + (id ? "/" + id : "");
6373 6972 }
6374 6973 let response;
6375 6974 try {
6376 - response = await (0, import_api_fetch8.default)({
6975 + response = await (0, import_api_fetch9.default)({
6377 6976 path: resourcePath,
6378 6977 method: "OPTIONS",
6379 6978 parse: false
6380 6979 });
@@ -6384,22 +6983,16 @@
6384 6983 const permissions = getUserPermissionsFromAllowHeader(
6385 6984 response.headers?.get("allow")
6386 6985 );
6387 6986 const receiveUserPermissionArgs = {};
6388 - const canUserResolutionsArgs = [];
6389 6987 for (const action of ALLOWED_RESOURCE_ACTIONS) {
6390 6988 receiveUserPermissionArgs[getUserPermissionCacheKey(action, resource, id)] = permissions[action];
6391 - if (action !== requestedAction) {
6392 - canUserResolutionsArgs.push([action, resource, id]);
6393 - }
6394 6989 }
6395 - registry.batch(() => {
6396 - dispatch3.receiveUserPermissions(receiveUserPermissionArgs);
6397 - dispatch3.finishResolutions("canUser", canUserResolutionsArgs);
6398 - });
6990 + dispatch3.receiveUserPermissions(receiveUserPermissionArgs);
6399 6991 };
6400 - var canUserEditEntityRecord2 = (kind, name, recordId) => async ({ dispatch: dispatch3 }) => {
6401 - await dispatch3(canUser2("update", { kind, name, id: recordId }));
6992 + canUser2.getResolutionArgs = (action, resource, id) => [resource, id];
6993 + var canUserEditEntityRecord2 = (kind, name, recordId) => async ({ resolveSelect: resolveSelect2 }) => {
6994 + await resolveSelect2.canUser("update", { kind, name, id: recordId });
6402 6995 };
6403 6996 var getAutosaves2 = (postType, postId) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => {
6404 6997 const {
6405 6998 rest_base: restBase,
@@ -6408,9 +7001,9 @@
6408 7001 } = await resolveSelect2.getPostType(postType);
6409 7002 if (!supports?.autosave) {
6410 7003 return;
6411 7004 }
6412 - const autosaves2 = await (0, import_api_fetch8.default)({
7005 + const autosaves2 = await (0, import_api_fetch9.default)({
6413 7006 path: `/${restNamespace}/${restBase}/${postId}/autosaves?context=edit`
6414 7007 });
6415 7008 if (autosaves2 && autosaves2.length) {
6416 7009 dispatch3.receiveAutosaves(postId, autosaves2);
@@ -6436,9 +7029,9 @@
6436 7029 }
6437 7030 };
6438 7031 var __experimentalGetCurrentThemeBaseGlobalStyles2 = () => async ({ resolveSelect: resolveSelect2, dispatch: dispatch3 }) => {
6439 7032 const currentTheme2 = await resolveSelect2.getCurrentTheme();
6440 - const themeGlobalStyles = await (0, import_api_fetch8.default)({
7033 + const themeGlobalStyles = await (0, import_api_fetch9.default)({
6441 7034 path: `/wp/v2/global-styles/themes/${currentTheme2.stylesheet}?context=view`
6442 7035 });
6443 7036 dispatch3.__experimentalReceiveThemeBaseGlobalStyles(
6444 7037 currentTheme2.stylesheet,
@@ -6446,9 +7039,9 @@
6446 7039 );
6447 7040 };
6448 7041 var __experimentalGetCurrentThemeGlobalStylesVariations2 = () => async ({ resolveSelect: resolveSelect2, dispatch: dispatch3 }) => {
6449 7042 const currentTheme2 = await resolveSelect2.getCurrentTheme();
6450 - const variations = await (0, import_api_fetch8.default)({
7043 + const variations = await (0, import_api_fetch9.default)({
6451 7044 path: `/wp/v2/global-styles/themes/${currentTheme2.stylesheet}/variations?context=view`
6452 7045 });
6453 7046 dispatch3.__experimentalReceiveThemeGlobalStyleVariations(
6454 7047 currentTheme2.stylesheet,
@@ -6463,9 +7056,9 @@
6463 7056 globalStylesId
6464 7057 ) : void 0;
6465 7058 const revisionsURL = record?._links?.["version-history"]?.[0]?.href;
6466 7059 if (revisionsURL) {
6467 - const resetRevisions = await (0, import_api_fetch8.default)({
7060 + const resetRevisions = await (0, import_api_fetch9.default)({
6468 7061 url: revisionsURL
6469 7062 });
6470 7063 const revisions = resetRevisions?.map(
6471 7064 (revision) => Object.fromEntries(
@@ -6488,9 +7081,9 @@
6488 7081 const patterns = await fetchBlockPatterns();
6489 7082 dispatch3({ type: "RECEIVE_BLOCK_PATTERNS", patterns });
6490 7083 };
6491 7084 var getBlockPatternCategories2 = () => async ({ dispatch: dispatch3 }) => {
6492 - const categories = await (0, import_api_fetch8.default)({
7085 + const categories = await (0, import_api_fetch9.default)({
6493 7086 path: "/wp/v2/block-patterns/categories"
6494 7087 });
6495 7088 dispatch3({ type: "RECEIVE_BLOCK_PATTERN_CATEGORIES", categories });
6496 7089 };
@@ -6505,9 +7098,9 @@
6505 7098 }
6506 7099 );
6507 7100 const mappedPatternCategories = patternCategories?.map((userCategory) => ({
6508 7101 ...userCategory,
6509 - label: (0, import_html_entities2.decodeEntities)(userCategory.name),
7102 + label: (0, import_html_entities3.decodeEntities)(userCategory.name),
6510 7103 name: userCategory.slug
6511 7104 })) || [];
6512 7105 dispatch3({
6513 7106 type: "RECEIVE_USER_PATTERN_CATEGORIES",
@@ -6514,9 +7107,9 @@
6514 7107 patternCategories: mappedPatternCategories
6515 7108 });
6516 7109 };
6517 7110 var getNavigationFallbackId2 = () => async ({ dispatch: dispatch3, select: select5, registry }) => {
6518 - const fallback = await (0, import_api_fetch8.default)({
7111 + const fallback = await (0, import_api_fetch9.default)({
6519 7112 path: (0, import_url6.addQueryArgs)("/wp-block-editor/v1/navigation-fallback", {
6520 7113 _embed: true
6521 7114 })
6522 7115 });
@@ -6546,13 +7139,13 @@
6546 7139 ]);
6547 7140 });
6548 7141 };
6549 7142 var getDefaultTemplateId2 = (query) => async ({ dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => {
6550 - const template = await (0, import_api_fetch8.default)({
7143 + const template = await (0, import_api_fetch9.default)({
6551 7144 path: (0, import_url6.addQueryArgs)("/wp/v2/templates/lookup", query)
6552 7145 });
6553 7146 await resolveSelect2.getEntitiesConfig("postType");
6554 - const id = window?.__experimentalTemplateActivate ? template?.wp_id || template?.id : template?.id;
7147 + const id = template?.id;
6555 7148 registry.batch(() => {
6556 7149 dispatch3.receiveDefaultTemplateId(query, id || "");
6557 7150 if (id) {
6558 7151 template.id = id;
@@ -6568,12 +7161,9 @@
6568 7161 ]);
6569 7162 }
6570 7163 });
6571 7164 };
6572 - getDefaultTemplateId2.shouldInvalidate = (action) => {
6573 - return action.type === "RECEIVE_ITEMS" && action.kind === "root" && action.name === "site";
6574 - };
6575 - var getRevisions2 = (kind, name, recordKey, query = {}) => async ({ dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => {
7165 + var getRevisions2 = (kind, name, recordKey, query = {}) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => {
6576 7166 const configs = await resolveSelect2.getEntitiesConfig(kind);
6577 7167 const entityConfig = configs.find(
6578 7168 (config) => config.name === name && config.kind === kind
6579 7169 );
@@ -6605,9 +7195,9 @@
6605 7195 let records, response;
6606 7196 const meta = {};
6607 7197 const isPaginated = entityConfig.supportsPagination && query.per_page !== -1;
6608 7198 try {
6609 - response = await (0, import_api_fetch8.default)({ path, parse: !isPaginated });
7199 + response = await (0, import_api_fetch9.default)({ path, parse: !isPaginated });
6610 7200 } catch {
6611 7201 return;
6612 7202 }
6613 7203 if (response) {
@@ -6612,11 +7202,11 @@
6612 7202 }
6613 7203 if (response) {
6614 7204 if (isPaginated) {
6615 7205 records = Object.values(await response.json());
6616 - meta.totalItems = parseInt(
6617 - response.headers.get("X-WP-Total")
6618 - );
7206 + meta.totalItems = getPaginationMeta(
7207 + response.headers
7208 + ).totalItems;
6619 7209 } else {
6620 7210 records = Object.values(response);
6621 7211 }
6622 7212 if (query._fields) {
@@ -6628,32 +7218,27 @@
6628 7218 });
6629 7219 return record;
6630 7220 });
6631 7221 }
6632 - registry.batch(() => {
6633 - dispatch3.receiveRevisions(
6634 - kind,
6635 - name,
6636 - recordKey,
6637 - records,
6638 - query,
6639 - false,
6640 - meta
6641 - );
6642 - const key = entityConfig.revisionKey || DEFAULT_ENTITY_KEY;
6643 - const normalizedQuery = normalizeQueryForResolution(rawQuery);
6644 - const resolutionsArgs = records.filter((record) => record[key]).map((record) => [
6645 - kind,
6646 - name,
6647 - recordKey,
6648 - record[key],
6649 - normalizedQuery
6650 - ]);
6651 - dispatch3.finishResolutions(
6652 - "getRevision",
6653 - resolutionsArgs
6654 - );
6655 - });
7222 + await dispatch3.receiveRevisions(
7223 + kind,
7224 + name,
7225 + recordKey,
7226 + records,
7227 + query,
7228 + false,
7229 + meta
7230 + );
7231 + const key = entityConfig.revisionKey || DEFAULT_ENTITY_KEY;
7232 + const normalizedQuery = normalizeQueryForResolution(rawQuery);
7233 + const resolutionsArgs = records.filter((record) => record[key]).map((record) => [
7234 + kind,
7235 + name,
7236 + recordKey,
7237 + record[key],
7238 + normalizedQuery
7239 + ]);
7240 + dispatch3.finishResolutions("getRevision", resolutionsArgs);
6656 7241 }
6657 7242 } finally {
6658 7243 dispatch3.__unstableReleaseStoreLock(lock2);
6659 7244 }
@@ -6700,14 +7285,14 @@
6700 7285 query
6701 7286 );
6702 7287 let record;
6703 7288 try {
6704 - record = await (0, import_api_fetch8.default)({ path });
7289 + record = await (0, import_api_fetch9.default)({ path });
6705 7290 } catch {
6706 7291 return;
6707 7292 }
6708 7293 if (record) {
6709 - dispatch3.receiveRevisions(
7294 + await dispatch3.receiveRevisions(
6710 7295 kind,
6711 7296 name,
6712 7297 recordKey,
6713 7298 record,
@@ -6724,9 +7309,9 @@
6724 7309 const {
6725 7310 rest_namespace: restNamespace = "wp/v2",
6726 7311 rest_base: restBase
6727 7312 } = await resolveSelect2.getPostType(postType) || {};
6728 - options = await (0, import_api_fetch8.default)({
7313 + options = await (0, import_api_fetch9.default)({
6729 7314 path: `${restNamespace}/${restBase}/?context=edit`,
6730 7315 method: "OPTIONS"
6731 7316 });
6732 7317 } catch {
@@ -6755,22 +7340,27 @@
6755 7340 } catch {
6756 7341 }
6757 7342 };
6758 7343 var getEditorSettings2 = () => async ({ dispatch: dispatch3 }) => {
6759 - const settings = await (0, import_api_fetch8.default)({
7344 + const settings = await (0, import_api_fetch9.default)({
6760 7345 path: "/wp-block-editor/v1/settings"
6761 7346 });
6762 7347 dispatch3.receiveEditorSettings(settings);
6763 7348 };
6764 7349 var getEditorAssets2 = () => async ({ dispatch: dispatch3 }) => {
6765 - const assets = await (0, import_api_fetch8.default)({
7350 + const assets = await (0, import_api_fetch9.default)({
6766 7351 path: "/wp-block-editor/v1/assets"
6767 7352 });
6768 7353 dispatch3.receiveEditorAssets(assets);
6769 7354 };
6770 - var getViewConfig2 = (kind, name) => async ({ dispatch: dispatch3 }) => {
6771 - const config = await (0, import_api_fetch8.default)({
6772 - path: (0, import_url6.addQueryArgs)("/wp/v2/view-config", { kind, name })
7355 + var getViewConfig2 = (kind, name, options = {}) => async ({ dispatch: dispatch3 }) => {
7356 + const query = { kind, name };
7357 + const fields = get_normalized_comma_separable_default(options.fields);
7358 + if (fields?.length) {
7359 + query._fields = fields.join(",");
7360 + }
7361 + const config = await (0, import_api_fetch9.default)({
7362 + path: (0, import_url6.addQueryArgs)("/wp/v2/view-config", query)
6773 7363 });
6774 7364 dispatch3.receiveViewConfig(kind, name, config);
6775 7365 };
6776 7366
@@ -6857,9 +7447,9 @@
6857 7447 const node = getNode(newTree, storePath);
6858 7448 node.locks = [...node.locks, lock2];
6859 7449 return {
6860 7450 ...state,
6861 - requests: state.requests.filter((r) => r !== request),
7451 + requests: state.requests.filter((r2) => r2 !== request),
6862 7452 tree: newTree
6863 7453 };
6864 7454 }
6865 7455 case "RELEASE_LOCK": {
@@ -6979,9 +7569,17 @@
6979 7569 ...parent?.[kind],
6980 7570 [name]: id
6981 7571 }
6982 7572 },
6983 - ...revisionId !== void 0 && { revisionId }
7573 + ...revisionId !== void 0 && kind && {
7574 + revision: {
7575 + ...parent?.revision,
7576 + [kind]: {
7577 + ...parent?.revision?.[kind],
7578 + [name]: revisionId
7579 + }
7580 + }
7581 + }
6984 7582 }),
6985 7583 [parent, kind, name, id, revisionId]
6986 7584 );
6987 7585 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EntityContext.Provider, { value: childContext, children });
@@ -6991,79 +7589,8 @@
6991 7589 var import_data11 = __toESM(require_data(), 1);
6992 7590 var import_deprecated4 = __toESM(require_deprecated(), 1);
6993 7591 var import_element3 = __toESM(require_element(), 1);
6994 7592
6995 - // packages/core-data/build-module/hooks/use-query-select.mjs
6996 - var import_data10 = __toESM(require_data(), 1);
6997 -
6998 - // node_modules/memize/dist/index.js
6999 - function memize(fn, options) {
7000 - var size = 0;
7001 - var head;
7002 - var tail;
7003 - options = options || {};
7004 - function memoized() {
7005 - var node = head, len = arguments.length, args, i;
7006 - searchCache: while (node) {
7007 - if (node.args.length !== arguments.length) {
7008 - node = node.next;
7009 - continue;
7010 - }
7011 - for (i = 0; i < len; i++) {
7012 - if (node.args[i] !== arguments[i]) {
7013 - node = node.next;
7014 - continue searchCache;
7015 - }
7016 - }
7017 - if (node !== head) {
7018 - if (node === tail) {
7019 - tail = node.prev;
7020 - }
7021 - node.prev.next = node.next;
7022 - if (node.next) {
7023 - node.next.prev = node.prev;
7024 - }
7025 - node.next = head;
7026 - node.prev = null;
7027 - head.prev = node;
7028 - head = node;
7029 - }
7030 - return node.val;
7031 - }
7032 - args = new Array(len);
7033 - for (i = 0; i < len; i++) {
7034 - args[i] = arguments[i];
7035 - }
7036 - node = {
7037 - args,
7038 - // Generate the result from original function
7039 - val: fn.apply(null, args)
7040 - };
7041 - if (head) {
7042 - head.prev = node;
7043 - node.next = head;
7044 - } else {
7045 - tail = node;
7046 - }
7047 - if (size === /** @type {MemizeOptions} */
7048 - options.maxSize) {
7049 - tail = /** @type {MemizeCacheNode} */
7050 - tail.prev;
7051 - tail.next = null;
7052 - } else {
7053 - size++;
7054 - }
7055 - head = node;
7056 - return node.val;
7057 - }
7058 - memoized.clear = function() {
7059 - head = null;
7060 - tail = null;
7061 - size = 0;
7062 - };
7063 - return memoized;
7064 - }
7065 -
7066 7593 // packages/core-data/build-module/hooks/constants.mjs
7067 7594 var Status = /* @__PURE__ */ ((Status2) => {
7068 7595 Status2["Idle"] = "IDLE";
7069 7596 Status2["Resolving"] = "RESOLVING";
@@ -7071,62 +7598,31 @@
7071 7598 Status2["Success"] = "SUCCESS";
7072 7599 return Status2;
7073 7600 })(Status || {});
7074 7601
7075 - // packages/core-data/build-module/hooks/use-query-select.mjs
7076 - var META_SELECTORS = [
7077 - "getIsResolving",
7078 - "hasStartedResolution",
7079 - "hasFinishedResolution",
7080 - "isResolving",
7081 - "getCachedResolvers"
7082 - ];
7083 - function useQuerySelect(mapQuerySelect, deps) {
7084 - return (0, import_data10.useSelect)((select5, registry) => {
7085 - const resolve = (store2) => enrichSelectors(select5(store2));
7086 - return mapQuerySelect(resolve, registry);
7087 - }, deps);
7602 + // packages/core-data/build-module/hooks/utils.mjs
7603 + function getResolutionStatus(resolutionStatus) {
7604 + let status;
7605 + switch (resolutionStatus) {
7606 + case "resolving":
7607 + status = Status.Resolving;
7608 + break;
7609 + case "finished":
7610 + status = Status.Success;
7611 + break;
7612 + case "error":
7613 + status = Status.Error;
7614 + break;
7615 + default:
7616 + status = Status.Idle;
7617 + }
7618 + return {
7619 + status,
7620 + isResolving: status === Status.Resolving,
7621 + hasStarted: status !== Status.Idle,
7622 + hasResolved: status === Status.Success || status === Status.Error
7623 + };
7088 7624 }
7089 - var enrichSelectors = memize(((selectors) => {
7090 - const resolvers = {};
7091 - for (const selectorName in selectors) {
7092 - if (META_SELECTORS.includes(selectorName)) {
7093 - continue;
7094 - }
7095 - Object.defineProperty(resolvers, selectorName, {
7096 - get: () => (...args) => {
7097 - const data = selectors[selectorName](...args);
7098 - const resolutionStatus = selectors.getResolutionState(
7099 - selectorName,
7100 - args
7101 - )?.status;
7102 - let status;
7103 - switch (resolutionStatus) {
7104 - case "resolving":
7105 - status = Status.Resolving;
7106 - break;
7107 - case "finished":
7108 - status = Status.Success;
7109 - break;
7110 - case "error":
7111 - status = Status.Error;
7112 - break;
7113 - case void 0:
7114 - status = Status.Idle;
7115 - break;
7116 - }
7117 - return {
7118 - data,
7119 - status,
7120 - isResolving: status === Status.Resolving,
7121 - hasStarted: status !== Status.Idle,
7122 - hasResolved: status === Status.Success || status === Status.Error
7123 - };
7124 - }
7125 - });
7126 - }
7127 - return resolvers;
7128 - }));
7129 7625
7130 7626 // packages/core-data/build-module/hooks/use-entity-record.mjs
7131 7627 var EMPTY_OBJECT3 = {};
7132 7628 function useEntityRecord(kind, name, recordId, options = { enabled: true }) {
@@ -7140,54 +7636,56 @@
7140 7636 })
7141 7637 }),
7142 7638 [editEntityRecord2, kind, name, recordId, saveEditedEntityRecord2]
7143 7639 );
7144 - const { editedRecord, hasEdits, edits } = (0, import_data11.useSelect)(
7640 + const { record, editedRecord, hasEdits, edits, ...resolution } = (0, import_data11.useSelect)(
7145 7641 (select5) => {
7146 7642 if (!options.enabled) {
7147 7643 return {
7644 + record: null,
7148 7645 editedRecord: EMPTY_OBJECT3,
7149 7646 hasEdits: false,
7150 - edits: EMPTY_OBJECT3
7647 + edits: EMPTY_OBJECT3,
7648 + ...getResolutionStatus()
7151 7649 };
7152 7650 }
7651 + const storeSelectors = select5(store);
7652 + const resolutionStatus = storeSelectors.getResolutionState(
7653 + "getEntityRecord",
7654 + [kind, name, recordId]
7655 + )?.status;
7153 7656 return {
7154 - editedRecord: select5(store).getEditedEntityRecord(
7657 + record: storeSelectors.getEntityRecord(
7155 7658 kind,
7156 7659 name,
7157 7660 recordId
7661 + ) ?? null,
7662 + editedRecord: storeSelectors.getEditedEntityRecord(
7663 + kind,
7664 + name,
7665 + recordId
7158 7666 ),
7159 - hasEdits: select5(store).hasEditsForEntityRecord(
7667 + hasEdits: storeSelectors.hasEditsForEntityRecord(
7160 7668 kind,
7161 7669 name,
7162 7670 recordId
7163 7671 ),
7164 - edits: select5(store).getEntityRecordNonTransientEdits(
7672 + edits: storeSelectors.getEntityRecordNonTransientEdits(
7165 7673 kind,
7166 7674 name,
7167 7675 recordId
7168 - )
7676 + ),
7677 + ...getResolutionStatus(resolutionStatus)
7169 7678 };
7170 7679 },
7171 7680 [kind, name, recordId, options.enabled]
7172 7681 );
7173 - const { data: record, ...querySelectRest } = useQuerySelect(
7174 - (query) => {
7175 - if (!options.enabled) {
7176 - return {
7177 - data: null
7178 - };
7179 - }
7180 - return query(store).getEntityRecord(kind, name, recordId);
7181 - },
7182 - [kind, name, recordId, options.enabled]
7183 - );
7184 7682 return {
7185 7683 record,
7186 7684 editedRecord,
7187 7685 hasEdits,
7188 7686 edits,
7189 - ...querySelectRest,
7687 + ...resolution,
7190 7688 ...mutations
7191 7689 };
7192 7690 }
7193 7691 function useDeprecatedEntityRecord(kind, name, recordId, options) {
@@ -7205,39 +7703,41 @@
7205 7703 var import_element4 = __toESM(require_element(), 1);
7206 7704 var EMPTY_ARRAY = [];
7207 7705 function useEntityRecords(kind, name, queryArgs = {}, options = { enabled: true }) {
7208 7706 const queryAsString = (0, import_url7.addQueryArgs)("", queryArgs);
7209 - const { data: records, ...rest } = useQuerySelect(
7210 - (query) => {
7707 + const { records, totalItems, totalPages, ...rest } = (0, import_data12.useSelect)(
7708 + (select5) => {
7211 7709 if (!options.enabled) {
7212 7710 return {
7213 7711 // Avoiding returning a new reference on every execution.
7214 - data: EMPTY_ARRAY
7215 - };
7216 - }
7217 - return query(store).getEntityRecords(kind, name, queryArgs);
7218 - },
7219 - [kind, name, queryAsString, options.enabled]
7220 - );
7221 - const { totalItems, totalPages } = (0, import_data12.useSelect)(
7222 - (select5) => {
7223 - if (!options.enabled) {
7224 - return {
7712 + records: EMPTY_ARRAY,
7225 7713 totalItems: null,
7226 - totalPages: null
7714 + totalPages: null,
7715 + ...getResolutionStatus()
7227 7716 };
7228 7717 }
7718 + const storeSelectors = select5(store);
7719 + const resolutionStatus = storeSelectors.getResolutionState(
7720 + "getEntityRecords",
7721 + [kind, name, queryArgs]
7722 + )?.status;
7229 7723 return {
7230 - totalItems: select5(store).getEntityRecordsTotalItems(
7724 + records: storeSelectors.getEntityRecords(
7231 7725 kind,
7232 7726 name,
7233 7727 queryArgs
7234 7728 ),
7235 - totalPages: select5(store).getEntityRecordsTotalPages(
7729 + totalItems: storeSelectors.getEntityRecordsTotalItems(
7236 7730 kind,
7237 7731 name,
7238 7732 queryArgs
7239 - )
7733 + ),
7734 + totalPages: storeSelectors.getEntityRecordsTotalPages(
7735 + kind,
7736 + name,
7737 + queryArgs
7738 + ),
7739 + ...getResolutionStatus(resolutionStatus)
7240 7740 };
7241 7741 },
7242 7742 [kind, name, queryAsString, options.enabled]
7243 7743 );
@@ -7280,9 +7780,9 @@
7280 7780 options
7281 7781 );
7282 7782 const ids = (0, import_element4.useMemo)(
7283 7783 () => data?.map(
7284 - // @ts-ignore
7784 + // @ts-expect-error `data` is `unknown[]`, so the callback signature does not line up.
7285 7785 (record) => record[entityConfig?.key ?? "id"]
7286 7786 ) ?? [],
7287 7787 [data, entityConfig?.key]
7288 7788 );
@@ -7296,9 +7796,9 @@
7296 7796 [ids, kind, name]
7297 7797 );
7298 7798 const dataWithPermissions = (0, import_element4.useMemo)(
7299 7799 () => data?.map((record, index) => ({
7300 - // @ts-ignore
7800 + // @ts-expect-error `record` is `unknown`, which cannot be spread.
7301 7801 ...record,
7302 7802 permissions: permissions[index]
7303 7803 })) ?? [],
7304 7804 [data, permissions]
@@ -7308,8 +7808,118 @@
7308 7808
7309 7809 // packages/core-data/build-module/hooks/use-resource-permissions.mjs
7310 7810 var import_deprecated6 = __toESM(require_deprecated(), 1);
7311 7811 var import_warning = __toESM(require_warning(), 1);
7812 +
7813 + // packages/core-data/build-module/hooks/use-query-select.mjs
7814 + var import_data13 = __toESM(require_data(), 1);
7815 +
7816 + // node_modules/memize/dist/index.js
7817 + function memize(fn, options) {
7818 + var size = 0;
7819 + var head;
7820 + var tail;
7821 + options = options || {};
7822 + function memoized() {
7823 + var node = head, len = arguments.length, args, i;
7824 + searchCache: while (node) {
7825 + if (node.args.length !== arguments.length) {
7826 + node = node.next;
7827 + continue;
7828 + }
7829 + for (i = 0; i < len; i++) {
7830 + if (node.args[i] !== arguments[i]) {
7831 + node = node.next;
7832 + continue searchCache;
7833 + }
7834 + }
7835 + if (node !== head) {
7836 + if (node === tail) {
7837 + tail = node.prev;
7838 + }
7839 + node.prev.next = node.next;
7840 + if (node.next) {
7841 + node.next.prev = node.prev;
7842 + }
7843 + node.next = head;
7844 + node.prev = null;
7845 + head.prev = node;
7846 + head = node;
7847 + }
7848 + return node.val;
7849 + }
7850 + args = new Array(len);
7851 + for (i = 0; i < len; i++) {
7852 + args[i] = arguments[i];
7853 + }
7854 + node = {
7855 + args,
7856 + // Generate the result from original function
7857 + val: fn.apply(null, args)
7858 + };
7859 + if (head) {
7860 + head.prev = node;
7861 + node.next = head;
7862 + } else {
7863 + tail = node;
7864 + }
7865 + if (size === /** @type {MemizeOptions} */
7866 + options.maxSize) {
7867 + tail = /** @type {MemizeCacheNode} */
7868 + tail.prev;
7869 + tail.next = null;
7870 + } else {
7871 + size++;
7872 + }
7873 + head = node;
7874 + return node.val;
7875 + }
7876 + memoized.clear = function() {
7877 + head = null;
7878 + tail = null;
7879 + size = 0;
7880 + };
7881 + return memoized;
7882 + }
7883 +
7884 + // packages/core-data/build-module/hooks/use-query-select.mjs
7885 + var META_SELECTORS = [
7886 + "getIsResolving",
7887 + "hasStartedResolution",
7888 + "hasFinishedResolution",
7889 + "isResolving",
7890 + "getCachedResolvers"
7891 + ];
7892 + function useQuerySelect(mapQuerySelect, deps) {
7893 + return (0, import_data13.useSelect)((select5, registry) => {
7894 + const resolve = (store2) => enrichSelectors(select5(store2));
7895 + return mapQuerySelect(resolve, registry);
7896 + }, deps);
7897 + }
7898 + var enrichSelectors = memize(((selectors) => {
7899 + const resolvers = {};
7900 + for (const selectorName in selectors) {
7901 + if (META_SELECTORS.includes(selectorName)) {
7902 + continue;
7903 + }
7904 + Object.defineProperty(resolvers, selectorName, {
7905 + get: () => (...args) => {
7906 + const data = selectors[selectorName](...args);
7907 + const resolutionStatus = selectors.getResolutionState(
7908 + selectorName,
7909 + args
7910 + )?.status;
7911 + return {
7912 + data,
7913 + ...getResolutionStatus(resolutionStatus)
7914 + };
7915 + }
7916 + });
7917 + }
7918 + return resolvers;
7919 + }));
7920 +
7921 + // packages/core-data/build-module/hooks/use-resource-permissions.mjs
7312 7922 function useResourcePermissions(resource, id) {
7313 7923 const isEntity = typeof resource === "object";
7314 7924 const resourceAsString = isEntity ? JSON.stringify(resource) : resource;
7315 7925 if (isEntity && typeof id !== "undefined") {
@@ -7320,14 +7930,12 @@
7320 7930 return useQuerySelect(
7321 7931 (resolve) => {
7322 7932 const hasId = isEntity ? !!resource.id : !!id;
7323 7933 const { canUser: canUser3 } = resolve(store);
7324 - const create3 = canUser3(
7325 - "create",
7326 - isEntity ? { kind: resource.kind, name: resource.name } : resource
7327 - );
7934 + const collectionResource = isEntity ? { kind: resource.kind, name: resource.name } : resource;
7935 + const create3 = canUser3("create", collectionResource);
7328 7936 if (!hasId) {
7329 - const read2 = canUser3("read", resource);
7937 + const read2 = canUser3("read", collectionResource);
7330 7938 const isResolving2 = create3.isResolving || read2.isResolving;
7331 7939 const hasResolved2 = create3.hasResolved && read2.hasResolved;
7332 7940 let status2 = Status.Idle;
7333 7941 if (isResolving2) {
@@ -7377,10 +7985,10 @@
7377 7985 }
7378 7986
7379 7987 // packages/core-data/build-module/hooks/use-entity-block-editor.mjs
7380 7988 var import_element6 = __toESM(require_element(), 1);
7381 - var import_data13 = __toESM(require_data(), 1);
7382 - var import_blocks5 = __toESM(require_blocks(), 1);
7989 + var import_data14 = __toESM(require_data(), 1);
7990 + var import_blocks6 = __toESM(require_blocks(), 1);
7383 7991
7384 7992 // packages/core-data/build-module/hooks/use-entity-id.mjs
7385 7993 var import_element5 = __toESM(require_element(), 1);
7386 7994 function useEntityId(kind, name) {
@@ -7389,16 +7997,17 @@
7389 7997 }
7390 7998
7391 7999 // packages/core-data/build-module/footnotes/index.mjs
7392 8000 var import_rich_text4 = __toESM(require_rich_text(), 1);
8001 + var import_warning2 = __toESM(require_warning(), 1);
7393 8002
7394 8003 // packages/core-data/build-module/footnotes/get-rich-text-values-cached.mjs
7395 - var import_block_editor5 = __toESM(require_block_editor(), 1);
8004 + var import_block_editor6 = __toESM(require_block_editor(), 1);
7396 8005 var unlockedApis;
7397 8006 var cache = /* @__PURE__ */ new WeakMap();
7398 8007 function getRichTextValuesCached(block) {
7399 8008 if (!unlockedApis) {
7400 - unlockedApis = unlock(import_block_editor5.privateApis);
8009 + unlockedApis = unlock(import_block_editor6.privateApis);
7401 8010 }
7402 8011 if (!cache.has(block)) {
7403 8012 const values = unlockedApis.getRichTextValues([block]);
7404 8013 cache.set(block, values);
@@ -7439,9 +8048,19 @@
7439 8048 if (meta.footnotes === void 0) {
7440 8049 return output;
7441 8050 }
7442 8051 const newOrder = getFootnotesOrder(blocks);
7443 - const footnotes = meta.footnotes ? JSON.parse(meta.footnotes) : [];
8052 + let parsed;
8053 + try {
8054 + parsed = JSON.parse(meta.footnotes || "[]");
8055 + } catch {
8056 + }
8057 + let footnotes = [];
8058 + if (Array.isArray(parsed)) {
8059 + footnotes = parsed;
8060 + } else {
8061 + (0, import_warning2.default)("Footnotes post meta is not a JSON array; ignoring it.");
8062 + }
7444 8063 const currentOrder = footnotes.map((fn) => fn.id);
7445 8064 if (currentOrder.join("") === newOrder.join("")) {
7446 8065 return output;
7447 8066 }
@@ -7524,13 +8143,12 @@
7524 8143 }
7525 8144
7526 8145 // packages/core-data/build-module/hooks/use-entity-block-editor.mjs
7527 8146 var EMPTY_ARRAY2 = [];
7528 - var parsedBlocksCache = /* @__PURE__ */ new Map();
7529 8147 function useEntityBlockEditor(kind, name, { id: _id } = {}) {
7530 8148 const providerId = useEntityId(kind, name);
7531 8149 const id = _id ?? providerId;
7532 - const { content, editedBlocks, meta } = (0, import_data13.useSelect)(
8150 + const { content, editedBlocks, meta } = (0, import_data14.useSelect)(
7533 8151 (select5) => {
7534 8152 if (!id) {
7535 8153 return {};
7536 8154 }
@@ -7543,9 +8161,9 @@
7543 8161 };
7544 8162 },
7545 8163 [kind, name, id]
7546 8164 );
7547 - const { __unstableCreateUndoLevel: __unstableCreateUndoLevel2, editEntityRecord: editEntityRecord2 } = (0, import_data13.useDispatch)(STORE_NAME);
8165 + const { __unstableCreateUndoLevel: __unstableCreateUndoLevel2, editEntityRecord: editEntityRecord2 } = (0, import_data14.useDispatch)(STORE_NAME);
7548 8166 const blocks = (0, import_element6.useMemo)(() => {
7549 8167 if (!id) {
7550 8168 return void 0;
7551 8169 }
@@ -7554,16 +8172,12 @@
7554 8172 }
7555 8173 if (!content || typeof content !== "string") {
7556 8174 return EMPTY_ARRAY2;
7557 8175 }
7558 - const cacheKey = `${kind}:${name}:${id}`;
7559 - const cached = parsedBlocksCache.get(cacheKey);
7560 - let _blocks;
7561 - if (cached && cached.content === content) {
7562 - _blocks = cached.blocks;
7563 - } else {
7564 - _blocks = (0, import_blocks5.parse)(content);
7565 - parsedBlocksCache.set(cacheKey, { content, blocks: _blocks });
8176 + let _blocks = getCachedBlocks(kind, name, id, content);
8177 + if (!_blocks) {
8178 + _blocks = (0, import_blocks6.parse)(content);
8179 + setCachedBlocks(kind, name, id, content, _blocks);
7566 8180 }
7567 8181 return _blocks;
7568 8182 }, [kind, name, id, editedBlocks, content]);
7569 8183 const onChange = (0, import_element6.useCallback)(
@@ -7574,9 +8188,9 @@
7574 8188 }
7575 8189 const { selection, ...rest } = options;
7576 8190 const edits = {
7577 8191 selection,
7578 - content: ({ blocks: blocksForSerialization = [] }) => (0, import_blocks5.__unstableSerializeAndClean)(blocksForSerialization),
8192 + content: ({ blocks: blocksForSerialization = [] }) => (0, import_blocks6.__unstableSerializeAndClean)(blocksForSerialization),
7579 8193 ...updateFootnotesFromMeta(newBlocks, meta)
7580 8194 };
7581 8195 editEntityRecord2(kind, name, id, edits, {
7582 8196 isCached: false,
@@ -7611,39 +8225,37 @@
7611 8225 }
7612 8226
7613 8227 // packages/core-data/build-module/hooks/use-entity-prop.mjs
7614 8228 var import_element7 = __toESM(require_element(), 1);
7615 - var import_data14 = __toESM(require_data(), 1);
8229 + var import_data15 = __toESM(require_data(), 1);
8230 + var REVISION_QUERY = {
8231 + context: "edit",
8232 + _fields: "id,date,author,meta,title,excerpt,content.raw"
8233 + };
7616 8234 function useEntityProp(kind, name, prop, _id) {
7617 8235 const providerId = useEntityId(kind, name);
7618 8236 const id = _id ?? providerId;
7619 8237 const context = (0, import_element7.useContext)(EntityContext);
7620 - const revisionId = context?.revisionId;
7621 - const { value, fullValue } = (0, import_data14.useSelect)(
8238 + const revisionId = String(id) === String(providerId) ? context?.revision?.[kind]?.[name] : void 0;
8239 + const { value, fullValue } = (0, import_data15.useSelect)(
7622 8240 (select5) => {
7623 8241 if (revisionId) {
7624 - const revisions = select5(STORE_NAME).getRevisions(
8242 + const revision = select5(STORE_NAME).getRevision(
7625 8243 kind,
7626 8244 name,
7627 8245 id,
7628 - {
7629 - per_page: -1,
7630 - context: "edit",
7631 - _fields: "id,date,author,meta,title.raw,excerpt.raw,content.raw"
7632 - }
8246 + revisionId,
8247 + REVISION_QUERY
7633 8248 );
7634 - const entityConfig = select5(STORE_NAME).getEntityConfig(
7635 - kind,
7636 - name
7637 - );
7638 - const revKey = entityConfig?.revisionKey || DEFAULT_ENTITY_KEY;
7639 - const revision = revisions?.find(
7640 - (r) => r[revKey] === revisionId
7641 - );
7642 - return revision ? {
7643 - value: revision[prop]?.raw ?? revision[prop],
7644 - fullValue: revision[prop]
7645 - } : {};
8249 + const propValue = revision?.[prop];
8250 + if (propValue === void 0) {
8251 + return {};
8252 + }
8253 + const isRawAttribute = propValue !== null && typeof propValue === "object" && "raw" in propValue;
8254 + return {
8255 + value: isRawAttribute ? propValue.raw : propValue,
8256 + fullValue: propValue
8257 + };
7646 8258 }
7647 8259 const { getEntityRecord: getEntityRecord3, getEditedEntityRecord: getEditedEntityRecord3 } = select5(STORE_NAME);
7648 8260 const record = getEntityRecord3(kind, name, id);
7649 8261 const editedRecord = getEditedEntityRecord3(kind, name, id);
@@ -7653,9 +8265,9 @@
7653 8265 } : {};
7654 8266 },
7655 8267 [kind, name, id, prop, revisionId]
7656 8268 );
7657 - const { editEntityRecord: editEntityRecord2 } = (0, import_data14.useDispatch)(STORE_NAME);
8269 + const { editEntityRecord: editEntityRecord2 } = (0, import_data15.useDispatch)(STORE_NAME);
7658 8270 const setValue = (0, import_element7.useCallback)(
7659 8271 (newValue) => {
7660 8272 if (revisionId) {
7661 8273 return;
@@ -7673,9 +8285,10 @@
7673 8285 var import_compose3 = __toESM(require_compose(), 1);
7674 8286 var import_element8 = __toESM(require_element(), 1);
7675 8287 var defaultResolvedSelection = {
7676 8288 richTextOffset: null,
7677 - localClientId: null
8289 + localClientId: null,
8290 + attributeKey: null
7678 8291 };
7679 8292 var defaultState = {
7680 8293 activeCollaborators: [],
7681 8294 resolveSelection: () => defaultResolvedSelection,
@@ -7686,12 +8299,14 @@
7686 8299 }),
7687 8300 isCurrentCollaboratorDisconnected: false
7688 8301 };
7689 8302 function getAwarenessState(awareness, newState) {
7690 - const activeCollaborators = newState ?? awareness.getCurrentState();
8303 + const activeCollaborators = (newState ?? awareness.getCurrentState()).filter(
8304 + (collaborator) => isCollaboratorInfo(collaborator.collaboratorInfo)
8305 + );
7691 8306 return {
7692 8307 activeCollaborators,
7693 - resolveSelection: (selection) => awareness.convertSelectionStateToAbsolute(selection),
8308 + resolveSelection: (selection, blocks) => awareness.convertSelectionStateToAbsolute(selection, blocks),
7694 8309 getDebugData: () => awareness.getDebugData(),
7695 8310 isCurrentCollaboratorDisconnected: activeCollaborators.find((collaborator) => collaborator.isMe)?.isConnected === false
7696 8311 };
7697 8312 }
@@ -7726,9 +8341,14 @@
7726 8341 function useActiveCollaborators(postId, postType) {
7727 8342 return usePostEditorAwarenessState(postId, postType).activeCollaborators;
7728 8343 }
7729 8344 function useResolvedSelection(postId, postType) {
7730 - return usePostEditorAwarenessState(postId, postType).resolveSelection;
8345 + const blocks = usePostContentBlocks();
8346 + const awarenessState = usePostEditorAwarenessState(postId, postType);
8347 + return (0, import_element8.useCallback)(
8348 + (selection) => awarenessState.resolveSelection(selection, blocks),
8349 + [blocks, awarenessState]
8350 + );
7731 8351 }
7732 8352 function useLastPostSave(postId, postType) {
7733 8353 const [lastSave, setLastSave] = (0, import_element8.useState)(null);
7734 8354 (0, import_element8.useEffect)(() => {
@@ -7841,20 +8461,711 @@
7841 8461 callback(lastPostSave, saver, prevPostSave ?? null);
7842 8462 }, [lastPostSave, prevPostSave, activeCollaborators, callback]);
7843 8463 }
7844 8464
8465 + // packages/icons/build-module/library/footer.mjs
8466 + var import_primitives = __toESM(require_primitives(), 1);
8467 + var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
8468 + var footer_default = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_primitives.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: [
8469 + /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_primitives.Path, { d: "M9.75 4.75H18C18.6904 4.75 19.25 5.30964 19.25 6V14.25M9.75 4.75H6C5.30964 4.75 4.75 5.30964 4.75 6V14.25M9.75 4.75V14.25M19.25 14.25V18C19.25 18.6904 18.6904 19.25 18 19.25H6C5.30964 19.25 4.75 18.6904 4.75 18V14.25M19.25 14.25H9.75M9.75 14.25H4.75", vectorEffect: "non-scaling-stroke" }),
8470 + /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_primitives.Path, { d: "M19.25 15.5V18C19.25 18.6904 18.6904 19.25 18 19.25H6C5.30964 19.25 4.75 18.6904 4.75 18V15.5C4.75 14.8096 5.30964 14.25 6 14.25H18C18.6904 14.25 19.25 14.8096 19.25 15.5Z", fill: "currentColor", vectorEffect: "non-scaling-stroke" })
8471 + ] });
8472 +
8473 + // packages/icons/build-module/library/header.mjs
8474 + var import_primitives2 = __toESM(require_primitives(), 1);
8475 + var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
8476 + var header_default = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_primitives2.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: [
8477 + /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_primitives2.Path, { d: "M9.75 19.25H18C18.6904 19.25 19.25 18.6904 19.25 18V9.75M9.75 19.25H6C5.30964 19.25 4.75 18.6904 4.75 18V9.75M9.75 19.25V9.75M19.25 9.75V6C19.25 5.30964 18.6904 4.75 18 4.75H6C5.30964 4.75 4.75 5.30964 4.75 6V9.75M19.25 9.75H9.75M9.75 9.75H4.75", vectorEffect: "non-scaling-stroke" }),
8478 + /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_primitives2.Path, { d: "M19.25 8.5V6C19.25 5.30964 18.6904 4.75 18 4.75H6C5.30964 4.75 4.75 5.30964 4.75 6V8.5C4.75 9.19036 5.30964 9.75 6 9.75H18C18.6904 9.75 19.25 9.19036 19.25 8.5Z", fill: "currentColor", vectorEffect: "non-scaling-stroke" })
8479 + ] });
8480 +
8481 + // packages/icons/build-module/library/layout.mjs
8482 + var import_primitives3 = __toESM(require_primitives(), 1);
8483 + var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
8484 + var layout_default = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_primitives3.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_primitives3.Path, { d: "M9.75 19.25H18C18.6904 19.25 19.25 18.6904 19.25 18V9.75M9.75 19.25H6C5.30964 19.25 4.75 18.6904 4.75 18V9.75M9.75 19.25V9.75M19.25 9.75V6C19.25 5.30964 18.6904 4.75 18 4.75H6C5.30964 4.75 4.75 5.30964 4.75 6V9.75M19.25 9.75H9.75M9.75 9.75H4.75", vectorEffect: "non-scaling-stroke" }) });
8485 +
8486 + // packages/icons/build-module/library/navigation-overlay.mjs
8487 + var import_primitives4 = __toESM(require_primitives(), 1);
8488 + var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
8489 + var navigation_overlay_default = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_primitives4.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: [
8490 + /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_primitives4.Path, { d: "M4.75 9.25V16C4.75 16.6904 5.30964 17.25 6 17.25H8M4.75 9.25V6C4.75 5.30964 5.30964 4.75 6 4.75H16C16.6904 4.75 17.25 5.30964 17.25 6V8M4.75 9.25H8", vectorEffect: "non-scaling-stroke" }),
8491 + /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_primitives4.Path, { d: "M10.75 11.25C10.75 10.9739 10.9739 10.75 11.25 10.75H18.75C19.0261 10.75 19.25 10.9739 19.25 11.25V18.75C19.25 19.0261 19.0261 19.25 18.75 19.25H11.25C10.9739 19.25 10.75 19.0261 10.75 18.75V11.25Z", fill: "currentColor", vectorEffect: "non-scaling-stroke" })
8492 + ] });
8493 +
8494 + // packages/icons/build-module/library/sidebar.mjs
8495 + var import_primitives5 = __toESM(require_primitives(), 1);
8496 + var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
8497 + var sidebar_default = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_primitives5.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: [
8498 + /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_primitives5.Path, { d: "M9.75 19.25H18C18.6904 19.25 19.25 18.6904 19.25 18V9.75M9.75 19.25H6C5.30964 19.25 4.75 18.6904 4.75 18V9.75M9.75 19.25V9.75M19.25 9.75V6C19.25 5.30964 18.6904 4.75 18 4.75H6C5.30964 4.75 4.75 5.30964 4.75 6V9.75M19.25 9.75H9.75M9.75 9.75H4.75", vectorEffect: "non-scaling-stroke" }),
8499 + /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_primitives5.Path, { d: "M6 19.25H9.75V9.75H4.75V18C4.75 18.6904 5.30964 19.25 6 19.25Z", fill: "currentColor", vectorEffect: "non-scaling-stroke" })
8500 + ] });
8501 +
8502 + // packages/icons/build-module/library/symbol-filled.mjs
8503 + var import_primitives6 = __toESM(require_primitives(), 1);
8504 + var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
8505 + var symbol_filled_default = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_primitives6.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: [
8506 + /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_primitives6.Path, { d: "M15.2071 6.20711L20.2929 11.2929C20.6834 11.6834 20.6834 12.3166 20.2929 12.7071L15.2071 17.7929C14.8166 18.1834 14.1834 18.1834 13.7929 17.7929L8.70711 12.7071C8.31658 12.3166 8.31658 11.6834 8.70711 11.2929L13.7929 6.20711C14.1834 5.81658 14.8166 5.81658 15.2071 6.20711Z", fill: "currentColor", vectorEffect: "non-scaling-stroke" }),
8507 + /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_primitives6.Path, { d: "M9.5 5.5L3.70711 11.2929C3.31658 11.6834 3.31658 12.3166 3.70711 12.7071L9.5 18.5", vectorEffect: "non-scaling-stroke" })
8508 + ] });
8509 +
8510 + // packages/core-data/build-module/utils/get-template-part-icon.mjs
8511 + function getTemplatePartIcon(areaOrIconName) {
8512 + if ("header" === areaOrIconName) {
8513 + return header_default;
8514 + } else if ("footer" === areaOrIconName) {
8515 + return footer_default;
8516 + } else if ("sidebar" === areaOrIconName) {
8517 + return sidebar_default;
8518 + } else if ("navigation-overlay" === areaOrIconName) {
8519 + return navigation_overlay_default;
8520 + }
8521 + return symbol_filled_default;
8522 + }
8523 +
8524 + // packages/core-data/build-module/utils/get-template-info.mjs
8525 + var EMPTY_OBJECT4 = {};
8526 + var getTemplateInfo = (params) => {
8527 + if (!params) {
8528 + return EMPTY_OBJECT4;
8529 + }
8530 + const { templateTypes, templateAreas, template } = params;
8531 + const { description, slug, title, area } = template;
8532 + const { title: defaultTitle, description: defaultDescription } = Object.values(templateTypes).find((type) => type.slug === slug) ?? EMPTY_OBJECT4;
8533 + const templateTitle = typeof title === "string" ? title : title?.rendered;
8534 + const templateDescription = typeof description === "string" ? description : description?.raw;
8535 + const templateAreasWithIcon = templateAreas?.map((item) => ({
8536 + ...item,
8537 + icon: getTemplatePartIcon(item.icon)
8538 + }));
8539 + const templateIcon = templateAreasWithIcon?.find((item) => area === item.area)?.icon || layout_default;
8540 + return {
8541 + title: templateTitle && templateTitle !== slug ? templateTitle : defaultTitle || slug,
8542 + description: templateDescription || defaultDescription,
8543 + icon: templateIcon
8544 + };
8545 + };
8546 +
8547 + // node_modules/clsx/dist/clsx.mjs
8548 + function r(e) {
8549 + var t, f, n = "";
8550 + if ("string" == typeof e || "number" == typeof e) n += e;
8551 + else if ("object" == typeof e) if (Array.isArray(e)) {
8552 + var o = e.length;
8553 + for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
8554 + } else for (f in e) e[f] && (n && (n += " "), n += f);
8555 + return n;
8556 + }
8557 + function clsx() {
8558 + for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
8559 + return n;
8560 + }
8561 + var clsx_default = clsx;
8562 +
8563 + // packages/core-data/build-module/components/entities-saved-states/index.mjs
8564 + var import_components3 = __toESM(require_components(), 1);
8565 + var import_i18n7 = __toESM(require_i18n(), 1);
8566 + var import_element10 = __toESM(require_element(), 1);
8567 + var import_compose4 = __toESM(require_compose(), 1);
8568 + var import_data19 = __toESM(require_data(), 1);
8569 +
8570 + // packages/core-data/build-module/components/entities-saved-states/entity-type-list.mjs
8571 + var import_i18n6 = __toESM(require_i18n(), 1);
8572 + var import_data17 = __toESM(require_data(), 1);
8573 + var import_components2 = __toESM(require_components(), 1);
8574 +
8575 + // packages/global-styles-engine/build-module/utils/get-global-styles-changes.mjs
8576 + var import_i18n4 = __toESM(require_i18n(), 1);
8577 + var import_blocks7 = __toESM(require_blocks(), 1);
8578 + var globalStylesChangesCache = /* @__PURE__ */ new Map();
8579 + var EMPTY_ARRAY3 = [];
8580 + var translationMap = {
8581 + caption: (0, import_i18n4.__)("Caption"),
8582 + link: (0, import_i18n4.__)("Link"),
8583 + button: (0, import_i18n4.__)("Button"),
8584 + heading: (0, import_i18n4.__)("Heading"),
8585 + h1: (0, import_i18n4.__)("H1"),
8586 + h2: (0, import_i18n4.__)("H2"),
8587 + h3: (0, import_i18n4.__)("H3"),
8588 + h4: (0, import_i18n4.__)("H4"),
8589 + h5: (0, import_i18n4.__)("H5"),
8590 + h6: (0, import_i18n4.__)("H6"),
8591 + "settings.color": (0, import_i18n4.__)("Color"),
8592 + "settings.typography": (0, import_i18n4.__)("Typography"),
8593 + "settings.shadow": (0, import_i18n4.__)("Shadow"),
8594 + "settings.layout": (0, import_i18n4.__)("Layout"),
8595 + "styles.color": (0, import_i18n4.__)("Colors"),
8596 + "styles.spacing": (0, import_i18n4.__)("Spacing"),
8597 + "styles.background": (0, import_i18n4.__)("Background"),
8598 + "styles.typography": (0, import_i18n4.__)("Typography"),
8599 + "styles.border": (0, import_i18n4.__)("Border"),
8600 + "styles.shadow": (0, import_i18n4.__)("Shadow"),
8601 + "styles.outline": (0, import_i18n4.__)("Outline"),
8602 + "styles.filter": (0, import_i18n4.__)("Filter"),
8603 + "styles.dimensions": (0, import_i18n4.__)("Dimensions")
8604 + };
8605 + var getBlockNames = memize(
8606 + () => (0, import_blocks7.getBlockTypes)().reduce(
8607 + (accumulator, {
8608 + name,
8609 + title
8610 + }) => {
8611 + accumulator[name] = title;
8612 + return accumulator;
8613 + },
8614 + {}
8615 + )
8616 + );
8617 + var isObject = (obj) => obj !== null && typeof obj === "object";
8618 + function getTranslation(key) {
8619 + if (translationMap[key]) {
8620 + return translationMap[key];
8621 + }
8622 + const keyArray = key.split(".");
8623 + if (keyArray?.[0] === "blocks") {
8624 + const blockName = getBlockNames()?.[keyArray[1]];
8625 + return blockName || keyArray[1];
8626 + }
8627 + if (keyArray?.[0] === "elements") {
8628 + return translationMap[keyArray[1]] || keyArray[1];
8629 + }
8630 + return void 0;
8631 + }
8632 + function deepCompare(changedObject, originalObject, parentPath = "") {
8633 + if (!isObject(changedObject) && !isObject(originalObject)) {
8634 + return changedObject !== originalObject ? parentPath.split(".").slice(0, 2).join(".") : void 0;
8635 + }
8636 + changedObject = isObject(changedObject) ? changedObject : {};
8637 + originalObject = isObject(originalObject) ? originalObject : {};
8638 + const allKeys = /* @__PURE__ */ new Set([
8639 + ...Object.keys(changedObject),
8640 + ...Object.keys(originalObject)
8641 + ]);
8642 + let diffs = [];
8643 + for (const key of allKeys) {
8644 + const path = parentPath ? parentPath + "." + key : key;
8645 + const changedPath = deepCompare(
8646 + changedObject[key],
8647 + originalObject[key],
8648 + path
8649 + );
8650 + if (changedPath) {
8651 + diffs = diffs.concat(changedPath);
8652 + }
8653 + }
8654 + return diffs;
8655 + }
8656 + var COMPARED_STYLE_KEYS = [
8657 + "background",
8658 + "color",
8659 + "typography",
8660 + "spacing",
8661 + "border",
8662 + "shadow",
8663 + "outline",
8664 + "filter",
8665 + "dimensions"
8666 + ];
8667 + function pickComparedStyles(config) {
8668 + return Object.fromEntries(
8669 + COMPARED_STYLE_KEYS.map((key) => [key, config?.styles?.[key]])
8670 + );
8671 + }
8672 + function getGlobalStylesChangelist(next, previous) {
8673 + const cacheKey = JSON.stringify({ next, previous });
8674 + if (globalStylesChangesCache.has(cacheKey)) {
8675 + return globalStylesChangesCache.get(cacheKey);
8676 + }
8677 + const changedValueTree = deepCompare(
8678 + {
8679 + styles: pickComparedStyles(next),
8680 + blocks: next?.styles?.blocks,
8681 + elements: next?.styles?.elements,
8682 + settings: next?.settings
8683 + },
8684 + {
8685 + styles: pickComparedStyles(previous),
8686 + blocks: previous?.styles?.blocks,
8687 + elements: previous?.styles?.elements,
8688 + settings: previous?.settings
8689 + }
8690 + );
8691 + if (!changedValueTree || Array.isArray(changedValueTree) && !changedValueTree.length) {
8692 + globalStylesChangesCache.set(cacheKey, []);
8693 + return [];
8694 + }
8695 + const changedValueArray = Array.isArray(changedValueTree) ? changedValueTree : [changedValueTree];
8696 + const result = [...new Set(changedValueArray)].reduce((acc, curr) => {
8697 + const translation = getTranslation(curr);
8698 + if (translation) {
8699 + acc.push([curr.split(".")[0], translation]);
8700 + }
8701 + return acc;
8702 + }, []);
8703 + globalStylesChangesCache.set(cacheKey, result);
8704 + return result;
8705 + }
8706 + function getGlobalStylesChanges(next, previous, options = {}) {
8707 + let changeList = getGlobalStylesChangelist(next, previous);
8708 + const changesLength = changeList.length;
8709 + const { maxResults } = options;
8710 + if (changesLength) {
8711 + if (!!maxResults && changesLength > maxResults) {
8712 + changeList = changeList.slice(0, maxResults);
8713 + }
8714 + return Object.entries(
8715 + changeList.reduce((acc, curr) => {
8716 + const group = acc[curr[0]] || [];
8717 + if (!group.includes(curr[1])) {
8718 + acc[curr[0]] = [...group, curr[1]];
8719 + }
8720 + return acc;
8721 + }, {})
8722 + ).map(([key, changeValues]) => {
8723 + const changeValuesLength = changeValues.length;
8724 + const joinedChangesValue = changeValues.join(
8725 + /* translators: Used between list items, there is a space after the comma. */
8726 + (0, import_i18n4.__)(", ")
8727 + // eslint-disable-line @wordpress/i18n-no-flanking-whitespace
8728 + );
8729 + switch (key) {
8730 + case "blocks": {
8731 + return (0, import_i18n4.sprintf)(
8732 + // translators: %s: a list of block names separated by a comma.
8733 + (0, import_i18n4._n)("%s block.", "%s blocks.", changeValuesLength),
8734 + joinedChangesValue
8735 + );
8736 + }
8737 + case "elements": {
8738 + return (0, import_i18n4.sprintf)(
8739 + // translators: %s: a list of element names separated by a comma.
8740 + (0, import_i18n4._n)("%s element.", "%s elements.", changeValuesLength),
8741 + joinedChangesValue
8742 + );
8743 + }
8744 + case "settings": {
8745 + return (0, import_i18n4.sprintf)(
8746 + // translators: %s: a list of theme.json setting labels separated by a comma.
8747 + (0, import_i18n4.__)("%s settings."),
8748 + joinedChangesValue
8749 + );
8750 + }
8751 + case "styles": {
8752 + return (0, import_i18n4.sprintf)(
8753 + // translators: %s: a list of theme.json top-level styles labels separated by a comma.
8754 + (0, import_i18n4.__)("%s styles."),
8755 + joinedChangesValue
8756 + );
8757 + }
8758 + default: {
8759 + return (0, import_i18n4.sprintf)(
8760 + // translators: %s: a list of global styles changes separated by a comma.
8761 + (0, import_i18n4.__)("%s."),
8762 + joinedChangesValue
8763 + );
8764 + }
8765 + }
8766 + });
8767 + }
8768 + return EMPTY_ARRAY3;
8769 + }
8770 +
8771 + // packages/core-data/build-module/components/entities-saved-states/entity-record-item.mjs
8772 + var import_components = __toESM(require_components(), 1);
8773 + var import_i18n5 = __toESM(require_i18n(), 1);
8774 + var import_data16 = __toESM(require_data(), 1);
8775 + var import_html_entities4 = __toESM(require_html_entities(), 1);
8776 + var import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
8777 + function EntityRecordItem({ record, checked, onChange }) {
8778 + const { name, kind, title, key } = record;
8779 + const { entityRecordTitle } = (0, import_data16.useSelect)(
8780 + (select5) => {
8781 + if ("postType" !== kind || "wp_template" !== name) {
8782 + return {
8783 + entityRecordTitle: title
8784 + };
8785 + }
8786 + const template = select5(STORE_NAME).getEditedEntityRecord(
8787 + kind,
8788 + name,
8789 + key
8790 + );
8791 + const { default_template_types: templateTypes = [] } = select5(STORE_NAME).getCurrentTheme() ?? {};
8792 + return {
8793 + entityRecordTitle: getTemplateInfo({
8794 + template,
8795 + templateTypes
8796 + }).title
8797 + };
8798 + },
8799 + [name, kind, title, key]
8800 + );
8801 + return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_components.PanelRow, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
8802 + import_components.CheckboxControl,
8803 + {
8804 + label: (0, import_html_entities4.decodeEntities)(entityRecordTitle) || (0, import_i18n5.__)("Untitled"),
8805 + checked,
8806 + onChange,
8807 + className: "entities-saved-states__change-control"
8808 + }
8809 + ) }) });
8810 + }
8811 +
8812 + // packages/core-data/build-module/components/entities-saved-states/entity-type-list.mjs
8813 + var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
8814 + function getEntityDescription(entity2, count) {
8815 + switch (entity2) {
8816 + case "site":
8817 + return 1 === count ? (0, import_i18n6.__)("This change will affect your whole site.") : (0, import_i18n6.__)("These changes will affect your whole site.");
8818 + case "wp_template":
8819 + return (0, import_i18n6.__)(
8820 + "This change will affect other parts of your site that use this template."
8821 + );
8822 + case "page":
8823 + case "post":
8824 + return (0, import_i18n6.__)("The following has been modified.");
8825 + }
8826 + }
8827 + function GlobalStylesDescription({ record }) {
8828 + const { editedRecord, savedRecord } = (0, import_data17.useSelect)(
8829 + (select5) => {
8830 + const { getEditedEntityRecord: getEditedEntityRecord3, getEntityRecord: getEntityRecord3 } = select5(STORE_NAME);
8831 + return {
8832 + editedRecord: getEditedEntityRecord3(
8833 + record.kind,
8834 + record.name,
8835 + record.key
8836 + ),
8837 + savedRecord: getEntityRecord3(
8838 + record.kind,
8839 + record.name,
8840 + record.key
8841 + )
8842 + };
8843 + },
8844 + [record.kind, record.name, record.key]
8845 + );
8846 + const globalStylesChanges = getGlobalStylesChanges(
8847 + editedRecord,
8848 + savedRecord,
8849 + {
8850 + maxResults: 10
8851 + }
8852 + );
8853 + return globalStylesChanges.length ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { className: "entities-saved-states__changes", children: globalStylesChanges.map((change) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("li", { children: change }, change)) }) : null;
8854 + }
8855 + function EntityDescription({ record, count }) {
8856 + if ("globalStyles" === record?.name) {
8857 + return null;
8858 + }
8859 + const description = getEntityDescription(record?.name, count);
8860 + return description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components2.PanelRow, { children: description }) : null;
8861 + }
8862 + function EntityTypeList({
8863 + list,
8864 + unselectedEntities,
8865 + setUnselectedEntities
8866 + }) {
8867 + const count = list.length;
8868 + const firstRecord = list[0];
8869 + const entityConfig = (0, import_data17.useSelect)(
8870 + (select5) => select5(STORE_NAME).getEntityConfig(
8871 + firstRecord.kind,
8872 + firstRecord.name
8873 + ),
8874 + [firstRecord.kind, firstRecord.name]
8875 + );
8876 + let entityLabel = entityConfig.label;
8877 + if (firstRecord?.name === "wp_template_part") {
8878 + entityLabel = 1 === count ? (0, import_i18n6.__)("Template Part") : (0, import_i18n6.__)("Template Parts");
8879 + }
8880 + return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
8881 + import_components2.PanelBody,
8882 + {
8883 + title: entityLabel,
8884 + initialOpen: true,
8885 + className: "entities-saved-states__panel-body",
8886 + children: [
8887 + /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(EntityDescription, { record: firstRecord, count }),
8888 + list.map((record) => {
8889 + return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
8890 + EntityRecordItem,
8891 + {
8892 + record,
8893 + checked: !unselectedEntities.some(
8894 + (elt) => elt.kind === record.kind && elt.name === record.name && elt.key === record.key && elt.property === record.property
8895 + ),
8896 + onChange: (value) => setUnselectedEntities(record, value)
8897 + },
8898 + record.key || record.property
8899 + );
8900 + }),
8901 + "globalStyles" === firstRecord?.name && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(GlobalStylesDescription, { record: firstRecord })
8902 + ]
8903 + }
8904 + );
8905 + }
8906 +
8907 + // packages/core-data/build-module/components/entities-saved-states/hooks/use-is-dirty.mjs
8908 + var import_data18 = __toESM(require_data(), 1);
8909 + var import_element9 = __toESM(require_element(), 1);
8910 + var useIsDirty = () => {
8911 + const { editedEntities, siteEdits, siteEntityConfig } = (0, import_data18.useSelect)(
8912 + (select5) => {
8913 + const {
8914 + __experimentalGetDirtyEntityRecords: __experimentalGetDirtyEntityRecords2,
8915 + getEntityRecordEdits: getEntityRecordEdits2,
8916 + getEntityConfig: getEntityConfig2
8917 + } = select5(STORE_NAME);
8918 + return {
8919 + editedEntities: __experimentalGetDirtyEntityRecords2(),
8920 + siteEdits: getEntityRecordEdits2("root", "site"),
8921 + siteEntityConfig: getEntityConfig2("root", "site")
8922 + };
8923 + },
8924 + []
8925 + );
8926 + const dirtyEntityRecords = (0, import_element9.useMemo)(() => {
8927 + const editedEntitiesWithoutSite = editedEntities.filter(
8928 + (record) => !(record.kind === "root" && record.name === "site")
8929 + );
8930 + const siteEntityLabels = siteEntityConfig?.meta?.labels ?? {};
8931 + const {
8932 + title: siteTitleEdit,
8933 + description: siteDescriptionEdit,
8934 + site_logo: siteLogoEdit,
8935 + site_icon: siteIconEdit,
8936 + ...otherSiteEdits
8937 + } = siteEdits ?? {};
8938 + const orderedSiteProperties = [
8939 + siteTitleEdit !== void 0 && "title",
8940 + siteDescriptionEdit !== void 0 && "description",
8941 + siteLogoEdit !== void 0 && "site_logo",
8942 + siteIconEdit !== void 0 && "site_icon",
8943 + ...Object.keys(otherSiteEdits)
8944 + ].filter(Boolean);
8945 + const editedSiteEntities = orderedSiteProperties.map(
8946 + (property) => ({
8947 + kind: "root",
8948 + name: "site",
8949 + title: siteEntityLabels[property] || property,
8950 + property
8951 + })
8952 + );
8953 + return [...editedEntitiesWithoutSite, ...editedSiteEntities];
8954 + }, [editedEntities, siteEdits, siteEntityConfig]);
8955 + const [unselectedEntities, _setUnselectedEntities] = (0, import_element9.useState)([]);
8956 + const setUnselectedEntities = ({ kind, name, key, property }, checked) => {
8957 + if (checked) {
8958 + _setUnselectedEntities(
8959 + unselectedEntities.filter(
8960 + (elt) => elt.kind !== kind || elt.name !== name || elt.key !== key || elt.property !== property
8961 + )
8962 + );
8963 + } else {
8964 + _setUnselectedEntities([
8965 + ...unselectedEntities,
8966 + { kind, name, key, property }
8967 + ]);
8968 + }
8969 + };
8970 + const isDirty = dirtyEntityRecords.length - unselectedEntities.length > 0;
8971 + return {
8972 + dirtyEntityRecords,
8973 + isDirty,
8974 + setUnselectedEntities,
8975 + unselectedEntities
8976 + };
8977 + };
8978 +
8979 + // packages/core-data/build-module/components/entities-saved-states/index.mjs
8980 + var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
8981 + function EntitiesSavedStates({
8982 + close,
8983 + renderDialog,
8984 + variant
8985 + }) {
8986 + const isDirtyProps = useIsDirty();
8987 + return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
8988 + EntitiesSavedStatesExtensible,
8989 + {
8990 + close,
8991 + renderDialog,
8992 + variant,
8993 + ...isDirtyProps
8994 + }
8995 + );
8996 + }
8997 + function EntitiesSavedStatesExtensible({
8998 + additionalPrompt = void 0,
8999 + close,
9000 + onSave = void 0,
9001 + saveEnabled: saveEnabledProp = void 0,
9002 + saveLabel = (0, import_i18n7.__)("Save"),
9003 + renderDialog,
9004 + dirtyEntityRecords,
9005 + isDirty,
9006 + setUnselectedEntities,
9007 + unselectedEntities,
9008 + variant = "default",
9009 + successNoticeContent
9010 + }) {
9011 + const saveButtonRef = (0, import_element10.useRef)();
9012 + const { saveDirtyEntities: saveDirtyEntities2 } = unlock((0, import_data19.useDispatch)(STORE_NAME));
9013 + const partitionedSavables = dirtyEntityRecords.reduce((acc, record) => {
9014 + const { name } = record;
9015 + if (!acc[name]) {
9016 + acc[name] = [];
9017 + }
9018 + acc[name].push(record);
9019 + return acc;
9020 + }, {});
9021 + const {
9022 + site: siteSavables,
9023 + wp_template: templateSavables,
9024 + wp_template_part: templatePartSavables,
9025 + ...contentSavables
9026 + } = partitionedSavables;
9027 + const sortedPartitionedSavables = [
9028 + siteSavables,
9029 + templateSavables,
9030 + templatePartSavables,
9031 + ...Object.values(contentSavables)
9032 + ].filter(Array.isArray);
9033 + const saveEnabled = saveEnabledProp ?? isDirty;
9034 + const dismissPanel = (0, import_element10.useCallback)(() => close(), [close]);
9035 + const [saveDialogRef, saveDialogProps] = (0, import_compose4.__experimentalUseDialog)({
9036 + onClose: () => dismissPanel()
9037 + });
9038 + const dialogLabelId = (0, import_compose4.useInstanceId)(
9039 + EntitiesSavedStatesExtensible,
9040 + "entities-saved-states__panel-label"
9041 + );
9042 + const dialogDescriptionId = (0, import_compose4.useInstanceId)(
9043 + EntitiesSavedStatesExtensible,
9044 + "entities-saved-states__panel-description"
9045 + );
9046 + const selectItemsToSaveDescription = !!dirtyEntityRecords.length ? (0, import_i18n7.__)("Select the items you want to save.") : void 0;
9047 + const isInline = variant === "inline";
9048 + const actionButtons = /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
9049 + /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
9050 + import_components3.FlexItem,
9051 + {
9052 + isBlock: isInline ? false : true,
9053 + as: import_components3.Button,
9054 + variant: isInline ? "tertiary" : "secondary",
9055 + size: isInline ? void 0 : "compact",
9056 + onClick: dismissPanel,
9057 + children: (0, import_i18n7.__)("Cancel")
9058 + }
9059 + ),
9060 + /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
9061 + import_components3.FlexItem,
9062 + {
9063 + isBlock: isInline ? false : true,
9064 + as: import_components3.Button,
9065 + ref: saveButtonRef,
9066 + variant: "primary",
9067 + size: isInline ? void 0 : "compact",
9068 + disabled: !saveEnabled,
9069 + accessibleWhenDisabled: true,
9070 + onClick: () => saveDirtyEntities2({
9071 + onSave,
9072 + dirtyEntityRecords,
9073 + entitiesToSkip: unselectedEntities,
9074 + close,
9075 + successNoticeContent
9076 + }),
9077 + className: "entities-saved-states__save-button",
9078 + children: saveLabel
9079 + }
9080 + )
9081 + ] });
9082 + return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
9083 + "div",
9084 + {
9085 + ref: renderDialog ? saveDialogRef : void 0,
9086 + ...renderDialog && saveDialogProps,
9087 + className: clsx_default("entities-saved-states__panel", {
9088 + "is-inline": isInline
9089 + }),
9090 + role: renderDialog ? "dialog" : void 0,
9091 + "aria-labelledby": renderDialog ? dialogLabelId : void 0,
9092 + "aria-describedby": renderDialog ? dialogDescriptionId : void 0,
9093 + children: [
9094 + !isInline && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_components3.Flex, { className: "entities-saved-states__panel-header", gap: 2, children: actionButtons }),
9095 + /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "entities-saved-states__text-prompt", children: [
9096 + /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "entities-saved-states__text-prompt--header-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
9097 + "strong",
9098 + {
9099 + id: renderDialog ? dialogLabelId : void 0,
9100 + className: "entities-saved-states__text-prompt--header",
9101 + children: (0, import_i18n7.__)("Are you ready to save?")
9102 + }
9103 + ) }),
9104 + /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { id: renderDialog ? dialogDescriptionId : void 0, children: [
9105 + additionalPrompt,
9106 + /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "entities-saved-states__text-prompt--changes-count", children: isDirty ? (0, import_element10.createInterpolateElement)(
9107 + (0, import_i18n7.sprintf)(
9108 + /* translators: %d: number of site changes waiting to be saved. */
9109 + (0, import_i18n7._n)(
9110 + "There is <strong>%d site change</strong> waiting to be saved.",
9111 + "There are <strong>%d site changes</strong> waiting to be saved.",
9112 + dirtyEntityRecords.length
9113 + ),
9114 + dirtyEntityRecords.length
9115 + ),
9116 + { strong: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", {}) }
9117 + ) : selectItemsToSaveDescription })
9118 + ] })
9119 + ] }),
9120 + sortedPartitionedSavables.map((list) => {
9121 + return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
9122 + EntityTypeList,
9123 + {
9124 + list,
9125 + unselectedEntities,
9126 + setUnselectedEntities
9127 + },
9128 + list[0].name
9129 + );
9130 + }),
9131 + isInline && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
9132 + import_components3.Flex,
9133 + {
9134 + direction: "row",
9135 + justify: "flex-end",
9136 + className: "entities-saved-states__panel-footer",
9137 + children: actionButtons
9138 + }
9139 + )
9140 + ]
9141 + }
9142 + );
9143 + }
9144 +
7845 9145 // packages/core-data/build-module/private-apis.mjs
7846 - var privateApis = {};
7847 - lock(privateApis, {
9146 + var lockedApis = {
9147 + EntitiesSavedStates,
9148 + EntitiesSavedStatesExtensible,
9149 + getTemplateInfo,
9150 + getTemplatePartIcon,
9151 + useEntitiesSavedStatesIsDirty: useIsDirty,
7848 9152 useEntityRecordsWithPermissions,
7849 9153 RECEIVE_INTERMEDIATE_RESULTS,
9154 + CRDT_AUTOSAVE_SNAPSHOT_KEY,
9155 + entityContainsSnapshot,
9156 + getEntitySnapshot,
7850 9157 retrySyncConnection,
7851 9158 useActiveCollaborators,
7852 9159 useResolvedSelection,
7853 9160 useOnCollaboratorJoin,
7854 9161 useOnCollaboratorLeave,
7855 - useOnPostSave
7856 - });
9162 + useOnPostSave,
9163 + SelectionType,
9164 + SelectionDirection
9165 + };
9166 + var privateApis = {};
9167 + lock(privateApis, lockedApis);
7857 9168
7858 9169 // packages/core-data/build-module/index.mjs
7859 9170 var entitiesConfig2 = [
7860 9171 ...rootEntitiesConfig,
@@ -7939,11 +9250,13 @@
7939 9250 ...entitySelectors
7940 9251 },
7941 9252 resolvers: { ...resolvers_exports, ...entityResolvers }
7942 9253 });
7943 - var store = (0, import_data15.createReduxStore)(STORE_NAME, storeConfig());
9254 + var store = (0, import_data20.createReduxStore)(STORE_NAME, storeConfig());
7944 9255 unlock(store).registerPrivateSelectors(private_selectors_exports);
7945 9256 unlock(store).registerPrivateActions(private_actions_exports);
7946 - (0, import_data15.register)(store);
9257 + (0, import_data20.register)(store);
7947 9258 return __toCommonJS(index_exports);
9259 +})();
9260 +(window.wp ||= {}).coreData = wp.coreData;
7948 9261 })();
7949 9262 //# sourceMappingURL=index.js.map