@apollohg/react-native-rich-text-editor 2.0.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.
Files changed (494) hide show
  1. package/LICENSE +160 -0
  2. package/README.md +259 -0
  3. package/RUST-STANDARD-LIBRARY-NOTICES.html +8266 -0
  4. package/ReactNativeProseEditor.podspec +59 -0
  5. package/THIRD_PARTY_NOTICES.md +31155 -0
  6. package/android/build.gradle +188 -0
  7. package/android/consumer-rules.pro +18 -0
  8. package/android/expo/build.gradle +17 -0
  9. package/android/src/debug/java/com/apollohg/editor/viewer/PreparedProseDrawInstrumentation.kt +7 -0
  10. package/android/src/main/assets/editor-icons/MaterialIcons.json +2236 -0
  11. package/android/src/main/assets/editor-icons/MaterialIcons.ttf +0 -0
  12. package/android/src/main/java/com/apollohg/editor/AndroidApiCompat.kt +19 -0
  13. package/android/src/main/java/com/apollohg/editor/AndroidCollaborationTransport.kt +860 -0
  14. package/android/src/main/java/com/apollohg/editor/CaretGeometry.kt +91 -0
  15. package/android/src/main/java/com/apollohg/editor/CodeHighlighting.kt +141 -0
  16. package/android/src/main/java/com/apollohg/editor/DecodedBitmapBudget.kt +250 -0
  17. package/android/src/main/java/com/apollohg/editor/EditorAddons.kt +133 -0
  18. package/android/src/main/java/com/apollohg/editor/EditorBlockSpacing.kt +51 -0
  19. package/android/src/main/java/com/apollohg/editor/EditorBoxDrawable.kt +16 -0
  20. package/android/src/main/java/com/apollohg/editor/EditorBoxDrawing.kt +234 -0
  21. package/android/src/main/java/com/apollohg/editor/EditorCheckboxSpan.kt +87 -0
  22. package/android/src/main/java/com/apollohg/editor/EditorCodeHighlighting.kt +120 -0
  23. package/android/src/main/java/com/apollohg/editor/EditorDecorationLayer.java +18 -0
  24. package/android/src/main/java/com/apollohg/editor/EditorDocumentLayout.kt +626 -0
  25. package/android/src/main/java/com/apollohg/editor/EditorEditText.kt +1042 -0
  26. package/android/src/main/java/com/apollohg/editor/EditorEditTextAnnotations.kt +191 -0
  27. package/android/src/main/java/com/apollohg/editor/EditorEditTextCaret.kt +100 -0
  28. package/android/src/main/java/com/apollohg/editor/EditorEditTextClipboard.kt +101 -0
  29. package/android/src/main/java/com/apollohg/editor/EditorEditTextComposition.kt +220 -0
  30. package/android/src/main/java/com/apollohg/editor/EditorEditTextConfiguration.kt +316 -0
  31. package/android/src/main/java/com/apollohg/editor/EditorEditTextCorrection.kt +303 -0
  32. package/android/src/main/java/com/apollohg/editor/EditorEditTextDeferredUpdates.kt +327 -0
  33. package/android/src/main/java/com/apollohg/editor/EditorEditTextDeletion.kt +258 -0
  34. package/android/src/main/java/com/apollohg/editor/EditorEditTextDiagnostics.kt +83 -0
  35. package/android/src/main/java/com/apollohg/editor/EditorEditTextDragDrop.kt +67 -0
  36. package/android/src/main/java/com/apollohg/editor/EditorEditTextExternalComposition.kt +357 -0
  37. package/android/src/main/java/com/apollohg/editor/EditorEditTextHardwareInput.kt +277 -0
  38. package/android/src/main/java/com/apollohg/editor/EditorEditTextImages.kt +280 -0
  39. package/android/src/main/java/com/apollohg/editor/EditorEditTextInputLifecycle.kt +183 -0
  40. package/android/src/main/java/com/apollohg/editor/EditorEditTextInputPreparation.kt +79 -0
  41. package/android/src/main/java/com/apollohg/editor/EditorEditTextInputTraits.kt +384 -0
  42. package/android/src/main/java/com/apollohg/editor/EditorEditTextLayout.kt +100 -0
  43. package/android/src/main/java/com/apollohg/editor/EditorEditTextNativeMutation.kt +243 -0
  44. package/android/src/main/java/com/apollohg/editor/EditorEditTextPlaceholder.kt +154 -0
  45. package/android/src/main/java/com/apollohg/editor/EditorEditTextRenderPatch.kt +347 -0
  46. package/android/src/main/java/com/apollohg/editor/EditorEditTextRendering.kt +313 -0
  47. package/android/src/main/java/com/apollohg/editor/EditorEditTextRustCommands.kt +281 -0
  48. package/android/src/main/java/com/apollohg/editor/EditorEditTextSelection.kt +352 -0
  49. package/android/src/main/java/com/apollohg/editor/EditorEditTextState.kt +113 -0
  50. package/android/src/main/java/com/apollohg/editor/EditorEditTextTaskMarkers.kt +92 -0
  51. package/android/src/main/java/com/apollohg/editor/EditorEditTextTextCommit.kt +327 -0
  52. package/android/src/main/java/com/apollohg/editor/EditorEditTextToolbar.kt +84 -0
  53. package/android/src/main/java/com/apollohg/editor/EditorEditTextUpdates.kt +245 -0
  54. package/android/src/main/java/com/apollohg/editor/EditorGlyphHeightCursorDrawable.kt +42 -0
  55. package/android/src/main/java/com/apollohg/editor/EditorHeightBehavior.kt +13 -0
  56. package/android/src/main/java/com/apollohg/editor/EditorInputConnection.kt +923 -0
  57. package/android/src/main/java/com/apollohg/editor/EditorInputCoordinates.kt +191 -0
  58. package/android/src/main/java/com/apollohg/editor/EditorInputCorrection.kt +107 -0
  59. package/android/src/main/java/com/apollohg/editor/EditorInputCursorGeometry.kt +128 -0
  60. package/android/src/main/java/com/apollohg/editor/EditorInputSnapshots.kt +134 -0
  61. package/android/src/main/java/com/apollohg/editor/EditorInputSurroundingDeletion.kt +321 -0
  62. package/android/src/main/java/com/apollohg/editor/EditorKeyboardToolbarView.kt +851 -0
  63. package/android/src/main/java/com/apollohg/editor/EditorMentionStyle.kt +192 -0
  64. package/android/src/main/java/com/apollohg/editor/EditorReconciliationWatcher.kt +46 -0
  65. package/android/src/main/java/com/apollohg/editor/EditorStyleSheet.kt +303 -0
  66. package/android/src/main/java/com/apollohg/editor/EditorStyleSheetSpans.kt +253 -0
  67. package/android/src/main/java/com/apollohg/editor/EditorSurfaceInputConnection.kt +67 -0
  68. package/android/src/main/java/com/apollohg/editor/EditorTextDecorationDrawing.kt +143 -0
  69. package/android/src/main/java/com/apollohg/editor/EditorTextSurface.kt +712 -0
  70. package/android/src/main/java/com/apollohg/editor/EditorTextSurfaceDragDrop.kt +94 -0
  71. package/android/src/main/java/com/apollohg/editor/EditorTextSurfaceInteraction.kt +708 -0
  72. package/android/src/main/java/com/apollohg/editor/EditorTheme.kt +650 -0
  73. package/android/src/main/java/com/apollohg/editor/EditorV2Adapter.kt +912 -0
  74. package/android/src/main/java/com/apollohg/editor/EditorV2AdapterMutations.kt +402 -0
  75. package/android/src/main/java/com/apollohg/editor/EditorV2AdapterRendering.kt +123 -0
  76. package/android/src/main/java/com/apollohg/editor/EditorV2AdapterSelection.kt +203 -0
  77. package/android/src/main/java/com/apollohg/editor/EditorV2Backend.kt +120 -0
  78. package/android/src/main/java/com/apollohg/editor/EditorV2Driver.kt +87 -0
  79. package/android/src/main/java/com/apollohg/editor/EditorV2Registry.kt +97 -0
  80. package/android/src/main/java/com/apollohg/editor/EditorV2RenderValidation.kt +409 -0
  81. package/android/src/main/java/com/apollohg/editor/ExpoAutoGrowStyleSizePublisher.kt +34 -0
  82. package/android/src/main/java/com/apollohg/editor/ImageResizeOverlayView.kt +266 -0
  83. package/android/src/main/java/com/apollohg/editor/ImeTextCoordinateMapper.kt +102 -0
  84. package/android/src/main/java/com/apollohg/editor/KeyboardToolbarImeAnimationController.kt +101 -0
  85. package/android/src/main/java/com/apollohg/editor/MentionSuggestionChipView.kt +234 -0
  86. package/android/src/main/java/com/apollohg/editor/NativeCollaborationTransportRegistry.kt +493 -0
  87. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoView.kt +813 -0
  88. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewAtoms.kt +68 -0
  89. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewBinding.kt +126 -0
  90. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewDiagnostics.kt +208 -0
  91. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewErrors.kt +146 -0
  92. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewEvents.kt +150 -0
  93. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewExternalComposition.kt +39 -0
  94. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewFocus.kt +176 -0
  95. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewLifecycle.kt +302 -0
  96. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewMentions.kt +259 -0
  97. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewNativeActions.kt +179 -0
  98. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewOutsideTap.kt +214 -0
  99. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewPendingUpdates.kt +376 -0
  100. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewProperties.kt +234 -0
  101. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewPropertyRetries.kt +197 -0
  102. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewToolbar.kt +285 -0
  103. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewTypes.kt +28 -0
  104. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewUpdates.kt +271 -0
  105. package/android/src/main/java/com/apollohg/editor/NativeEditorModule.kt +687 -0
  106. package/android/src/main/java/com/apollohg/editor/NativeEditorOutsideTapDispatcher.kt +380 -0
  107. package/android/src/main/java/com/apollohg/editor/NativeEditorV2Numbers.kt +45 -0
  108. package/android/src/main/java/com/apollohg/editor/NativeEditorViewRegistry.kt +372 -0
  109. package/android/src/main/java/com/apollohg/editor/NativeImagePipeline.kt +22 -0
  110. package/android/src/main/java/com/apollohg/editor/NativeToolbar.kt +193 -0
  111. package/android/src/main/java/com/apollohg/editor/NativeToolbarIcons.kt +177 -0
  112. package/android/src/main/java/com/apollohg/editor/NativeToolbarItem.kt +274 -0
  113. package/android/src/main/java/com/apollohg/editor/OkHttpCollaborationSocket.kt +102 -0
  114. package/android/src/main/java/com/apollohg/editor/OrderedListMarkerFormatter.kt +130 -0
  115. package/android/src/main/java/com/apollohg/editor/PointerTransparentView.java +18 -0
  116. package/android/src/main/java/com/apollohg/editor/PositionBridge.kt +128 -0
  117. package/android/src/main/java/com/apollohg/editor/ProseViewerView.kt +854 -0
  118. package/android/src/main/java/com/apollohg/editor/RemoteSelectionOverlayView.kt +314 -0
  119. package/android/src/main/java/com/apollohg/editor/RenderBlockSpans.kt +314 -0
  120. package/android/src/main/java/com/apollohg/editor/RenderBridge.kt +224 -0
  121. package/android/src/main/java/com/apollohg/editor/RenderBridgeBlockStyles.kt +407 -0
  122. package/android/src/main/java/com/apollohg/editor/RenderBridgeElements.kt +544 -0
  123. package/android/src/main/java/com/apollohg/editor/RenderBridgeInlineAndAtoms.kt +631 -0
  124. package/android/src/main/java/com/apollohg/editor/RenderBridgeParagraphs.kt +215 -0
  125. package/android/src/main/java/com/apollohg/editor/RenderImageDecoder.kt +748 -0
  126. package/android/src/main/java/com/apollohg/editor/RenderImageLoader.kt +900 -0
  127. package/android/src/main/java/com/apollohg/editor/RenderLayoutConstants.kt +117 -0
  128. package/android/src/main/java/com/apollohg/editor/RenderMediaSpans.kt +337 -0
  129. package/android/src/main/java/com/apollohg/editor/RenderParagraphSpans.kt +182 -0
  130. package/android/src/main/java/com/apollohg/editor/RichTextEditorView.kt +951 -0
  131. package/android/src/main/java/com/apollohg/editor/SharedNativeImagePipeline.kt +78 -0
  132. package/android/src/main/java/com/apollohg/editor/UniffiEditorV2Backend.kt +261 -0
  133. package/android/src/main/java/com/apollohg/editor/viewer/AndroidProseLayoutEngine.kt +1656 -0
  134. package/android/src/main/java/com/apollohg/editor/viewer/FabricAttachmentSidecars.kt +80 -0
  135. package/android/src/main/java/com/apollohg/editor/viewer/FabricLeaseHandleBridge.kt +59 -0
  136. package/android/src/main/java/com/apollohg/editor/viewer/FallbackSelectionGeometry.kt +450 -0
  137. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseDrawingView.kt +678 -0
  138. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseInstrumentation.kt +608 -0
  139. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayout.kt +186 -0
  140. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayoutCache.kt +393 -0
  141. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayoutRegistry.kt +828 -0
  142. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseTheme.kt +316 -0
  143. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseViewerManager.kt +900 -0
  144. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseViewerPackage.kt +16 -0
  145. package/android/src/main/java/com/apollohg/editor/viewer/PreparedViewerAtoms.kt +89 -0
  146. package/android/src/main/java/com/apollohg/editor/viewer/ViewerCodeHighlighting.kt +91 -0
  147. package/android/src/main/java/com/apollohg/editor/viewer/ViewerDocument.kt +453 -0
  148. package/android/src/main/java/com/apollohg/editor/viewer/ViewerFontEnvironment.kt +282 -0
  149. package/android/src/main/java/com/apollohg/editor/viewer/ViewerImagePipeline.kt +460 -0
  150. package/android/src/main/jni/CMakeLists.txt +85 -0
  151. package/android/src/main/jni/PreparedProseViewerMeasurementsManager.cpp +334 -0
  152. package/android/src/main/jni/ReactNativeProseEditorSpec.h +17 -0
  153. package/android/src/main/jni/reactnativeproseeditor.h +6 -0
  154. package/android/src/main/res/values/attrs.xml +6 -0
  155. package/android/src/release/java/com/apollohg/editor/viewer/PreparedProseDrawInstrumentation.kt +9 -0
  156. package/app.plugin.js +62 -0
  157. package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseMeasurementsManager.h +62 -0
  158. package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerComponentDescriptor.h +30 -0
  159. package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerShadowNode.cpp +192 -0
  160. package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerShadowNode.h +46 -0
  161. package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerState.h +145 -0
  162. package/dist/AtomHost.d.ts +17 -0
  163. package/dist/AtomHost.js +135 -0
  164. package/dist/DefaultAtomChip.d.ts +2 -0
  165. package/dist/DefaultAtomChip.js +22 -0
  166. package/dist/EditorAddon.d.ts +32 -0
  167. package/dist/EditorAddon.js +29 -0
  168. package/dist/EditorAddonNormalization.d.ts +6 -0
  169. package/dist/EditorAddonNormalization.js +48 -0
  170. package/dist/EditorMentionThemeNormalization.d.ts +8 -0
  171. package/dist/EditorMentionThemeNormalization.js +22 -0
  172. package/dist/EditorMentionThemeValidation.d.ts +12 -0
  173. package/dist/EditorMentionThemeValidation.js +95 -0
  174. package/dist/EditorStyleSheet.d.ts +4 -0
  175. package/dist/EditorStyleSheet.js +10 -0
  176. package/dist/EditorStyleSheetNormalization.d.ts +3 -0
  177. package/dist/EditorStyleSheetNormalization.js +226 -0
  178. package/dist/EditorStyleSheetTypes.d.ts +151 -0
  179. package/dist/EditorStyleSheetTypes.js +2 -0
  180. package/dist/EditorTheme.d.ts +117 -0
  181. package/dist/EditorTheme.js +41 -0
  182. package/dist/EditorToolbar.d.ts +4 -0
  183. package/dist/EditorToolbar.js +17 -0
  184. package/dist/EditorToolbarComponent.d.ts +13 -0
  185. package/dist/EditorToolbarComponent.js +24 -0
  186. package/dist/EditorToolbarItems.d.ts +9 -0
  187. package/dist/EditorToolbarItems.js +58 -0
  188. package/dist/EditorToolbarRegistry.d.ts +59 -0
  189. package/dist/EditorToolbarRegistry.js +175 -0
  190. package/dist/EditorToolbarTypes.d.ts +273 -0
  191. package/dist/EditorToolbarTypes.js +2 -0
  192. package/dist/EditorToolbarVisuals.d.ts +154 -0
  193. package/dist/EditorToolbarVisuals.js +228 -0
  194. package/dist/EditorUpdateRevision.d.ts +8 -0
  195. package/dist/EditorUpdateRevision.js +22 -0
  196. package/dist/ExternalTextComposition.d.ts +45 -0
  197. package/dist/ExternalTextComposition.js +537 -0
  198. package/dist/ImageLoadingPolicy.d.ts +54 -0
  199. package/dist/ImageLoadingPolicy.js +60 -0
  200. package/dist/NativeEditorBoundaryError.d.ts +111 -0
  201. package/dist/NativeEditorBoundaryError.js +268 -0
  202. package/dist/NativeEditorBridge.d.ts +9 -0
  203. package/dist/NativeEditorBridge.js +37 -0
  204. package/dist/NativeEditorCollaborationTransport.d.ts +154 -0
  205. package/dist/NativeEditorCollaborationTransport.js +275 -0
  206. package/dist/NativeEditorCreateConfig.d.ts +16 -0
  207. package/dist/NativeEditorCreateConfig.js +249 -0
  208. package/dist/NativeEditorCreateJson.d.ts +76 -0
  209. package/dist/NativeEditorCreateJson.js +474 -0
  210. package/dist/NativeEditorCreateValidation.d.ts +32 -0
  211. package/dist/NativeEditorCreateValidation.js +150 -0
  212. package/dist/NativeEditorDocumentBridge.d.ts +72 -0
  213. package/dist/NativeEditorDocumentBridge.js +305 -0
  214. package/dist/NativeEditorDocumentHandle.d.ts +70 -0
  215. package/dist/NativeEditorDocumentHandle.js +89 -0
  216. package/dist/NativeEditorLocalAwareness.d.ts +34 -0
  217. package/dist/NativeEditorLocalAwareness.js +153 -0
  218. package/dist/NativeEditorNativeModule.d.ts +48 -0
  219. package/dist/NativeEditorNativeModule.js +34 -0
  220. package/dist/NativeEditorRenderNormalization.d.ts +22 -0
  221. package/dist/NativeEditorRenderNormalization.js +274 -0
  222. package/dist/NativeEditorResultNormalization.d.ts +108 -0
  223. package/dist/NativeEditorResultNormalization.js +400 -0
  224. package/dist/NativeEditorTypes.d.ts +318 -0
  225. package/dist/NativeEditorTypes.js +15 -0
  226. package/dist/NativeEditorV2Decimal.d.ts +5 -0
  227. package/dist/NativeEditorV2Decimal.js +18 -0
  228. package/dist/NativeProseViewer.d.ts +122 -0
  229. package/dist/NativeProseViewer.js +130 -0
  230. package/dist/NativeRichTextEditor.d.ts +3 -0
  231. package/dist/NativeRichTextEditor.js +6 -0
  232. package/dist/ResourceLimits.d.ts +100 -0
  233. package/dist/ResourceLimits.js +80 -0
  234. package/dist/RichTextEditor.d.ts +4 -0
  235. package/dist/RichTextEditor.js +25 -0
  236. package/dist/RichTextEditorNativeTypes.d.ts +122 -0
  237. package/dist/RichTextEditorNativeTypes.js +2 -0
  238. package/dist/RichTextEditorNativeView.d.ts +12 -0
  239. package/dist/RichTextEditorNativeView.js +15 -0
  240. package/dist/RichTextEditorSerialization.d.ts +53 -0
  241. package/dist/RichTextEditorSerialization.js +283 -0
  242. package/dist/RichTextEditorTypes.d.ts +281 -0
  243. package/dist/RichTextEditorTypes.js +2 -0
  244. package/dist/ViewerConfiguration.d.ts +22 -0
  245. package/dist/ViewerConfiguration.js +6 -0
  246. package/dist/YjsCollaboration.d.ts +146 -0
  247. package/dist/YjsCollaboration.js +496 -0
  248. package/dist/addons.d.ts +193 -0
  249. package/dist/addons.js +122 -0
  250. package/dist/atomConstants.d.ts +3 -0
  251. package/dist/atomConstants.js +6 -0
  252. package/dist/atomInstances.d.ts +35 -0
  253. package/dist/atomInstances.js +79 -0
  254. package/dist/atomPolicy.d.ts +4 -0
  255. package/dist/atomPolicy.js +47 -0
  256. package/dist/atomUpdates.d.ts +2 -0
  257. package/dist/atomUpdates.js +38 -0
  258. package/dist/atoms.d.ts +92 -0
  259. package/dist/atoms.js +222 -0
  260. package/dist/attributeValidation.d.ts +4 -0
  261. package/dist/attributeValidation.js +97 -0
  262. package/dist/contentExpression.d.ts +6 -0
  263. package/dist/contentExpression.js +335 -0
  264. package/dist/index.d.ts +21 -0
  265. package/dist/index.js +78 -0
  266. package/dist/listMarkers.d.ts +15 -0
  267. package/dist/listMarkers.js +21 -0
  268. package/dist/schemaDefinition.d.ts +143 -0
  269. package/dist/schemaDefinition.js +206 -0
  270. package/dist/schemaDocument.d.ts +17 -0
  271. package/dist/schemaDocument.js +69 -0
  272. package/dist/schemaDocumentConstruction.d.ts +5 -0
  273. package/dist/schemaDocumentConstruction.js +125 -0
  274. package/dist/schemaNormalization.d.ts +29 -0
  275. package/dist/schemaNormalization.js +313 -0
  276. package/dist/schemaPresets.d.ts +68 -0
  277. package/dist/schemaPresets.js +198 -0
  278. package/dist/schemaResolution.d.ts +9 -0
  279. package/dist/schemaResolution.js +211 -0
  280. package/dist/schemas.d.ts +5 -0
  281. package/dist/schemas.js +28 -0
  282. package/dist/specs/PreparedProseViewerNativeComponent.d.ts +37 -0
  283. package/dist/specs/PreparedProseViewerNativeComponent.js +6 -0
  284. package/dist/useEditorToolbarInteractions.d.ts +12 -0
  285. package/dist/useEditorToolbarInteractions.js +218 -0
  286. package/dist/useEditorToolbarItems.d.ts +8 -0
  287. package/dist/useEditorToolbarItems.js +280 -0
  288. package/dist/useEditorToolbarPresentation.d.ts +4 -0
  289. package/dist/useEditorToolbarPresentation.js +203 -0
  290. package/dist/useEditorToolbarState.d.ts +63 -0
  291. package/dist/useEditorToolbarState.js +108 -0
  292. package/dist/useFocusPreservingFrames.d.ts +17 -0
  293. package/dist/useFocusPreservingFrames.js +108 -0
  294. package/dist/useNativeEditor.d.ts +66 -0
  295. package/dist/useNativeEditor.js +370 -0
  296. package/dist/useRichTextEditorCommands.d.ts +21 -0
  297. package/dist/useRichTextEditorCommands.js +299 -0
  298. package/dist/useRichTextEditorEvents.d.ts +18 -0
  299. package/dist/useRichTextEditorEvents.js +216 -0
  300. package/dist/useRichTextEditorMentions.d.ts +11 -0
  301. package/dist/useRichTextEditorMentions.js +316 -0
  302. package/dist/useRichTextEditorPresentation.d.ts +5 -0
  303. package/dist/useRichTextEditorPresentation.js +178 -0
  304. package/dist/useRichTextEditorState.d.ts +180 -0
  305. package/dist/useRichTextEditorState.js +405 -0
  306. package/dist/useRichTextEditorUpdates.d.ts +10 -0
  307. package/dist/useRichTextEditorUpdates.js +308 -0
  308. package/dist/useViewerAtoms.d.ts +38 -0
  309. package/dist/useViewerAtoms.js +288 -0
  310. package/expo-module.config.json +13 -0
  311. package/ios/EditorAddons.swift +354 -0
  312. package/ios/EditorCodeHighlighting.swift +184 -0
  313. package/ios/EditorCore.xcframework/Info.plist +44 -0
  314. package/ios/EditorCore.xcframework/ios-arm64/libeditor_core.a +0 -0
  315. package/ios/EditorCore.xcframework/ios-arm64_x86_64-simulator/libeditor_core.a +0 -0
  316. package/ios/EditorInteractionOverlays.swift +697 -0
  317. package/ios/EditorLayoutManager.swift +971 -0
  318. package/ios/EditorNodeTypes.swift +37 -0
  319. package/ios/EditorStyleSheet.swift +461 -0
  320. package/ios/EditorTextView+AttributedPatch.swift +305 -0
  321. package/ios/EditorTextView+Binding.swift +61 -0
  322. package/ios/EditorTextView+Caret.swift +333 -0
  323. package/ios/EditorTextView+Commands.swift +203 -0
  324. package/ios/EditorTextView+Delegate.swift +65 -0
  325. package/ios/EditorTextView+Diagnostics.swift +225 -0
  326. package/ios/EditorTextView+DragDrop.swift +290 -0
  327. package/ios/EditorTextView+ExternalComposition.swift +364 -0
  328. package/ios/EditorTextView+Images.swift +354 -0
  329. package/ios/EditorTextView+InputTraits.swift +200 -0
  330. package/ios/EditorTextView+KeyboardInput.swift +318 -0
  331. package/ios/EditorTextView+Layout.swift +245 -0
  332. package/ios/EditorTextView+MarkedText.swift +267 -0
  333. package/ios/EditorTextView+NativeInputLifecycle.swift +372 -0
  334. package/ios/EditorTextView+NativeMutation.swift +471 -0
  335. package/ios/EditorTextView+Reconciliation.swift +97 -0
  336. package/ios/EditorTextView+RenderPatch.swift +573 -0
  337. package/ios/EditorTextView+Rendering.swift +539 -0
  338. package/ios/EditorTextView+Selection.swift +542 -0
  339. package/ios/EditorTextView.swift +953 -0
  340. package/ios/EditorTheme.swift +626 -0
  341. package/ios/EditorV2Adapter+Commands.swift +204 -0
  342. package/ios/EditorV2Adapter+Envelope.swift +238 -0
  343. package/ios/EditorV2Adapter+Mutation.swift +392 -0
  344. package/ios/EditorV2Adapter+Registry.swift +185 -0
  345. package/ios/EditorV2Adapter+RenderState.swift +360 -0
  346. package/ios/EditorV2Adapter+RenderValidation.swift +420 -0
  347. package/ios/EditorV2Adapter+Selection.swift +329 -0
  348. package/ios/EditorV2Adapter+TextCommands.swift +430 -0
  349. package/ios/EditorV2Adapter.swift +376 -0
  350. package/ios/EditorV2Shadow.swift +353 -0
  351. package/ios/Generated_editor_core.swift +2378 -0
  352. package/ios/NativeCodeHighlighting.swift +159 -0
  353. package/ios/NativeCollaborationSocket.swift +144 -0
  354. package/ios/NativeCollaborationTransport+Protocol.swift +258 -0
  355. package/ios/NativeCollaborationTransport+Socket.swift +379 -0
  356. package/ios/NativeCollaborationTransport+Validation.swift +103 -0
  357. package/ios/NativeCollaborationTransport.swift +322 -0
  358. package/ios/NativeCollaborationTransportRegistry.swift +521 -0
  359. package/ios/NativeEditorExpoView+AccessoryRetry.swift +219 -0
  360. package/ios/NativeEditorExpoView+Binding.swift +268 -0
  361. package/ios/NativeEditorExpoView+Diagnostics.swift +66 -0
  362. package/ios/NativeEditorExpoView+Events.swift +131 -0
  363. package/ios/NativeEditorExpoView+Focus.swift +169 -0
  364. package/ios/NativeEditorExpoView+MentionRetry.swift +288 -0
  365. package/ios/NativeEditorExpoView+Mentions.swift +288 -0
  366. package/ios/NativeEditorExpoView+Properties.swift +300 -0
  367. package/ios/NativeEditorExpoView+Toolbar.swift +86 -0
  368. package/ios/NativeEditorExpoView+Updates.swift +312 -0
  369. package/ios/NativeEditorExpoView.swift +349 -0
  370. package/ios/NativeEditorModule.swift +856 -0
  371. package/ios/NativeEditorViewRegistry.swift +226 -0
  372. package/ios/NativeToolbar+ButtonStyle.swift +214 -0
  373. package/ios/NativeToolbar+Buttons.swift +228 -0
  374. package/ios/NativeToolbar+Diagnostics.swift +114 -0
  375. package/ios/NativeToolbar+Menu.swift +101 -0
  376. package/ios/NativeToolbar+Models.swift +519 -0
  377. package/ios/NativeToolbar+Placeholder.swift +39 -0
  378. package/ios/NativeToolbar.swift +612 -0
  379. package/ios/OrderedListMarkerFormatter.swift +103 -0
  380. package/ios/PositionBridge.swift +596 -0
  381. package/ios/ProseViewerView.swift +462 -0
  382. package/ios/RenderBridge+Atoms.swift +288 -0
  383. package/ios/RenderBridge+Attachments.swift +246 -0
  384. package/ios/RenderBridge+BlockBoundaries.swift +313 -0
  385. package/ios/RenderBridge+Style.swift +343 -0
  386. package/ios/RenderBridge.swift +704 -0
  387. package/ios/RichTextEditorView.swift +930 -0
  388. package/ios/SharedNativeImagePipeline+Cache.swift +189 -0
  389. package/ios/SharedNativeImagePipeline+Transport.swift +328 -0
  390. package/ios/SharedNativeImagePipeline.swift +533 -0
  391. package/ios/Viewer/CoreTextProseLayoutEngine+AttributedText.swift +436 -0
  392. package/ios/Viewer/CoreTextProseLayoutEngine+Models.swift +322 -0
  393. package/ios/Viewer/CoreTextProseLayoutEngine.swift +635 -0
  394. package/ios/Viewer/Fabric/PREPPreparedProseViewerComponentView.h +4 -0
  395. package/ios/Viewer/Fabric/PREPPreparedProseViewerComponentView.mm +767 -0
  396. package/ios/Viewer/Fabric/PreparedProseMeasurementsManager.mm +118 -0
  397. package/ios/Viewer/NativeSVGImageDecoder.h +9 -0
  398. package/ios/Viewer/NativeSVGImageDecoder.mm +106 -0
  399. package/ios/Viewer/NativeSVGPreflight.h +11 -0
  400. package/ios/Viewer/NativeSVGPreflight.mm +219 -0
  401. package/ios/Viewer/PreparedProseDrawingView.swift +639 -0
  402. package/ios/Viewer/PreparedProseInstrumentation.swift +387 -0
  403. package/ios/Viewer/PreparedProseLayout.swift +326 -0
  404. package/ios/Viewer/PreparedProseLayoutCache.swift +766 -0
  405. package/ios/Viewer/PreparedProseLayoutRegistry+Artifacts.swift +377 -0
  406. package/ios/Viewer/PreparedProseLayoutRegistry+Fabric.swift +582 -0
  407. package/ios/Viewer/PreparedProseLayoutRegistry+FabricOwnership.swift +128 -0
  408. package/ios/Viewer/PreparedProseLayoutRegistry.swift +381 -0
  409. package/ios/Viewer/ViewerDocument.swift +575 -0
  410. package/ios/Viewer/ViewerFontEnvironment.swift +283 -0
  411. package/ios/Viewer/ViewerImagePipeline.swift +478 -0
  412. package/ios/editor_coreFFI/editor_coreFFI.h +1023 -0
  413. package/ios/editor_coreFFI/module.modulemap +7 -0
  414. package/package.json +151 -0
  415. package/react-native.config.js +17 -0
  416. package/rust/android/arm64-v8a/libeditor_core.so +0 -0
  417. package/rust/android/armeabi-v7a/libeditor_core.so +0 -0
  418. package/rust/android/x86/libeditor_core.so +0 -0
  419. package/rust/android/x86_64/libeditor_core.so +0 -0
  420. package/rust/bindings/kotlin/uniffi/editor_core/editor_core.kt +3146 -0
  421. package/src/AtomHost.tsx +180 -0
  422. package/src/DefaultAtomChip.tsx +27 -0
  423. package/src/EditorAddon.ts +65 -0
  424. package/src/EditorAddonNormalization.ts +49 -0
  425. package/src/EditorMentionThemeNormalization.ts +25 -0
  426. package/src/EditorMentionThemeValidation.ts +133 -0
  427. package/src/EditorStyleSheet.ts +9 -0
  428. package/src/EditorStyleSheetNormalization.ts +219 -0
  429. package/src/EditorStyleSheetTypes.ts +189 -0
  430. package/src/EditorTheme.ts +196 -0
  431. package/src/EditorToolbar.tsx +31 -0
  432. package/src/EditorToolbarComponent.tsx +23 -0
  433. package/src/EditorToolbarItems.tsx +64 -0
  434. package/src/EditorToolbarRegistry.tsx +254 -0
  435. package/src/EditorToolbarTypes.tsx +322 -0
  436. package/src/EditorToolbarVisuals.tsx +270 -0
  437. package/src/EditorUpdateRevision.ts +26 -0
  438. package/src/ExternalTextComposition.ts +658 -0
  439. package/src/ImageLoadingPolicy.ts +125 -0
  440. package/src/NativeEditorBoundaryError.ts +345 -0
  441. package/src/NativeEditorBridge.ts +93 -0
  442. package/src/NativeEditorCollaborationTransport.ts +493 -0
  443. package/src/NativeEditorCreateConfig.ts +326 -0
  444. package/src/NativeEditorCreateJson.ts +579 -0
  445. package/src/NativeEditorCreateValidation.ts +178 -0
  446. package/src/NativeEditorDocumentBridge.ts +485 -0
  447. package/src/NativeEditorDocumentHandle.ts +168 -0
  448. package/src/NativeEditorLocalAwareness.ts +168 -0
  449. package/src/NativeEditorNativeModule.ts +97 -0
  450. package/src/NativeEditorRenderNormalization.ts +320 -0
  451. package/src/NativeEditorResultNormalization.ts +469 -0
  452. package/src/NativeEditorTypes.ts +366 -0
  453. package/src/NativeEditorV2Decimal.ts +13 -0
  454. package/src/NativeProseViewer.tsx +356 -0
  455. package/src/NativeRichTextEditor.tsx +33 -0
  456. package/src/ResourceLimits.ts +187 -0
  457. package/src/RichTextEditor.tsx +27 -0
  458. package/src/RichTextEditorNativeTypes.tsx +144 -0
  459. package/src/RichTextEditorNativeView.tsx +21 -0
  460. package/src/RichTextEditorSerialization.tsx +381 -0
  461. package/src/RichTextEditorTypes.tsx +327 -0
  462. package/src/ViewerConfiguration.ts +23 -0
  463. package/src/YjsCollaboration.ts +692 -0
  464. package/src/addons.ts +311 -0
  465. package/src/atomConstants.ts +3 -0
  466. package/src/atomInstances.ts +123 -0
  467. package/src/atomPolicy.ts +47 -0
  468. package/src/atomUpdates.ts +52 -0
  469. package/src/atoms.ts +379 -0
  470. package/src/attributeValidation.ts +116 -0
  471. package/src/contentExpression.ts +338 -0
  472. package/src/index.ts +295 -0
  473. package/src/listMarkers.ts +18 -0
  474. package/src/schemaDefinition.ts +395 -0
  475. package/src/schemaDocument.ts +92 -0
  476. package/src/schemaDocumentConstruction.ts +148 -0
  477. package/src/schemaNormalization.ts +367 -0
  478. package/src/schemaPresets.ts +250 -0
  479. package/src/schemaResolution.ts +242 -0
  480. package/src/schemas.ts +43 -0
  481. package/src/specs/PreparedProseViewerNativeComponent.ts +40 -0
  482. package/src/useEditorToolbarInteractions.tsx +329 -0
  483. package/src/useEditorToolbarItems.tsx +390 -0
  484. package/src/useEditorToolbarPresentation.tsx +483 -0
  485. package/src/useEditorToolbarState.tsx +172 -0
  486. package/src/useFocusPreservingFrames.ts +171 -0
  487. package/src/useNativeEditor.ts +534 -0
  488. package/src/useRichTextEditorCommands.tsx +478 -0
  489. package/src/useRichTextEditorEvents.tsx +342 -0
  490. package/src/useRichTextEditorMentions.tsx +441 -0
  491. package/src/useRichTextEditorPresentation.tsx +563 -0
  492. package/src/useRichTextEditorState.tsx +620 -0
  493. package/src/useRichTextEditorUpdates.tsx +403 -0
  494. package/src/useViewerAtoms.tsx +427 -0
@@ -0,0 +1,387 @@
1
+ import Foundation
2
+ import QuartzCore
3
+
4
+ /// Debug/device-only accounting. Samples belong to the traversal that caused
5
+ /// them; a phase transition is serialized with every producer under `lock`.
6
+ /// Percentiles use nearest-rank: sorted[ceil(p * n) - 1].
7
+ enum PreparedProseInstrumentation {
8
+ enum Owner: String, CaseIterable { case compiled, unmountedLayout, fabricLeaseHandoff, directMounted, image, sidecars, other }
9
+ enum InvalidationReason: String { case content, width, attachment, font, appearance, memoryPressure, cacheReset, reuse }
10
+ enum TraversalPhase: String, CaseIterable { case cold, warm, imagesDisabled, reset }
11
+ enum ViewerWorkKind: String, Codable { case layout, draw, lifecycle }
12
+ struct ViewerWorkSpan: Equatable {
13
+ let startNanos: UInt64
14
+ let endNanos: UInt64
15
+ let kind: ViewerWorkKind
16
+ }
17
+ struct FrameClassification: Equatable {
18
+ let nominalFrameCount: Int
19
+ let isDelayed: Bool
20
+ }
21
+ struct FrameCallbackSample: Codable {
22
+ let callbackTimestampNanos: UInt64
23
+ let callbackDurationNanos: UInt64
24
+ let targetLeadNanos: Int64
25
+ }
26
+ struct CacheSnapshot: Codable, Equatable {
27
+ var unmountedCurrentBytes = 0
28
+ var unmountedHighWaterBytes = 0
29
+ var unmountedCurrentResidentCount = 0
30
+ var unmountedHighWaterResidentCount = 0
31
+ var compiledCurrentBytes = 0
32
+ var compiledCurrentResidentCount = 0
33
+ }
34
+ struct DelayedInterval: Codable {
35
+ let startNanos: UInt64
36
+ let endNanos: UInt64
37
+ let rawDeltaNanos: UInt64
38
+ let viewerLayoutNanos: UInt64
39
+ let viewerDrawNanos: UInt64
40
+ let viewerLifecycleNanos: UInt64
41
+ let viewerWorkUnionNanos: UInt64
42
+ let viewerCaused: Bool
43
+ }
44
+ struct PhaseSamples: Codable {
45
+ var compileNanos: [UInt64] = []; var layoutNanos: [UInt64] = []; var combinedCompileLayoutNanos: [UInt64] = []
46
+ var cacheLookupNanos: [UInt64] = []; var drawNanos: [UInt64] = []; var rawFrameDeltasNanos: [UInt64] = []
47
+ var frameCallbackSamples: [FrameCallbackSample] = []
48
+ var compileCount = 0; var layoutCount = 0; var cacheHits = 0; var cacheMisses = 0; var cacheWaits = 0; var drawCount = 0; var visibleBlocksDrawn = 0
49
+ var imageRequestCount = 0; var imageMetadataCount = 0; var imageDecodeCount = 0
50
+ var nominalFrameCount = 0; var onTimeNominalFrameCount = 0; var delayedIntervalCount = 0; var viewerCausedDelayedIntervals: [DelayedInterval] = []
51
+ var invalidations: [String: Int] = [:]
52
+ }
53
+ struct WindowEvidence: Codable {
54
+ let windowId: String
55
+ let entryIds: [String]
56
+ let phase: String
57
+ let residentKeyCount: Int
58
+ let residentKeyDigest: String
59
+ let cache: CacheSnapshot
60
+ let compileCount: Int
61
+ let layoutCount: Int
62
+ let cacheMisses: Int
63
+ }
64
+ struct Snapshot: Codable {
65
+ let schemaVersion: Int
66
+ let percentileDefinition: String
67
+ let nominalFramePeriodNanos: UInt64
68
+ let singleTickToleranceNanos: UInt64
69
+ let phaseSamples: [String: PhaseSamples]
70
+ let windowEvidence: [WindowEvidence]
71
+ let preResetSnapshot: CacheSnapshot
72
+ let postResetSnapshot: CacheSnapshot
73
+ let duplicatePublications: Int
74
+ }
75
+
76
+ static let nominalFramePeriodNanos: UInt64 = 16_666_667
77
+ static let singleTickToleranceNanos: UInt64 = 1_000_000
78
+ static let benchmarkPreferredFrameRate: Float = 60
79
+ private static let lock = NSLock(); private static let sampleLimit = 20_000
80
+ private static var enabled = false; private static var phase: TraversalPhase?
81
+ private static var samples: [TraversalPhase: PhaseSamples] = [:]
82
+ private static var completedPhases: Set<TraversalPhase> = []
83
+ private static var pendingCompileNanos: [TraversalPhase: [String: UInt64]] = [:]
84
+ private static var viewerWorkSpans: [TraversalPhase: [ViewerWorkSpan]] = [:]
85
+ private static var cacheSnapshot = CacheSnapshot(); private static var preResetSnapshot = CacheSnapshot(); private static var postResetSnapshot = CacheSnapshot()
86
+ private static var windowEvidence: [WindowEvidence] = []; private static var duplicatePublications = 0
87
+ private static var previousDisplayTimestampNanos: UInt64 = 0; private static var previousMonotonicNanos: UInt64 = 0
88
+
89
+ static func classifyFrame(rawDeltaNanos: UInt64, nominalFramePeriodNanos: UInt64, singleTickToleranceNanos: UInt64) -> FrameClassification {
90
+ precondition(nominalFramePeriodNanos > 0)
91
+ if rawDeltaNanos <= nominalFramePeriodNanos + singleTickToleranceNanos { return .init(nominalFrameCount: 1, isDelayed: false) }
92
+ return .init(nominalFrameCount: Int((rawDeltaNanos + nominalFramePeriodNanos - 1) / nominalFramePeriodNanos), isDelayed: true)
93
+ }
94
+
95
+ static func cadencePassRatio(rawFrameDeltasNanos: [UInt64]) -> Double {
96
+ let classifications = rawFrameDeltasNanos.map {
97
+ classifyFrame(
98
+ rawDeltaNanos: $0,
99
+ nominalFramePeriodNanos: nominalFramePeriodNanos,
100
+ singleTickToleranceNanos: singleTickToleranceNanos
101
+ )
102
+ }
103
+ let nominalSlots = classifications.reduce(0) { $0 + $1.nominalFrameCount }
104
+ guard nominalSlots > 0 else { return 0 }
105
+ let onTimeSlots = classifications.reduce(0) { $0 + ($1.isDelayed ? 0 : $1.nominalFrameCount) }
106
+ return Double(onTimeSlots) / Double(nominalSlots)
107
+ }
108
+
109
+ /// Benchmark-only cadence control. This is deliberately not used by
110
+ /// production viewer display links, whose cadence remains system-managed.
111
+ static func configureBenchmarkCadence(_ displayLink: CADisplayLink) {
112
+ displayLink.preferredFrameRateRange = CAFrameRateRange(
113
+ minimum: benchmarkPreferredFrameRate,
114
+ maximum: benchmarkPreferredFrameRate,
115
+ preferred: benchmarkPreferredFrameRate
116
+ )
117
+ }
118
+
119
+ static func viewerCaused(
120
+ _ start: UInt64,
121
+ _ end: UInt64,
122
+ _ spans: [ViewerWorkSpan],
123
+ rawDeltaNanos: UInt64,
124
+ nominalFramePeriodNanos: UInt64
125
+ ) -> Bool {
126
+ let lateness = rawDeltaNanos > nominalFramePeriodNanos
127
+ ? rawDeltaNanos - nominalFramePeriodNanos
128
+ : 0
129
+ return lateness > 0 && viewerWorkNanos(start, end, spans) >= lateness
130
+ }
131
+
132
+ static func viewerWorkNanos(_ start: UInt64, _ end: UInt64, _ spans: [ViewerWorkSpan]) -> UInt64 {
133
+ mergedWorkNanos(start, end, spans)
134
+ }
135
+
136
+ static func beginBenchmark() {
137
+ #if DEBUG
138
+ lock.lock(); enabled = true; resetLocked(); lock.unlock()
139
+ #endif
140
+ }
141
+ static func reset() {
142
+ #if DEBUG
143
+ lock.lock(); resetLocked(); lock.unlock()
144
+ #endif
145
+ }
146
+ static func beginPhase(_ value: TraversalPhase, preservingDisplayLinkBaseline: Bool = false) {
147
+ #if DEBUG
148
+ lock.lock()
149
+ guard enabled else { lock.unlock(); return }
150
+ phase = value; completedPhases.remove(value)
151
+ if !preservingDisplayLinkBaseline {
152
+ previousDisplayTimestampNanos = 0; previousMonotonicNanos = 0
153
+ }
154
+ lock.unlock()
155
+ #endif
156
+ }
157
+ static func transitionPhase(_ value: TraversalPhase) {
158
+ #if DEBUG
159
+ lock.lock()
160
+ guard enabled else { lock.unlock(); return }
161
+ if let phase { completedPhases.insert(phase); viewerWorkSpans[phase] = [] }
162
+ phase = value; completedPhases.remove(value)
163
+ lock.unlock()
164
+ #endif
165
+ }
166
+ static func endPhase() {
167
+ #if DEBUG
168
+ lock.lock()
169
+ if let phase { completedPhases.insert(phase); viewerWorkSpans[phase] = [] }
170
+ phase = nil; previousDisplayTimestampNanos = 0; previousMonotonicNanos = 0
171
+ lock.unlock()
172
+ #endif
173
+ }
174
+ static func beginTraversal(_ value: TraversalPhase) { beginPhase(value) }
175
+ static func endTraversal() { endPhase() }
176
+
177
+ static func displayLinkDidTick(_ displayLink: CADisplayLink) {
178
+ #if DEBUG
179
+ recordDisplayLinkTick(
180
+ callbackTimestampNanos: timeIntervalNanos(displayLink.timestamp),
181
+ observedMonotonicNanos: DispatchTime.now().uptimeNanoseconds,
182
+ callbackDurationNanos: timeIntervalNanos(displayLink.duration),
183
+ targetLeadNanos: signedTimeIntervalNanos(displayLink.targetTimestamp - displayLink.timestamp)
184
+ )
185
+ #endif
186
+ }
187
+
188
+ static func recordDisplayLinkTick(
189
+ callbackTimestampNanos: UInt64,
190
+ observedMonotonicNanos: UInt64,
191
+ callbackDurationNanos: UInt64,
192
+ targetLeadNanos: Int64
193
+ ) {
194
+ #if DEBUG
195
+ lock.lock(); defer { lock.unlock() }
196
+ guard enabled, let phase else { return }
197
+ mutate(phase) { sample in
198
+ append(
199
+ .init(
200
+ callbackTimestampNanos: callbackTimestampNanos,
201
+ callbackDurationNanos: callbackDurationNanos,
202
+ targetLeadNanos: targetLeadNanos
203
+ ),
204
+ to: &sample.frameCallbackSamples
205
+ )
206
+ }
207
+ defer { previousDisplayTimestampNanos = callbackTimestampNanos; previousMonotonicNanos = observedMonotonicNanos }
208
+ guard previousDisplayTimestampNanos > 0, previousMonotonicNanos > 0,
209
+ callbackTimestampNanos > previousDisplayTimestampNanos
210
+ else { return }
211
+ let rawDeltaNanos = callbackTimestampNanos - previousDisplayTimestampNanos
212
+ guard rawDeltaNanos > 0 else { return }
213
+ let intervalStart = previousMonotonicNanos
214
+ let intervalEnd = observedMonotonicNanos
215
+ let spans = viewerWorkSpans[phase] ?? []
216
+ mutate(phase) { sample in
217
+ append(rawDeltaNanos, to: &sample.rawFrameDeltasNanos)
218
+ let classification = classifyFrame(rawDeltaNanos: rawDeltaNanos, nominalFramePeriodNanos: nominalFramePeriodNanos, singleTickToleranceNanos: singleTickToleranceNanos)
219
+ sample.nominalFrameCount += classification.nominalFrameCount
220
+ if !classification.isDelayed { sample.onTimeNominalFrameCount += classification.nominalFrameCount }
221
+ if classification.isDelayed {
222
+ sample.delayedIntervalCount += 1
223
+ let caused = viewerCaused(
224
+ intervalStart,
225
+ intervalEnd,
226
+ spans,
227
+ rawDeltaNanos: rawDeltaNanos,
228
+ nominalFramePeriodNanos: nominalFramePeriodNanos
229
+ )
230
+ let interval = DelayedInterval(
231
+ startNanos: intervalStart,
232
+ endNanos: intervalEnd,
233
+ rawDeltaNanos: rawDeltaNanos,
234
+ viewerLayoutNanos: clippedWork(intervalStart, intervalEnd, spans, kind: .layout),
235
+ viewerDrawNanos: clippedWork(intervalStart, intervalEnd, spans, kind: .draw),
236
+ viewerLifecycleNanos: clippedWork(intervalStart, intervalEnd, spans, kind: .lifecycle),
237
+ viewerWorkUnionNanos: viewerWorkNanos(intervalStart, intervalEnd, spans),
238
+ viewerCaused: caused
239
+ )
240
+ if caused { append(interval, to: &sample.viewerCausedDelayedIntervals) }
241
+ }
242
+ }
243
+ viewerWorkSpans[phase] = spans.filter { $0.endNanos > intervalStart }
244
+ #endif
245
+ }
246
+
247
+ static func recordViewerWork(startNanos: UInt64, endNanos: UInt64, kind: ViewerWorkKind) {
248
+ #if DEBUG
249
+ guard startNanos < endNanos else { return }
250
+ lock.lock(); defer { lock.unlock() }
251
+ guard enabled, let phase else { return }
252
+ viewerWorkSpans[phase, default: []].append(.init(startNanos: startNanos, endNanos: endNanos, kind: kind))
253
+ #endif
254
+ }
255
+ static func snapshotCache() -> CacheSnapshot {
256
+ #if DEBUG
257
+ lock.lock(); defer { lock.unlock() }; return cacheSnapshot
258
+ #else
259
+ return CacheSnapshot()
260
+ #endif
261
+ }
262
+ static func capturePreResetSnapshot() {
263
+ #if DEBUG
264
+ lock.lock(); if enabled { preResetSnapshot = cacheSnapshot }; lock.unlock()
265
+ #endif
266
+ }
267
+ static func capturePostResetSnapshot() {
268
+ #if DEBUG
269
+ lock.lock(); if enabled { postResetSnapshot = cacheSnapshot }; lock.unlock()
270
+ #endif
271
+ }
272
+ struct PhaseCounters {
273
+ var compileCount = 0
274
+ var layoutCount = 0
275
+ var cacheMisses = 0
276
+ }
277
+
278
+ static func phaseCounters() -> PhaseCounters {
279
+ #if DEBUG
280
+ lock.lock(); defer { lock.unlock() }
281
+ guard let phase else { return PhaseCounters() }
282
+ let value = samples[phase] ?? PhaseSamples()
283
+ return PhaseCounters(compileCount: value.compileCount, layoutCount: value.layoutCount, cacheMisses: value.cacheMisses)
284
+ #else
285
+ return PhaseCounters()
286
+ #endif
287
+ }
288
+ static func recordWindow(
289
+ windowId: String,
290
+ entryIds: [String],
291
+ phase: TraversalPhase,
292
+ residentKeyCount: Int,
293
+ residentKeyDigest: String,
294
+ cache: CacheSnapshot,
295
+ counters: PhaseCounters
296
+ ) {
297
+ #if DEBUG
298
+ lock.lock(); defer { lock.unlock() }
299
+ guard enabled else { return }
300
+ windowEvidence.append(
301
+ .init(
302
+ windowId: windowId,
303
+ entryIds: entryIds,
304
+ phase: phase.rawValue,
305
+ residentKeyCount: residentKeyCount,
306
+ residentKeyDigest: residentKeyDigest,
307
+ cache: cache,
308
+ compileCount: counters.compileCount,
309
+ layoutCount: counters.layoutCount,
310
+ cacheMisses: counters.cacheMisses
311
+ )
312
+ )
313
+ #endif
314
+ }
315
+ static func cacheUpdated(unmountedBytes: Int? = nil, unmountedResidentCount: Int? = nil, compiledBytes: Int? = nil, compiledResidentCount: Int? = nil) {
316
+ #if DEBUG
317
+ lock.lock(); defer { lock.unlock() }
318
+ guard enabled else { return }
319
+ if let unmountedBytes { cacheSnapshot.unmountedCurrentBytes = max(0, unmountedBytes); cacheSnapshot.unmountedHighWaterBytes = max(cacheSnapshot.unmountedHighWaterBytes, cacheSnapshot.unmountedCurrentBytes) }
320
+ if let unmountedResidentCount { cacheSnapshot.unmountedCurrentResidentCount = max(0, unmountedResidentCount); cacheSnapshot.unmountedHighWaterResidentCount = max(cacheSnapshot.unmountedHighWaterResidentCount, cacheSnapshot.unmountedCurrentResidentCount) }
321
+ if let compiledBytes { cacheSnapshot.compiledCurrentBytes = max(0, compiledBytes) }
322
+ if let compiledResidentCount { cacheSnapshot.compiledCurrentResidentCount = max(0, compiledResidentCount) }
323
+ #endif
324
+ }
325
+
326
+ static func exportJSON() -> String {
327
+ #if DEBUG
328
+ lock.lock()
329
+ let exportedPhases = [TraversalPhase.cold, .warm, .imagesDisabled]
330
+ let completedSamples = Dictionary(uniqueKeysWithValues: exportedPhases.map { ($0.rawValue, samples[$0] ?? PhaseSamples()) })
331
+ let snapshot = Snapshot(schemaVersion: 3, percentileDefinition: "nearest-rank: sorted[ceil(p*n)-1]", nominalFramePeriodNanos: nominalFramePeriodNanos, singleTickToleranceNanos: singleTickToleranceNanos, phaseSamples: completedSamples, windowEvidence: windowEvidence, preResetSnapshot: preResetSnapshot, postResetSnapshot: postResetSnapshot, duplicatePublications: duplicatePublications)
332
+ lock.unlock()
333
+ return String(data: (try? JSONEncoder().encode(snapshot)) ?? Data("{}".utf8), encoding: .utf8) ?? "{}"
334
+ #else
335
+ return "{}"
336
+ #endif
337
+ }
338
+
339
+ @inline(__always) static func now() -> UInt64 {
340
+ #if DEBUG
341
+ lock.lock(); let active = enabled; lock.unlock(); return active ? DispatchTime.now().uptimeNanoseconds : 0
342
+ #else
343
+ return 0
344
+ #endif
345
+ }
346
+ @inline(__always) static func compiled(_ start: UInt64, generation: String) { record(start) { phase, elapsed, _ in mutate(phase) { samples in samples.compileCount += 1; append(elapsed, to: &samples.compileNanos) }; pendingCompileNanos[phase, default: [:]][generation] = elapsed } }
347
+ @inline(__always) static func laidOut(_ start: UInt64, generation: String) { record(start) { phase, elapsed, end in mutate(phase) { samples in samples.layoutCount += 1; append(elapsed, to: &samples.layoutNanos); if let compile = pendingCompileNanos[phase]?.removeValue(forKey: generation) { append(compile + elapsed, to: &samples.combinedCompileLayoutNanos) } }; recordViewerWorkLocked(startNanos: start, endNanos: end, kind: .layout, phase: phase) } }
348
+ @inline(__always) static func cacheLookup(_ start: UInt64, hit: Bool, waited: Bool = false) { record(start) { phase, elapsed, _ in mutate(phase) { samples in append(elapsed, to: &samples.cacheLookupNanos); if hit { samples.cacheHits += 1 } else { samples.cacheMisses += 1 }; if waited { samples.cacheWaits += 1 } } } }
349
+ @inline(__always) static func drew(_ start: UInt64, visibleBlocks: Int) { record(start) { phase, elapsed, end in mutate(phase) { samples in append(elapsed, to: &samples.drawNanos); samples.drawCount += 1; samples.visibleBlocksDrawn += visibleBlocks }; recordViewerWorkLocked(startNanos: start, endNanos: end, kind: .draw, phase: phase) } }
350
+ static func imageRequested() { incrementImageCounter { $0.imageRequestCount += 1 } }
351
+ static func imageMetadataRead() { incrementImageCounter { $0.imageMetadataCount += 1 } }
352
+ static func imageDecoded() { incrementImageCounter { $0.imageDecodeCount += 1 } }
353
+ static func retained(_ owner: Owner, scope: String, bytes: Int) { }
354
+ static func invalidated(_ reason: InvalidationReason) {
355
+ #if DEBUG
356
+ lock.lock(); if enabled, let phase { mutate(phase) { samples in samples.invalidations[reason.rawValue, default: 0] += 1 } }; lock.unlock()
357
+ #endif
358
+ }
359
+ static func duplicatePublication() {
360
+ #if DEBUG
361
+ lock.lock(); if enabled { duplicatePublications += 1 }; lock.unlock()
362
+ #endif
363
+ }
364
+ private static func record(_ start: UInt64, _ body: (TraversalPhase, UInt64, UInt64) -> Void) {
365
+ #if DEBUG
366
+ guard start != 0 else { return }; lock.lock(); defer { lock.unlock() }; guard enabled, let phase else { return }; let end = DispatchTime.now().uptimeNanoseconds; body(phase, end - start, end)
367
+ #endif
368
+ }
369
+ private static func incrementImageCounter(_ body: (inout PhaseSamples) -> Void) {
370
+ #if DEBUG
371
+ lock.lock(); defer { lock.unlock() }; guard enabled, let phase else { return }; mutate(phase, body)
372
+ #endif
373
+ }
374
+ private static func recordViewerWorkLocked(startNanos: UInt64, endNanos: UInt64, kind: ViewerWorkKind, phase: TraversalPhase) { guard startNanos < endNanos else { return }; viewerWorkSpans[phase, default: []].append(.init(startNanos: startNanos, endNanos: endNanos, kind: kind)) }
375
+ private static func clippedWork(_ start: UInt64, _ end: UInt64, _ spans: [ViewerWorkSpan], kind: ViewerWorkKind) -> UInt64 {
376
+ mergedWorkNanos(start, end, spans.filter { $0.kind == kind })
377
+ }
378
+ private static func mergedWorkNanos(_ start: UInt64, _ end: UInt64, _ spans: [ViewerWorkSpan]) -> UInt64 {
379
+ let clipped = spans.compactMap { span -> Range<UInt64>? in let lower = max(start, span.startNanos), upper = min(end, span.endNanos); return lower < upper ? lower..<upper : nil }.sorted { $0.lowerBound < $1.lowerBound }
380
+ return clipped.reduce(into: [Range<UInt64>]()) { merged, range in if let last = merged.last, range.lowerBound <= last.upperBound { merged[merged.count - 1] = last.lowerBound..<max(last.upperBound, range.upperBound) } else { merged.append(range) } }.reduce(0) { $0 + ($1.upperBound - $1.lowerBound) }
381
+ }
382
+ private static func mutate(_ phase: TraversalPhase, _ body: (inout PhaseSamples) -> Void) { var value = samples[phase] ?? PhaseSamples(); body(&value); samples[phase] = value }
383
+ private static func append<T>(_ value: T, to samples: inout [T]) { if samples.count < sampleLimit { samples.append(value) } }
384
+ private static func timeIntervalNanos(_ seconds: CFTimeInterval) -> UInt64 { guard seconds.isFinite, seconds > 0 else { return 0 }; return UInt64((seconds * 1_000_000_000).rounded(.towardZero)) }
385
+ private static func signedTimeIntervalNanos(_ seconds: CFTimeInterval) -> Int64 { guard seconds.isFinite else { return 0 }; return Int64((seconds * 1_000_000_000).rounded(.towardZero)) }
386
+ private static func resetLocked() { phase = nil; samples = [:]; completedPhases = []; pendingCompileNanos = [:]; viewerWorkSpans = [:]; cacheSnapshot = CacheSnapshot(); preResetSnapshot = CacheSnapshot(); postResetSnapshot = CacheSnapshot(); windowEvidence = []; duplicatePublications = 0; previousDisplayTimestampNanos = 0; previousMonotonicNanos = 0 }
387
+ }