@apollohg/react-native-rich-text-editor 2.0.0 → 2.0.2

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.
Files changed (180) hide show
  1. package/README.md +8 -116
  2. package/THIRD_PARTY_NOTICES.md +1 -1
  3. package/android/build.gradle +3 -0
  4. package/android/src/main/java/com/apollohg/editor/EditorEditTextImages.kt +25 -0
  5. package/android/src/main/java/com/apollohg/editor/EditorV2RenderValidation.kt +1 -0
  6. package/android/src/main/java/com/apollohg/editor/ImageResizeOverlayView.kt +101 -33
  7. package/android/src/main/java/com/apollohg/editor/RenderMediaSpans.kt +15 -3
  8. package/android/src/main/java/com/apollohg/editor/RichTextEditorView.kt +14 -0
  9. package/android/src/main/java/com/apollohg/editor/viewer/AndroidProseLayoutEngine.kt +1 -1
  10. package/app.plugin.js +42 -39
  11. package/dist/AtomHost.js +18 -11
  12. package/dist/EditorAddon.js +4 -2
  13. package/dist/EditorAddonNormalization.js +17 -9
  14. package/dist/EditorMentionThemeNormalization.js +6 -3
  15. package/dist/EditorMentionThemeValidation.js +28 -11
  16. package/dist/EditorStyleSheetNormalization.js +85 -38
  17. package/dist/EditorStyleSheetTypes.d.ts +1 -1
  18. package/dist/EditorTheme.d.ts +4 -0
  19. package/dist/EditorTheme.js +5 -3
  20. package/dist/EditorToolbarComponent.d.ts +1 -1
  21. package/dist/EditorToolbarComponent.js +1 -1
  22. package/dist/EditorToolbarRegistry.js +5 -5
  23. package/dist/EditorToolbarTypes.d.ts +12 -12
  24. package/dist/EditorToolbarVisuals.js +1 -1
  25. package/dist/ExternalTextComposition.js +89 -43
  26. package/dist/ImageLoadingPolicy.d.ts +1 -1
  27. package/dist/NativeEditorBoundaryError.d.ts +7 -7
  28. package/dist/NativeEditorBoundaryError.js +9 -5
  29. package/dist/NativeEditorCollaborationTransport.d.ts +7 -7
  30. package/dist/NativeEditorCollaborationTransport.js +28 -15
  31. package/dist/NativeEditorCreateConfig.js +11 -6
  32. package/dist/NativeEditorCreateJson.js +51 -25
  33. package/dist/NativeEditorCreateValidation.js +11 -6
  34. package/dist/NativeEditorDocumentBridge.d.ts +1 -1
  35. package/dist/NativeEditorDocumentBridge.js +32 -18
  36. package/dist/NativeEditorDocumentHandle.d.ts +4 -4
  37. package/dist/NativeEditorDocumentHandle.js +1 -1
  38. package/dist/NativeEditorLocalAwareness.js +25 -13
  39. package/dist/NativeEditorNativeModule.d.ts +8 -1
  40. package/dist/NativeEditorNativeModule.js +7 -5
  41. package/dist/NativeEditorRenderNormalization.js +66 -25
  42. package/dist/NativeEditorResultNormalization.js +53 -29
  43. package/dist/NativeEditorTypes.d.ts +10 -10
  44. package/dist/NativeEditorV2Decimal.js +6 -3
  45. package/dist/NativeProseViewer.js +11 -3
  46. package/dist/ResourceLimits.d.ts +2 -2
  47. package/dist/ResourceLimits.js +7 -2
  48. package/dist/RichTextEditor.js +1 -1
  49. package/dist/RichTextEditorNativeTypes.d.ts +1 -1
  50. package/dist/RichTextEditorNativeView.d.ts +1 -3
  51. package/dist/RichTextEditorSerialization.js +24 -14
  52. package/dist/RichTextEditorTypes.d.ts +1 -1
  53. package/dist/YjsCollaboration.d.ts +7 -7
  54. package/dist/YjsCollaboration.js +42 -26
  55. package/dist/addons.d.ts +4 -4
  56. package/dist/addons.js +3 -3
  57. package/dist/atomInstances.js +6 -3
  58. package/dist/atomUpdates.js +7 -4
  59. package/dist/atoms.js +20 -12
  60. package/dist/attributeValidation.js +55 -24
  61. package/dist/contentExpression.js +80 -42
  62. package/dist/listMarkers.d.ts +1 -1
  63. package/dist/listMarkers.js +1 -1
  64. package/dist/schemaDefinition.d.ts +1 -1
  65. package/dist/schemaDefinition.js +23 -14
  66. package/dist/schemaDocument.js +1 -1
  67. package/dist/schemaDocumentConstruction.js +25 -14
  68. package/dist/schemaNormalization.js +51 -29
  69. package/dist/schemaPresets.d.ts +1 -1
  70. package/dist/schemaPresets.js +9 -4
  71. package/dist/schemaResolution.js +46 -25
  72. package/dist/specs/PreparedProseViewerNativeComponent.d.ts +4 -0
  73. package/dist/useEditorToolbarInteractions.d.ts +2 -2
  74. package/dist/useEditorToolbarInteractions.js +45 -23
  75. package/dist/useEditorToolbarItems.d.ts +1 -1
  76. package/dist/useEditorToolbarItems.js +4 -3
  77. package/dist/useEditorToolbarPresentation.d.ts +3 -3
  78. package/dist/useEditorToolbarPresentation.js +4 -4
  79. package/dist/useEditorToolbarState.d.ts +1 -1
  80. package/dist/useEditorToolbarState.js +1 -1
  81. package/dist/useFocusPreservingFrames.js +11 -8
  82. package/dist/useNativeEditor.d.ts +1 -1
  83. package/dist/useNativeEditor.js +21 -11
  84. package/dist/useRichTextEditorCommands.d.ts +2 -2
  85. package/dist/useRichTextEditorCommands.js +59 -29
  86. package/dist/useRichTextEditorEvents.d.ts +3 -3
  87. package/dist/useRichTextEditorEvents.js +75 -32
  88. package/dist/useRichTextEditorMentions.d.ts +4 -4
  89. package/dist/useRichTextEditorMentions.js +48 -29
  90. package/dist/useRichTextEditorPresentation.d.ts +4 -4
  91. package/dist/useRichTextEditorPresentation.js +25 -23
  92. package/dist/useRichTextEditorState.d.ts +3 -3
  93. package/dist/useRichTextEditorState.js +20 -15
  94. package/dist/useRichTextEditorUpdates.d.ts +1 -1
  95. package/dist/useRichTextEditorUpdates.js +99 -41
  96. package/dist/useViewerAtoms.js +63 -36
  97. package/ios/EditorCore.xcframework/ios-arm64/libeditor_core.a +0 -0
  98. package/ios/EditorCore.xcframework/ios-arm64_x86_64-simulator/libeditor_core.a +0 -0
  99. package/ios/EditorInteractionOverlays.swift +114 -122
  100. package/ios/EditorLayoutManager.swift +13 -3
  101. package/ios/EditorStyleSheet.swift +12 -1
  102. package/ios/EditorTextView+Images.swift +32 -10
  103. package/ios/EditorTextView.swift +1 -1
  104. package/ios/EditorV2Adapter+RenderValidation.swift +2 -2
  105. package/ios/NativeToolbar+ButtonStyle.swift +17 -5
  106. package/ios/NativeToolbar+Diagnostics.swift +15 -0
  107. package/ios/RenderBridge+Atoms.swift +0 -1
  108. package/ios/RenderBridge+Attachments.swift +0 -29
  109. package/ios/RichTextEditorView.swift +4 -12
  110. package/ios/Viewer/CoreTextProseLayoutEngine+AttributedText.swift +3 -2
  111. package/package.json +11 -3
  112. package/react-native.config.js +1 -1
  113. package/rust/android/arm64-v8a/libeditor_core.so +0 -0
  114. package/rust/android/armeabi-v7a/libeditor_core.so +0 -0
  115. package/rust/android/x86/libeditor_core.so +0 -0
  116. package/rust/android/x86_64/libeditor_core.so +0 -0
  117. package/src/AtomHost.tsx +58 -28
  118. package/src/EditorAddon.ts +18 -8
  119. package/src/EditorAddonNormalization.ts +40 -11
  120. package/src/EditorMentionThemeNormalization.ts +15 -4
  121. package/src/EditorMentionThemeValidation.ts +51 -14
  122. package/src/EditorStyleSheet.ts +1 -0
  123. package/src/EditorStyleSheetNormalization.ts +195 -64
  124. package/src/EditorStyleSheetTypes.ts +1 -1
  125. package/src/EditorTheme.ts +13 -5
  126. package/src/EditorToolbarComponent.tsx +2 -1
  127. package/src/EditorToolbarRegistry.tsx +23 -13
  128. package/src/EditorToolbarTypes.tsx +12 -12
  129. package/src/EditorToolbarVisuals.tsx +6 -3
  130. package/src/EditorUpdateRevision.ts +1 -0
  131. package/src/ExternalTextComposition.ts +259 -49
  132. package/src/ImageLoadingPolicy.ts +3 -1
  133. package/src/NativeEditorBoundaryError.ts +38 -11
  134. package/src/NativeEditorCollaborationTransport.ts +108 -27
  135. package/src/NativeEditorCreateConfig.ts +92 -19
  136. package/src/NativeEditorCreateJson.ts +163 -26
  137. package/src/NativeEditorCreateValidation.ts +33 -12
  138. package/src/NativeEditorDocumentBridge.ts +111 -19
  139. package/src/NativeEditorDocumentHandle.ts +9 -4
  140. package/src/NativeEditorLocalAwareness.ts +70 -15
  141. package/src/NativeEditorNativeModule.ts +13 -9
  142. package/src/NativeEditorRenderNormalization.ts +128 -29
  143. package/src/NativeEditorResultNormalization.ts +143 -32
  144. package/src/NativeEditorTypes.ts +12 -11
  145. package/src/NativeEditorV2Decimal.ts +12 -3
  146. package/src/NativeProseViewer.tsx +46 -16
  147. package/src/ResourceLimits.ts +15 -8
  148. package/src/RichTextEditor.tsx +3 -1
  149. package/src/RichTextEditorNativeTypes.tsx +1 -1
  150. package/src/RichTextEditorNativeView.tsx +2 -8
  151. package/src/RichTextEditorSerialization.tsx +70 -24
  152. package/src/RichTextEditorTypes.tsx +1 -1
  153. package/src/YjsCollaboration.ts +143 -47
  154. package/src/addons.ts +12 -8
  155. package/src/atomInstances.ts +25 -5
  156. package/src/atomUpdates.ts +23 -6
  157. package/src/atoms.ts +85 -18
  158. package/src/attributeValidation.ts +97 -33
  159. package/src/contentExpression.ts +218 -63
  160. package/src/listMarkers.ts +1 -1
  161. package/src/schemaDefinition.ts +82 -20
  162. package/src/schemaDocument.ts +15 -1
  163. package/src/schemaDocumentConstruction.ts +80 -16
  164. package/src/schemaNormalization.ts +155 -41
  165. package/src/schemaPresets.ts +37 -31
  166. package/src/schemaResolution.ts +126 -27
  167. package/src/specs/PreparedProseViewerNativeComponent.ts +4 -2
  168. package/src/useEditorToolbarInteractions.tsx +85 -36
  169. package/src/useEditorToolbarItems.tsx +50 -22
  170. package/src/useEditorToolbarPresentation.tsx +81 -58
  171. package/src/useEditorToolbarState.tsx +8 -6
  172. package/src/useFocusPreservingFrames.ts +43 -15
  173. package/src/useNativeEditor.ts +111 -51
  174. package/src/useRichTextEditorCommands.tsx +127 -54
  175. package/src/useRichTextEditorEvents.tsx +144 -42
  176. package/src/useRichTextEditorMentions.tsx +118 -37
  177. package/src/useRichTextEditorPresentation.tsx +128 -114
  178. package/src/useRichTextEditorState.tsx +76 -40
  179. package/src/useRichTextEditorUpdates.tsx +207 -56
  180. package/src/useViewerAtoms.tsx +162 -66
@@ -7,6 +7,7 @@ export function getNativeModule(): NativeEditorModule {
7
7
  if (!_nativeModule) {
8
8
  _nativeModule = requireNativeModule<NativeEditorModule>('NativeEditor');
9
9
  }
10
+
10
11
  return _nativeModule;
11
12
  }
12
13
 
@@ -15,12 +16,13 @@ export function _resetNativeModuleCache(): void {
15
16
  _nativeModule = null;
16
17
  }
17
18
 
18
- // The only construction path. Consumes the frozen v2 result records
19
- // ({ value, error }, exactly one side set), normalizes them at the JS boundary
20
- // (decimal-string u64s, direct binaries, unsafe-integer rejection), and raises
21
- // typed per-domain errors with a non-retryable class for
22
- // ENGINE_INVARIANT_FAILED and destroyed lifecycles.
23
-
19
+ /**
20
+ * The only construction path. Consumes the frozen v2 result records
21
+ * ({ value, error }, exactly one side set), normalizes them at the JS boundary
22
+ * (decimal-string u64s, direct binaries, unsafe-integer rejection), and raises
23
+ * typed per-domain errors with a non-retryable class for
24
+ * ENGINE_INVARIANT_FAILED and destroyed lifecycles.
25
+ */
24
26
  export const ERR_V2_NATIVE_RESPONSE =
25
27
  'NativeEditorBridge: invalid v2 result record from native module';
26
28
 
@@ -29,7 +31,7 @@ export const ERR_V2_DESTROYED = 'NativeEditorBridge: v2 editor handle has been d
29
31
  export const V2_ENVELOPE_VERSION = 1;
30
32
 
31
33
  /**
32
- * The v2 surface of the NativeEditor native module the complete
34
+ * The v2 surface of the NativeEditor native module : the complete
33
35
  * production ABI. Every call resolves the method lazily and fails clearly
34
36
  * when the v2 surface is absent. Decimal-string identifiers keep full u64
35
37
  * fidelity across the JavaScript boundary, and binaries travel as direct
@@ -81,13 +83,15 @@ export function invokeNativeEditorV2<K extends keyof NativeEditorModule>(
81
83
  name: K,
82
84
  ...args: Parameters<NativeEditorModule[K]>
83
85
  ): unknown {
84
- const nativeModule = getNativeModule() as unknown as Record<string, unknown>;
85
- const method = nativeModule[name as string];
86
+ const nativeModule = getNativeModule();
87
+ const method = nativeModule[name];
88
+
86
89
  if (typeof method !== 'function') {
87
90
  throw new Error(
88
91
  `NativeEditorBridge: native module does not expose the v2 entry ${String(name)}`
89
92
  );
90
93
  }
94
+
91
95
  return (method as (...fnArgs: unknown[]) => unknown).apply(nativeModule, args);
92
96
  }
93
97
 
@@ -28,7 +28,10 @@ import {
28
28
  import { validEditorMentionTheme } from './EditorMentionThemeValidation';
29
29
 
30
30
  export function validListContext(value: unknown): value is ListContext {
31
- if (!isPlainRecord(value)) return false;
31
+ if (!isPlainRecord(value)) {
32
+ return false;
33
+ }
34
+
32
35
  return (
33
36
  hasOnlyOwnKeys(value, [
34
37
  'ordered',
@@ -55,34 +58,43 @@ export function validRenderElement(value: unknown): value is RenderElement {
55
58
  if (!isPlainRecord(value) || !RENDER_ELEMENT_TYPES.has(value.type as RenderElement['type'])) {
56
59
  return false;
57
60
  }
61
+
58
62
  switch (value.type) {
59
63
  case 'textRun':
60
64
  return (
61
- hasExactOwnKeys(value, ['type', 'text', 'marks']) &&
65
+ hasExactOwnKeys(value, [ 'type', 'text', 'marks' ]) &&
62
66
  typeof value.text === 'string' &&
63
67
  Array.isArray(value.marks) &&
64
68
  value.marks.every(validRenderMark)
65
69
  );
66
70
  case 'blockStart':
67
71
  return (
68
- hasOnlyOwnKeys(value, ['type', 'nodeType', 'depth', 'listContext', 'language']) &&
72
+ hasOnlyOwnKeys(value, [ 'type',
73
+ 'nodeType',
74
+ 'depth',
75
+ 'listContext',
76
+ 'language' ]) &&
69
77
  typeof value.nodeType === 'string' &&
70
78
  nativeEditorV2U32(value.depth) != null &&
71
79
  (value.language === undefined || typeof value.language === 'string') &&
72
80
  (value.listContext === undefined || validListContext(value.listContext))
73
81
  );
74
82
  case 'blockEnd':
75
- return hasExactOwnKeys(value, ['type']);
83
+ return hasExactOwnKeys(value, [ 'type' ]);
76
84
  case 'voidInline':
77
85
  return (
78
- hasOnlyOwnKeys(value, ['type', 'nodeType', 'docPos', 'attrs']) &&
86
+ hasOnlyOwnKeys(value, [ 'type', 'nodeType', 'docPos', 'attrs' ]) &&
79
87
  typeof value.nodeType === 'string' &&
80
88
  nativeEditorV2U32(value.docPos) != null &&
81
89
  (value.attrs === undefined || isPlainRecord(value.attrs))
82
90
  );
83
91
  case 'voidBlock':
84
92
  return (
85
- hasOnlyOwnKeys(value, ['type', 'nodeType', 'docPos', 'attrs', 'atomId']) &&
93
+ hasOnlyOwnKeys(value, [ 'type',
94
+ 'nodeType',
95
+ 'docPos',
96
+ 'attrs',
97
+ 'atomId' ]) &&
86
98
  typeof value.nodeType === 'string' &&
87
99
  nativeEditorV2U32(value.docPos) != null &&
88
100
  (value.attrs === undefined || isPlainRecord(value.attrs)) &&
@@ -106,27 +118,38 @@ export function validRenderElement(value: unknown): value is RenderElement {
106
118
  );
107
119
  case 'opaqueBlockAtom':
108
120
  return (
109
- hasOnlyOwnKeys(value, ['type', 'nodeType', 'label', 'docPos', 'attrs']) &&
121
+ hasOnlyOwnKeys(value, [ 'type',
122
+ 'nodeType',
123
+ 'label',
124
+ 'docPos',
125
+ 'attrs' ]) &&
110
126
  typeof value.nodeType === 'string' &&
111
127
  typeof value.label === 'string' &&
112
128
  nativeEditorV2U32(value.docPos) != null &&
113
129
  (value.attrs === undefined || isPlainRecord(value.attrs))
114
130
  );
115
131
  }
132
+
116
133
  return false;
117
134
  }
118
135
 
119
136
  export function normalizeRenderBlocks(value: unknown): RenderElement[][] | null {
120
- if (!Array.isArray(value)) return null;
137
+ if (!Array.isArray(value)) {
138
+ return null;
139
+ }
140
+
121
141
  return value.every(
122
- (block) => Array.isArray(block) && block.every((element) => validRenderElement(element))
142
+ block => Array.isArray(block) && block.every(element => validRenderElement(element))
123
143
  )
124
- ? (value as RenderElement[][])
144
+ ? (value)
125
145
  : null;
126
146
  }
127
147
 
128
148
  export function normalizeRenderPatch(value: unknown): RenderBlocksPatch | null | undefined {
129
- if (value === null) return null;
149
+ if (value === null) {
150
+ return null;
151
+ }
152
+
130
153
  if (
131
154
  !isPlainRecord(value) ||
132
155
  !hasExactOwnKeys(value, [
@@ -138,10 +161,12 @@ export function normalizeRenderPatch(value: unknown): RenderBlocksPatch | null |
138
161
  ) {
139
162
  return undefined;
140
163
  }
164
+
141
165
  const renderBlocks = normalizeRenderBlocks(value.renderBlocks);
142
166
  const baseDocumentVersion = normalizeNativeEditorV2DecimalId(value.baseDocumentVersion);
143
167
  const startIndex = nativeEditorV2U32(value.startIndex);
144
168
  const deleteCount = nativeEditorV2U32(value.deleteCount);
169
+
145
170
  if (
146
171
  renderBlocks == null ||
147
172
  baseDocumentVersion == null ||
@@ -150,36 +175,65 @@ export function normalizeRenderPatch(value: unknown): RenderBlocksPatch | null |
150
175
  ) {
151
176
  return undefined;
152
177
  }
178
+
153
179
  return { baseDocumentVersion, startIndex, deleteCount, renderBlocks };
154
180
  }
155
181
 
156
182
  export function normalizeRenderSelection(value: unknown): Selection | null {
157
- if (!isPlainRecord(value)) return null;
158
- if (value.type === 'all') return hasExactOwnKeys(value, ['type']) ? { type: 'all' } : null;
183
+ if (!isPlainRecord(value)) {
184
+ return null;
185
+ }
186
+
187
+ if (value.type === 'all') {
188
+ return hasExactOwnKeys(value, [ 'type' ]) ? { type: 'all' } : null;
189
+ }
190
+
159
191
  if (value.type === 'text') {
160
- if (!hasExactOwnKeys(value, ['type', 'anchor', 'head', 'anchorScalar', 'headScalar'])) {
192
+ if (!hasExactOwnKeys(value, [ 'type',
193
+ 'anchor',
194
+ 'head',
195
+ 'anchorScalar',
196
+ 'headScalar' ])) {
161
197
  return null;
162
198
  }
199
+
163
200
  const anchor = nativeEditorV2U32(value.anchor);
164
201
  const head = nativeEditorV2U32(value.head);
165
202
  const anchorScalar = nativeEditorV2U32(value.anchorScalar);
166
203
  const headScalar = nativeEditorV2U32(value.headScalar);
167
- if (anchor == null || head == null || anchorScalar == null || headScalar == null)
204
+
205
+ if (anchor == null || head == null || anchorScalar == null || headScalar == null) {
168
206
  return null;
169
- return { type: 'text', anchor, head, anchorScalar, headScalar };
207
+ }
208
+
209
+ return {
210
+ type: 'text', anchor, head, anchorScalar, headScalar,
211
+ };
170
212
  }
213
+
171
214
  if (value.type === 'node') {
172
- if (!hasExactOwnKeys(value, ['type', 'pos', 'posScalar'])) return null;
215
+ if (!hasExactOwnKeys(value, [ 'type', 'pos', 'posScalar' ])) {
216
+ return null;
217
+ }
218
+
173
219
  const pos = nativeEditorV2U32(value.pos);
174
220
  const posScalar = nativeEditorV2U32(value.posScalar);
175
- if (pos == null || posScalar == null) return null;
221
+
222
+ if (pos == null || posScalar == null) {
223
+ return null;
224
+ }
225
+
176
226
  return { type: 'node', pos, posScalar };
177
227
  }
228
+
178
229
  return null;
179
230
  }
180
231
 
181
232
  export function normalizeRenderActiveState(value: unknown): ActiveState | null {
182
- if (!isPlainRecord(value)) return null;
233
+ if (!isPlainRecord(value)) {
234
+ return null;
235
+ }
236
+
183
237
  if (
184
238
  !hasExactOwnKeys(value, [
185
239
  'marks',
@@ -199,13 +253,25 @@ export function normalizeRenderActiveState(value: unknown): ActiveState | null {
199
253
  ) {
200
254
  return null;
201
255
  }
202
- return value as unknown as ActiveState;
256
+
257
+ return {
258
+ marks: value.marks,
259
+ markAttrs: value.markAttrs as ActiveState['markAttrs'],
260
+ nodes: value.nodes,
261
+ commands: value.commands,
262
+ allowedMarks: value.allowedMarks,
263
+ insertableNodes: value.insertableNodes,
264
+ };
203
265
  }
204
266
 
205
267
  export function normalizeRenderHistoryState(value: unknown): HistoryState | null {
206
- if (!isPlainRecord(value) || !hasExactOwnKeys(value, ['canUndo', 'canRedo'])) return null;
268
+ if (!isPlainRecord(value) || !hasExactOwnKeys(value, [ 'canUndo', 'canRedo' ])) {
269
+ return null;
270
+ }
271
+
207
272
  const canUndo = optionalBoolean(value.canUndo);
208
273
  const canRedo = optionalBoolean(value.canRedo);
274
+
209
275
  return canUndo == null || canRedo == null ? null : { canUndo, canRedo };
210
276
  }
211
277
 
@@ -214,8 +280,10 @@ export function deepFreezeV2Value<T>(value: T): T {
214
280
  for (const child of Object.values(value as Record<string, unknown>)) {
215
281
  deepFreezeV2Value(child);
216
282
  }
283
+
217
284
  Object.freeze(value);
218
285
  }
286
+
219
287
  return value;
220
288
  }
221
289
 
@@ -224,7 +292,11 @@ export function normalizeNativeEditorV2RenderUpdateValue(
224
292
  value: unknown
225
293
  ): NativeEditorAtomicRenderSnapshot | null {
226
294
  const parsed = parseNativeEditorV2JsonValue(value);
227
- if (!isPlainRecord(parsed)) return null;
295
+
296
+ if (!isPlainRecord(parsed)) {
297
+ return null;
298
+ }
299
+
228
300
  if (
229
301
  !hasExactOwnKeys(parsed, [
230
302
  'renderBlocks',
@@ -240,8 +312,10 @@ export function normalizeNativeEditorV2RenderUpdateValue(
240
312
  ) {
241
313
  return null;
242
314
  }
315
+
243
316
  const renderBlocks =
244
317
  parsed.renderBlocks === null ? null : normalizeRenderBlocks(parsed.renderBlocks);
318
+
245
319
  const renderPatch = normalizeRenderPatch(parsed.renderPatch);
246
320
  const selection = normalizeRenderSelection(parsed.selection);
247
321
  const activeState = normalizeRenderActiveState(parsed.activeState);
@@ -250,6 +324,7 @@ export function normalizeNativeEditorV2RenderUpdateValue(
250
324
  const stateRevision = normalizeRevisionField(parsed, 'stateRevision');
251
325
  const scalarLength = nativeEditorV2U32(parsed.scalarLength);
252
326
  const documentIsEmpty = parsed.documentIsEmpty;
327
+
253
328
  if (
254
329
  renderPatch === undefined ||
255
330
  selection == null ||
@@ -262,14 +337,23 @@ export function normalizeNativeEditorV2RenderUpdateValue(
262
337
  ) {
263
338
  return null;
264
339
  }
340
+
265
341
  let renderPayload: NativeEditorAtomicRenderPayload;
342
+
266
343
  if (renderBlocks == null) {
267
- if (parsed.renderBlocks !== null || renderPatch == null) return null;
344
+ if (parsed.renderBlocks !== null || renderPatch == null) {
345
+ return null;
346
+ }
347
+
268
348
  renderPayload = { renderBlocks: null, renderPatch };
269
349
  } else {
270
- if (renderPatch !== null) return null;
350
+ if (renderPatch !== null) {
351
+ return null;
352
+ }
353
+
271
354
  renderPayload = { renderBlocks, renderPatch: null };
272
355
  }
356
+
273
357
  return deepFreezeV2Value({
274
358
  ...renderPayload,
275
359
  selection,
@@ -284,17 +368,20 @@ export function normalizeNativeEditorV2RenderUpdateValue(
284
368
 
285
369
  export function normalizeNativeEditorV2DocumentJsonValue(value: unknown): DocumentJSON | null {
286
370
  const parsed = parseNativeEditorV2JsonValue(value);
287
- return isPlainRecord(parsed) ? (parsed as DocumentJSON) : null;
371
+
372
+ return isPlainRecord(parsed) ? (parsed) : null;
288
373
  }
289
374
 
290
375
  export function normalizeNativeEditorV2ContentSnapshotValue(
291
376
  value: unknown
292
377
  ): ContentSnapshot | null {
293
378
  const parsed = parseNativeEditorV2JsonValue(value);
379
+
294
380
  if (!isPlainRecord(parsed) || typeof parsed.html !== 'string' || !isPlainRecord(parsed.json)) {
295
381
  return null;
296
382
  }
297
- return { html: parsed.html, json: parsed.json as DocumentJSON };
383
+
384
+ return { html: parsed.html, json: parsed.json };
298
385
  }
299
386
 
300
387
  export interface NativeEditorSnapshotExport {
@@ -306,15 +393,27 @@ export interface NativeEditorSnapshotExport {
306
393
  export function normalizeNativeEditorV2SnapshotExportValue(
307
394
  value: unknown
308
395
  ): NativeEditorSnapshotExport | null {
309
- if (!isPlainRecord(value) || typeof value.metadataJson !== 'string') return null;
396
+ if (!isPlainRecord(value) || typeof value.metadataJson !== 'string') {
397
+ return null;
398
+ }
399
+
310
400
  const encodedState = normalizeNativeEditorV2Bytes(value.encodedState);
311
- if (encodedState == null) return null;
401
+
402
+ if (encodedState == null) {
403
+ return null;
404
+ }
405
+
312
406
  return { metadataJson: value.metadataJson, encodedState };
313
407
  }
314
408
 
315
409
  export function normalizeNativeEditorV2CreateValue(value: unknown): { editorId: string } | null {
316
410
  const parsed = parseNativeEditorV2JsonValue(value);
317
- if (!isPlainRecord(parsed)) return null;
411
+
412
+ if (!isPlainRecord(parsed)) {
413
+ return null;
414
+ }
415
+
318
416
  const editorId = normalizeNativeEditorV2DecimalId(parsed.editorId);
417
+
319
418
  return editorId == null ? null : { editorId };
320
419
  }