@wordpress/core-data 7.33.1 → 7.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,14 @@
1
1
  import fastDeepEqual from "fast-deep-equal/es6";
2
+ import { __unstableSerializeAndClean } from "@wordpress/blocks";
2
3
  import { Y } from "@wordpress/sync";
3
4
  import {
4
5
  mergeCrdtBlocks
5
6
  } from "./crdt-blocks";
6
- import { CRDT_RECORD_MAP_KEY } from "../sync";
7
+ import {
8
+ CRDT_DOC_META_PERSISTENCE_KEY,
9
+ CRDT_RECORD_MAP_KEY,
10
+ WORDPRESS_META_KEY_FOR_CRDT_DOC_PERSISTENCE
11
+ } from "../sync";
7
12
  let lastSelection = null;
8
13
  const allowedPostProperties = /* @__PURE__ */ new Set([
9
14
  "author",
@@ -14,6 +19,7 @@ const allowedPostProperties = /* @__PURE__ */ new Set([
14
19
  "featured_media",
15
20
  "format",
16
21
  "ping_status",
22
+ "meta",
17
23
  "slug",
18
24
  "status",
19
25
  "sticky",
@@ -21,6 +27,9 @@ const allowedPostProperties = /* @__PURE__ */ new Set([
21
27
  "template",
22
28
  "title"
23
29
  ]);
30
+ const disallowedPostMetaKeys = /* @__PURE__ */ new Set([
31
+ WORDPRESS_META_KEY_FOR_CRDT_DOC_PERSISTENCE
32
+ ]);
24
33
  function defaultApplyChangesToCRDTDoc(ydoc, changes) {
25
34
  const ymap = ydoc.getMap(CRDT_RECORD_MAP_KEY);
26
35
  Object.entries(changes).forEach(([key, newValue]) => {
@@ -39,7 +48,7 @@ function defaultApplyChangesToCRDTDoc(ydoc, changes) {
39
48
  }
40
49
  });
41
50
  }
42
- function applyPostChangesToCRDTDoc(ydoc, changes, postType) {
51
+ function applyPostChangesToCRDTDoc(ydoc, changes, _postType) {
43
52
  const ymap = ydoc.getMap(CRDT_RECORD_MAP_KEY);
44
53
  Object.entries(changes).forEach(([key, newValue]) => {
45
54
  if (!allowedPostProperties.has(key)) {
@@ -68,6 +77,31 @@ function applyPostChangesToCRDTDoc(ydoc, changes, postType) {
68
77
  mergeValue(currentValue, rawNewValue, setValue);
69
78
  break;
70
79
  }
80
+ // "Meta" is overloaded term; here, it refers to post meta.
81
+ case "meta": {
82
+ let metaMap = ymap.get("meta");
83
+ if (!(metaMap instanceof Y.Map)) {
84
+ metaMap = new Y.Map();
85
+ setValue(metaMap);
86
+ }
87
+ Object.entries(newValue ?? {}).forEach(
88
+ ([metaKey, metaValue]) => {
89
+ if (disallowedPostMetaKeys.has(metaKey)) {
90
+ return;
91
+ }
92
+ mergeValue(
93
+ metaMap.get(metaKey),
94
+ // current value in CRDT
95
+ metaValue,
96
+ // new value from changes
97
+ (updatedMetaValue) => {
98
+ metaMap.set(metaKey, updatedMetaValue);
99
+ }
100
+ );
101
+ }
102
+ );
103
+ break;
104
+ }
71
105
  case "slug": {
72
106
  if (!newValue) {
73
107
  break;
@@ -99,9 +133,10 @@ function applyPostChangesToCRDTDoc(ydoc, changes, postType) {
99
133
  function defaultGetChangesFromCRDTDoc(crdtDoc) {
100
134
  return crdtDoc.getMap(CRDT_RECORD_MAP_KEY).toJSON();
101
135
  }
102
- function getPostChangesFromCRDTDoc(ydoc, editedRecord, postType) {
136
+ function getPostChangesFromCRDTDoc(ydoc, editedRecord, _postType) {
103
137
  const ymap = ydoc.getMap(CRDT_RECORD_MAP_KEY);
104
- return Object.fromEntries(
138
+ let allowedMetaChanges = {};
139
+ const changes = Object.fromEntries(
105
140
  Object.entries(ymap.toJSON()).filter(([key, newValue]) => {
106
141
  if (!allowedPostProperties.has(key)) {
107
142
  return false;
@@ -109,6 +144,12 @@ function getPostChangesFromCRDTDoc(ydoc, editedRecord, postType) {
109
144
  const currentValue = editedRecord[key];
110
145
  switch (key) {
111
146
  case "blocks": {
147
+ if (ydoc.meta?.get(CRDT_DOC_META_PERSISTENCE_KEY) && editedRecord.content) {
148
+ const blocks = ymap.get("blocks");
149
+ return __unstableSerializeAndClean(
150
+ blocks.toJSON()
151
+ ).trim() !== editedRecord.content.raw.trim();
152
+ }
112
153
  return true;
113
154
  }
114
155
  case "date": {
@@ -120,6 +161,18 @@ function getPostChangesFromCRDTDoc(ydoc, editedRecord, postType) {
120
161
  }
121
162
  return haveValuesChanged(currentValue, newValue);
122
163
  }
164
+ case "meta": {
165
+ allowedMetaChanges = Object.fromEntries(
166
+ Object.entries(newValue ?? {}).filter(
167
+ ([metaKey]) => !disallowedPostMetaKeys.has(metaKey)
168
+ )
169
+ );
170
+ const mergedValue = {
171
+ ...currentValue,
172
+ ...allowedMetaChanges
173
+ };
174
+ return haveValuesChanged(currentValue, mergedValue);
175
+ }
123
176
  case "status": {
124
177
  if ("auto-draft" === newValue) {
125
178
  return false;
@@ -140,6 +193,13 @@ function getPostChangesFromCRDTDoc(ydoc, editedRecord, postType) {
140
193
  }
141
194
  })
142
195
  );
196
+ if ("object" === typeof changes.meta) {
197
+ changes.meta = {
198
+ ...editedRecord.meta,
199
+ ...allowedMetaChanges
200
+ };
201
+ }
202
+ return changes;
143
203
  }
144
204
  function getRawValue(value) {
145
205
  if ("string" === typeof value) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/crdt.ts"],
4
- "sourcesContent": ["/**\n * External dependencies\n */\nimport fastDeepEqual from 'fast-deep-equal/es6';\n\n/**\n * WordPress dependencies\n */\nimport { type CRDTDoc, type ObjectData, Y } from '@wordpress/sync';\n\n/**\n * Internal dependencies\n */\nimport {\n\tmergeCrdtBlocks,\n\ttype Block,\n\ttype YBlock,\n\ttype YBlocks,\n} from './crdt-blocks';\nimport { type Post } from '../entity-types/post';\nimport { type Type } from '../entity-types';\nimport { CRDT_RECORD_MAP_KEY } from '../sync';\nimport type { WPBlockSelection, WPSelection } from '../types';\n\nexport type PostChanges = Partial< Post > & {\n\tblocks?: Block[];\n\texcerpt?: Post[ 'excerpt' ] | string;\n\tselection?: WPSelection;\n\ttitle?: Post[ 'title' ] | string;\n};\n\n// Hold a reference to the last known selection to help compute Y.Text deltas.\nlet lastSelection: WPBlockSelection | null = null;\n\n// Properties that are allowed to be synced for a post.\nconst allowedPostProperties = new Set< string >( [\n\t'author',\n\t'blocks',\n\t'comment_status',\n\t'date',\n\t'excerpt',\n\t'featured_media',\n\t'format',\n\t'ping_status',\n\t'slug',\n\t'status',\n\t'sticky',\n\t'tags',\n\t'template',\n\t'title',\n] );\n\n/**\n * Given a set of local changes to a generic entity record, apply those changes\n * to the local Y.Doc.\n *\n * @param {CRDTDoc} ydoc\n * @param {Partial< ObjectData >} changes\n * @return {void}\n */\nexport function defaultApplyChangesToCRDTDoc(\n\tydoc: CRDTDoc,\n\tchanges: ObjectData\n): void {\n\tconst ymap = ydoc.getMap( CRDT_RECORD_MAP_KEY );\n\n\tObject.entries( changes ).forEach( ( [ key, newValue ] ) => {\n\t\t// Cannot serialize function values, so cannot sync them.\n\t\tif ( 'function' === typeof newValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Set the value in the root document.\n\t\tfunction setValue< T = unknown >( updatedValue: T ): void {\n\t\t\tymap.set( key, updatedValue );\n\t\t}\n\n\t\tswitch ( key ) {\n\t\t\t// Add support for additional data types here.\n\n\t\t\tdefault: {\n\t\t\t\tconst currentValue = ymap.get( key );\n\t\t\t\tmergeValue( currentValue, newValue, setValue );\n\t\t\t}\n\t\t}\n\t} );\n}\n\n/**\n * Given a set of local changes to a post record, apply those changes to the\n * local Y.Doc.\n *\n * @param {CRDTDoc} ydoc\n * @param {PostChanges} changes\n * @param {Type} postType\n * @return {void}\n */\nexport function applyPostChangesToCRDTDoc(\n\tydoc: CRDTDoc,\n\tchanges: PostChanges,\n\tpostType: Type // eslint-disable-line @typescript-eslint/no-unused-vars\n): void {\n\tconst ymap = ydoc.getMap( CRDT_RECORD_MAP_KEY );\n\n\tObject.entries( changes ).forEach( ( [ key, newValue ] ) => {\n\t\tif ( ! allowedPostProperties.has( key ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Cannot serialize function values, so cannot sync them.\n\t\tif ( 'function' === typeof newValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Set the value in the root document.\n\t\tfunction setValue< T = unknown >( updatedValue: T ): void {\n\t\t\tymap.set( key, updatedValue );\n\t\t}\n\n\t\tswitch ( key ) {\n\t\t\tcase 'blocks': {\n\t\t\t\tlet currentBlocks = ymap.get( 'blocks' ) as YBlocks;\n\n\t\t\t\t// Initialize.\n\t\t\t\tif ( ! ( currentBlocks instanceof Y.Array ) ) {\n\t\t\t\t\tcurrentBlocks = new Y.Array< YBlock >();\n\t\t\t\t\tsetValue( currentBlocks );\n\t\t\t\t}\n\n\t\t\t\t// Block[] from local changes.\n\t\t\t\tconst newBlocks = ( newValue as PostChanges[ 'blocks' ] ) ?? [];\n\n\t\t\t\t// Merge blocks does not need `setValue` because it is operating on a\n\t\t\t\t// Yjs type that is already in the Y.Doc.\n\t\t\t\tmergeCrdtBlocks( currentBlocks, newBlocks, lastSelection );\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'excerpt': {\n\t\t\t\tconst currentValue = ymap.get( 'excerpt' ) as\n\t\t\t\t\t| string\n\t\t\t\t\t| undefined;\n\t\t\t\tconst rawNewValue = getRawValue( newValue );\n\n\t\t\t\tmergeValue( currentValue, rawNewValue, setValue );\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'slug': {\n\t\t\t\t// Do not sync an empty slug. This indicates that the post is using\n\t\t\t\t// the default auto-generated slug.\n\t\t\t\tif ( ! newValue ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tconst currentValue = ymap.get( 'slug' ) as string;\n\t\t\t\tmergeValue( currentValue, newValue, setValue );\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'title': {\n\t\t\t\tconst currentValue = ymap.get( 'title' ) as string | undefined;\n\n\t\t\t\t// Copy logic from prePersistPostType to ensure that the \"Auto\n\t\t\t\t// Draft\" template title is not synced.\n\t\t\t\tlet rawNewValue = getRawValue( newValue );\n\t\t\t\tif ( ! currentValue && 'Auto Draft' === rawNewValue ) {\n\t\t\t\t\trawNewValue = '';\n\t\t\t\t}\n\n\t\t\t\tmergeValue( currentValue, rawNewValue, setValue );\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Add support for additional data types here.\n\n\t\t\tdefault: {\n\t\t\t\tconst currentValue = ymap.get( key );\n\t\t\t\tmergeValue( currentValue, newValue, setValue );\n\t\t\t}\n\t\t}\n\t} );\n\n\t// Update the lastSelection for use in computing Y.Text deltas.\n\tif ( 'selection' in changes ) {\n\t\tlastSelection = changes.selection?.selectionStart ?? null;\n\t}\n}\n\nexport function defaultGetChangesFromCRDTDoc( crdtDoc: CRDTDoc ): ObjectData {\n\treturn crdtDoc.getMap( CRDT_RECORD_MAP_KEY ).toJSON();\n}\n\n/**\n * Given a local Y.Doc that *may* contain changes from remote peers, compare\n * against the local record and determine if there are changes (edits) we want\n * to dispatch.\n *\n * @param {CRDTDoc} ydoc\n * @param {Post} editedRecord\n * @param {Type} postType\n * @return {Partial<PostChanges>} The changes that should be applied to the local record.\n */\nexport function getPostChangesFromCRDTDoc(\n\tydoc: CRDTDoc,\n\teditedRecord: Post,\n\tpostType: Type // eslint-disable-line @typescript-eslint/no-unused-vars\n): PostChanges {\n\tconst ymap = ydoc.getMap( CRDT_RECORD_MAP_KEY );\n\n\treturn Object.fromEntries(\n\t\tObject.entries( ymap.toJSON() ).filter( ( [ key, newValue ] ) => {\n\t\t\tif ( ! allowedPostProperties.has( key ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst currentValue = editedRecord[ key ];\n\n\t\t\tswitch ( key ) {\n\t\t\t\tcase 'blocks': {\n\t\t\t\t\t// The consumers of blocks have memoization that renders optimization\n\t\t\t\t\t// here unnecessary.\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tcase 'date': {\n\t\t\t\t\t// Do not sync an empty date if our current value is a \"floating\" date.\n\t\t\t\t\t// Borrowing logic from the isEditedPostDateFloating selector.\n\t\t\t\t\tconst currentDateIsFloating =\n\t\t\t\t\t\t[ 'draft', 'auto-draft', 'pending' ].includes(\n\t\t\t\t\t\t\tymap.get( 'status' ) as string\n\t\t\t\t\t\t) &&\n\t\t\t\t\t\t( null === currentValue ||\n\t\t\t\t\t\t\teditedRecord.modified === currentValue );\n\n\t\t\t\t\tif ( ! newValue && currentDateIsFloating ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn haveValuesChanged( currentValue, newValue );\n\t\t\t\t}\n\n\t\t\t\tcase 'status': {\n\t\t\t\t\t// Do not sync an invalid status.\n\t\t\t\t\tif ( 'auto-draft' === newValue ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn haveValuesChanged( currentValue, newValue );\n\t\t\t\t}\n\n\t\t\t\tcase 'excerpt':\n\t\t\t\tcase 'title': {\n\t\t\t\t\treturn haveValuesChanged(\n\t\t\t\t\t\tgetRawValue( currentValue ),\n\t\t\t\t\t\tnewValue\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Add support for additional data types here.\n\n\t\t\t\tdefault: {\n\t\t\t\t\treturn haveValuesChanged( currentValue, newValue );\n\t\t\t\t}\n\t\t\t}\n\t\t} )\n\t);\n}\n\n/**\n * Extract the raw string value from a property that may be a string or an object\n * with a `raw` property (`RenderedText`).\n *\n * @param {unknown} value The value to extract from.\n * @return {string|undefined} The raw string value, or undefined if it could not be determined.\n */\nfunction getRawValue( value?: unknown ): string | undefined {\n\t// Value may be a string property or a nested object with a `raw` property.\n\tif ( 'string' === typeof value ) {\n\t\treturn value;\n\t}\n\n\tif (\n\t\tvalue &&\n\t\t'object' === typeof value &&\n\t\t'raw' in value &&\n\t\t'string' === typeof value.raw\n\t) {\n\t\treturn value.raw;\n\t}\n\n\treturn undefined;\n}\n\nfunction haveValuesChanged< ValueType = any >(\n\tcurrentValue: ValueType,\n\tnewValue: ValueType\n): boolean {\n\treturn ! fastDeepEqual( currentValue, newValue );\n}\n\nfunction mergeValue< ValueType = any >(\n\tcurrentValue: ValueType,\n\tnewValue: ValueType,\n\tsetValue: ( value: ValueType ) => void\n): void {\n\tif ( haveValuesChanged< ValueType >( currentValue, newValue ) ) {\n\t\tsetValue( newValue );\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport fastDeepEqual from 'fast-deep-equal/es6';\n\n/**\n * WordPress dependencies\n */\n// @ts-expect-error No exported types.\nimport { __unstableSerializeAndClean } from '@wordpress/blocks';\nimport { type CRDTDoc, type ObjectData, Y } from '@wordpress/sync';\n\n/**\n * Internal dependencies\n */\nimport {\n\tmergeCrdtBlocks,\n\ttype Block,\n\ttype YBlock,\n\ttype YBlocks,\n} from './crdt-blocks';\nimport { type Post } from '../entity-types/post';\nimport { type Type } from '../entity-types';\nimport {\n\tCRDT_DOC_META_PERSISTENCE_KEY,\n\tCRDT_RECORD_MAP_KEY,\n\tWORDPRESS_META_KEY_FOR_CRDT_DOC_PERSISTENCE,\n} from '../sync';\nimport type { WPBlockSelection, WPSelection } from '../types';\n\nexport type PostChanges = Partial< Post > & {\n\tblocks?: Block[];\n\texcerpt?: Post[ 'excerpt' ] | string;\n\tselection?: WPSelection;\n\ttitle?: Post[ 'title' ] | string;\n};\n\n// Hold a reference to the last known selection to help compute Y.Text deltas.\nlet lastSelection: WPBlockSelection | null = null;\n\n// Properties that are allowed to be synced for a post.\nconst allowedPostProperties = new Set< string >( [\n\t'author',\n\t'blocks',\n\t'comment_status',\n\t'date',\n\t'excerpt',\n\t'featured_media',\n\t'format',\n\t'ping_status',\n\t'meta',\n\t'slug',\n\t'status',\n\t'sticky',\n\t'tags',\n\t'template',\n\t'title',\n] );\n\n// Post meta keys that should *not* be synced.\nconst disallowedPostMetaKeys = new Set< string >( [\n\tWORDPRESS_META_KEY_FOR_CRDT_DOC_PERSISTENCE,\n] );\n\n/**\n * Given a set of local changes to a generic entity record, apply those changes\n * to the local Y.Doc.\n *\n * @param {CRDTDoc} ydoc\n * @param {Partial< ObjectData >} changes\n * @return {void}\n */\nexport function defaultApplyChangesToCRDTDoc(\n\tydoc: CRDTDoc,\n\tchanges: ObjectData\n): void {\n\tconst ymap = ydoc.getMap( CRDT_RECORD_MAP_KEY );\n\n\tObject.entries( changes ).forEach( ( [ key, newValue ] ) => {\n\t\t// Cannot serialize function values, so cannot sync them.\n\t\tif ( 'function' === typeof newValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Set the value in the root document.\n\t\tfunction setValue< T = unknown >( updatedValue: T ): void {\n\t\t\tymap.set( key, updatedValue );\n\t\t}\n\n\t\tswitch ( key ) {\n\t\t\t// Add support for additional data types here.\n\n\t\t\tdefault: {\n\t\t\t\tconst currentValue = ymap.get( key );\n\t\t\t\tmergeValue( currentValue, newValue, setValue );\n\t\t\t}\n\t\t}\n\t} );\n}\n\n/**\n * Given a set of local changes to a post record, apply those changes to the\n * local Y.Doc.\n *\n * @param {CRDTDoc} ydoc\n * @param {PostChanges} changes\n * @param {Type} _postType\n * @return {void}\n */\nexport function applyPostChangesToCRDTDoc(\n\tydoc: CRDTDoc,\n\tchanges: PostChanges,\n\t_postType: Type // eslint-disable-line @typescript-eslint/no-unused-vars\n): void {\n\tconst ymap = ydoc.getMap( CRDT_RECORD_MAP_KEY );\n\n\tObject.entries( changes ).forEach( ( [ key, newValue ] ) => {\n\t\tif ( ! allowedPostProperties.has( key ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Cannot serialize function values, so cannot sync them.\n\t\tif ( 'function' === typeof newValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Set the value in the root document.\n\t\tfunction setValue< T = unknown >( updatedValue: T ): void {\n\t\t\tymap.set( key, updatedValue );\n\t\t}\n\n\t\tswitch ( key ) {\n\t\t\tcase 'blocks': {\n\t\t\t\tlet currentBlocks = ymap.get( 'blocks' ) as YBlocks;\n\n\t\t\t\t// Initialize.\n\t\t\t\tif ( ! ( currentBlocks instanceof Y.Array ) ) {\n\t\t\t\t\tcurrentBlocks = new Y.Array< YBlock >();\n\t\t\t\t\tsetValue( currentBlocks );\n\t\t\t\t}\n\n\t\t\t\t// Block[] from local changes.\n\t\t\t\tconst newBlocks = ( newValue as PostChanges[ 'blocks' ] ) ?? [];\n\n\t\t\t\t// Merge blocks does not need `setValue` because it is operating on a\n\t\t\t\t// Yjs type that is already in the Y.Doc.\n\t\t\t\tmergeCrdtBlocks( currentBlocks, newBlocks, lastSelection );\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'excerpt': {\n\t\t\t\tconst currentValue = ymap.get( 'excerpt' ) as\n\t\t\t\t\t| string\n\t\t\t\t\t| undefined;\n\t\t\t\tconst rawNewValue = getRawValue( newValue );\n\n\t\t\t\tmergeValue( currentValue, rawNewValue, setValue );\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// \"Meta\" is overloaded term; here, it refers to post meta.\n\t\t\tcase 'meta': {\n\t\t\t\tlet metaMap = ymap.get( 'meta' ) as Y.Map< unknown >;\n\n\t\t\t\t// Initialize.\n\t\t\t\tif ( ! ( metaMap instanceof Y.Map ) ) {\n\t\t\t\t\tmetaMap = new Y.Map();\n\t\t\t\t\tsetValue( metaMap );\n\t\t\t\t}\n\n\t\t\t\t// Iterate over each meta property in the new value and merge it if it\n\t\t\t\t// should be synced.\n\t\t\t\tObject.entries( newValue ?? {} ).forEach(\n\t\t\t\t\t( [ metaKey, metaValue ] ) => {\n\t\t\t\t\t\tif ( disallowedPostMetaKeys.has( metaKey ) ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tmergeValue(\n\t\t\t\t\t\t\tmetaMap.get( metaKey ), // current value in CRDT\n\t\t\t\t\t\t\tmetaValue, // new value from changes\n\t\t\t\t\t\t\t( updatedMetaValue: unknown ): void => {\n\t\t\t\t\t\t\t\tmetaMap.set( metaKey, updatedMetaValue );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'slug': {\n\t\t\t\t// Do not sync an empty slug. This indicates that the post is using\n\t\t\t\t// the default auto-generated slug.\n\t\t\t\tif ( ! newValue ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tconst currentValue = ymap.get( 'slug' ) as string;\n\t\t\t\tmergeValue( currentValue, newValue, setValue );\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'title': {\n\t\t\t\tconst currentValue = ymap.get( 'title' ) as string | undefined;\n\n\t\t\t\t// Copy logic from prePersistPostType to ensure that the \"Auto\n\t\t\t\t// Draft\" template title is not synced.\n\t\t\t\tlet rawNewValue = getRawValue( newValue );\n\t\t\t\tif ( ! currentValue && 'Auto Draft' === rawNewValue ) {\n\t\t\t\t\trawNewValue = '';\n\t\t\t\t}\n\n\t\t\t\tmergeValue( currentValue, rawNewValue, setValue );\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Add support for additional data types here.\n\n\t\t\tdefault: {\n\t\t\t\tconst currentValue = ymap.get( key );\n\t\t\t\tmergeValue( currentValue, newValue, setValue );\n\t\t\t}\n\t\t}\n\t} );\n\n\t// Update the lastSelection for use in computing Y.Text deltas.\n\tif ( 'selection' in changes ) {\n\t\tlastSelection = changes.selection?.selectionStart ?? null;\n\t}\n}\n\nexport function defaultGetChangesFromCRDTDoc( crdtDoc: CRDTDoc ): ObjectData {\n\treturn crdtDoc.getMap( CRDT_RECORD_MAP_KEY ).toJSON();\n}\n\n/**\n * Given a local Y.Doc that *may* contain changes from remote peers, compare\n * against the local record and determine if there are changes (edits) we want\n * to dispatch.\n *\n * @param {CRDTDoc} ydoc\n * @param {Post} editedRecord\n * @param {Type} _postType\n * @return {Partial<PostChanges>} The changes that should be applied to the local record.\n */\nexport function getPostChangesFromCRDTDoc(\n\tydoc: CRDTDoc,\n\teditedRecord: Post,\n\t_postType: Type // eslint-disable-line @typescript-eslint/no-unused-vars\n): PostChanges {\n\tconst ymap = ydoc.getMap( CRDT_RECORD_MAP_KEY );\n\n\tlet allowedMetaChanges: Post[ 'meta' ] = {};\n\n\tconst changes = Object.fromEntries(\n\t\tObject.entries( ymap.toJSON() ).filter( ( [ key, newValue ] ) => {\n\t\t\tif ( ! allowedPostProperties.has( key ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst currentValue = editedRecord[ key ];\n\n\t\t\tswitch ( key ) {\n\t\t\t\tcase 'blocks': {\n\t\t\t\t\t// When we are passed a persisted CRDT document, make a special\n\t\t\t\t\t// comparison of the content and blocks.\n\t\t\t\t\t//\n\t\t\t\t\t// When other fields (besides `blocks`) are mutated outside the block\n\t\t\t\t\t// editor, the change is caught by an equality check (see other cases\n\t\t\t\t\t// in this `switch` statement). As a transient property, `blocks`\n\t\t\t\t\t// cannot be directly mutated outside the block editor -- only\n\t\t\t\t\t// `content` can.\n\t\t\t\t\t//\n\t\t\t\t\t// Therefore, for this special comparison, we serialize the `blocks`\n\t\t\t\t\t// from the persisted CRDT document and compare that to the content\n\t\t\t\t\t// from the persisted record. If they differ, we know that the content\n\t\t\t\t\t// in the database has changed, and therefore the blocks have changed.\n\t\t\t\t\t//\n\t\t\t\t\t// We cannot directly compare the `blocks` from the CRDT document to\n\t\t\t\t\t// the `blocks` derived from the `content` in the persisted record,\n\t\t\t\t\t// because the latter will have different client IDs.\n\t\t\t\t\tif (\n\t\t\t\t\t\tydoc.meta?.get( CRDT_DOC_META_PERSISTENCE_KEY ) &&\n\t\t\t\t\t\teditedRecord.content\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst blocks = ymap.get( 'blocks' ) as YBlocks;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t__unstableSerializeAndClean(\n\t\t\t\t\t\t\t\tblocks.toJSON()\n\t\t\t\t\t\t\t).trim() !== editedRecord.content.raw.trim()\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\t// The consumers of blocks have memoization that renders optimization\n\t\t\t\t\t// here unnecessary.\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tcase 'date': {\n\t\t\t\t\t// Do not sync an empty date if our current value is a \"floating\" date.\n\t\t\t\t\t// Borrowing logic from the isEditedPostDateFloating selector.\n\t\t\t\t\tconst currentDateIsFloating =\n\t\t\t\t\t\t[ 'draft', 'auto-draft', 'pending' ].includes(\n\t\t\t\t\t\t\tymap.get( 'status' ) as string\n\t\t\t\t\t\t) &&\n\t\t\t\t\t\t( null === currentValue ||\n\t\t\t\t\t\t\teditedRecord.modified === currentValue );\n\n\t\t\t\t\tif ( ! newValue && currentDateIsFloating ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn haveValuesChanged( currentValue, newValue );\n\t\t\t\t}\n\n\t\t\t\tcase 'meta': {\n\t\t\t\t\tallowedMetaChanges = Object.fromEntries(\n\t\t\t\t\t\tObject.entries( newValue ?? {} ).filter(\n\t\t\t\t\t\t\t( [ metaKey ] ) =>\n\t\t\t\t\t\t\t\t! disallowedPostMetaKeys.has( metaKey )\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\n\t\t\t\t\t// Merge the allowed meta changes with the current meta values since\n\t\t\t\t\t// not all meta properties are synced.\n\t\t\t\t\tconst mergedValue = {\n\t\t\t\t\t\t...( currentValue as PostChanges[ 'meta' ] ),\n\t\t\t\t\t\t...allowedMetaChanges,\n\t\t\t\t\t};\n\n\t\t\t\t\treturn haveValuesChanged( currentValue, mergedValue );\n\t\t\t\t}\n\n\t\t\t\tcase 'status': {\n\t\t\t\t\t// Do not sync an invalid status.\n\t\t\t\t\tif ( 'auto-draft' === newValue ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn haveValuesChanged( currentValue, newValue );\n\t\t\t\t}\n\n\t\t\t\tcase 'excerpt':\n\t\t\t\tcase 'title': {\n\t\t\t\t\treturn haveValuesChanged(\n\t\t\t\t\t\tgetRawValue( currentValue ),\n\t\t\t\t\t\tnewValue\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Add support for additional data types here.\n\n\t\t\t\tdefault: {\n\t\t\t\t\treturn haveValuesChanged( currentValue, newValue );\n\t\t\t\t}\n\t\t\t}\n\t\t} )\n\t);\n\n\t// Meta changes must be merged with the edited record since not all meta\n\t// properties are synced.\n\tif ( 'object' === typeof changes.meta ) {\n\t\tchanges.meta = {\n\t\t\t...editedRecord.meta,\n\t\t\t...allowedMetaChanges,\n\t\t};\n\t}\n\n\treturn changes;\n}\n\n/**\n * Extract the raw string value from a property that may be a string or an object\n * with a `raw` property (`RenderedText`).\n *\n * @param {unknown} value The value to extract from.\n * @return {string|undefined} The raw string value, or undefined if it could not be determined.\n */\nfunction getRawValue( value?: unknown ): string | undefined {\n\t// Value may be a string property or a nested object with a `raw` property.\n\tif ( 'string' === typeof value ) {\n\t\treturn value;\n\t}\n\n\tif (\n\t\tvalue &&\n\t\t'object' === typeof value &&\n\t\t'raw' in value &&\n\t\t'string' === typeof value.raw\n\t) {\n\t\treturn value.raw;\n\t}\n\n\treturn undefined;\n}\n\nfunction haveValuesChanged< ValueType = any >(\n\tcurrentValue: ValueType,\n\tnewValue: ValueType\n): boolean {\n\treturn ! fastDeepEqual( currentValue, newValue );\n}\n\nfunction mergeValue< ValueType = any >(\n\tcurrentValue: ValueType,\n\tnewValue: ValueType,\n\tsetValue: ( value: ValueType ) => void\n): void {\n\tif ( haveValuesChanged< ValueType >( currentValue, newValue ) ) {\n\t\tsetValue( newValue );\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -295,7 +295,7 @@ export const additionalEntityConfigLoaders: ({
295
295
  plural: string;
296
296
  loadEntities: typeof loadSiteEntity;
297
297
  })[];
298
- export function prePersistPostType(persistedRecord: any, edits: any): any;
298
+ export function prePersistPostType(persistedRecord: any, edits: any, name: string, isTemplate: boolean): any;
299
299
  export function getMethodName(kind: string, name: string, prefix?: string): string;
300
300
  /**
301
301
  * Returns the list of post type entities.
@@ -1 +1 @@
1
- {"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../src/entities.js"],"names":[],"mappings":"AAsBA,iCAAkC,IAAI,CAAC;AAYvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkLE;;;;;;;;;;;;AAcF;;;;;;;;;;KASE;AASK,0EAqBN;AAmLM,oCANI,MAAM,QACN,MAAM,WACN,MAAM,GAEL,MAAM,CAMjB;AArLD;;;;GAIG;AACH,sDAoFC;AAyBD;;;;GAIG;AACH,gDAsCC"}
1
+ {"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../src/entities.js"],"names":[],"mappings":"AAuBA,iCAAkC,IAAI,CAAC;AAYvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkLE;;;;;;;;;;;;AAcF;;;;;;;;;;KASE;AAWK,2EAJI,MAAM,cACN,OAAO,OA0CjB;AAsLM,oCANI,MAAM,QACN,MAAM,WACN,MAAM,GAEL,MAAM,CAMjB;AAxLD;;;;GAIG;AACH,sDAuFC;AAyBD;;;;GAIG;AACH,gDAsCC"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../src/resolvers.js"],"names":[],"mappings":"AAkCO,kCAHI,MAAO,SAAS;;oBAYzB;AAKK;;oBAKL;AAYK,sCAPI,MAAM,QACN,MAAM,OACN,MAAM,GAAC,MAAM,qBACb,MAAO,SAAS;;;;;oBAyKzB;;IAIF,kEAcC;;AAED;;GAEG;AACH,0CAAuE;AAEvE;;GAEG;AACH,6CAA0E;AAUnE,uCALI,MAAM,QACN,MAAM,UACN,UAAO;;;;oBAoOhB;;IAEF,kEAOC;;AAED;;GAEG;AACH,kDAAgF;AAEhF;;GAEG;AACH,kDAAgF;AAKzE;;;oBAUL;AAEF;;GAEG;AACH,wCAAqE;AAO9D,qCAFI,MAAM;;oBAcf;AAYK,yCANI,MAAM,YAEN,MAAM,MAAO,MAEZ,MAAM,OAAA;;;;oBAqFhB;AAUK,8CAJI,MAAM,QACN,MAAM,YACN,MAAM,GAAC,MAAM;;oBAMtB;AAQK,uCAHI,MAAM,UACN,MAAM;;;oBAqBf;AAWK,sCAHI,MAAM,UACN,MAAM;;oBAMf;AAEK;;;oBAuBL;AAEK;;;oBAYL;AAEK;;;oBAYL;AAKK;;;oBA+BL;;IAEF,gDAOC;;AAEM;;oBAKL;AAEK;;oBAOL;AAEK;;;oBAwBL;AAEK;;;;oBA0CL;AAEK;;;;oBA0BL;;IAEF,gDAMC;;AAYM,mCAPI,MAAM,QACN,MAAM,aACN,MAAM,GAAC,MAAM,UACb,MAAO,SAAS;;;;oBAwGzB;;IAGF,sFAK8B;;AAavB,kCARI,MAAM,QACN,MAAM,aACN,MAAM,GAAC,MAAM,eACb,MAAM,GAAC,MAAM,SACb,MAAO,SAAS;;;oBA+CzB;AAOK,gDAFI,MAAM;;;oBA0Bf;AAOK,wCAFI,MAAM;;oBAuBf"}
1
+ {"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../src/resolvers.js"],"names":[],"mappings":"AAkCO,kCAHI,MAAO,SAAS;;oBAYzB;AAKK;;oBAKL;AAYK,sCAPI,MAAM,QACN,MAAM,OACN,MAAM,GAAC,MAAM,qBACb,MAAO,SAAS;;;;;oBAiLzB;;IAIF,kEAcC;;AAED;;GAEG;AACH,0CAAuE;AAEvE;;GAEG;AACH,6CAA0E;AAUnE,uCALI,MAAM,QACN,MAAM,UACN,UAAO;;;;oBAoOhB;;IAEF,kEAOC;;AAED;;GAEG;AACH,kDAAgF;AAEhF;;GAEG;AACH,kDAAgF;AAKzE;;;oBAUL;AAEF;;GAEG;AACH,wCAAqE;AAO9D,qCAFI,MAAM;;oBAcf;AAYK,yCANI,MAAM,YAEN,MAAM,MAAO,MAEZ,MAAM,OAAA;;;;oBAqFhB;AAUK,8CAJI,MAAM,QACN,MAAM,YACN,MAAM,GAAC,MAAM;;oBAMtB;AAQK,uCAHI,MAAM,UACN,MAAM;;;oBAqBf;AAWK,sCAHI,MAAM,UACN,MAAM;;oBAMf;AAEK;;;oBAuBL;AAEK;;;oBAYL;AAEK;;;oBAYL;AAKK;;;oBA+BL;;IAEF,gDAOC;;AAEM;;oBAKL;AAEK;;oBAOL;AAEK;;;oBAwBL;AAEK;;;;oBA0CL;AAEK;;;;oBA0BL;;IAEF,gDAMC;;AAYM,mCAPI,MAAM,QACN,MAAM,aACN,MAAM,GAAC,MAAM,UACb,MAAO,SAAS;;;;oBAwGzB;;IAGF,sFAK8B;;AAavB,kCARI,MAAM,QACN,MAAM,aACN,MAAM,GAAC,MAAM,eACb,MAAM,GAAC,MAAM,SACb,MAAO,SAAS;;;oBA+CzB;AAOK,gDAFI,MAAM;;;oBA0Bf;AAOK,wCAFI,MAAM;;oBAuBf"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { CRDT_RECORD_MAP_KEY, LOCAL_EDITOR_ORIGIN, LOCAL_SYNC_MANAGER_ORIGIN, type SyncManager } from '@wordpress/sync';
5
- export { CRDT_RECORD_MAP_KEY, LOCAL_EDITOR_ORIGIN, LOCAL_SYNC_MANAGER_ORIGIN };
4
+ import { CRDT_DOC_META_PERSISTENCE_KEY, CRDT_RECORD_MAP_KEY, LOCAL_EDITOR_ORIGIN, LOCAL_SYNC_MANAGER_ORIGIN, WORDPRESS_META_KEY_FOR_CRDT_DOC_PERSISTENCE, type SyncManager } from '@wordpress/sync';
5
+ export { CRDT_DOC_META_PERSISTENCE_KEY, CRDT_RECORD_MAP_KEY, LOCAL_EDITOR_ORIGIN, LOCAL_SYNC_MANAGER_ORIGIN, WORDPRESS_META_KEY_FOR_CRDT_DOC_PERSISTENCE, };
6
6
  export declare function getSyncManager(): SyncManager | undefined;
7
7
  //# sourceMappingURL=sync.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACN,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,KAAK,WAAW,EAEhB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,CAAC;AAI/E,wBAAgB,cAAc,IAAI,WAAW,GAAG,SAAS,CAQxD"}
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACN,6BAA6B,EAC7B,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,2CAA2C,EAC3C,KAAK,WAAW,EAEhB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACN,6BAA6B,EAC7B,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,2CAA2C,GAC3C,CAAC;AAIF,wBAAgB,cAAc,IAAI,WAAW,GAAG,SAAS,CAQxD"}
@@ -1,6 +1,3 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
1
  import { type CRDTDoc, type ObjectData } from '@wordpress/sync';
5
2
  /**
6
3
  * Internal dependencies
@@ -30,10 +27,10 @@ export declare function defaultApplyChangesToCRDTDoc(ydoc: CRDTDoc, changes: Obj
30
27
  *
31
28
  * @param {CRDTDoc} ydoc
32
29
  * @param {PostChanges} changes
33
- * @param {Type} postType
30
+ * @param {Type} _postType
34
31
  * @return {void}
35
32
  */
36
- export declare function applyPostChangesToCRDTDoc(ydoc: CRDTDoc, changes: PostChanges, postType: Type): void;
33
+ export declare function applyPostChangesToCRDTDoc(ydoc: CRDTDoc, changes: PostChanges, _postType: Type): void;
37
34
  export declare function defaultGetChangesFromCRDTDoc(crdtDoc: CRDTDoc): ObjectData;
38
35
  /**
39
36
  * Given a local Y.Doc that *may* contain changes from remote peers, compare
@@ -42,8 +39,8 @@ export declare function defaultGetChangesFromCRDTDoc(crdtDoc: CRDTDoc): ObjectDa
42
39
  *
43
40
  * @param {CRDTDoc} ydoc
44
41
  * @param {Post} editedRecord
45
- * @param {Type} postType
42
+ * @param {Type} _postType
46
43
  * @return {Partial<PostChanges>} The changes that should be applied to the local record.
47
44
  */
48
- export declare function getPostChangesFromCRDTDoc(ydoc: CRDTDoc, editedRecord: Post, postType: Type): PostChanges;
45
+ export declare function getPostChangesFromCRDTDoc(ydoc: CRDTDoc, editedRecord: Post, _postType: Type): PostChanges;
49
46
  //# sourceMappingURL=crdt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"crdt.d.ts","sourceRoot":"","sources":["../../src/utils/crdt.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,UAAU,EAAK,MAAM,iBAAiB,CAAC;AAEnE;;GAEG;AACH,OAAO,EAEN,KAAK,KAAK,EAGV,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAoB,WAAW,EAAE,MAAM,UAAU,CAAC;AAE9D,MAAM,MAAM,WAAW,GAAG,OAAO,CAAE,IAAI,CAAE,GAAG;IAC3C,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,IAAI,CAAE,SAAS,CAAE,GAAG,MAAM,CAAC;IACrC,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,KAAK,CAAC,EAAE,IAAI,CAAE,OAAO,CAAE,GAAG,MAAM,CAAC;CACjC,CAAC;AAuBF;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAC3C,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,UAAU,GACjB,IAAI,CAuBN;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACxC,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,IAAI,GACZ,IAAI,CAsFN;AAED,wBAAgB,4BAA4B,CAAE,OAAO,EAAE,OAAO,GAAI,UAAU,CAE3E;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACxC,IAAI,EAAE,OAAO,EACb,YAAY,EAAE,IAAI,EAClB,QAAQ,EAAE,IAAI,GACZ,WAAW,CA4Db"}
1
+ {"version":3,"file":"crdt.d.ts","sourceRoot":"","sources":["../../src/utils/crdt.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,UAAU,EAAK,MAAM,iBAAiB,CAAC;AAEnE;;GAEG;AACH,OAAO,EAEN,KAAK,KAAK,EAGV,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAM5C,OAAO,KAAK,EAAoB,WAAW,EAAE,MAAM,UAAU,CAAC;AAE9D,MAAM,MAAM,WAAW,GAAG,OAAO,CAAE,IAAI,CAAE,GAAG;IAC3C,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,IAAI,CAAE,SAAS,CAAE,GAAG,MAAM,CAAC;IACrC,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,KAAK,CAAC,EAAE,IAAI,CAAE,OAAO,CAAE,GAAG,MAAM,CAAC;CACjC,CAAC;AA6BF;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAC3C,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,UAAU,GACjB,IAAI,CAuBN;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACxC,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,IAAI,GACb,IAAI,CAoHN;AAED,wBAAgB,4BAA4B,CAAE,OAAO,EAAE,OAAO,GAAI,UAAU,CAE3E;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACxC,IAAI,EAAE,OAAO,EACb,YAAY,EAAE,IAAI,EAClB,SAAS,EAAE,IAAI,GACb,WAAW,CAwHb"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/core-data",
3
- "version": "7.33.1",
3
+ "version": "7.34.0",
4
4
  "description": "Access to and manipulation of core WordPress entities.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -40,22 +40,22 @@
40
40
  "{src,build,build-module}/index.js"
41
41
  ],
42
42
  "dependencies": {
43
- "@wordpress/api-fetch": "^7.33.1",
44
- "@wordpress/block-editor": "^15.6.1",
45
- "@wordpress/blocks": "^15.6.1",
46
- "@wordpress/compose": "^7.33.1",
47
- "@wordpress/data": "^10.33.1",
48
- "@wordpress/deprecated": "^4.33.1",
49
- "@wordpress/element": "^6.33.1",
50
- "@wordpress/html-entities": "^4.33.1",
51
- "@wordpress/i18n": "^6.6.1",
52
- "@wordpress/is-shallow-equal": "^5.33.1",
53
- "@wordpress/private-apis": "^1.33.1",
54
- "@wordpress/rich-text": "^7.33.1",
55
- "@wordpress/sync": "^1.33.1",
56
- "@wordpress/undo-manager": "^1.33.1",
57
- "@wordpress/url": "^4.33.1",
58
- "@wordpress/warning": "^3.33.1",
43
+ "@wordpress/api-fetch": "^7.34.0",
44
+ "@wordpress/block-editor": "^15.7.0",
45
+ "@wordpress/blocks": "^15.7.0",
46
+ "@wordpress/compose": "^7.34.0",
47
+ "@wordpress/data": "^10.34.0",
48
+ "@wordpress/deprecated": "^4.34.0",
49
+ "@wordpress/element": "^6.34.0",
50
+ "@wordpress/html-entities": "^4.34.0",
51
+ "@wordpress/i18n": "^6.7.0",
52
+ "@wordpress/is-shallow-equal": "^5.34.0",
53
+ "@wordpress/private-apis": "^1.34.0",
54
+ "@wordpress/rich-text": "^7.34.0",
55
+ "@wordpress/sync": "^1.34.0",
56
+ "@wordpress/undo-manager": "^1.34.0",
57
+ "@wordpress/url": "^4.34.0",
58
+ "@wordpress/warning": "^3.34.0",
59
59
  "change-case": "^4.1.2",
60
60
  "equivalent-key-map": "^0.2.2",
61
61
  "fast-deep-equal": "^3.1.3",
@@ -69,5 +69,5 @@
69
69
  "publishConfig": {
70
70
  "access": "public"
71
71
  },
72
- "gitHead": "5f84bafdec1bed05247c1080c12f6a237951b862"
72
+ "gitHead": "ceebff807958d2e8fc755b5a20473939c78b4d1d"
73
73
  }
package/src/entities.js CHANGED
@@ -13,6 +13,7 @@ import { __ } from '@wordpress/i18n';
13
13
  /**
14
14
  * Internal dependencies
15
15
  */
16
+ import { getSyncManager } from './sync';
16
17
  import {
17
18
  applyPostChangesToCRDTDoc,
18
19
  defaultApplyChangesToCRDTDoc,
@@ -236,16 +237,23 @@ export const additionalEntityConfigLoaders = [
236
237
  ];
237
238
 
238
239
  /**
239
- * Returns a function to be used to retrieve extra edits to apply before persisting a post type.
240
+ * Apply extra edits before persisting a post type.
240
241
  *
241
- * @param {Object} persistedRecord Already persisted Post
242
- * @param {Object} edits Edits.
242
+ * @param {Object} persistedRecord Already persisted Post
243
+ * @param {Object} edits Edits.
244
+ * @param {string} name Post type name.
245
+ * @param {boolean} isTemplate Whether the post type is a template.
243
246
  * @return {Object} Updated edits.
244
247
  */
245
- export const prePersistPostType = ( persistedRecord, edits ) => {
248
+ export const prePersistPostType = (
249
+ persistedRecord,
250
+ edits,
251
+ name,
252
+ isTemplate
253
+ ) => {
246
254
  const newEdits = {};
247
255
 
248
- if ( persistedRecord?.status === 'auto-draft' ) {
256
+ if ( ! isTemplate && persistedRecord?.status === 'auto-draft' ) {
249
257
  // Saving an auto-draft should create a draft by default.
250
258
  if ( ! edits.status && ! newEdits.status ) {
251
259
  newEdits.status = 'draft';
@@ -262,6 +270,19 @@ export const prePersistPostType = ( persistedRecord, edits ) => {
262
270
  }
263
271
  }
264
272
 
273
+ // Add meta for persisted CRDT document.
274
+ if ( persistedRecord && window.__experimentalEnableSync ) {
275
+ if ( globalThis.IS_GUTENBERG_PLUGIN ) {
276
+ const objectType = `postType/${ name }`;
277
+ const objectId = persistedRecord.id;
278
+ const meta = getSyncManager()?.createMeta( objectType, objectId );
279
+ newEdits.meta = {
280
+ ...edits.meta,
281
+ ...meta,
282
+ };
283
+ }
284
+ }
285
+
265
286
  return newEdits;
266
287
  };
267
288
 
@@ -298,7 +319,8 @@ async function loadPostTypeEntities() {
298
319
  ( isTemplate
299
320
  ? capitalCase( record.slug ?? '' )
300
321
  : String( record.id ) ),
301
- __unstablePrePersist: isTemplate ? undefined : prePersistPostType,
322
+ __unstablePrePersist: ( persistedRecord, edits ) =>
323
+ prePersistPostType( persistedRecord, edits, name, isTemplate ),
302
324
  __unstable_rest_base: postType.rest_base,
303
325
  supportsPagination: true,
304
326
  getRevisionsUrl: ( parentId, revisionId ) =>
@@ -347,7 +369,9 @@ async function loadPostTypeEntities() {
347
369
  *
348
370
  * @type {Record< string, boolean >}
349
371
  */
350
- supports: {},
372
+ supports: {
373
+ crdtPersistence: true,
374
+ },
351
375
  };
352
376
  }
353
377
  }
package/src/resolvers.js CHANGED
@@ -215,6 +215,14 @@ export const getEntityRecord =
215
215
  name,
216
216
  key
217
217
  ),
218
+ // Save the current entity record's unsaved edits.
219
+ saveRecord: () => {
220
+ dispatch.saveEditedEntityRecord(
221
+ kind,
222
+ name,
223
+ key
224
+ );
225
+ },
218
226
  }
219
227
  );
220
228
  }
package/src/sync.ts CHANGED
@@ -2,14 +2,22 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import {
5
+ CRDT_DOC_META_PERSISTENCE_KEY,
5
6
  CRDT_RECORD_MAP_KEY,
6
7
  LOCAL_EDITOR_ORIGIN,
7
8
  LOCAL_SYNC_MANAGER_ORIGIN,
9
+ WORDPRESS_META_KEY_FOR_CRDT_DOC_PERSISTENCE,
8
10
  type SyncManager,
9
11
  createSyncManager,
10
12
  } from '@wordpress/sync';
11
13
 
12
- export { CRDT_RECORD_MAP_KEY, LOCAL_EDITOR_ORIGIN, LOCAL_SYNC_MANAGER_ORIGIN };
14
+ export {
15
+ CRDT_DOC_META_PERSISTENCE_KEY,
16
+ CRDT_RECORD_MAP_KEY,
17
+ LOCAL_EDITOR_ORIGIN,
18
+ LOCAL_SYNC_MANAGER_ORIGIN,
19
+ WORDPRESS_META_KEY_FOR_CRDT_DOC_PERSISTENCE,
20
+ };
13
21
 
14
22
  let syncManager: SyncManager;
15
23
 
@@ -50,7 +50,7 @@ describe( 'prePersistPostType', () => {
50
50
  status: 'auto-draft',
51
51
  };
52
52
  const edits = {};
53
- expect( prePersistPostType( record, edits ) ).toEqual( {
53
+ expect( prePersistPostType( record, edits, 'post', false ) ).toEqual( {
54
54
  status: 'draft',
55
55
  title: '',
56
56
  } );
@@ -58,13 +58,15 @@ describe( 'prePersistPostType', () => {
58
58
  record = {
59
59
  status: 'publish',
60
60
  };
61
- expect( prePersistPostType( record, edits ) ).toEqual( {} );
61
+ expect( prePersistPostType( record, edits, 'post', false ) ).toEqual(
62
+ {}
63
+ );
62
64
 
63
65
  record = {
64
66
  status: 'auto-draft',
65
67
  title: 'Auto Draft',
66
68
  };
67
- expect( prePersistPostType( record, edits ) ).toEqual( {
69
+ expect( prePersistPostType( record, edits, 'post', false ) ).toEqual( {
68
70
  status: 'draft',
69
71
  title: '',
70
72
  } );
@@ -73,7 +75,20 @@ describe( 'prePersistPostType', () => {
73
75
  status: 'publish',
74
76
  title: 'My Title',
75
77
  };
76
- expect( prePersistPostType( record, edits ) ).toEqual( {} );
78
+ expect( prePersistPostType( record, edits, 'post', false ) ).toEqual(
79
+ {}
80
+ );
81
+ } );
82
+
83
+ it( 'does not set the status to draft and empty the title when saving templates', () => {
84
+ const record = {
85
+ status: 'auto-draft',
86
+ title: 'Auto Draft',
87
+ };
88
+ const edits = {};
89
+ expect( prePersistPostType( record, edits, 'post', true ) ).toEqual(
90
+ {}
91
+ );
77
92
  } );
78
93
  } );
79
94
 
@@ -175,6 +175,7 @@ describe( 'getEntityRecord', () => {
175
175
  {
176
176
  editRecord: expect.any( Function ),
177
177
  getEditedRecord: expect.any( Function ),
178
+ saveRecord: expect.any( Function ),
178
179
  }
179
180
  );
180
181
  } );
@@ -228,6 +229,7 @@ describe( 'getEntityRecord', () => {
228
229
  {
229
230
  editRecord: expect.any( Function ),
230
231
  getEditedRecord: expect.any( Function ),
232
+ saveRecord: expect.any( Function ),
231
233
  }
232
234
  );
233
235
  } );