@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
@@ -95,7 +95,10 @@ export type V2JsonSerializationFrame =
95
95
  | V2JsonSerializationObjectFrame;
96
96
 
97
97
  export function chargeV2JsonWork(state: V2JsonNormalizationTraversal, label: string): void {
98
- if (state.work >= V2_CREATE_JSON_MAX_WORK) invalidV2JsonValue(label);
98
+ if (state.work >= V2_CREATE_JSON_MAX_WORK) {
99
+ invalidV2JsonValue(label);
100
+ }
101
+
99
102
  state.work += 1;
100
103
  }
101
104
 
@@ -111,6 +114,7 @@ export function chargeV2JsonBytes(
111
114
  ) {
112
115
  invalidV2JsonValue(label);
113
116
  }
117
+
114
118
  budget.bytes += amount;
115
119
  }
116
120
 
@@ -118,7 +122,10 @@ export function chargeV2JsonSerializationWork(
118
122
  state: V2JsonSerializationState,
119
123
  label: string
120
124
  ): void {
121
- if (state.work >= V2_CREATE_WIRE_MAX_BYTES) invalidV2JsonValue(label);
125
+ if (state.work >= V2_CREATE_WIRE_MAX_BYTES) {
126
+ invalidV2JsonValue(label);
127
+ }
128
+
122
129
  state.work += 1;
123
130
  }
124
131
 
@@ -134,13 +141,16 @@ export function chargeV2JsonSerializationBytes(
134
141
  ) {
135
142
  invalidV2JsonValue(label);
136
143
  }
144
+
137
145
  state.bytes += amount;
138
146
  }
139
147
 
140
148
  export function utf8V2JsonByteLength(value: string): number {
141
149
  let bytes = 0;
150
+
142
151
  for (let index = 0; index < value.length; index += 1) {
143
152
  const code = V2_CREATE_STRING_CHAR_CODE_AT.call(value, index);
153
+
144
154
  if (code <= 0x7f) {
145
155
  bytes += 1;
146
156
  } else if (code <= 0x7ff) {
@@ -150,6 +160,7 @@ export function utf8V2JsonByteLength(value: string): number {
150
160
  index + 1 < value.length
151
161
  ? V2_CREATE_STRING_CHAR_CODE_AT.call(value, index + 1)
152
162
  : -1;
163
+
153
164
  if (next >= 0xdc00 && next <= 0xdfff) {
154
165
  bytes += 4;
155
166
  index += 1;
@@ -160,11 +171,15 @@ export function utf8V2JsonByteLength(value: string): number {
160
171
  bytes += 3;
161
172
  }
162
173
  }
174
+
163
175
  return bytes;
164
176
  }
165
177
 
166
178
  export function serializeV2JsonNumber(value: number, label: string): string {
167
- if (!Number.isFinite(value)) invalidV2JsonValue(label);
179
+ if (!Number.isFinite(value)) {
180
+ invalidV2JsonValue(label);
181
+ }
182
+
168
183
  return value === 0 ? '0' : V2_CREATE_NUMBER_TO_STRING.call(value);
169
184
  }
170
185
 
@@ -174,8 +189,10 @@ export function chargeV2JsonStringBytes(
174
189
  label: string
175
190
  ): void {
176
191
  chargeV2JsonBytes(budget, 2, label);
192
+
177
193
  for (let index = 0; index < value.length; index += 1) {
178
194
  const code = V2_CREATE_STRING_CHAR_CODE_AT.call(value, index);
195
+
179
196
  if (code === 0x22 || code === 0x5c || code === 0x08 || code === 0x09) {
180
197
  chargeV2JsonBytes(budget, 2, label);
181
198
  } else if (code === 0x0a || code === 0x0c || code === 0x0d) {
@@ -191,6 +208,7 @@ export function chargeV2JsonStringBytes(
191
208
  index + 1 < value.length
192
209
  ? V2_CREATE_STRING_CHAR_CODE_AT.call(value, index + 1)
193
210
  : -1;
211
+
194
212
  if (next >= 0xdc00 && next <= 0xdfff) {
195
213
  chargeV2JsonBytes(budget, 4, label);
196
214
  index += 1;
@@ -212,8 +230,11 @@ export function normalizeV2JsonValue(
212
230
  budget: V2JsonNormalizationBudget = { bytes: 0 }
213
231
  ): unknown {
214
232
  let normalizedRoot: unknown;
233
+
215
234
  const frames: V2JsonNormalizationFrame[] = [
216
- { type: 'value', value, depth: 0, target: null, key: null },
235
+ {
236
+ type: 'value', value, depth: 0, target: null, key: null,
237
+ },
217
238
  ];
218
239
 
219
240
  const installNormalizedValue = (
@@ -223,9 +244,14 @@ export function normalizeV2JsonValue(
223
244
  ): void => {
224
245
  if (target === null) {
225
246
  normalizedRoot = normalized;
247
+
226
248
  return;
227
249
  }
228
- if (key === null) invalidV2JsonValue(label);
250
+
251
+ if (key === null) {
252
+ invalidV2JsonValue(label);
253
+ }
254
+
229
255
  Object.defineProperty(target, key, {
230
256
  configurable: true,
231
257
  enumerable: true,
@@ -236,23 +262,34 @@ export function normalizeV2JsonValue(
236
262
 
237
263
  while (frames.length > 0) {
238
264
  const frame = frames.pop();
239
- if (frame === undefined) invalidV2JsonValue(label);
265
+
266
+ if (frame === undefined) {
267
+ invalidV2JsonValue(label);
268
+ }
240
269
 
241
270
  if (frame.type === 'array') {
242
271
  if (frame.nextKeyIndex === frame.keys.length) {
243
- if (frame.elementCount !== frame.length) invalidV2JsonValue(label);
272
+ if (frame.elementCount !== frame.length) {
273
+ invalidV2JsonValue(label);
274
+ }
275
+
244
276
  Object.setPrototypeOf(frame.normalized, null);
245
277
  continue;
246
278
  }
279
+
247
280
  const key = frame.keys[frame.nextKeyIndex];
281
+
248
282
  if (key === 'length') {
249
283
  frames.push({ ...frame, nextKeyIndex: frame.nextKeyIndex + 1 });
250
284
  continue;
251
285
  }
286
+
252
287
  if (typeof key !== 'string' || !/^(0|[1-9]\d*)$/.test(key)) {
253
288
  invalidV2JsonValue(label);
254
289
  }
290
+
255
291
  const index = Number(key);
292
+
256
293
  if (
257
294
  !Number.isSafeInteger(index) ||
258
295
  index !== frame.elementCount ||
@@ -261,7 +298,9 @@ export function normalizeV2JsonValue(
261
298
  ) {
262
299
  invalidV2JsonValue(label);
263
300
  }
301
+
264
302
  const descriptor = Object.getOwnPropertyDescriptor(frame.value, key);
303
+
265
304
  if (
266
305
  descriptor === undefined ||
267
306
  !('value' in descriptor) ||
@@ -269,12 +308,17 @@ export function normalizeV2JsonValue(
269
308
  ) {
270
309
  invalidV2JsonValue(label);
271
310
  }
272
- if (frame.elementCount > 0) chargeV2JsonBytes(budget, 1, label);
311
+
312
+ if (frame.elementCount > 0) {
313
+ chargeV2JsonBytes(budget, 1, label);
314
+ }
315
+
273
316
  frames.push({
274
317
  ...frame,
275
318
  nextKeyIndex: frame.nextKeyIndex + 1,
276
319
  elementCount: frame.elementCount + 1,
277
320
  });
321
+
278
322
  frames.push({
279
323
  type: 'value',
280
324
  value: descriptor.value,
@@ -282,14 +326,23 @@ export function normalizeV2JsonValue(
282
326
  target: frame.normalized,
283
327
  key: frame.elementCount,
284
328
  });
329
+
285
330
  continue;
286
331
  }
287
332
 
288
333
  if (frame.type === 'object') {
289
- if (frame.nextKeyIndex === frame.keys.length) continue;
334
+ if (frame.nextKeyIndex === frame.keys.length) {
335
+ continue;
336
+ }
337
+
290
338
  const key = frame.keys[frame.nextKeyIndex];
291
- if (typeof key !== 'string') invalidV2JsonValue(label);
339
+
340
+ if (typeof key !== 'string') {
341
+ invalidV2JsonValue(label);
342
+ }
343
+
292
344
  const descriptor = Object.getOwnPropertyDescriptor(frame.value, key);
345
+
293
346
  if (
294
347
  descriptor === undefined ||
295
348
  !('value' in descriptor) ||
@@ -297,21 +350,29 @@ export function normalizeV2JsonValue(
297
350
  ) {
298
351
  invalidV2JsonValue(label);
299
352
  }
353
+
300
354
  if (descriptor.value === undefined) {
301
355
  frames.push({
302
356
  ...frame,
303
357
  nextKeyIndex: frame.nextKeyIndex + 1,
304
358
  });
359
+
305
360
  continue;
306
361
  }
307
- if (frame.fieldCount > 0) chargeV2JsonBytes(budget, 1, label);
362
+
363
+ if (frame.fieldCount > 0) {
364
+ chargeV2JsonBytes(budget, 1, label);
365
+ }
366
+
308
367
  chargeV2JsonStringBytes(key, budget, label);
309
368
  chargeV2JsonBytes(budget, 1, label);
369
+
310
370
  frames.push({
311
371
  ...frame,
312
372
  nextKeyIndex: frame.nextKeyIndex + 1,
313
373
  fieldCount: frame.fieldCount + 1,
314
374
  });
375
+
315
376
  frames.push({
316
377
  type: 'value',
317
378
  value: descriptor.value,
@@ -319,42 +380,62 @@ export function normalizeV2JsonValue(
319
380
  target: frame.normalized,
320
381
  key,
321
382
  });
383
+
322
384
  continue;
323
385
  }
324
386
 
325
- if (frame.depth > V2_CREATE_JSON_MAX_DEPTH) invalidV2JsonValue(label);
387
+ if (frame.depth > V2_CREATE_JSON_MAX_DEPTH) {
388
+ invalidV2JsonValue(label);
389
+ }
390
+
326
391
  chargeV2JsonWork(traversal, label);
392
+
327
393
  if (frame.value === null) {
328
394
  chargeV2JsonBytes(budget, 4, label);
329
395
  installNormalizedValue(frame.target, frame.key, frame.value);
330
396
  continue;
331
397
  }
398
+
332
399
  if (typeof frame.value === 'string') {
333
400
  chargeV2JsonStringBytes(frame.value, budget, label);
334
401
  installNormalizedValue(frame.target, frame.key, frame.value);
335
402
  continue;
336
403
  }
404
+
337
405
  if (typeof frame.value === 'boolean') {
338
406
  chargeV2JsonBytes(budget, frame.value ? 4 : 5, label);
339
407
  installNormalizedValue(frame.target, frame.key, frame.value);
340
408
  continue;
341
409
  }
410
+
342
411
  if (typeof frame.value === 'number') {
343
412
  const serialized = serializeV2JsonNumber(frame.value, label);
344
413
  chargeV2JsonBytes(budget, serialized.length, label);
345
414
  installNormalizedValue(frame.target, frame.key, frame.value);
346
415
  continue;
347
416
  }
348
- if (typeof frame.value !== 'object') invalidV2JsonValue(label);
349
417
 
350
- if (traversal.seen.has(frame.value)) invalidV2JsonValue(label);
418
+ if (typeof frame.value !== 'object') {
419
+ invalidV2JsonValue(label);
420
+ }
421
+
422
+ if (traversal.seen.has(frame.value)) {
423
+ invalidV2JsonValue(label);
424
+ }
425
+
351
426
  traversal.seen.add(frame.value);
352
427
  chargeV2JsonBytes(budget, 2, label);
353
428
  const childDepth = frame.depth + 1;
429
+
354
430
  if (Array.isArray(frame.value)) {
355
431
  const prototype = Object.getPrototypeOf(frame.value);
356
- if (prototype !== Array.prototype && prototype !== null) invalidV2JsonValue(label);
432
+
433
+ if (prototype !== Array.prototype && prototype !== null) {
434
+ invalidV2JsonValue(label);
435
+ }
436
+
357
437
  const lengthDescriptor = Object.getOwnPropertyDescriptor(frame.value, 'length');
438
+
358
439
  if (
359
440
  lengthDescriptor === undefined ||
360
441
  !('value' in lengthDescriptor) ||
@@ -362,8 +443,10 @@ export function normalizeV2JsonValue(
362
443
  ) {
363
444
  invalidV2JsonValue(label);
364
445
  }
446
+
365
447
  const normalized: unknown[] = [];
366
448
  installNormalizedValue(frame.target, frame.key, normalized);
449
+
367
450
  frames.push({
368
451
  type: 'array',
369
452
  value: frame.value,
@@ -374,12 +457,17 @@ export function normalizeV2JsonValue(
374
457
  nextKeyIndex: 0,
375
458
  elementCount: 0,
376
459
  });
460
+
377
461
  continue;
378
462
  }
379
463
 
380
- if (!isV2CreateRecord(frame.value)) invalidV2JsonValue(label);
464
+ if (!isV2CreateRecord(frame.value)) {
465
+ invalidV2JsonValue(label);
466
+ }
467
+
381
468
  const normalized = emptyV2CreateRecord();
382
469
  installNormalizedValue(frame.target, frame.key, normalized);
470
+
383
471
  frames.push({
384
472
  type: 'object',
385
473
  value: frame.value,
@@ -391,17 +479,22 @@ export function normalizeV2JsonValue(
391
479
  });
392
480
  }
393
481
 
394
- if (normalizedRoot === undefined) invalidV2JsonValue(label);
482
+ if (normalizedRoot === undefined) {
483
+ invalidV2JsonValue(label);
484
+ }
485
+
395
486
  return normalizedRoot;
396
487
  }
397
488
 
398
489
  export class V2JsonSerializationWriter {
399
490
  private readonly _chunks: string[] = [];
491
+
400
492
  private _current = '';
401
493
 
402
494
  append(value: string, state: V2JsonSerializationState, label: string): void {
403
495
  chargeV2JsonSerializationBytes(state, utf8V2JsonByteLength(value), label);
404
496
  this._current += value;
497
+
405
498
  if (this._current.length >= V2_CREATE_JSON_OUTPUT_CHUNK_SIZE) {
406
499
  this._chunks.push(this._current);
407
500
  this._current = '';
@@ -409,7 +502,10 @@ export class V2JsonSerializationWriter {
409
502
  }
410
503
 
411
504
  finish(): string {
412
- if (this._current.length > 0) this._chunks.push(this._current);
505
+ if (this._current.length > 0) {
506
+ this._chunks.push(this._current);
507
+ }
508
+
413
509
  return this._chunks.join('');
414
510
  }
415
511
  }
@@ -422,10 +518,12 @@ export function appendV2JsonString(
422
518
  ): void {
423
519
  writer.append('"', state, label);
424
520
  let segmentStart = 0;
521
+
425
522
  for (let index = 0; index < value.length; index += 1) {
426
523
  chargeV2JsonSerializationWork(state, label);
427
524
  const code = V2_CREATE_STRING_CHAR_CODE_AT.call(value, index);
428
525
  let escape: string | undefined;
526
+
429
527
  switch (code) {
430
528
  case 0x08:
431
529
  escape = '\\b';
@@ -456,6 +554,7 @@ export function appendV2JsonString(
456
554
  index + 1 < value.length
457
555
  ? V2_CREATE_STRING_CHAR_CODE_AT.call(value, index + 1)
458
556
  : -1;
557
+
459
558
  if (next >= 0xdc00 && next <= 0xdfff) {
460
559
  chargeV2JsonSerializationWork(state, label);
461
560
  index += 1;
@@ -465,18 +564,26 @@ export function appendV2JsonString(
465
564
  } else if (code >= 0xdc00 && code <= 0xdfff) {
466
565
  escape = `\\u${code.toString(16).padStart(4, '0')}`;
467
566
  }
567
+
468
568
  break;
469
569
  }
470
- if (escape === undefined) continue;
570
+
571
+ if (escape === undefined) {
572
+ continue;
573
+ }
574
+
471
575
  if (segmentStart < index) {
472
576
  writer.append(V2_CREATE_STRING_SLICE.call(value, segmentStart, index), state, label);
473
577
  }
578
+
474
579
  writer.append(escape, state, label);
475
580
  segmentStart = index + 1;
476
581
  }
582
+
477
583
  if (segmentStart < value.length) {
478
584
  writer.append(V2_CREATE_STRING_SLICE.call(value, segmentStart), state, label);
479
585
  }
586
+
480
587
  writer.append('"', state, label);
481
588
  }
482
589
 
@@ -484,19 +591,27 @@ export function serializeV2CreateEnvelope(value: Record<string, unknown>): strin
484
591
  const label = 'v2 create config';
485
592
  const writer = new V2JsonSerializationWriter();
486
593
  const state: V2JsonSerializationState = { bytes: 0, work: 0 };
487
- const frames: V2JsonSerializationFrame[] = [{ type: 'value', value, depth: 0 }];
594
+ const frames: V2JsonSerializationFrame[] = [ { type: 'value', value, depth: 0 } ];
488
595
 
489
596
  while (frames.length > 0) {
490
597
  const frame = frames.pop();
491
- if (frame === undefined) invalidV2JsonValue(label);
598
+
599
+ if (frame === undefined) {
600
+ invalidV2JsonValue(label);
601
+ }
492
602
 
493
603
  if (frame.type === 'array') {
494
604
  if (frame.index === frame.length) {
495
605
  writer.append(']', state, label);
496
606
  continue;
497
607
  }
498
- if (frame.index > 0) writer.append(',', state, label);
608
+
609
+ if (frame.index > 0) {
610
+ writer.append(',', state, label);
611
+ }
612
+
499
613
  const descriptor = Object.getOwnPropertyDescriptor(frame.value, String(frame.index));
614
+
500
615
  if (
501
616
  descriptor === undefined ||
502
617
  !('value' in descriptor) ||
@@ -504,6 +619,7 @@ export function serializeV2CreateEnvelope(value: Record<string, unknown>): strin
504
619
  ) {
505
620
  invalidV2JsonValue(label);
506
621
  }
622
+
507
623
  frames.push({ ...frame, index: frame.index + 1 });
508
624
  frames.push({ type: 'value', value: descriptor.value, depth: frame.depth + 1 });
509
625
  continue;
@@ -514,9 +630,14 @@ export function serializeV2CreateEnvelope(value: Record<string, unknown>): strin
514
630
  writer.append('}', state, label);
515
631
  continue;
516
632
  }
517
- if (frame.index > 0) writer.append(',', state, label);
633
+
634
+ if (frame.index > 0) {
635
+ writer.append(',', state, label);
636
+ }
637
+
518
638
  const key = frame.keys[frame.index];
519
639
  const descriptor = Object.getOwnPropertyDescriptor(frame.value, key);
640
+
520
641
  if (
521
642
  descriptor === undefined ||
522
643
  !('value' in descriptor) ||
@@ -524,6 +645,7 @@ export function serializeV2CreateEnvelope(value: Record<string, unknown>): strin
524
645
  ) {
525
646
  invalidV2JsonValue(label);
526
647
  }
648
+
527
649
  appendV2JsonString(writer, key, state, label);
528
650
  writer.append(':', state, label);
529
651
  frames.push({ ...frame, index: frame.index + 1 });
@@ -531,8 +653,12 @@ export function serializeV2CreateEnvelope(value: Record<string, unknown>): strin
531
653
  continue;
532
654
  }
533
655
 
534
- if (frame.depth > V2_CREATE_ENVELOPE_JSON_MAX_DEPTH) invalidV2JsonValue(label);
656
+ if (frame.depth > V2_CREATE_ENVELOPE_JSON_MAX_DEPTH) {
657
+ invalidV2JsonValue(label);
658
+ }
659
+
535
660
  chargeV2JsonSerializationWork(state, label);
661
+
536
662
  if (frame.value === null) {
537
663
  writer.append('null', state, label);
538
664
  } else if (typeof frame.value === 'string') {
@@ -542,8 +668,12 @@ export function serializeV2CreateEnvelope(value: Record<string, unknown>): strin
542
668
  } else if (typeof frame.value === 'number') {
543
669
  writer.append(serializeV2JsonNumber(frame.value, label), state, label);
544
670
  } else if (Array.isArray(frame.value)) {
545
- if (Object.getPrototypeOf(frame.value) !== null) invalidV2JsonValue(label);
671
+ if (Object.getPrototypeOf(frame.value) !== null) {
672
+ invalidV2JsonValue(label);
673
+ }
674
+
546
675
  const lengthDescriptor = Object.getOwnPropertyDescriptor(frame.value, 'length');
676
+
547
677
  if (
548
678
  lengthDescriptor === undefined ||
549
679
  !('value' in lengthDescriptor) ||
@@ -551,7 +681,9 @@ export function serializeV2CreateEnvelope(value: Record<string, unknown>): strin
551
681
  ) {
552
682
  invalidV2JsonValue(label);
553
683
  }
684
+
554
685
  writer.append('[', state, label);
686
+
555
687
  frames.push({
556
688
  type: 'array',
557
689
  value: frame.value,
@@ -561,8 +693,13 @@ export function serializeV2CreateEnvelope(value: Record<string, unknown>): strin
561
693
  });
562
694
  } else if (isV2CreateRecord(frame.value) && Object.getPrototypeOf(frame.value) === null) {
563
695
  const keys = Reflect.ownKeys(frame.value);
564
- if (keys.some((key) => typeof key !== 'string')) invalidV2JsonValue(label);
696
+
697
+ if (keys.some(key => typeof key !== 'string')) {
698
+ invalidV2JsonValue(label);
699
+ }
700
+
565
701
  writer.append('{', state, label);
702
+
566
703
  frames.push({
567
704
  type: 'object',
568
705
  value: frame.value,
@@ -20,7 +20,7 @@ export const V2_CREATE_POLICY_KEYS = new Set([
20
20
  'allowBase64Images',
21
21
  ]);
22
22
 
23
- export const V2_CREATE_LIMIT_KEYS = new Set(['resource', 'editing', 'collaboration']);
23
+ export const V2_CREATE_LIMIT_KEYS = new Set([ 'resource', 'editing', 'collaboration' ]);
24
24
 
25
25
  export const V2_CREATE_RESOURCE_LIMIT_KEYS = new Set([
26
26
  'maxInputBytes',
@@ -53,13 +53,13 @@ export const V2_CREATE_COLLABORATION_LIMIT_KEYS = new Set([
53
53
  ]);
54
54
 
55
55
  export const V2_CREATE_INITIALIZATION_KEYS: Readonly<Record<string, ReadonlySet<string>>> = {
56
- localEmpty: new Set(['type']),
57
- localJson: new Set(['type', 'json']),
58
- localHtml: new Set(['type', 'html']),
59
- room: new Set(['type', 'documentId', 'lineageId', 'snapshot']),
56
+ localEmpty: new Set([ 'type' ]),
57
+ localJson: new Set([ 'type', 'json' ]),
58
+ localHtml: new Set([ 'type', 'html' ]),
59
+ room: new Set([ 'type', 'documentId', 'lineageId', 'snapshot' ]),
60
60
  };
61
61
 
62
- export const V2_CREATE_ROOM_SNAPSHOT_KEYS = new Set(['metadata', 'encodedState']);
62
+ export const V2_CREATE_ROOM_SNAPSHOT_KEYS = new Set([ 'metadata', 'encodedState' ]);
63
63
 
64
64
  export const V2_CREATE_SNAPSHOT_METADATA_KEYS = new Set([
65
65
  'formatVersion',
@@ -107,7 +107,10 @@ export function validateV2CreateLimits(limits: NativeEditorCreateConfig['limits'
107
107
  try {
108
108
  validateEditorCreateLimits(limits);
109
109
  } catch (error) {
110
- if (!(error instanceof NativeEditorBoundaryError)) throw error;
110
+ if (!(error instanceof NativeEditorBoundaryError)) {
111
+ throw error;
112
+ }
113
+
111
114
  throw new NativeEditorEngineBoundaryError({
112
115
  domain: 'boundary',
113
116
  code: error.code,
@@ -126,8 +129,12 @@ export function emptyV2CreateRecord(): Record<string, unknown> {
126
129
  }
127
130
 
128
131
  export function isV2CreateRecord(value: unknown): value is Record<string, unknown> {
129
- if (value == null || typeof value !== 'object' || Array.isArray(value)) return false;
132
+ if (value == null || typeof value !== 'object' || Array.isArray(value)) {
133
+ return false;
134
+ }
135
+
130
136
  const prototype = Object.getPrototypeOf(value);
137
+
131
138
  return prototype === Object.prototype || prototype === null;
132
139
  }
133
140
 
@@ -137,12 +144,17 @@ export function hasOwnV2CreateKey(value: Record<string, unknown>, key: string):
137
144
 
138
145
  export function ownV2CreateValue(value: Record<string, unknown>, key: string): unknown {
139
146
  const descriptor = Object.getOwnPropertyDescriptor(value, key);
140
- if (descriptor === undefined) return undefined;
147
+
148
+ if (descriptor === undefined) {
149
+ return undefined;
150
+ }
151
+
141
152
  if (!('value' in descriptor)) {
142
153
  throw invalidV2CreateRequestError(
143
154
  `NativeEditorBridge: accessor ${key} is not allowed for v2 create`
144
155
  );
145
156
  }
157
+
146
158
  return descriptor.value;
147
159
  }
148
160
 
@@ -153,7 +165,7 @@ export function requireKnownV2CreateKeys(
153
165
  ): asserts value is Record<string, unknown> {
154
166
  if (
155
167
  !isV2CreateRecord(value) ||
156
- Reflect.ownKeys(value).some((key) => typeof key !== 'string' || !allowed.has(key))
168
+ Reflect.ownKeys(value).some(key => typeof key !== 'string' || !allowed.has(key))
157
169
  ) {
158
170
  throw invalidV2CreateRequestError(`NativeEditorBridge: invalid ${label} for v2 create`);
159
171
  }
@@ -166,13 +178,22 @@ export function normalizeV2CreateRecord(
166
178
  ): Record<string, unknown> {
167
179
  requireKnownV2CreateKeys(value, allowed, label);
168
180
  const normalized = emptyV2CreateRecord();
181
+
169
182
  for (const key of allowed) {
170
- if (!hasOwnV2CreateKey(value, key)) continue;
183
+ if (!hasOwnV2CreateKey(value, key)) {
184
+ continue;
185
+ }
186
+
171
187
  const fieldValue = ownV2CreateValue(value, key);
188
+
172
189
  if (fieldValue === null) {
173
190
  throw invalidV2CreateRequestError(`NativeEditorBridge: invalid ${label} for v2 create`);
174
191
  }
175
- if (fieldValue !== undefined) normalized[key] = fieldValue;
192
+
193
+ if (fieldValue !== undefined) {
194
+ normalized[key] = fieldValue;
195
+ }
176
196
  }
197
+
177
198
  return normalized;
178
199
  }