@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.
- package/LICENSE +160 -0
- package/README.md +259 -0
- package/RUST-STANDARD-LIBRARY-NOTICES.html +8266 -0
- package/ReactNativeProseEditor.podspec +59 -0
- package/THIRD_PARTY_NOTICES.md +31155 -0
- package/android/build.gradle +188 -0
- package/android/consumer-rules.pro +18 -0
- package/android/expo/build.gradle +17 -0
- package/android/src/debug/java/com/apollohg/editor/viewer/PreparedProseDrawInstrumentation.kt +7 -0
- package/android/src/main/assets/editor-icons/MaterialIcons.json +2236 -0
- package/android/src/main/assets/editor-icons/MaterialIcons.ttf +0 -0
- package/android/src/main/java/com/apollohg/editor/AndroidApiCompat.kt +19 -0
- package/android/src/main/java/com/apollohg/editor/AndroidCollaborationTransport.kt +860 -0
- package/android/src/main/java/com/apollohg/editor/CaretGeometry.kt +91 -0
- package/android/src/main/java/com/apollohg/editor/CodeHighlighting.kt +141 -0
- package/android/src/main/java/com/apollohg/editor/DecodedBitmapBudget.kt +250 -0
- package/android/src/main/java/com/apollohg/editor/EditorAddons.kt +133 -0
- package/android/src/main/java/com/apollohg/editor/EditorBlockSpacing.kt +51 -0
- package/android/src/main/java/com/apollohg/editor/EditorBoxDrawable.kt +16 -0
- package/android/src/main/java/com/apollohg/editor/EditorBoxDrawing.kt +234 -0
- package/android/src/main/java/com/apollohg/editor/EditorCheckboxSpan.kt +87 -0
- package/android/src/main/java/com/apollohg/editor/EditorCodeHighlighting.kt +120 -0
- package/android/src/main/java/com/apollohg/editor/EditorDecorationLayer.java +18 -0
- package/android/src/main/java/com/apollohg/editor/EditorDocumentLayout.kt +626 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditText.kt +1042 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextAnnotations.kt +191 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextCaret.kt +100 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextClipboard.kt +101 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextComposition.kt +220 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextConfiguration.kt +316 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextCorrection.kt +303 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextDeferredUpdates.kt +327 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextDeletion.kt +258 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextDiagnostics.kt +83 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextDragDrop.kt +67 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextExternalComposition.kt +357 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextHardwareInput.kt +277 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextImages.kt +280 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextInputLifecycle.kt +183 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextInputPreparation.kt +79 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextInputTraits.kt +384 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextLayout.kt +100 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextNativeMutation.kt +243 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextPlaceholder.kt +154 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextRenderPatch.kt +347 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextRendering.kt +313 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextRustCommands.kt +281 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextSelection.kt +352 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextState.kt +113 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextTaskMarkers.kt +92 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextTextCommit.kt +327 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextToolbar.kt +84 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextUpdates.kt +245 -0
- package/android/src/main/java/com/apollohg/editor/EditorGlyphHeightCursorDrawable.kt +42 -0
- package/android/src/main/java/com/apollohg/editor/EditorHeightBehavior.kt +13 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputConnection.kt +923 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputCoordinates.kt +191 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputCorrection.kt +107 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputCursorGeometry.kt +128 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputSnapshots.kt +134 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputSurroundingDeletion.kt +321 -0
- package/android/src/main/java/com/apollohg/editor/EditorKeyboardToolbarView.kt +851 -0
- package/android/src/main/java/com/apollohg/editor/EditorMentionStyle.kt +192 -0
- package/android/src/main/java/com/apollohg/editor/EditorReconciliationWatcher.kt +46 -0
- package/android/src/main/java/com/apollohg/editor/EditorStyleSheet.kt +303 -0
- package/android/src/main/java/com/apollohg/editor/EditorStyleSheetSpans.kt +253 -0
- package/android/src/main/java/com/apollohg/editor/EditorSurfaceInputConnection.kt +67 -0
- package/android/src/main/java/com/apollohg/editor/EditorTextDecorationDrawing.kt +143 -0
- package/android/src/main/java/com/apollohg/editor/EditorTextSurface.kt +712 -0
- package/android/src/main/java/com/apollohg/editor/EditorTextSurfaceDragDrop.kt +94 -0
- package/android/src/main/java/com/apollohg/editor/EditorTextSurfaceInteraction.kt +708 -0
- package/android/src/main/java/com/apollohg/editor/EditorTheme.kt +650 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2Adapter.kt +912 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2AdapterMutations.kt +402 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2AdapterRendering.kt +123 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2AdapterSelection.kt +203 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2Backend.kt +120 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2Driver.kt +87 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2Registry.kt +97 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2RenderValidation.kt +409 -0
- package/android/src/main/java/com/apollohg/editor/ExpoAutoGrowStyleSizePublisher.kt +34 -0
- package/android/src/main/java/com/apollohg/editor/ImageResizeOverlayView.kt +266 -0
- package/android/src/main/java/com/apollohg/editor/ImeTextCoordinateMapper.kt +102 -0
- package/android/src/main/java/com/apollohg/editor/KeyboardToolbarImeAnimationController.kt +101 -0
- package/android/src/main/java/com/apollohg/editor/MentionSuggestionChipView.kt +234 -0
- package/android/src/main/java/com/apollohg/editor/NativeCollaborationTransportRegistry.kt +493 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoView.kt +813 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewAtoms.kt +68 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewBinding.kt +126 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewDiagnostics.kt +208 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewErrors.kt +146 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewEvents.kt +150 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewExternalComposition.kt +39 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewFocus.kt +176 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewLifecycle.kt +302 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewMentions.kt +259 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewNativeActions.kt +179 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewOutsideTap.kt +214 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewPendingUpdates.kt +376 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewProperties.kt +234 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewPropertyRetries.kt +197 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewToolbar.kt +285 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewTypes.kt +28 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewUpdates.kt +271 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorModule.kt +687 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorOutsideTapDispatcher.kt +380 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorV2Numbers.kt +45 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorViewRegistry.kt +372 -0
- package/android/src/main/java/com/apollohg/editor/NativeImagePipeline.kt +22 -0
- package/android/src/main/java/com/apollohg/editor/NativeToolbar.kt +193 -0
- package/android/src/main/java/com/apollohg/editor/NativeToolbarIcons.kt +177 -0
- package/android/src/main/java/com/apollohg/editor/NativeToolbarItem.kt +274 -0
- package/android/src/main/java/com/apollohg/editor/OkHttpCollaborationSocket.kt +102 -0
- package/android/src/main/java/com/apollohg/editor/OrderedListMarkerFormatter.kt +130 -0
- package/android/src/main/java/com/apollohg/editor/PointerTransparentView.java +18 -0
- package/android/src/main/java/com/apollohg/editor/PositionBridge.kt +128 -0
- package/android/src/main/java/com/apollohg/editor/ProseViewerView.kt +854 -0
- package/android/src/main/java/com/apollohg/editor/RemoteSelectionOverlayView.kt +314 -0
- package/android/src/main/java/com/apollohg/editor/RenderBlockSpans.kt +314 -0
- package/android/src/main/java/com/apollohg/editor/RenderBridge.kt +224 -0
- package/android/src/main/java/com/apollohg/editor/RenderBridgeBlockStyles.kt +407 -0
- package/android/src/main/java/com/apollohg/editor/RenderBridgeElements.kt +544 -0
- package/android/src/main/java/com/apollohg/editor/RenderBridgeInlineAndAtoms.kt +631 -0
- package/android/src/main/java/com/apollohg/editor/RenderBridgeParagraphs.kt +215 -0
- package/android/src/main/java/com/apollohg/editor/RenderImageDecoder.kt +748 -0
- package/android/src/main/java/com/apollohg/editor/RenderImageLoader.kt +900 -0
- package/android/src/main/java/com/apollohg/editor/RenderLayoutConstants.kt +117 -0
- package/android/src/main/java/com/apollohg/editor/RenderMediaSpans.kt +337 -0
- package/android/src/main/java/com/apollohg/editor/RenderParagraphSpans.kt +182 -0
- package/android/src/main/java/com/apollohg/editor/RichTextEditorView.kt +951 -0
- package/android/src/main/java/com/apollohg/editor/SharedNativeImagePipeline.kt +78 -0
- package/android/src/main/java/com/apollohg/editor/UniffiEditorV2Backend.kt +261 -0
- package/android/src/main/java/com/apollohg/editor/viewer/AndroidProseLayoutEngine.kt +1656 -0
- package/android/src/main/java/com/apollohg/editor/viewer/FabricAttachmentSidecars.kt +80 -0
- package/android/src/main/java/com/apollohg/editor/viewer/FabricLeaseHandleBridge.kt +59 -0
- package/android/src/main/java/com/apollohg/editor/viewer/FallbackSelectionGeometry.kt +450 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseDrawingView.kt +678 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseInstrumentation.kt +608 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayout.kt +186 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayoutCache.kt +393 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayoutRegistry.kt +828 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseTheme.kt +316 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseViewerManager.kt +900 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseViewerPackage.kt +16 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedViewerAtoms.kt +89 -0
- package/android/src/main/java/com/apollohg/editor/viewer/ViewerCodeHighlighting.kt +91 -0
- package/android/src/main/java/com/apollohg/editor/viewer/ViewerDocument.kt +453 -0
- package/android/src/main/java/com/apollohg/editor/viewer/ViewerFontEnvironment.kt +282 -0
- package/android/src/main/java/com/apollohg/editor/viewer/ViewerImagePipeline.kt +460 -0
- package/android/src/main/jni/CMakeLists.txt +85 -0
- package/android/src/main/jni/PreparedProseViewerMeasurementsManager.cpp +334 -0
- package/android/src/main/jni/ReactNativeProseEditorSpec.h +17 -0
- package/android/src/main/jni/reactnativeproseeditor.h +6 -0
- package/android/src/main/res/values/attrs.xml +6 -0
- package/android/src/release/java/com/apollohg/editor/viewer/PreparedProseDrawInstrumentation.kt +9 -0
- package/app.plugin.js +62 -0
- package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseMeasurementsManager.h +62 -0
- package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerComponentDescriptor.h +30 -0
- package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerShadowNode.cpp +192 -0
- package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerShadowNode.h +46 -0
- package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerState.h +145 -0
- package/dist/AtomHost.d.ts +17 -0
- package/dist/AtomHost.js +135 -0
- package/dist/DefaultAtomChip.d.ts +2 -0
- package/dist/DefaultAtomChip.js +22 -0
- package/dist/EditorAddon.d.ts +32 -0
- package/dist/EditorAddon.js +29 -0
- package/dist/EditorAddonNormalization.d.ts +6 -0
- package/dist/EditorAddonNormalization.js +48 -0
- package/dist/EditorMentionThemeNormalization.d.ts +8 -0
- package/dist/EditorMentionThemeNormalization.js +22 -0
- package/dist/EditorMentionThemeValidation.d.ts +12 -0
- package/dist/EditorMentionThemeValidation.js +95 -0
- package/dist/EditorStyleSheet.d.ts +4 -0
- package/dist/EditorStyleSheet.js +10 -0
- package/dist/EditorStyleSheetNormalization.d.ts +3 -0
- package/dist/EditorStyleSheetNormalization.js +226 -0
- package/dist/EditorStyleSheetTypes.d.ts +151 -0
- package/dist/EditorStyleSheetTypes.js +2 -0
- package/dist/EditorTheme.d.ts +117 -0
- package/dist/EditorTheme.js +41 -0
- package/dist/EditorToolbar.d.ts +4 -0
- package/dist/EditorToolbar.js +17 -0
- package/dist/EditorToolbarComponent.d.ts +13 -0
- package/dist/EditorToolbarComponent.js +24 -0
- package/dist/EditorToolbarItems.d.ts +9 -0
- package/dist/EditorToolbarItems.js +58 -0
- package/dist/EditorToolbarRegistry.d.ts +59 -0
- package/dist/EditorToolbarRegistry.js +175 -0
- package/dist/EditorToolbarTypes.d.ts +273 -0
- package/dist/EditorToolbarTypes.js +2 -0
- package/dist/EditorToolbarVisuals.d.ts +154 -0
- package/dist/EditorToolbarVisuals.js +228 -0
- package/dist/EditorUpdateRevision.d.ts +8 -0
- package/dist/EditorUpdateRevision.js +22 -0
- package/dist/ExternalTextComposition.d.ts +45 -0
- package/dist/ExternalTextComposition.js +537 -0
- package/dist/ImageLoadingPolicy.d.ts +54 -0
- package/dist/ImageLoadingPolicy.js +60 -0
- package/dist/NativeEditorBoundaryError.d.ts +111 -0
- package/dist/NativeEditorBoundaryError.js +268 -0
- package/dist/NativeEditorBridge.d.ts +9 -0
- package/dist/NativeEditorBridge.js +37 -0
- package/dist/NativeEditorCollaborationTransport.d.ts +154 -0
- package/dist/NativeEditorCollaborationTransport.js +275 -0
- package/dist/NativeEditorCreateConfig.d.ts +16 -0
- package/dist/NativeEditorCreateConfig.js +249 -0
- package/dist/NativeEditorCreateJson.d.ts +76 -0
- package/dist/NativeEditorCreateJson.js +474 -0
- package/dist/NativeEditorCreateValidation.d.ts +32 -0
- package/dist/NativeEditorCreateValidation.js +150 -0
- package/dist/NativeEditorDocumentBridge.d.ts +72 -0
- package/dist/NativeEditorDocumentBridge.js +305 -0
- package/dist/NativeEditorDocumentHandle.d.ts +70 -0
- package/dist/NativeEditorDocumentHandle.js +89 -0
- package/dist/NativeEditorLocalAwareness.d.ts +34 -0
- package/dist/NativeEditorLocalAwareness.js +153 -0
- package/dist/NativeEditorNativeModule.d.ts +48 -0
- package/dist/NativeEditorNativeModule.js +34 -0
- package/dist/NativeEditorRenderNormalization.d.ts +22 -0
- package/dist/NativeEditorRenderNormalization.js +274 -0
- package/dist/NativeEditorResultNormalization.d.ts +108 -0
- package/dist/NativeEditorResultNormalization.js +400 -0
- package/dist/NativeEditorTypes.d.ts +318 -0
- package/dist/NativeEditorTypes.js +15 -0
- package/dist/NativeEditorV2Decimal.d.ts +5 -0
- package/dist/NativeEditorV2Decimal.js +18 -0
- package/dist/NativeProseViewer.d.ts +122 -0
- package/dist/NativeProseViewer.js +130 -0
- package/dist/NativeRichTextEditor.d.ts +3 -0
- package/dist/NativeRichTextEditor.js +6 -0
- package/dist/ResourceLimits.d.ts +100 -0
- package/dist/ResourceLimits.js +80 -0
- package/dist/RichTextEditor.d.ts +4 -0
- package/dist/RichTextEditor.js +25 -0
- package/dist/RichTextEditorNativeTypes.d.ts +122 -0
- package/dist/RichTextEditorNativeTypes.js +2 -0
- package/dist/RichTextEditorNativeView.d.ts +12 -0
- package/dist/RichTextEditorNativeView.js +15 -0
- package/dist/RichTextEditorSerialization.d.ts +53 -0
- package/dist/RichTextEditorSerialization.js +283 -0
- package/dist/RichTextEditorTypes.d.ts +281 -0
- package/dist/RichTextEditorTypes.js +2 -0
- package/dist/ViewerConfiguration.d.ts +22 -0
- package/dist/ViewerConfiguration.js +6 -0
- package/dist/YjsCollaboration.d.ts +146 -0
- package/dist/YjsCollaboration.js +496 -0
- package/dist/addons.d.ts +193 -0
- package/dist/addons.js +122 -0
- package/dist/atomConstants.d.ts +3 -0
- package/dist/atomConstants.js +6 -0
- package/dist/atomInstances.d.ts +35 -0
- package/dist/atomInstances.js +79 -0
- package/dist/atomPolicy.d.ts +4 -0
- package/dist/atomPolicy.js +47 -0
- package/dist/atomUpdates.d.ts +2 -0
- package/dist/atomUpdates.js +38 -0
- package/dist/atoms.d.ts +92 -0
- package/dist/atoms.js +222 -0
- package/dist/attributeValidation.d.ts +4 -0
- package/dist/attributeValidation.js +97 -0
- package/dist/contentExpression.d.ts +6 -0
- package/dist/contentExpression.js +335 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +78 -0
- package/dist/listMarkers.d.ts +15 -0
- package/dist/listMarkers.js +21 -0
- package/dist/schemaDefinition.d.ts +143 -0
- package/dist/schemaDefinition.js +206 -0
- package/dist/schemaDocument.d.ts +17 -0
- package/dist/schemaDocument.js +69 -0
- package/dist/schemaDocumentConstruction.d.ts +5 -0
- package/dist/schemaDocumentConstruction.js +125 -0
- package/dist/schemaNormalization.d.ts +29 -0
- package/dist/schemaNormalization.js +313 -0
- package/dist/schemaPresets.d.ts +68 -0
- package/dist/schemaPresets.js +198 -0
- package/dist/schemaResolution.d.ts +9 -0
- package/dist/schemaResolution.js +211 -0
- package/dist/schemas.d.ts +5 -0
- package/dist/schemas.js +28 -0
- package/dist/specs/PreparedProseViewerNativeComponent.d.ts +37 -0
- package/dist/specs/PreparedProseViewerNativeComponent.js +6 -0
- package/dist/useEditorToolbarInteractions.d.ts +12 -0
- package/dist/useEditorToolbarInteractions.js +218 -0
- package/dist/useEditorToolbarItems.d.ts +8 -0
- package/dist/useEditorToolbarItems.js +280 -0
- package/dist/useEditorToolbarPresentation.d.ts +4 -0
- package/dist/useEditorToolbarPresentation.js +203 -0
- package/dist/useEditorToolbarState.d.ts +63 -0
- package/dist/useEditorToolbarState.js +108 -0
- package/dist/useFocusPreservingFrames.d.ts +17 -0
- package/dist/useFocusPreservingFrames.js +108 -0
- package/dist/useNativeEditor.d.ts +66 -0
- package/dist/useNativeEditor.js +370 -0
- package/dist/useRichTextEditorCommands.d.ts +21 -0
- package/dist/useRichTextEditorCommands.js +299 -0
- package/dist/useRichTextEditorEvents.d.ts +18 -0
- package/dist/useRichTextEditorEvents.js +216 -0
- package/dist/useRichTextEditorMentions.d.ts +11 -0
- package/dist/useRichTextEditorMentions.js +316 -0
- package/dist/useRichTextEditorPresentation.d.ts +5 -0
- package/dist/useRichTextEditorPresentation.js +178 -0
- package/dist/useRichTextEditorState.d.ts +180 -0
- package/dist/useRichTextEditorState.js +405 -0
- package/dist/useRichTextEditorUpdates.d.ts +10 -0
- package/dist/useRichTextEditorUpdates.js +308 -0
- package/dist/useViewerAtoms.d.ts +38 -0
- package/dist/useViewerAtoms.js +288 -0
- package/expo-module.config.json +13 -0
- package/ios/EditorAddons.swift +354 -0
- package/ios/EditorCodeHighlighting.swift +184 -0
- package/ios/EditorCore.xcframework/Info.plist +44 -0
- package/ios/EditorCore.xcframework/ios-arm64/libeditor_core.a +0 -0
- package/ios/EditorCore.xcframework/ios-arm64_x86_64-simulator/libeditor_core.a +0 -0
- package/ios/EditorInteractionOverlays.swift +697 -0
- package/ios/EditorLayoutManager.swift +971 -0
- package/ios/EditorNodeTypes.swift +37 -0
- package/ios/EditorStyleSheet.swift +461 -0
- package/ios/EditorTextView+AttributedPatch.swift +305 -0
- package/ios/EditorTextView+Binding.swift +61 -0
- package/ios/EditorTextView+Caret.swift +333 -0
- package/ios/EditorTextView+Commands.swift +203 -0
- package/ios/EditorTextView+Delegate.swift +65 -0
- package/ios/EditorTextView+Diagnostics.swift +225 -0
- package/ios/EditorTextView+DragDrop.swift +290 -0
- package/ios/EditorTextView+ExternalComposition.swift +364 -0
- package/ios/EditorTextView+Images.swift +354 -0
- package/ios/EditorTextView+InputTraits.swift +200 -0
- package/ios/EditorTextView+KeyboardInput.swift +318 -0
- package/ios/EditorTextView+Layout.swift +245 -0
- package/ios/EditorTextView+MarkedText.swift +267 -0
- package/ios/EditorTextView+NativeInputLifecycle.swift +372 -0
- package/ios/EditorTextView+NativeMutation.swift +471 -0
- package/ios/EditorTextView+Reconciliation.swift +97 -0
- package/ios/EditorTextView+RenderPatch.swift +573 -0
- package/ios/EditorTextView+Rendering.swift +539 -0
- package/ios/EditorTextView+Selection.swift +542 -0
- package/ios/EditorTextView.swift +953 -0
- package/ios/EditorTheme.swift +626 -0
- package/ios/EditorV2Adapter+Commands.swift +204 -0
- package/ios/EditorV2Adapter+Envelope.swift +238 -0
- package/ios/EditorV2Adapter+Mutation.swift +392 -0
- package/ios/EditorV2Adapter+Registry.swift +185 -0
- package/ios/EditorV2Adapter+RenderState.swift +360 -0
- package/ios/EditorV2Adapter+RenderValidation.swift +420 -0
- package/ios/EditorV2Adapter+Selection.swift +329 -0
- package/ios/EditorV2Adapter+TextCommands.swift +430 -0
- package/ios/EditorV2Adapter.swift +376 -0
- package/ios/EditorV2Shadow.swift +353 -0
- package/ios/Generated_editor_core.swift +2378 -0
- package/ios/NativeCodeHighlighting.swift +159 -0
- package/ios/NativeCollaborationSocket.swift +144 -0
- package/ios/NativeCollaborationTransport+Protocol.swift +258 -0
- package/ios/NativeCollaborationTransport+Socket.swift +379 -0
- package/ios/NativeCollaborationTransport+Validation.swift +103 -0
- package/ios/NativeCollaborationTransport.swift +322 -0
- package/ios/NativeCollaborationTransportRegistry.swift +521 -0
- package/ios/NativeEditorExpoView+AccessoryRetry.swift +219 -0
- package/ios/NativeEditorExpoView+Binding.swift +268 -0
- package/ios/NativeEditorExpoView+Diagnostics.swift +66 -0
- package/ios/NativeEditorExpoView+Events.swift +131 -0
- package/ios/NativeEditorExpoView+Focus.swift +169 -0
- package/ios/NativeEditorExpoView+MentionRetry.swift +288 -0
- package/ios/NativeEditorExpoView+Mentions.swift +288 -0
- package/ios/NativeEditorExpoView+Properties.swift +300 -0
- package/ios/NativeEditorExpoView+Toolbar.swift +86 -0
- package/ios/NativeEditorExpoView+Updates.swift +312 -0
- package/ios/NativeEditorExpoView.swift +349 -0
- package/ios/NativeEditorModule.swift +856 -0
- package/ios/NativeEditorViewRegistry.swift +226 -0
- package/ios/NativeToolbar+ButtonStyle.swift +214 -0
- package/ios/NativeToolbar+Buttons.swift +228 -0
- package/ios/NativeToolbar+Diagnostics.swift +114 -0
- package/ios/NativeToolbar+Menu.swift +101 -0
- package/ios/NativeToolbar+Models.swift +519 -0
- package/ios/NativeToolbar+Placeholder.swift +39 -0
- package/ios/NativeToolbar.swift +612 -0
- package/ios/OrderedListMarkerFormatter.swift +103 -0
- package/ios/PositionBridge.swift +596 -0
- package/ios/ProseViewerView.swift +462 -0
- package/ios/RenderBridge+Atoms.swift +288 -0
- package/ios/RenderBridge+Attachments.swift +246 -0
- package/ios/RenderBridge+BlockBoundaries.swift +313 -0
- package/ios/RenderBridge+Style.swift +343 -0
- package/ios/RenderBridge.swift +704 -0
- package/ios/RichTextEditorView.swift +930 -0
- package/ios/SharedNativeImagePipeline+Cache.swift +189 -0
- package/ios/SharedNativeImagePipeline+Transport.swift +328 -0
- package/ios/SharedNativeImagePipeline.swift +533 -0
- package/ios/Viewer/CoreTextProseLayoutEngine+AttributedText.swift +436 -0
- package/ios/Viewer/CoreTextProseLayoutEngine+Models.swift +322 -0
- package/ios/Viewer/CoreTextProseLayoutEngine.swift +635 -0
- package/ios/Viewer/Fabric/PREPPreparedProseViewerComponentView.h +4 -0
- package/ios/Viewer/Fabric/PREPPreparedProseViewerComponentView.mm +767 -0
- package/ios/Viewer/Fabric/PreparedProseMeasurementsManager.mm +118 -0
- package/ios/Viewer/NativeSVGImageDecoder.h +9 -0
- package/ios/Viewer/NativeSVGImageDecoder.mm +106 -0
- package/ios/Viewer/NativeSVGPreflight.h +11 -0
- package/ios/Viewer/NativeSVGPreflight.mm +219 -0
- package/ios/Viewer/PreparedProseDrawingView.swift +639 -0
- package/ios/Viewer/PreparedProseInstrumentation.swift +387 -0
- package/ios/Viewer/PreparedProseLayout.swift +326 -0
- package/ios/Viewer/PreparedProseLayoutCache.swift +766 -0
- package/ios/Viewer/PreparedProseLayoutRegistry+Artifacts.swift +377 -0
- package/ios/Viewer/PreparedProseLayoutRegistry+Fabric.swift +582 -0
- package/ios/Viewer/PreparedProseLayoutRegistry+FabricOwnership.swift +128 -0
- package/ios/Viewer/PreparedProseLayoutRegistry.swift +381 -0
- package/ios/Viewer/ViewerDocument.swift +575 -0
- package/ios/Viewer/ViewerFontEnvironment.swift +283 -0
- package/ios/Viewer/ViewerImagePipeline.swift +478 -0
- package/ios/editor_coreFFI/editor_coreFFI.h +1023 -0
- package/ios/editor_coreFFI/module.modulemap +7 -0
- package/package.json +151 -0
- package/react-native.config.js +17 -0
- package/rust/android/arm64-v8a/libeditor_core.so +0 -0
- package/rust/android/armeabi-v7a/libeditor_core.so +0 -0
- package/rust/android/x86/libeditor_core.so +0 -0
- package/rust/android/x86_64/libeditor_core.so +0 -0
- package/rust/bindings/kotlin/uniffi/editor_core/editor_core.kt +3146 -0
- package/src/AtomHost.tsx +180 -0
- package/src/DefaultAtomChip.tsx +27 -0
- package/src/EditorAddon.ts +65 -0
- package/src/EditorAddonNormalization.ts +49 -0
- package/src/EditorMentionThemeNormalization.ts +25 -0
- package/src/EditorMentionThemeValidation.ts +133 -0
- package/src/EditorStyleSheet.ts +9 -0
- package/src/EditorStyleSheetNormalization.ts +219 -0
- package/src/EditorStyleSheetTypes.ts +189 -0
- package/src/EditorTheme.ts +196 -0
- package/src/EditorToolbar.tsx +31 -0
- package/src/EditorToolbarComponent.tsx +23 -0
- package/src/EditorToolbarItems.tsx +64 -0
- package/src/EditorToolbarRegistry.tsx +254 -0
- package/src/EditorToolbarTypes.tsx +322 -0
- package/src/EditorToolbarVisuals.tsx +270 -0
- package/src/EditorUpdateRevision.ts +26 -0
- package/src/ExternalTextComposition.ts +658 -0
- package/src/ImageLoadingPolicy.ts +125 -0
- package/src/NativeEditorBoundaryError.ts +345 -0
- package/src/NativeEditorBridge.ts +93 -0
- package/src/NativeEditorCollaborationTransport.ts +493 -0
- package/src/NativeEditorCreateConfig.ts +326 -0
- package/src/NativeEditorCreateJson.ts +579 -0
- package/src/NativeEditorCreateValidation.ts +178 -0
- package/src/NativeEditorDocumentBridge.ts +485 -0
- package/src/NativeEditorDocumentHandle.ts +168 -0
- package/src/NativeEditorLocalAwareness.ts +168 -0
- package/src/NativeEditorNativeModule.ts +97 -0
- package/src/NativeEditorRenderNormalization.ts +320 -0
- package/src/NativeEditorResultNormalization.ts +469 -0
- package/src/NativeEditorTypes.ts +366 -0
- package/src/NativeEditorV2Decimal.ts +13 -0
- package/src/NativeProseViewer.tsx +356 -0
- package/src/NativeRichTextEditor.tsx +33 -0
- package/src/ResourceLimits.ts +187 -0
- package/src/RichTextEditor.tsx +27 -0
- package/src/RichTextEditorNativeTypes.tsx +144 -0
- package/src/RichTextEditorNativeView.tsx +21 -0
- package/src/RichTextEditorSerialization.tsx +381 -0
- package/src/RichTextEditorTypes.tsx +327 -0
- package/src/ViewerConfiguration.ts +23 -0
- package/src/YjsCollaboration.ts +692 -0
- package/src/addons.ts +311 -0
- package/src/atomConstants.ts +3 -0
- package/src/atomInstances.ts +123 -0
- package/src/atomPolicy.ts +47 -0
- package/src/atomUpdates.ts +52 -0
- package/src/atoms.ts +379 -0
- package/src/attributeValidation.ts +116 -0
- package/src/contentExpression.ts +338 -0
- package/src/index.ts +295 -0
- package/src/listMarkers.ts +18 -0
- package/src/schemaDefinition.ts +395 -0
- package/src/schemaDocument.ts +92 -0
- package/src/schemaDocumentConstruction.ts +148 -0
- package/src/schemaNormalization.ts +367 -0
- package/src/schemaPresets.ts +250 -0
- package/src/schemaResolution.ts +242 -0
- package/src/schemas.ts +43 -0
- package/src/specs/PreparedProseViewerNativeComponent.ts +40 -0
- package/src/useEditorToolbarInteractions.tsx +329 -0
- package/src/useEditorToolbarItems.tsx +390 -0
- package/src/useEditorToolbarPresentation.tsx +483 -0
- package/src/useEditorToolbarState.tsx +172 -0
- package/src/useFocusPreservingFrames.ts +171 -0
- package/src/useNativeEditor.ts +534 -0
- package/src/useRichTextEditorCommands.tsx +478 -0
- package/src/useRichTextEditorEvents.tsx +342 -0
- package/src/useRichTextEditorMentions.tsx +441 -0
- package/src/useRichTextEditorPresentation.tsx +563 -0
- package/src/useRichTextEditorState.tsx +620 -0
- package/src/useRichTextEditorUpdates.tsx +403 -0
- package/src/useViewerAtoms.tsx +427 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { type DocumentJSON, type NativeCollaborationTransportConfig, type NativeEditorDocumentHandle, type NativeEditorPeerInfo, type Selection } from './NativeEditorBridge';
|
|
2
|
+
import type { RemoteSelectionDecoration } from './NativeRichTextEditor';
|
|
3
|
+
/**
|
|
4
|
+
* Transport lifecycle, projected from the Rust transport state.
|
|
5
|
+
*
|
|
6
|
+
* - `idle` — no transport configured; the handle is detached.
|
|
7
|
+
* - `disconnected` — configured but not currently connected.
|
|
8
|
+
* - `connecting` — opening the physical socket.
|
|
9
|
+
* - `handshaking` — socket open, Yjs sync in progress.
|
|
10
|
+
* - `synchronized` — sync complete; edits flow in both directions.
|
|
11
|
+
* - `incompatible` — the server's document cannot be reconciled with this one.
|
|
12
|
+
* - `destroyed` — the handle was destroyed.
|
|
13
|
+
*/
|
|
14
|
+
export type YjsTransportStatus = 'idle' | 'disconnected' | 'connecting' | 'handshaking' | 'synchronized' | 'incompatible' | 'destroyed';
|
|
15
|
+
/** Identity this client publishes to other peers through awareness. */
|
|
16
|
+
export interface LocalAwarenessUser {
|
|
17
|
+
/** Application-level user identity. */
|
|
18
|
+
userId: string;
|
|
19
|
+
/** Display name shown beside this user's remote caret. */
|
|
20
|
+
name: string;
|
|
21
|
+
/** Caret and label color, as a color string. */
|
|
22
|
+
color: string;
|
|
23
|
+
avatarUrl?: string;
|
|
24
|
+
/** Extra application data carried alongside the user record. */
|
|
25
|
+
extra?: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
/** The full local awareness record: who this client is, and where its caret sits. */
|
|
28
|
+
export interface LocalAwarenessState {
|
|
29
|
+
user: LocalAwarenessUser;
|
|
30
|
+
/** Local caret. Only a text selection is published; anything else clears the cursor. */
|
|
31
|
+
selection?: Selection;
|
|
32
|
+
/** Whether the editor currently holds focus. */
|
|
33
|
+
focused?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** Observable state of a collaboration session. */
|
|
36
|
+
export interface YjsCollaborationState {
|
|
37
|
+
documentId: string;
|
|
38
|
+
status: YjsTransportStatus;
|
|
39
|
+
/** True only while `status` is `'synchronized'`. */
|
|
40
|
+
isConnected: boolean;
|
|
41
|
+
/** Latest engine document, or null while awaiting the server's document. */
|
|
42
|
+
documentJson: DocumentJSON | null;
|
|
43
|
+
/** Decimal-string engine revision, or null while awaiting the server's document. */
|
|
44
|
+
documentRevision: string | null;
|
|
45
|
+
/** The most recent transport or engine failure, if any. */
|
|
46
|
+
lastError?: Error;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Configuration for {@link useYjsCollaboration} and
|
|
50
|
+
* {@link createYjsCollaborationController}.
|
|
51
|
+
*/
|
|
52
|
+
export interface YjsCollaborationOptions {
|
|
53
|
+
/** Room identity. Must match the `documentId` the handle was created with. */
|
|
54
|
+
documentId: string;
|
|
55
|
+
/** The shared document session. Create it with `initialization.type === 'room'`. */
|
|
56
|
+
handle: NativeEditorDocumentHandle;
|
|
57
|
+
/** Server endpoint and connect intent, or null to stay detached. */
|
|
58
|
+
transport: NativeCollaborationTransportConfig | null;
|
|
59
|
+
/** Identity published to other peers. Omit to join without presence. */
|
|
60
|
+
localAwareness?: LocalAwarenessUser;
|
|
61
|
+
/** Called whenever the peer list changes. */
|
|
62
|
+
onPeersChange?: (peers: NativeEditorPeerInfo[]) => void;
|
|
63
|
+
/** Called on every state transition. */
|
|
64
|
+
onStateChange?: (state: YjsCollaborationState) => void;
|
|
65
|
+
/** Called on transport and engine failures. */
|
|
66
|
+
onError?: (error: Error) => void;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Imperative collaboration session, for hosts outside React. The React entry
|
|
70
|
+
* point is {@link useYjsCollaboration}.
|
|
71
|
+
*/
|
|
72
|
+
export interface YjsCollaborationController {
|
|
73
|
+
readonly state: YjsCollaborationState;
|
|
74
|
+
readonly peers: NativeEditorPeerInfo[];
|
|
75
|
+
readonly documentHandle: NativeEditorDocumentHandle;
|
|
76
|
+
/** Open the transport. */
|
|
77
|
+
connect(): void;
|
|
78
|
+
/** Close the transport, keeping the document handle alive. */
|
|
79
|
+
disconnect(): void;
|
|
80
|
+
/** Close and reopen the transport. */
|
|
81
|
+
reconnect(): void;
|
|
82
|
+
/** Tear down the controller. Does not destroy the document handle. */
|
|
83
|
+
destroy(): void;
|
|
84
|
+
/** Publish a partial awareness update. Omitting `selection` keeps the published cursor. */
|
|
85
|
+
updateLocalAwareness(partial: Partial<LocalAwarenessState>): void;
|
|
86
|
+
/** Publish a new local caret position. */
|
|
87
|
+
handleSelectionChange(selection: Selection): void;
|
|
88
|
+
/** Publish a focus change. */
|
|
89
|
+
handleFocusChange(focused: boolean): void;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Props bound to one collaboration-aware editor view. There is no
|
|
93
|
+
* selection binding: the native adapters publish the local caret straight
|
|
94
|
+
* into Rust, which holds it as a sticky index. Mirroring it through
|
|
95
|
+
* JavaScript would only add a stale copy of a document position.
|
|
96
|
+
*/
|
|
97
|
+
export interface YjsCollaborationEditorBindings {
|
|
98
|
+
documentHandle: NativeEditorDocumentHandle;
|
|
99
|
+
documentRevision: string | null;
|
|
100
|
+
remoteSelections: RemoteSelectionDecoration[];
|
|
101
|
+
onFocus: () => void;
|
|
102
|
+
onBlur: () => void;
|
|
103
|
+
}
|
|
104
|
+
/** What {@link useYjsCollaboration} returns. */
|
|
105
|
+
export interface UseYjsCollaborationResult {
|
|
106
|
+
state: YjsCollaborationState;
|
|
107
|
+
/** Connected peers, including the local one. */
|
|
108
|
+
peers: NativeEditorPeerInfo[];
|
|
109
|
+
/** True only while the transport is synchronized. */
|
|
110
|
+
isConnected: boolean;
|
|
111
|
+
connect(): void;
|
|
112
|
+
disconnect(): void;
|
|
113
|
+
reconnect(): void;
|
|
114
|
+
updateLocalAwareness(partial: Partial<LocalAwarenessState>): void;
|
|
115
|
+
/** Spread onto `RichTextEditor` to bind the editor to this session. */
|
|
116
|
+
editorBindings: YjsCollaborationEditorBindings;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Create an imperative collaboration session over a room-backed document
|
|
120
|
+
* handle. The caller owns the lifecycle: call `destroy()` on the controller,
|
|
121
|
+
* then `destroy()` on the handle.
|
|
122
|
+
*
|
|
123
|
+
* React hosts should use {@link useYjsCollaboration} instead.
|
|
124
|
+
*/
|
|
125
|
+
export declare function createYjsCollaborationController(options: YjsCollaborationOptions): YjsCollaborationController;
|
|
126
|
+
/**
|
|
127
|
+
* Connect a room-backed document handle to a Yjs sync and awareness server.
|
|
128
|
+
* The editor and this hook must share the same handle; the hook never creates
|
|
129
|
+
* or destroys it.
|
|
130
|
+
*
|
|
131
|
+
* Native owns the socket and Rust owns sync, awareness, and retries, so there
|
|
132
|
+
* is no Yjs document in JavaScript to manage.
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```tsx
|
|
136
|
+
* const collaboration = useYjsCollaboration({
|
|
137
|
+
* documentId,
|
|
138
|
+
* handle: documentHandle,
|
|
139
|
+
* transport: { url: `wss://example.com/collab?documentId=${documentId}`, connect: true },
|
|
140
|
+
* localAwareness: { userId: 'user-1', name: 'Ada', color: '#0A84FF' },
|
|
141
|
+
* });
|
|
142
|
+
*
|
|
143
|
+
* return <RichTextEditor {...collaboration.editorBindings} />;
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export declare function useYjsCollaboration(options: YjsCollaborationOptions): UseYjsCollaborationResult;
|
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createYjsCollaborationController = createYjsCollaborationController;
|
|
4
|
+
exports.useYjsCollaboration = useYjsCollaboration;
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const NativeEditorBridge_1 = require("./NativeEditorBridge");
|
|
7
|
+
function mapTransportState(transport) {
|
|
8
|
+
switch (transport) {
|
|
9
|
+
case 'Detached':
|
|
10
|
+
return 'idle';
|
|
11
|
+
case 'Disconnected':
|
|
12
|
+
return 'disconnected';
|
|
13
|
+
case 'Connecting':
|
|
14
|
+
return 'connecting';
|
|
15
|
+
case 'Handshaking':
|
|
16
|
+
return 'handshaking';
|
|
17
|
+
case 'Synchronized':
|
|
18
|
+
return 'synchronized';
|
|
19
|
+
case 'Incompatible':
|
|
20
|
+
return 'incompatible';
|
|
21
|
+
case 'Destroying':
|
|
22
|
+
case 'Destroyed':
|
|
23
|
+
return 'destroyed';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function asError(value, fallbackMessage) {
|
|
27
|
+
return value instanceof Error ? value : new Error(fallbackMessage);
|
|
28
|
+
}
|
|
29
|
+
function isStrictlyNewerSequence(candidate, current) {
|
|
30
|
+
if (current === null)
|
|
31
|
+
return true;
|
|
32
|
+
if (candidate.length !== current.length)
|
|
33
|
+
return candidate.length > current.length;
|
|
34
|
+
return candidate > current;
|
|
35
|
+
}
|
|
36
|
+
function peersToRemoteSelections(peers) {
|
|
37
|
+
return peers.flatMap((peer) => {
|
|
38
|
+
if (peer.isLocal || peer.cursor == null)
|
|
39
|
+
return [];
|
|
40
|
+
const applicationState = peer.state && typeof peer.state.state === 'object' && peer.state.state !== null
|
|
41
|
+
? peer.state.state
|
|
42
|
+
: null;
|
|
43
|
+
const user = applicationState &&
|
|
44
|
+
typeof applicationState.user === 'object' &&
|
|
45
|
+
applicationState.user !== null
|
|
46
|
+
? applicationState.user
|
|
47
|
+
: null;
|
|
48
|
+
return [
|
|
49
|
+
{
|
|
50
|
+
clientId: peer.clientId,
|
|
51
|
+
anchor: peer.cursor.anchor,
|
|
52
|
+
head: peer.cursor.head,
|
|
53
|
+
color: typeof user?.color === 'string' && user.color.length > 0
|
|
54
|
+
? user.color
|
|
55
|
+
: '#007AFF',
|
|
56
|
+
name: typeof user?.name === 'string' && user.name.length > 0 ? user.name : undefined,
|
|
57
|
+
avatarUrl: typeof user?.avatarUrl === 'string' && user.avatarUrl.length > 0
|
|
58
|
+
? user.avatarUrl
|
|
59
|
+
: undefined,
|
|
60
|
+
isFocused: peer.state?.focused !== false,
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Narrow a caller selection to the text-only cursor awareness carries.
|
|
67
|
+
* Anything else — a node or all-document selection, or an absent one — is
|
|
68
|
+
* an explicit "no cursor", never a silently retained stale position.
|
|
69
|
+
*/
|
|
70
|
+
function normalizeAwarenessSelection(selection) {
|
|
71
|
+
if (selection === undefined || selection.type !== 'text')
|
|
72
|
+
return undefined;
|
|
73
|
+
if (selection.anchor === undefined || selection.head === undefined)
|
|
74
|
+
return undefined;
|
|
75
|
+
return (0, NativeEditorBridge_1.createNativeEditorLocalAwarenessSelection)(selection.anchor, selection.head);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Copy the caller's transport intent into a controller-owned record. A
|
|
79
|
+
* nullish config means "no transport": the handle stays detached, exactly
|
|
80
|
+
* as the transport-less reads elsewhere in this module assume.
|
|
81
|
+
*/
|
|
82
|
+
function copyTransportConfig(config) {
|
|
83
|
+
if (config == null)
|
|
84
|
+
return null;
|
|
85
|
+
return {
|
|
86
|
+
url: config.url,
|
|
87
|
+
connect: config.connect,
|
|
88
|
+
...(config.protocolAdapter === undefined
|
|
89
|
+
? {}
|
|
90
|
+
: { protocolAdapter: config.protocolAdapter }),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function copyLocalAwarenessUser(user) {
|
|
94
|
+
return {
|
|
95
|
+
userId: user.userId,
|
|
96
|
+
name: user.name,
|
|
97
|
+
color: user.color,
|
|
98
|
+
...(user.avatarUrl === undefined ? {} : { avatarUrl: user.avatarUrl }),
|
|
99
|
+
...(user.extra === undefined ? {} : { extra: user.extra }),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function localAwarenessDependencyKey(user) {
|
|
103
|
+
try {
|
|
104
|
+
return `json:${JSON.stringify(user ?? null)}`;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return 'invalid';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function mergeAwarenessPartial(base, partial) {
|
|
111
|
+
const state = { ...base.state };
|
|
112
|
+
if (partial.user != null) {
|
|
113
|
+
const baseUser = state.user != null && typeof state.user === 'object'
|
|
114
|
+
? state.user
|
|
115
|
+
: {};
|
|
116
|
+
state.user = copyLocalAwarenessUser({
|
|
117
|
+
...baseUser,
|
|
118
|
+
...partial.user,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
const next = {
|
|
122
|
+
state,
|
|
123
|
+
focused: 'focused' in partial && partial.focused !== undefined
|
|
124
|
+
? partial.focused
|
|
125
|
+
: base.focused,
|
|
126
|
+
};
|
|
127
|
+
// Selection is stated only when the caller states it. Rust holds the
|
|
128
|
+
// local cursor as a sticky index that already tracks every document
|
|
129
|
+
// change, so an omitted key means "retain it" — never "resend the last
|
|
130
|
+
// position I happened to see", which the document may have invalidated.
|
|
131
|
+
if ('selection' in partial) {
|
|
132
|
+
next.selection = normalizeAwarenessSelection(partial.selection) ?? null;
|
|
133
|
+
}
|
|
134
|
+
return next;
|
|
135
|
+
}
|
|
136
|
+
class YjsCollaborationControllerImpl {
|
|
137
|
+
constructor(options, callbacks = {}) {
|
|
138
|
+
this.removeTransportListener = null;
|
|
139
|
+
this.desiredAwareness = null;
|
|
140
|
+
/** Serialized form of the last intent Rust accepted, for dedup. */
|
|
141
|
+
this.publishedAwarenessJson = null;
|
|
142
|
+
this.lastEventSequence = null;
|
|
143
|
+
this.destroyed = false;
|
|
144
|
+
this._peers = [];
|
|
145
|
+
(0, NativeEditorBridge_1._assertNativeEditorDocumentHandle)(options.handle);
|
|
146
|
+
this.handle = options.handle;
|
|
147
|
+
this.documentId = options.documentId;
|
|
148
|
+
this.callbacks = callbacks;
|
|
149
|
+
this.transport = copyTransportConfig(options.transport);
|
|
150
|
+
this._state = this.readEngineState(this.handle.bridge.getState());
|
|
151
|
+
this.removeTransportListener = this.handle.addCollaborationTransportListener((event) => {
|
|
152
|
+
this.handleTransportEvent(event);
|
|
153
|
+
});
|
|
154
|
+
try {
|
|
155
|
+
this.applyLocalAwarenessOption(options.localAwareness);
|
|
156
|
+
this.handle.configureCollaborationTransport(this.transport);
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
this.removeTransportListener();
|
|
160
|
+
this.removeTransportListener = null;
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
get state() {
|
|
165
|
+
return this._state;
|
|
166
|
+
}
|
|
167
|
+
get peers() {
|
|
168
|
+
return this._peers;
|
|
169
|
+
}
|
|
170
|
+
get documentHandle() {
|
|
171
|
+
return this.handle;
|
|
172
|
+
}
|
|
173
|
+
connect() {
|
|
174
|
+
this.setConnectionEnabled(true);
|
|
175
|
+
}
|
|
176
|
+
disconnect() {
|
|
177
|
+
this.setConnectionEnabled(false);
|
|
178
|
+
}
|
|
179
|
+
reconnect() {
|
|
180
|
+
if (this.destroyed || this.transport === null)
|
|
181
|
+
return;
|
|
182
|
+
this.handle.configureCollaborationTransport({ ...this.transport, connect: false });
|
|
183
|
+
this.transport = { ...this.transport, connect: true };
|
|
184
|
+
this.handle.configureCollaborationTransport(this.transport);
|
|
185
|
+
}
|
|
186
|
+
destroy() {
|
|
187
|
+
if (this.destroyed)
|
|
188
|
+
return;
|
|
189
|
+
this.destroyed = true;
|
|
190
|
+
this.removeTransportListener?.();
|
|
191
|
+
this.removeTransportListener = null;
|
|
192
|
+
if (!this.handle.isDestroyed) {
|
|
193
|
+
this.handle.configureCollaborationTransport(null);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
updateLocalAwareness(partial) {
|
|
197
|
+
if (this.destroyed)
|
|
198
|
+
return;
|
|
199
|
+
// Presence exists only while there is a local user. Once awareness
|
|
200
|
+
// is withdrawn, focus and selection updates must not resurrect it
|
|
201
|
+
// as an anonymous entry; only a fresh user re-establishes it.
|
|
202
|
+
if (this.desiredAwareness === null && partial.user == null)
|
|
203
|
+
return;
|
|
204
|
+
const base = this.desiredAwareness ?? { state: {}, focused: false };
|
|
205
|
+
this.publishAwareness(mergeAwarenessPartial(base, partial));
|
|
206
|
+
}
|
|
207
|
+
handleSelectionChange(selection) {
|
|
208
|
+
this.updateLocalAwareness({ selection });
|
|
209
|
+
}
|
|
210
|
+
handleFocusChange(focused) {
|
|
211
|
+
this.updateLocalAwareness({ focused });
|
|
212
|
+
}
|
|
213
|
+
applyLocalAwarenessOption(user) {
|
|
214
|
+
if (this.destroyed)
|
|
215
|
+
return;
|
|
216
|
+
if (user == null) {
|
|
217
|
+
// Always withdraw: a fresh controller inherits whatever presence
|
|
218
|
+
// a previous one left retained natively on this shared handle.
|
|
219
|
+
try {
|
|
220
|
+
this.handle.setLocalAwareness(null);
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
this.reportError(asError(error, 'Local awareness withdrawal failed'));
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
this.desiredAwareness = null;
|
|
227
|
+
this.publishedAwarenessJson = null;
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const current = this.desiredAwareness;
|
|
231
|
+
// No `selection` key: the Rust-owned cursor carries across a user
|
|
232
|
+
// change untouched.
|
|
233
|
+
this.publishAwareness({
|
|
234
|
+
state: {
|
|
235
|
+
...(current?.state ?? {}),
|
|
236
|
+
user: copyLocalAwarenessUser(user),
|
|
237
|
+
},
|
|
238
|
+
focused: current?.focused ?? false,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
setConnectionEnabled(connect) {
|
|
242
|
+
if (this.destroyed || this.transport === null)
|
|
243
|
+
return;
|
|
244
|
+
this.transport = { ...this.transport, connect };
|
|
245
|
+
this.handle.configureCollaborationTransport(this.transport);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Hand one desired presence to Rust. An intent identical to the last
|
|
249
|
+
* accepted one is skipped: republishing it would mint a fresh awareness
|
|
250
|
+
* clock and broadcast a frame that carries no new information.
|
|
251
|
+
* `desiredAwareness` advances only after native acceptance.
|
|
252
|
+
*
|
|
253
|
+
* Presence is ambient UI state, not user data. A refusal is reported
|
|
254
|
+
* through `onError` and retried on the next change — it never escapes
|
|
255
|
+
* into a host focus, blur, or selection handler, and never fails an
|
|
256
|
+
* edit. The candidate is discarded so state stays consistent with Rust.
|
|
257
|
+
*/
|
|
258
|
+
publishAwareness(intent) {
|
|
259
|
+
let intentJson;
|
|
260
|
+
try {
|
|
261
|
+
// Serializing caller-owned application state can itself fail on
|
|
262
|
+
// a cyclic or non-encodable value, so it stays inside the guard.
|
|
263
|
+
intentJson = JSON.stringify(intent);
|
|
264
|
+
if (intentJson === this.publishedAwarenessJson)
|
|
265
|
+
return;
|
|
266
|
+
this.handle.setLocalAwareness(intent);
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
this.reportError(asError(error, 'Local awareness publication failed'));
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
this.desiredAwareness = intent;
|
|
273
|
+
this.publishedAwarenessJson = intentJson;
|
|
274
|
+
}
|
|
275
|
+
reportError(error) {
|
|
276
|
+
this.setState({ lastError: error });
|
|
277
|
+
this.callbacks.onError?.(error);
|
|
278
|
+
}
|
|
279
|
+
handleTransportEvent(event) {
|
|
280
|
+
if (this.destroyed ||
|
|
281
|
+
!isStrictlyNewerSequence(event.eventSequence, this.lastEventSequence)) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
this.lastEventSequence = event.eventSequence;
|
|
285
|
+
if (event.kind === 'error') {
|
|
286
|
+
const error = event.error ?? new Error('Native collaboration transport failed');
|
|
287
|
+
this.setState({ lastError: error });
|
|
288
|
+
this.callbacks.onError?.(error);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (event.kind !== 'state')
|
|
292
|
+
return;
|
|
293
|
+
this._peers = [...event.peers];
|
|
294
|
+
this.callbacks.onPeersChange?.(this._peers);
|
|
295
|
+
try {
|
|
296
|
+
this.setState({
|
|
297
|
+
...this.readEngineState(event.state, this._state),
|
|
298
|
+
lastError: undefined,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
catch (error) {
|
|
302
|
+
const nextError = asError(error, 'Native collaboration document refresh failed');
|
|
303
|
+
this.setState({ lastError: nextError });
|
|
304
|
+
this.callbacks.onError?.(nextError);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
readEngineState(engineState, previous) {
|
|
308
|
+
const awaitingRemote = engineState.documentState === 'AwaitRemote';
|
|
309
|
+
const documentJson = !awaitingRemote &&
|
|
310
|
+
previous?.documentRevision === engineState.documentRevision &&
|
|
311
|
+
previous.documentJson !== null
|
|
312
|
+
? previous.documentJson
|
|
313
|
+
: awaitingRemote
|
|
314
|
+
? null
|
|
315
|
+
: this.handle.bridge.getDocumentJson();
|
|
316
|
+
return {
|
|
317
|
+
documentId: this.documentId,
|
|
318
|
+
status: mapTransportState(engineState.transportState),
|
|
319
|
+
isConnected: engineState.transportState === 'Synchronized',
|
|
320
|
+
documentJson,
|
|
321
|
+
documentRevision: awaitingRemote ? null : engineState.documentRevision,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
setState(patch) {
|
|
325
|
+
this._state = { ...this._state, ...patch };
|
|
326
|
+
this.callbacks.onStateChange?.(this._state);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Create an imperative collaboration session over a room-backed document
|
|
331
|
+
* handle. The caller owns the lifecycle: call `destroy()` on the controller,
|
|
332
|
+
* then `destroy()` on the handle.
|
|
333
|
+
*
|
|
334
|
+
* React hosts should use {@link useYjsCollaboration} instead.
|
|
335
|
+
*/
|
|
336
|
+
function createYjsCollaborationController(options) {
|
|
337
|
+
return new YjsCollaborationControllerImpl(options, {
|
|
338
|
+
onStateChange: options.onStateChange,
|
|
339
|
+
onPeersChange: options.onPeersChange,
|
|
340
|
+
onError: options.onError,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Connect a room-backed document handle to a Yjs sync and awareness server.
|
|
345
|
+
* The editor and this hook must share the same handle; the hook never creates
|
|
346
|
+
* or destroys it.
|
|
347
|
+
*
|
|
348
|
+
* Native owns the socket and Rust owns sync, awareness, and retries, so there
|
|
349
|
+
* is no Yjs document in JavaScript to manage.
|
|
350
|
+
*
|
|
351
|
+
* @example
|
|
352
|
+
* ```tsx
|
|
353
|
+
* const collaboration = useYjsCollaboration({
|
|
354
|
+
* documentId,
|
|
355
|
+
* handle: documentHandle,
|
|
356
|
+
* transport: { url: `wss://example.com/collab?documentId=${documentId}`, connect: true },
|
|
357
|
+
* localAwareness: { userId: 'user-1', name: 'Ada', color: '#0A84FF' },
|
|
358
|
+
* });
|
|
359
|
+
*
|
|
360
|
+
* return <RichTextEditor {...collaboration.editorBindings} />;
|
|
361
|
+
* ```
|
|
362
|
+
*/
|
|
363
|
+
function useYjsCollaboration(options) {
|
|
364
|
+
(0, NativeEditorBridge_1._assertNativeEditorDocumentHandle)(options.handle);
|
|
365
|
+
const callbacksRef = (0, react_1.useRef)({});
|
|
366
|
+
callbacksRef.current = {
|
|
367
|
+
onPeersChange: options.onPeersChange,
|
|
368
|
+
onStateChange: options.onStateChange,
|
|
369
|
+
onError: options.onError,
|
|
370
|
+
};
|
|
371
|
+
const controllerRef = (0, react_1.useRef)(null);
|
|
372
|
+
const localAwarenessKey = localAwarenessDependencyKey(options.localAwareness);
|
|
373
|
+
const transportUrl = options.transport?.url ?? null;
|
|
374
|
+
const transportConnect = options.transport?.connect ?? false;
|
|
375
|
+
const transportProtocolAdapterRef = (0, react_1.useRef)(null);
|
|
376
|
+
transportProtocolAdapterRef.current = options.transport?.protocolAdapter ?? null;
|
|
377
|
+
const transportProtocolAdapterMetadata = JSON.stringify(options.transport?.protocolAdapter == null
|
|
378
|
+
? null
|
|
379
|
+
: {
|
|
380
|
+
protocols: options.transport.protocolAdapter.protocols,
|
|
381
|
+
timeoutMillis: options.transport.protocolAdapter.timeoutMillis,
|
|
382
|
+
terminalCloseCodes: options.transport.protocolAdapter.terminalCloseCodes,
|
|
383
|
+
});
|
|
384
|
+
const stableTransportProtocolAdapter = (0, react_1.useMemo)(() => {
|
|
385
|
+
const current = transportProtocolAdapterRef.current;
|
|
386
|
+
if (current === null)
|
|
387
|
+
return null;
|
|
388
|
+
return {
|
|
389
|
+
protocols: [...current.protocols],
|
|
390
|
+
...(current.timeoutMillis === undefined
|
|
391
|
+
? {}
|
|
392
|
+
: { timeoutMillis: current.timeoutMillis }),
|
|
393
|
+
...(current.terminalCloseCodes === undefined
|
|
394
|
+
? {}
|
|
395
|
+
: { terminalCloseCodes: [...current.terminalCloseCodes] }),
|
|
396
|
+
onOpen: (context) => transportProtocolAdapterRef.current?.onOpen(context) ?? {
|
|
397
|
+
action: 'reject',
|
|
398
|
+
},
|
|
399
|
+
onMessage: (context, frame) => transportProtocolAdapterRef.current?.onMessage(context, frame) ?? {
|
|
400
|
+
action: 'reject',
|
|
401
|
+
},
|
|
402
|
+
};
|
|
403
|
+
// Static metadata changes require a new native socket descriptor.
|
|
404
|
+
// Callback identity alone is read through the ref and never reconnects.
|
|
405
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
406
|
+
}, [transportProtocolAdapterMetadata]);
|
|
407
|
+
const [state, setState] = (0, react_1.useState)({
|
|
408
|
+
documentId: options.documentId,
|
|
409
|
+
status: 'idle',
|
|
410
|
+
isConnected: false,
|
|
411
|
+
documentJson: null,
|
|
412
|
+
documentRevision: null,
|
|
413
|
+
});
|
|
414
|
+
const [peers, setPeers] = (0, react_1.useState)([]);
|
|
415
|
+
(0, react_1.useEffect)(() => {
|
|
416
|
+
let controller;
|
|
417
|
+
try {
|
|
418
|
+
controller = new YjsCollaborationControllerImpl({
|
|
419
|
+
...options,
|
|
420
|
+
transport: options.transport == null
|
|
421
|
+
? null
|
|
422
|
+
: {
|
|
423
|
+
url: options.transport.url,
|
|
424
|
+
connect: options.transport.connect,
|
|
425
|
+
...(stableTransportProtocolAdapter === null
|
|
426
|
+
? {}
|
|
427
|
+
: { protocolAdapter: stableTransportProtocolAdapter }),
|
|
428
|
+
},
|
|
429
|
+
}, {
|
|
430
|
+
onStateChange: (nextState) => {
|
|
431
|
+
setState({ ...nextState });
|
|
432
|
+
callbacksRef.current.onStateChange?.(nextState);
|
|
433
|
+
},
|
|
434
|
+
onPeersChange: (nextPeers) => {
|
|
435
|
+
setPeers([...nextPeers]);
|
|
436
|
+
callbacksRef.current.onPeersChange?.(nextPeers);
|
|
437
|
+
},
|
|
438
|
+
onError: (error) => callbacksRef.current.onError?.(error),
|
|
439
|
+
});
|
|
440
|
+
controllerRef.current = controller;
|
|
441
|
+
setState({ ...controller.state });
|
|
442
|
+
setPeers([...controller.peers]);
|
|
443
|
+
}
|
|
444
|
+
catch (error) {
|
|
445
|
+
const nextError = asError(error, 'Native collaboration initialization failed');
|
|
446
|
+
controllerRef.current = null;
|
|
447
|
+
setState({
|
|
448
|
+
documentId: options.documentId,
|
|
449
|
+
status: 'idle',
|
|
450
|
+
isConnected: false,
|
|
451
|
+
documentJson: null,
|
|
452
|
+
documentRevision: null,
|
|
453
|
+
lastError: nextError,
|
|
454
|
+
});
|
|
455
|
+
setPeers([]);
|
|
456
|
+
callbacksRef.current.onError?.(nextError);
|
|
457
|
+
}
|
|
458
|
+
return () => {
|
|
459
|
+
controllerRef.current?.destroy();
|
|
460
|
+
controllerRef.current = null;
|
|
461
|
+
};
|
|
462
|
+
// The controller owns one URL/handle binding. Connection intent is
|
|
463
|
+
// updated independently below without recreating the observer.
|
|
464
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
465
|
+
}, [options.documentId, options.handle, stableTransportProtocolAdapter, transportUrl]);
|
|
466
|
+
(0, react_1.useEffect)(() => {
|
|
467
|
+
controllerRef.current?.applyLocalAwarenessOption(options.localAwareness);
|
|
468
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
469
|
+
}, [localAwarenessKey]);
|
|
470
|
+
(0, react_1.useEffect)(() => {
|
|
471
|
+
if (transportUrl === null)
|
|
472
|
+
return;
|
|
473
|
+
if (transportConnect) {
|
|
474
|
+
controllerRef.current?.connect();
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
controllerRef.current?.disconnect();
|
|
478
|
+
}
|
|
479
|
+
}, [transportConnect, stableTransportProtocolAdapter, transportUrl]);
|
|
480
|
+
return {
|
|
481
|
+
state,
|
|
482
|
+
peers,
|
|
483
|
+
isConnected: state.isConnected,
|
|
484
|
+
connect: () => controllerRef.current?.connect(),
|
|
485
|
+
disconnect: () => controllerRef.current?.disconnect(),
|
|
486
|
+
reconnect: () => controllerRef.current?.reconnect(),
|
|
487
|
+
updateLocalAwareness: (partial) => controllerRef.current?.updateLocalAwareness(partial),
|
|
488
|
+
editorBindings: {
|
|
489
|
+
documentHandle: options.handle,
|
|
490
|
+
documentRevision: state.documentRevision,
|
|
491
|
+
remoteSelections: peersToRemoteSelections(peers),
|
|
492
|
+
onFocus: () => controllerRef.current?.handleFocusChange(true),
|
|
493
|
+
onBlur: () => controllerRef.current?.handleFocusChange(false),
|
|
494
|
+
},
|
|
495
|
+
};
|
|
496
|
+
}
|