@apollohg/react-native-prose-editor 0.4.0 → 0.4.1

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 (30) hide show
  1. package/README.md +18 -0
  2. package/android/build.gradle +23 -0
  3. package/android/src/main/java/com/apollohg/editor/EditorEditText.kt +502 -39
  4. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoView.kt +56 -28
  5. package/android/src/main/java/com/apollohg/editor/NativeEditorModule.kt +6 -0
  6. package/android/src/main/java/com/apollohg/editor/PositionBridge.kt +57 -27
  7. package/android/src/main/java/com/apollohg/editor/RemoteSelectionOverlayView.kt +147 -78
  8. package/android/src/main/java/com/apollohg/editor/RenderBridge.kt +249 -71
  9. package/android/src/main/java/com/apollohg/editor/RichTextEditorView.kt +7 -6
  10. package/dist/NativeEditorBridge.d.ts +36 -1
  11. package/dist/NativeEditorBridge.js +173 -94
  12. package/dist/NativeRichTextEditor.d.ts +2 -0
  13. package/dist/NativeRichTextEditor.js +160 -53
  14. package/dist/YjsCollaboration.d.ts +2 -0
  15. package/dist/YjsCollaboration.js +142 -20
  16. package/ios/EditorCore.xcframework/ios-arm64/libeditor_core.a +0 -0
  17. package/ios/EditorCore.xcframework/ios-arm64_x86_64-simulator/libeditor_core.a +0 -0
  18. package/ios/EditorLayoutManager.swift +3 -3
  19. package/ios/Generated_editor_core.swift +41 -0
  20. package/ios/NativeEditorExpoView.swift +43 -11
  21. package/ios/NativeEditorModule.swift +6 -0
  22. package/ios/PositionBridge.swift +310 -75
  23. package/ios/RenderBridge.swift +362 -27
  24. package/ios/RichTextEditorView.swift +1983 -187
  25. package/ios/editor_coreFFI/editor_coreFFI.h +33 -0
  26. package/package.json +11 -2
  27. package/rust/android/arm64-v8a/libeditor_core.so +0 -0
  28. package/rust/android/armeabi-v7a/libeditor_core.so +0 -0
  29. package/rust/android/x86_64/libeditor_core.so +0 -0
  30. package/rust/bindings/kotlin/uniffi/editor_core/editor_core.kt +63 -0
@@ -337,6 +337,11 @@ uint64_t uniffi_editor_core_fn_func_editor_create(RustBuffer config_json, RustCa
337
337
  RustBuffer uniffi_editor_core_fn_func_editor_delete_and_split_scalar(uint64_t id, uint32_t scalar_from, uint32_t scalar_to, RustCallStatus *_Nonnull out_status
338
338
  );
339
339
  #endif
340
+ #ifndef UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_FN_FUNC_EDITOR_DELETE_BACKWARD_AT_SELECTION_SCALAR
341
+ #define UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_FN_FUNC_EDITOR_DELETE_BACKWARD_AT_SELECTION_SCALAR
342
+ RustBuffer uniffi_editor_core_fn_func_editor_delete_backward_at_selection_scalar(uint64_t id, uint32_t scalar_anchor, uint32_t scalar_head, RustCallStatus *_Nonnull out_status
343
+ );
344
+ #endif
340
345
  #ifndef UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_FN_FUNC_EDITOR_DELETE_RANGE
341
346
  #define UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_FN_FUNC_EDITOR_DELETE_RANGE
342
347
  RustBuffer uniffi_editor_core_fn_func_editor_delete_range(uint64_t id, uint32_t from, uint32_t to, RustCallStatus *_Nonnull out_status
@@ -357,6 +362,11 @@ void uniffi_editor_core_fn_func_editor_destroy(uint64_t id, RustCallStatus *_Non
357
362
  uint32_t uniffi_editor_core_fn_func_editor_doc_to_scalar(uint64_t id, uint32_t doc_pos, RustCallStatus *_Nonnull out_status
358
363
  );
359
364
  #endif
365
+ #ifndef UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_FN_FUNC_EDITOR_GET_CONTENT_SNAPSHOT
366
+ #define UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_FN_FUNC_EDITOR_GET_CONTENT_SNAPSHOT
367
+ RustBuffer uniffi_editor_core_fn_func_editor_get_content_snapshot(uint64_t id, RustCallStatus *_Nonnull out_status
368
+ );
369
+ #endif
360
370
  #ifndef UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_FN_FUNC_EDITOR_GET_CURRENT_STATE
361
371
  #define UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_FN_FUNC_EDITOR_GET_CURRENT_STATE
362
372
  RustBuffer uniffi_editor_core_fn_func_editor_get_current_state(uint64_t id, RustCallStatus *_Nonnull out_status
@@ -377,6 +387,11 @@ RustBuffer uniffi_editor_core_fn_func_editor_get_json(uint64_t id, RustCallStatu
377
387
  RustBuffer uniffi_editor_core_fn_func_editor_get_selection(uint64_t id, RustCallStatus *_Nonnull out_status
378
388
  );
379
389
  #endif
390
+ #ifndef UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_FN_FUNC_EDITOR_GET_SELECTION_STATE
391
+ #define UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_FN_FUNC_EDITOR_GET_SELECTION_STATE
392
+ RustBuffer uniffi_editor_core_fn_func_editor_get_selection_state(uint64_t id, RustCallStatus *_Nonnull out_status
393
+ );
394
+ #endif
380
395
  #ifndef UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_FN_FUNC_EDITOR_INDENT_LIST_ITEM
381
396
  #define UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_FN_FUNC_EDITOR_INDENT_LIST_ITEM
382
397
  RustBuffer uniffi_editor_core_fn_func_editor_indent_list_item(uint64_t id, RustCallStatus *_Nonnull out_status
@@ -952,6 +967,12 @@ uint16_t uniffi_editor_core_checksum_func_editor_create(void
952
967
  #define UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_CHECKSUM_FUNC_EDITOR_DELETE_AND_SPLIT_SCALAR
953
968
  uint16_t uniffi_editor_core_checksum_func_editor_delete_and_split_scalar(void
954
969
 
970
+ );
971
+ #endif
972
+ #ifndef UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_CHECKSUM_FUNC_EDITOR_DELETE_BACKWARD_AT_SELECTION_SCALAR
973
+ #define UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_CHECKSUM_FUNC_EDITOR_DELETE_BACKWARD_AT_SELECTION_SCALAR
974
+ uint16_t uniffi_editor_core_checksum_func_editor_delete_backward_at_selection_scalar(void
975
+
955
976
  );
956
977
  #endif
957
978
  #ifndef UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_CHECKSUM_FUNC_EDITOR_DELETE_RANGE
@@ -976,6 +997,12 @@ uint16_t uniffi_editor_core_checksum_func_editor_destroy(void
976
997
  #define UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_CHECKSUM_FUNC_EDITOR_DOC_TO_SCALAR
977
998
  uint16_t uniffi_editor_core_checksum_func_editor_doc_to_scalar(void
978
999
 
1000
+ );
1001
+ #endif
1002
+ #ifndef UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_CHECKSUM_FUNC_EDITOR_GET_CONTENT_SNAPSHOT
1003
+ #define UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_CHECKSUM_FUNC_EDITOR_GET_CONTENT_SNAPSHOT
1004
+ uint16_t uniffi_editor_core_checksum_func_editor_get_content_snapshot(void
1005
+
979
1006
  );
980
1007
  #endif
981
1008
  #ifndef UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_CHECKSUM_FUNC_EDITOR_GET_CURRENT_STATE
@@ -1000,6 +1027,12 @@ uint16_t uniffi_editor_core_checksum_func_editor_get_json(void
1000
1027
  #define UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_CHECKSUM_FUNC_EDITOR_GET_SELECTION
1001
1028
  uint16_t uniffi_editor_core_checksum_func_editor_get_selection(void
1002
1029
 
1030
+ );
1031
+ #endif
1032
+ #ifndef UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_CHECKSUM_FUNC_EDITOR_GET_SELECTION_STATE
1033
+ #define UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_CHECKSUM_FUNC_EDITOR_GET_SELECTION_STATE
1034
+ uint16_t uniffi_editor_core_checksum_func_editor_get_selection_state(void
1035
+
1003
1036
  );
1004
1037
  #endif
1005
1038
  #ifndef UNIFFI_FFIDEF_UNIFFI_EDITOR_CORE_CHECKSUM_FUNC_EDITOR_INDENT_LIST_ITEM
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apollohg/react-native-prose-editor",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Native rich text editor with Rust core for React Native",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/apollohg/react-native-prose-editor",
@@ -30,11 +30,21 @@
30
30
  "build": "tsc -p tsconfig.build.json",
31
31
  "prepack": "npm run build",
32
32
  "test": "jest --runInBand --watchman=false",
33
+ "bench:rust": "cargo bench --manifest-path rust/editor-core/Cargo.toml --bench perf_suite --",
34
+ "bench:rust:quick": "cargo bench --manifest-path rust/editor-core/Cargo.toml --bench perf_suite -- --quick",
33
35
  "typecheck": "tsc --noEmit",
34
36
  "sync:version": "node scripts/sync-version.mjs",
37
+ "publish:prepare": "bash ./scripts/prepare-publish.sh",
35
38
  "version": "node scripts/sync-version.mjs",
36
39
  "android:compile": "cd example/android && ./gradlew :apollohg-react-native-prose-editor:compileDebugKotlin",
37
40
  "android:test": "cd example/android && ./gradlew :apollohg-react-native-prose-editor:testDebugUnitTest",
41
+ "android:test:perf": "cd example/android && ./gradlew :apollohg-react-native-prose-editor:testDebugUnitTest -PapollohgShowPerfTestOutput=true --tests com.apollohg.editor.NativePerformanceTest",
42
+ "android:test:device": "bash ./scripts/run-android-on-device.sh",
43
+ "android:test:perf:device": "bash ./scripts/run-android-on-device.sh --class com.apollohg.editor.NativeDevicePerformanceTest",
44
+ "ios:test": "bash ./scripts/run-ios-tests.sh",
45
+ "ios:test:perf": "bash ./scripts/run-ios-tests.sh -only-testing:NativeEditorTests/NativePerformanceTests",
46
+ "ios:test:device": "bash ./scripts/run-ios-on-device.sh",
47
+ "ios:test:perf:device": "bash ./scripts/run-ios-on-device.sh -only-testing:NativeEditorTests/NativePerformanceTests",
38
48
  "android:assemble": "cd example/android && ./gradlew app:assembleDebug -x lint -x test --configure-on-demand --build-cache -PreactNativeDevServerPort=8081 -PreactNativeArchitectures=arm64-v8a",
39
49
  "example:prebuild": "npm --prefix example run prebuild",
40
50
  "example:start": "npm --prefix example start",
@@ -47,7 +57,6 @@
47
57
  "peerDependencies": {
48
58
  "@expo/vector-icons": ">=14.0.0",
49
59
  "expo": ">=52.0.0",
50
- "expo-modules-core": ">=2.0.0",
51
60
  "react": ">=18.0.0",
52
61
  "react-native": ">=0.76.0"
53
62
  },
@@ -832,6 +832,12 @@ internal interface UniffiForeignFutureCompleteVoid : com.sun.jna.Callback {
832
832
 
833
833
 
834
834
 
835
+
836
+
837
+
838
+
839
+
840
+
835
841
 
836
842
 
837
843
 
@@ -888,6 +894,8 @@ fun uniffi_editor_core_checksum_func_editor_create(
888
894
  ): Short
889
895
  fun uniffi_editor_core_checksum_func_editor_delete_and_split_scalar(
890
896
  ): Short
897
+ fun uniffi_editor_core_checksum_func_editor_delete_backward_at_selection_scalar(
898
+ ): Short
891
899
  fun uniffi_editor_core_checksum_func_editor_delete_range(
892
900
  ): Short
893
901
  fun uniffi_editor_core_checksum_func_editor_delete_scalar_range(
@@ -896,6 +904,8 @@ fun uniffi_editor_core_checksum_func_editor_destroy(
896
904
  ): Short
897
905
  fun uniffi_editor_core_checksum_func_editor_doc_to_scalar(
898
906
  ): Short
907
+ fun uniffi_editor_core_checksum_func_editor_get_content_snapshot(
908
+ ): Short
899
909
  fun uniffi_editor_core_checksum_func_editor_get_current_state(
900
910
  ): Short
901
911
  fun uniffi_editor_core_checksum_func_editor_get_html(
@@ -904,6 +914,8 @@ fun uniffi_editor_core_checksum_func_editor_get_json(
904
914
  ): Short
905
915
  fun uniffi_editor_core_checksum_func_editor_get_selection(
906
916
  ): Short
917
+ fun uniffi_editor_core_checksum_func_editor_get_selection_state(
918
+ ): Short
907
919
  fun uniffi_editor_core_checksum_func_editor_indent_list_item(
908
920
  ): Short
909
921
  fun uniffi_editor_core_checksum_func_editor_indent_list_item_at_selection_scalar(
@@ -1061,6 +1073,8 @@ fun uniffi_editor_core_fn_func_editor_create(`configJson`: RustBuffer.ByValue,un
1061
1073
  ): Long
1062
1074
  fun uniffi_editor_core_fn_func_editor_delete_and_split_scalar(`id`: Long,`scalarFrom`: Int,`scalarTo`: Int,uniffi_out_err: UniffiRustCallStatus,
1063
1075
  ): RustBuffer.ByValue
1076
+ fun uniffi_editor_core_fn_func_editor_delete_backward_at_selection_scalar(`id`: Long,`scalarAnchor`: Int,`scalarHead`: Int,uniffi_out_err: UniffiRustCallStatus,
1077
+ ): RustBuffer.ByValue
1064
1078
  fun uniffi_editor_core_fn_func_editor_delete_range(`id`: Long,`from`: Int,`to`: Int,uniffi_out_err: UniffiRustCallStatus,
1065
1079
  ): RustBuffer.ByValue
1066
1080
  fun uniffi_editor_core_fn_func_editor_delete_scalar_range(`id`: Long,`scalarFrom`: Int,`scalarTo`: Int,uniffi_out_err: UniffiRustCallStatus,
@@ -1069,6 +1083,8 @@ fun uniffi_editor_core_fn_func_editor_destroy(`id`: Long,uniffi_out_err: UniffiR
1069
1083
  ): Unit
1070
1084
  fun uniffi_editor_core_fn_func_editor_doc_to_scalar(`id`: Long,`docPos`: Int,uniffi_out_err: UniffiRustCallStatus,
1071
1085
  ): Int
1086
+ fun uniffi_editor_core_fn_func_editor_get_content_snapshot(`id`: Long,uniffi_out_err: UniffiRustCallStatus,
1087
+ ): RustBuffer.ByValue
1072
1088
  fun uniffi_editor_core_fn_func_editor_get_current_state(`id`: Long,uniffi_out_err: UniffiRustCallStatus,
1073
1089
  ): RustBuffer.ByValue
1074
1090
  fun uniffi_editor_core_fn_func_editor_get_html(`id`: Long,uniffi_out_err: UniffiRustCallStatus,
@@ -1077,6 +1093,8 @@ fun uniffi_editor_core_fn_func_editor_get_json(`id`: Long,uniffi_out_err: Uniffi
1077
1093
  ): RustBuffer.ByValue
1078
1094
  fun uniffi_editor_core_fn_func_editor_get_selection(`id`: Long,uniffi_out_err: UniffiRustCallStatus,
1079
1095
  ): RustBuffer.ByValue
1096
+ fun uniffi_editor_core_fn_func_editor_get_selection_state(`id`: Long,uniffi_out_err: UniffiRustCallStatus,
1097
+ ): RustBuffer.ByValue
1080
1098
  fun uniffi_editor_core_fn_func_editor_indent_list_item(`id`: Long,uniffi_out_err: UniffiRustCallStatus,
1081
1099
  ): RustBuffer.ByValue
1082
1100
  fun uniffi_editor_core_fn_func_editor_indent_list_item_at_selection_scalar(`id`: Long,`scalarAnchor`: Int,`scalarHead`: Int,uniffi_out_err: UniffiRustCallStatus,
@@ -1332,6 +1350,9 @@ private fun uniffiCheckApiChecksums(lib: IntegrityCheckingUniffiLib) {
1332
1350
  if (lib.uniffi_editor_core_checksum_func_editor_delete_and_split_scalar() != 13764.toShort()) {
1333
1351
  throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
1334
1352
  }
1353
+ if (lib.uniffi_editor_core_checksum_func_editor_delete_backward_at_selection_scalar() != 7697.toShort()) {
1354
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
1355
+ }
1335
1356
  if (lib.uniffi_editor_core_checksum_func_editor_delete_range() != 6109.toShort()) {
1336
1357
  throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
1337
1358
  }
@@ -1344,6 +1365,9 @@ private fun uniffiCheckApiChecksums(lib: IntegrityCheckingUniffiLib) {
1344
1365
  if (lib.uniffi_editor_core_checksum_func_editor_doc_to_scalar() != 48291.toShort()) {
1345
1366
  throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
1346
1367
  }
1368
+ if (lib.uniffi_editor_core_checksum_func_editor_get_content_snapshot() != 32837.toShort()) {
1369
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
1370
+ }
1347
1371
  if (lib.uniffi_editor_core_checksum_func_editor_get_current_state() != 13946.toShort()) {
1348
1372
  throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
1349
1373
  }
@@ -1356,6 +1380,9 @@ private fun uniffiCheckApiChecksums(lib: IntegrityCheckingUniffiLib) {
1356
1380
  if (lib.uniffi_editor_core_checksum_func_editor_get_selection() != 20571.toShort()) {
1357
1381
  throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
1358
1382
  }
1383
+ if (lib.uniffi_editor_core_checksum_func_editor_get_selection_state() != 16471.toShort()) {
1384
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
1385
+ }
1359
1386
  if (lib.uniffi_editor_core_checksum_func_editor_indent_list_item() != 10818.toShort()) {
1360
1387
  throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
1361
1388
  }
@@ -1913,6 +1940,18 @@ public object FfiConverterString: FfiConverter<String, RustBuffer.ByValue> {
1913
1940
  }
1914
1941
 
1915
1942
 
1943
+ /**
1944
+ * Delete backward relative to an explicit scalar selection. Returns an update JSON string.
1945
+ */ fun `editorDeleteBackwardAtSelectionScalar`(`id`: kotlin.ULong, `scalarAnchor`: kotlin.UInt, `scalarHead`: kotlin.UInt): kotlin.String {
1946
+ return FfiConverterString.lift(
1947
+ uniffiRustCall() { _status ->
1948
+ UniffiLib.INSTANCE.uniffi_editor_core_fn_func_editor_delete_backward_at_selection_scalar(
1949
+ FfiConverterULong.lower(`id`),FfiConverterUInt.lower(`scalarAnchor`),FfiConverterUInt.lower(`scalarHead`),_status)
1950
+ }
1951
+ )
1952
+ }
1953
+
1954
+
1916
1955
  /**
1917
1956
  * Delete a range. Returns an update JSON string.
1918
1957
  */ fun `editorDeleteRange`(`id`: kotlin.ULong, `from`: kotlin.UInt, `to`: kotlin.UInt): kotlin.String {
@@ -1960,6 +1999,18 @@ public object FfiConverterString: FfiConverter<String, RustBuffer.ByValue> {
1960
1999
  }
1961
2000
 
1962
2001
 
2002
+ /**
2003
+ * Get both HTML and ProseMirror JSON content in one payload.
2004
+ */ fun `editorGetContentSnapshot`(`id`: kotlin.ULong): kotlin.String {
2005
+ return FfiConverterString.lift(
2006
+ uniffiRustCall() { _status ->
2007
+ UniffiLib.INSTANCE.uniffi_editor_core_fn_func_editor_get_content_snapshot(
2008
+ FfiConverterULong.lower(`id`),_status)
2009
+ }
2010
+ )
2011
+ }
2012
+
2013
+
1963
2014
  /**
1964
2015
  * Get the current editor state (render elements, selection, active state,
1965
2016
  * history state) without performing any edits. Used by native views to pull
@@ -2010,6 +2061,18 @@ public object FfiConverterString: FfiConverter<String, RustBuffer.ByValue> {
2010
2061
  }
2011
2062
 
2012
2063
 
2064
+ /**
2065
+ * Get the current selection-related editor state without render elements.
2066
+ */ fun `editorGetSelectionState`(`id`: kotlin.ULong): kotlin.String {
2067
+ return FfiConverterString.lift(
2068
+ uniffiRustCall() { _status ->
2069
+ UniffiLib.INSTANCE.uniffi_editor_core_fn_func_editor_get_selection_state(
2070
+ FfiConverterULong.lower(`id`),_status)
2071
+ }
2072
+ )
2073
+ }
2074
+
2075
+
2013
2076
  /**
2014
2077
  * Indent the current list item into a nested list. Returns an update JSON string.
2015
2078
  */ fun `editorIndentListItem`(`id`: kotlin.ULong): kotlin.String {