PluginProbe
Gutenberg / trunk
Gutenberg vtrunk
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.1 → trunk 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