@actualwave/react-native-codeditor 1.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 (210) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +790 -0
  3. package/app.plugin.js +133 -0
  4. package/lib/module/BlockingView.js +25 -0
  5. package/lib/module/CodeEditor.js +239 -0
  6. package/lib/module/EditorAPI.js +2 -0
  7. package/lib/module/WebViewAPI.js +133 -0
  8. package/lib/module/index.js +6 -0
  9. package/lib/module/package.json +1 -0
  10. package/lib/typescript/app.plugin.d.ts +3 -0
  11. package/lib/typescript/babel.config.d.ts +10 -0
  12. package/lib/typescript/package.json +1 -0
  13. package/lib/typescript/react-native.config.d.ts +2 -0
  14. package/lib/typescript/scripts/copy-assets.d.ts +2 -0
  15. package/lib/typescript/src/BlockingView.d.ts +3 -0
  16. package/lib/typescript/src/CodeEditor.d.ts +33 -0
  17. package/lib/typescript/src/EditorAPI.d.ts +66 -0
  18. package/lib/typescript/src/WebViewAPI.d.ts +46 -0
  19. package/lib/typescript/src/index.d.ts +7 -0
  20. package/package.json +106 -0
  21. package/react-native.config.js +3 -0
  22. package/src/assets/codemirror/@actualwave_codemirror-lang-sksl.js +15 -0
  23. package/src/assets/codemirror/@babel_runtime_helpers_interopRequireDefault.js +1 -0
  24. package/src/assets/codemirror/@babel_runtime_helpers_objectSpread2.js +1 -0
  25. package/src/assets/codemirror/@babel_runtime_helpers_toConsumableArray.js +1 -0
  26. package/src/assets/codemirror/@codemirror_autocomplete.js +206 -0
  27. package/src/assets/codemirror/@codemirror_collab.js +31 -0
  28. package/src/assets/codemirror/@codemirror_commands.js +411 -0
  29. package/src/assets/codemirror/@codemirror_lang-angular.js +7 -0
  30. package/src/assets/codemirror/@codemirror_lang-cpp.js +7 -0
  31. package/src/assets/codemirror/@codemirror_lang-css.js +14 -0
  32. package/src/assets/codemirror/@codemirror_lang-go.js +13 -0
  33. package/src/assets/codemirror/@codemirror_lang-html.js +20 -0
  34. package/src/assets/codemirror/@codemirror_lang-java.js +7 -0
  35. package/src/assets/codemirror/@codemirror_lang-javascript.js +54 -0
  36. package/src/assets/codemirror/@codemirror_lang-jinja.js +15 -0
  37. package/src/assets/codemirror/@codemirror_lang-json.js +10 -0
  38. package/src/assets/codemirror/@codemirror_lang-less.js +10 -0
  39. package/src/assets/codemirror/@codemirror_lang-lezer.js +7 -0
  40. package/src/assets/codemirror/@codemirror_lang-liquid.js +15 -0
  41. package/src/assets/codemirror/@codemirror_lang-markdown.js +55 -0
  42. package/src/assets/codemirror/@codemirror_lang-php.js +7 -0
  43. package/src/assets/codemirror/@codemirror_lang-python.js +19 -0
  44. package/src/assets/codemirror/@codemirror_lang-rust.js +7 -0
  45. package/src/assets/codemirror/@codemirror_lang-sass.js +10 -0
  46. package/src/assets/codemirror/@codemirror_lang-sql.js +52 -0
  47. package/src/assets/codemirror/@codemirror_lang-vue.js +6 -0
  48. package/src/assets/codemirror/@codemirror_lang-wast.js +2 -0
  49. package/src/assets/codemirror/@codemirror_lang-xml.js +13 -0
  50. package/src/assets/codemirror/@codemirror_lang-yaml.js +13 -0
  51. package/src/assets/codemirror/@codemirror_language-data.js +5 -0
  52. package/src/assets/codemirror/@codemirror_language.js +524 -0
  53. package/src/assets/codemirror/@codemirror_legacy-modes_mode_apl.js +1 -0
  54. package/src/assets/codemirror/@codemirror_legacy-modes_mode_asciiarmor.js +1 -0
  55. package/src/assets/codemirror/@codemirror_legacy-modes_mode_asn1.js +3 -0
  56. package/src/assets/codemirror/@codemirror_legacy-modes_mode_asterisk.js +9 -0
  57. package/src/assets/codemirror/@codemirror_legacy-modes_mode_brainfuck.js +13 -0
  58. package/src/assets/codemirror/@codemirror_legacy-modes_mode_clike.js +31 -0
  59. package/src/assets/codemirror/@codemirror_legacy-modes_mode_clojure.js +5 -0
  60. package/src/assets/codemirror/@codemirror_legacy-modes_mode_cmake.js +6 -0
  61. package/src/assets/codemirror/@codemirror_legacy-modes_mode_cobol.js +7 -0
  62. package/src/assets/codemirror/@codemirror_legacy-modes_mode_coffeescript.js +14 -0
  63. package/src/assets/codemirror/@codemirror_legacy-modes_mode_commonlisp.js +1 -0
  64. package/src/assets/codemirror/@codemirror_legacy-modes_mode_crystal.js +18 -0
  65. package/src/assets/codemirror/@codemirror_legacy-modes_mode_css.js +5 -0
  66. package/src/assets/codemirror/@codemirror_legacy-modes_mode_cypher.js +1 -0
  67. package/src/assets/codemirror/@codemirror_legacy-modes_mode_d.js +2 -0
  68. package/src/assets/codemirror/@codemirror_legacy-modes_mode_diff.js +1 -0
  69. package/src/assets/codemirror/@codemirror_legacy-modes_mode_dockerfile.js +9 -0
  70. package/src/assets/codemirror/@codemirror_legacy-modes_mode_dtd.js +3 -0
  71. package/src/assets/codemirror/@codemirror_legacy-modes_mode_dylan.js +35 -0
  72. package/src/assets/codemirror/@codemirror_legacy-modes_mode_ebnf.js +9 -0
  73. package/src/assets/codemirror/@codemirror_legacy-modes_mode_ecl.js +3 -0
  74. package/src/assets/codemirror/@codemirror_legacy-modes_mode_eiffel.js +1 -0
  75. package/src/assets/codemirror/@codemirror_legacy-modes_mode_elm.js +3 -0
  76. package/src/assets/codemirror/@codemirror_legacy-modes_mode_erlang.js +52 -0
  77. package/src/assets/codemirror/@codemirror_legacy-modes_mode_factor.js +14 -0
  78. package/src/assets/codemirror/@codemirror_legacy-modes_mode_fcl.js +2 -0
  79. package/src/assets/codemirror/@codemirror_legacy-modes_mode_forth.js +5 -0
  80. package/src/assets/codemirror/@codemirror_legacy-modes_mode_fortran.js +2 -0
  81. package/src/assets/codemirror/@codemirror_legacy-modes_mode_gas.js +13 -0
  82. package/src/assets/codemirror/@codemirror_legacy-modes_mode_gherkin.js +5 -0
  83. package/src/assets/codemirror/@codemirror_legacy-modes_mode_go.js +2 -0
  84. package/src/assets/codemirror/@codemirror_legacy-modes_mode_groovy.js +3 -0
  85. package/src/assets/codemirror/@codemirror_legacy-modes_mode_haskell.js +5 -0
  86. package/src/assets/codemirror/@codemirror_legacy-modes_mode_haxe.js +12 -0
  87. package/src/assets/codemirror/@codemirror_legacy-modes_mode_http.js +1 -0
  88. package/src/assets/codemirror/@codemirror_legacy-modes_mode_idl.js +7 -0
  89. package/src/assets/codemirror/@codemirror_legacy-modes_mode_javascript.js +23 -0
  90. package/src/assets/codemirror/@codemirror_legacy-modes_mode_jinja2.js +8 -0
  91. package/src/assets/codemirror/@codemirror_legacy-modes_mode_julia.js +17 -0
  92. package/src/assets/codemirror/@codemirror_legacy-modes_mode_livescript.js +1 -0
  93. package/src/assets/codemirror/@codemirror_legacy-modes_mode_lua.js +2 -0
  94. package/src/assets/codemirror/@codemirror_legacy-modes_mode_mathematica.js +26 -0
  95. package/src/assets/codemirror/@codemirror_legacy-modes_mode_mbox.js +11 -0
  96. package/src/assets/codemirror/@codemirror_legacy-modes_mode_mirc.js +1 -0
  97. package/src/assets/codemirror/@codemirror_legacy-modes_mode_mllike.js +8 -0
  98. package/src/assets/codemirror/@codemirror_legacy-modes_mode_modelica.js +12 -0
  99. package/src/assets/codemirror/@codemirror_legacy-modes_mode_mscgen.js +3 -0
  100. package/src/assets/codemirror/@codemirror_legacy-modes_mode_mumps.js +16 -0
  101. package/src/assets/codemirror/@codemirror_legacy-modes_mode_nginx.js +1 -0
  102. package/src/assets/codemirror/@codemirror_legacy-modes_mode_nsis.js +20 -0
  103. package/src/assets/codemirror/@codemirror_legacy-modes_mode_ntriples.js +1 -0
  104. package/src/assets/codemirror/@codemirror_legacy-modes_mode_octave.js +8 -0
  105. package/src/assets/codemirror/@codemirror_legacy-modes_mode_oz.js +17 -0
  106. package/src/assets/codemirror/@codemirror_legacy-modes_mode_pascal.js +2 -0
  107. package/src/assets/codemirror/@codemirror_legacy-modes_mode_pegjs.js +25 -0
  108. package/src/assets/codemirror/@codemirror_legacy-modes_mode_perl.js +247 -0
  109. package/src/assets/codemirror/@codemirror_legacy-modes_mode_pig.js +6 -0
  110. package/src/assets/codemirror/@codemirror_legacy-modes_mode_powershell.js +7 -0
  111. package/src/assets/codemirror/@codemirror_legacy-modes_mode_properties.js +5 -0
  112. package/src/assets/codemirror/@codemirror_legacy-modes_mode_protobuf.js +7 -0
  113. package/src/assets/codemirror/@codemirror_legacy-modes_mode_pug.js +24 -0
  114. package/src/assets/codemirror/@codemirror_legacy-modes_mode_puppet.js +42 -0
  115. package/src/assets/codemirror/@codemirror_legacy-modes_mode_python.js +15 -0
  116. package/src/assets/codemirror/@codemirror_legacy-modes_mode_q.js +2 -0
  117. package/src/assets/codemirror/@codemirror_legacy-modes_mode_r.js +1 -0
  118. package/src/assets/codemirror/@codemirror_legacy-modes_mode_rpm.js +9 -0
  119. package/src/assets/codemirror/@codemirror_legacy-modes_mode_ruby.js +4 -0
  120. package/src/assets/codemirror/@codemirror_legacy-modes_mode_rust.js +5 -0
  121. package/src/assets/codemirror/@codemirror_legacy-modes_mode_sas.js +23 -0
  122. package/src/assets/codemirror/@codemirror_legacy-modes_mode_sass.js +26 -0
  123. package/src/assets/codemirror/@codemirror_legacy-modes_mode_scheme.js +14 -0
  124. package/src/assets/codemirror/@codemirror_legacy-modes_mode_shell.js +1 -0
  125. package/src/assets/codemirror/@codemirror_legacy-modes_mode_sieve.js +7 -0
  126. package/src/assets/codemirror/@codemirror_legacy-modes_mode_simple-mode.js +1 -0
  127. package/src/assets/codemirror/@codemirror_legacy-modes_mode_smalltalk.js +1 -0
  128. package/src/assets/codemirror/@codemirror_legacy-modes_mode_solr.js +1 -0
  129. package/src/assets/codemirror/@codemirror_legacy-modes_mode_sparql.js +1 -0
  130. package/src/assets/codemirror/@codemirror_legacy-modes_mode_spreadsheet.js +6 -0
  131. package/src/assets/codemirror/@codemirror_legacy-modes_mode_sql.js +84 -0
  132. package/src/assets/codemirror/@codemirror_legacy-modes_mode_stex.js +11 -0
  133. package/src/assets/codemirror/@codemirror_legacy-modes_mode_stylus.js +45 -0
  134. package/src/assets/codemirror/@codemirror_legacy-modes_mode_swift.js +2 -0
  135. package/src/assets/codemirror/@codemirror_legacy-modes_mode_tcl.js +1 -0
  136. package/src/assets/codemirror/@codemirror_legacy-modes_mode_textile.js +2 -0
  137. package/src/assets/codemirror/@codemirror_legacy-modes_mode_tiddlywiki.js +33 -0
  138. package/src/assets/codemirror/@codemirror_legacy-modes_mode_tiki.js +20 -0
  139. package/src/assets/codemirror/@codemirror_legacy-modes_mode_toml.js +4 -0
  140. package/src/assets/codemirror/@codemirror_legacy-modes_mode_troff.js +1 -0
  141. package/src/assets/codemirror/@codemirror_legacy-modes_mode_ttcn-cfg.js +3 -0
  142. package/src/assets/codemirror/@codemirror_legacy-modes_mode_ttcn.js +3 -0
  143. package/src/assets/codemirror/@codemirror_legacy-modes_mode_turtle.js +1 -0
  144. package/src/assets/codemirror/@codemirror_legacy-modes_mode_vb.js +11 -0
  145. package/src/assets/codemirror/@codemirror_legacy-modes_mode_vbscript.js +26 -0
  146. package/src/assets/codemirror/@codemirror_legacy-modes_mode_velocity.js +15 -0
  147. package/src/assets/codemirror/@codemirror_legacy-modes_mode_verilog.js +67 -0
  148. package/src/assets/codemirror/@codemirror_legacy-modes_mode_vhdl.js +2 -0
  149. package/src/assets/codemirror/@codemirror_legacy-modes_mode_wast.js +7 -0
  150. package/src/assets/codemirror/@codemirror_legacy-modes_mode_webidl.js +25 -0
  151. package/src/assets/codemirror/@codemirror_legacy-modes_mode_xml.js +6 -0
  152. package/src/assets/codemirror/@codemirror_legacy-modes_mode_xquery.js +51 -0
  153. package/src/assets/codemirror/@codemirror_legacy-modes_mode_yacas.js +16 -0
  154. package/src/assets/codemirror/@codemirror_legacy-modes_mode_yaml.js +1 -0
  155. package/src/assets/codemirror/@codemirror_legacy-modes_mode_z80.js +1 -0
  156. package/src/assets/codemirror/@codemirror_lint.js +46 -0
  157. package/src/assets/codemirror/@codemirror_merge.js +167 -0
  158. package/src/assets/codemirror/@codemirror_search.js +121 -0
  159. package/src/assets/codemirror/@codemirror_state.js +793 -0
  160. package/src/assets/codemirror/@codemirror_theme-one-dark.js +12 -0
  161. package/src/assets/codemirror/@codemirror_view.js +1210 -0
  162. package/src/assets/codemirror/@lezer_common.js +407 -0
  163. package/src/assets/codemirror/@lezer_cpp.js +4 -0
  164. package/src/assets/codemirror/@lezer_css.js +4 -0
  165. package/src/assets/codemirror/@lezer_go.js +3 -0
  166. package/src/assets/codemirror/@lezer_highlight.js +380 -0
  167. package/src/assets/codemirror/@lezer_html.js +20 -0
  168. package/src/assets/codemirror/@lezer_java.js +2 -0
  169. package/src/assets/codemirror/@lezer_javascript.js +7 -0
  170. package/src/assets/codemirror/@lezer_json.js +2 -0
  171. package/src/assets/codemirror/@lezer_lezer.js +2 -0
  172. package/src/assets/codemirror/@lezer_lr.js +325 -0
  173. package/src/assets/codemirror/@lezer_markdown.js +286 -0
  174. package/src/assets/codemirror/@lezer_php.js +3 -0
  175. package/src/assets/codemirror/@lezer_python.js +5 -0
  176. package/src/assets/codemirror/@lezer_rust.js +3 -0
  177. package/src/assets/codemirror/@lezer_sass.js +5 -0
  178. package/src/assets/codemirror/@lezer_xml.js +3 -0
  179. package/src/assets/codemirror/@lezer_yaml.js +12 -0
  180. package/src/assets/codemirror/@marijn_find-cluster-break.js +10 -0
  181. package/src/assets/codemirror/@uiw_codemirror-theme-androidstudio.js +3 -0
  182. package/src/assets/codemirror/@uiw_codemirror-theme-andromeda.js +1 -0
  183. package/src/assets/codemirror/@uiw_codemirror-theme-atomone.js +6 -0
  184. package/src/assets/codemirror/@uiw_codemirror-theme-aura.js +1 -0
  185. package/src/assets/codemirror/@uiw_codemirror-theme-basic.js +1 -0
  186. package/src/assets/codemirror/@uiw_codemirror-theme-bbedit.js +1 -0
  187. package/src/assets/codemirror/@uiw_codemirror-theme-copilot.js +1 -0
  188. package/src/assets/codemirror/@uiw_codemirror-theme-darcula.js +6 -0
  189. package/src/assets/codemirror/@uiw_codemirror-theme-dracula.js +6 -0
  190. package/src/assets/codemirror/@uiw_codemirror-theme-duotone.js +5 -0
  191. package/src/assets/codemirror/@uiw_codemirror-theme-eclipse.js +1 -0
  192. package/src/assets/codemirror/@uiw_codemirror-theme-github.js +3 -0
  193. package/src/assets/codemirror/@uiw_codemirror-theme-material.js +1 -0
  194. package/src/assets/codemirror/@uiw_codemirror-theme-monokai.js +1 -0
  195. package/src/assets/codemirror/@uiw_codemirror-theme-nord.js +2 -0
  196. package/src/assets/codemirror/@uiw_codemirror-theme-okaidia.js +2 -0
  197. package/src/assets/codemirror/@uiw_codemirror-theme-solarized.js +1 -0
  198. package/src/assets/codemirror/@uiw_codemirror-theme-sublime.js +2 -0
  199. package/src/assets/codemirror/@uiw_codemirror-theme-tokyo-night.js +1 -0
  200. package/src/assets/codemirror/@uiw_codemirror-theme-vscode.js +5 -0
  201. package/src/assets/codemirror/@uiw_codemirror-theme-xcode.js +3 -0
  202. package/src/assets/codemirror/@uiw_codemirror-themes.js +1 -0
  203. package/src/assets/codemirror/_core.js +4494 -0
  204. package/src/assets/codemirror/codemirror.js +46 -0
  205. package/src/assets/codemirror/crelt.js +1 -0
  206. package/src/assets/codemirror/style-mod.js +36 -0
  207. package/src/assets/codemirror/w3c-keyname.js +8 -0
  208. package/src/assets/codemirror-editor.umd.js +415 -0
  209. package/src/assets/editor.html +377 -0
  210. package/src/assets/webview-interface.umd.js +2 -0
package/app.plugin.js ADDED
@@ -0,0 +1,133 @@
1
+ const { withDangerousMod, withXcodeProject } = require("@expo/config-plugins");
2
+ const fs = require("fs");
3
+ const path = require("path");
4
+
5
+ // Resolved once at require-time — works both when published (node_modules/react-native-codeditor/)
6
+ // and when linked from a monorepo workspace (package root).
7
+ const ASSETS_SRC = path.resolve(__dirname, "src/assets");
8
+
9
+ function copyDirSync(src, dest) {
10
+ fs.mkdirSync(dest, { recursive: true });
11
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
12
+ const srcPath = path.join(src, entry.name);
13
+ const destPath = path.join(dest, entry.name);
14
+ if (entry.isDirectory()) {
15
+ copyDirSync(srcPath, destPath);
16
+ } else {
17
+ fs.copyFileSync(srcPath, destPath);
18
+ }
19
+ }
20
+ }
21
+
22
+ function withCodeditorAssets(config) {
23
+ // ── Android ──────────────────────────────────────────────────────────────
24
+ config = withDangerousMod(config, [
25
+ "android",
26
+ (modConfig) => {
27
+ const destDir = path.resolve(
28
+ modConfig.modRequest.projectRoot,
29
+ "android/app/src/main/assets/codeditor"
30
+ );
31
+ if (!fs.existsSync(ASSETS_SRC)) {
32
+ console.warn("[@actualwave/react-native-codeditor] ⚠️ src/assets not found — run `npm run prepare` in the library first");
33
+ return modConfig;
34
+ }
35
+ copyDirSync(ASSETS_SRC, destDir);
36
+ console.log("[@actualwave/react-native-codeditor] ✅ Android assets copied to android/app/src/main/assets/codeditor");
37
+ return modConfig;
38
+ },
39
+ ]);
40
+
41
+ // ── iOS: copy files ───────────────────────────────────────────────────────
42
+ config = withDangerousMod(config, [
43
+ "ios",
44
+ (modConfig) => {
45
+ const { projectRoot, projectName } = modConfig.modRequest;
46
+ const destDir = path.resolve(projectRoot, `ios/${projectName}/assets/codeditor`);
47
+ if (!fs.existsSync(ASSETS_SRC)) {
48
+ console.warn("[@actualwave/react-native-codeditor] ⚠️ src/assets not found — run `npm run prepare` in the library first");
49
+ return modConfig;
50
+ }
51
+ copyDirSync(ASSETS_SRC, destDir);
52
+ console.log(`[@actualwave/react-native-codeditor] ✅ iOS assets copied to ios/${projectName}/assets/codeditor`);
53
+ return modConfig;
54
+ },
55
+ ]);
56
+
57
+ // ── iOS: add folder reference to Xcode project ───────────────────────────
58
+ config = withXcodeProject(config, (modConfig) => {
59
+ const xcodeProject = modConfig.modResults;
60
+ const { projectName } = modConfig.modRequest;
61
+
62
+ // Idempotent — skip if already present
63
+ const existing = Object.values(
64
+ xcodeProject.hash.project.objects.PBXFileReference || {}
65
+ ).find(
66
+ (ref) =>
67
+ ref &&
68
+ typeof ref === "object" &&
69
+ ref.name === "assets" &&
70
+ ref.lastKnownFileType === "folder"
71
+ );
72
+ if (existing) {
73
+ return modConfig;
74
+ }
75
+
76
+ // Find the main app group (named after the project)
77
+ const groups = xcodeProject.hash.project.objects.PBXGroup || {};
78
+ const mainGroupEntry = Object.entries(groups).find(
79
+ ([, g]) => g && typeof g === "object" && g.name === projectName
80
+ );
81
+ if (!mainGroupEntry) {
82
+ console.warn(
83
+ `[@actualwave/react-native-codeditor] ⚠️ Xcode group "${projectName}" not found — add the assets folder reference manually`
84
+ );
85
+ return modConfig;
86
+ }
87
+ const [, mainGroupObj] = mainGroupEntry;
88
+
89
+ // PBXFileReference
90
+ // path must be relative to the Xcode project root (ios/), so it includes the project name.
91
+ const fileRefUuid = xcodeProject.generateUuid();
92
+ xcodeProject.hash.project.objects.PBXFileReference[fileRefUuid] = {
93
+ isa: "PBXFileReference",
94
+ lastKnownFileType: "folder",
95
+ name: "assets",
96
+ path: `${projectName}/assets`,
97
+ sourceTree: '"<group>"',
98
+ };
99
+ xcodeProject.hash.project.objects.PBXFileReference[`${fileRefUuid}_comment`] = "assets";
100
+
101
+ // Add to group children
102
+ if (!mainGroupObj.children) mainGroupObj.children = [];
103
+ mainGroupObj.children.push({ value: fileRefUuid, comment: "assets" });
104
+
105
+ // PBXBuildFile
106
+ const buildFileUuid = xcodeProject.generateUuid();
107
+ const pbxBuildFile = xcodeProject.hash.project.objects.PBXBuildFile || {};
108
+ pbxBuildFile[buildFileUuid] = {
109
+ isa: "PBXBuildFile",
110
+ fileRef: fileRefUuid,
111
+ settings: "{}",
112
+ };
113
+ pbxBuildFile[`${buildFileUuid}_comment`] = "assets in Resources";
114
+ xcodeProject.hash.project.objects.PBXBuildFile = pbxBuildFile;
115
+
116
+ // Add to PBXResourcesBuildPhase
117
+ const resourcesPhases =
118
+ xcodeProject.hash.project.objects.PBXResourcesBuildPhase || {};
119
+ for (const [, phase] of Object.entries(resourcesPhases)) {
120
+ if (phase && typeof phase === "object" && Array.isArray(phase.files)) {
121
+ phase.files.push({ value: buildFileUuid, comment: "assets in Resources" });
122
+ break;
123
+ }
124
+ }
125
+
126
+ console.log("[@actualwave/react-native-codeditor] ✅ Xcode folder reference added to project.pbxproj");
127
+ return modConfig;
128
+ });
129
+
130
+ return config;
131
+ }
132
+
133
+ module.exports = withCodeditorAssets;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ import { View, Text } from 'react-native';
4
+ import { jsx as _jsx } from "react/jsx-runtime";
5
+ const BlockingView = () => /*#__PURE__*/_jsx(View, {
6
+ style: {
7
+ position: 'absolute',
8
+ top: 0,
9
+ right: 0,
10
+ bottom: 0,
11
+ left: 0,
12
+ backgroundColor: '#00000066',
13
+ justifyContent: 'center',
14
+ alignItems: 'center'
15
+ },
16
+ children: /*#__PURE__*/_jsx(Text, {
17
+ style: {
18
+ color: '#fff',
19
+ fontSize: 12
20
+ },
21
+ children: "Initializing, please wait..."
22
+ })
23
+ });
24
+ export default BlockingView;
25
+ //# sourceMappingURL=BlockingView.js.map
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+
3
+ import React, { useState, useEffect, useRef, useCallback } from "react";
4
+ import { Platform, View, StyleSheet } from "react-native";
5
+ import WebView from "react-native-webview";
6
+ import WebViewAPI from "./WebViewAPI.js";
7
+ import BlockingView from "./BlockingView.js";
8
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
+ const styles = StyleSheet.create({
10
+ container: {
11
+ position: "relative",
12
+ flex: 1
13
+ },
14
+ webView: {
15
+ flex: 1
16
+ }
17
+ });
18
+
19
+ // Stable empty array used as the default for the extensions prop.
20
+ // A new [] on every render would cause the extensions effect to fire every re-render,
21
+ // calling setExtensions([]) and wiping the theme from the extensionCompartment.
22
+ const DEFAULT_EXTENSIONS = [];
23
+
24
+ /**
25
+ * Default WebView source URI for the bundled editor page.
26
+ * Android: assets are copied to android/app/src/main/assets/ by react-native link.
27
+ * iOS: override via editorUri prop until a MainBundlePath helper is added.
28
+ */
29
+ const DEFAULT_EDITOR_URI = Platform.select({
30
+ android: "file:///android_asset/codeditor/editor.html",
31
+ default: "file:///android_asset/codeditor/editor.html",
32
+ ios: "assets/codeditor/editor.html"
33
+ });
34
+ const CodeEditor = ({
35
+ onInitialized,
36
+ onHistorySizeUpdate,
37
+ onLog,
38
+ onError,
39
+ onContentUpdate,
40
+ onSelectionChange,
41
+ onWebViewRefUpdated,
42
+ onLoad,
43
+ onLoadStart,
44
+ onLoadProgress,
45
+ onLoadEnd,
46
+ onNavigationStateChange,
47
+ renderBlockingView = () => /*#__PURE__*/_jsx(BlockingView, {}),
48
+ language,
49
+ extensions = DEFAULT_EXTENSIONS,
50
+ theme,
51
+ content = "",
52
+ viewport,
53
+ allowFileAccess = true,
54
+ editorUri = DEFAULT_EDITOR_URI
55
+ }) => {
56
+ const [initialized, setInitialized] = useState(false);
57
+ const apiRef = useRef(null);
58
+ const currentContentRef = useRef(content);
59
+ const initializedRef = useRef(false);
60
+
61
+ // Always-current prop snapshot for stable callbacks
62
+ const callbacksRef = useRef({
63
+ onInitialized,
64
+ onContentUpdate,
65
+ onSelectionChange,
66
+ onHistorySizeUpdate,
67
+ onLog,
68
+ onError,
69
+ onWebViewRefUpdated
70
+ });
71
+ callbacksRef.current = {
72
+ onInitialized,
73
+ onContentUpdate,
74
+ onSelectionChange,
75
+ onHistorySizeUpdate,
76
+ onLog,
77
+ onError,
78
+ onWebViewRefUpdated
79
+ };
80
+ const propsRef = useRef({
81
+ content,
82
+ language,
83
+ extensions,
84
+ theme,
85
+ viewport
86
+ });
87
+ propsRef.current = {
88
+ content,
89
+ language,
90
+ extensions,
91
+ theme,
92
+ viewport
93
+ };
94
+ if (apiRef.current === null) {
95
+ apiRef.current = new WebViewAPI({
96
+ onInitialized: api => {
97
+ initializedRef.current = true;
98
+ setInitialized(true);
99
+ callbacksRef.current.onInitialized(api);
100
+ },
101
+ onContentUpdate: value => {
102
+ currentContentRef.current = value;
103
+ callbacksRef.current.onContentUpdate(value);
104
+ },
105
+ onSelectionChange: text => callbacksRef.current.onSelectionChange?.(text),
106
+ onHistorySizeUpdate: size => callbacksRef.current.onHistorySizeUpdate(size),
107
+ onLog: (...args) => callbacksRef.current.onLog(...args),
108
+ onError: error => callbacksRef.current.onError(error)
109
+ });
110
+ }
111
+ const callEditor = fn => {
112
+ if (initializedRef.current) {
113
+ void (async () => {
114
+ try {
115
+ await fn(apiRef.current.editor);
116
+ } catch (e) {
117
+ callbacksRef.current.onError(e);
118
+ }
119
+ })();
120
+ }
121
+ };
122
+
123
+ // Push content changes to live editor (skip initial render)
124
+ const prevContentRef = useRef(null);
125
+ useEffect(() => {
126
+ if (prevContentRef.current === null) {
127
+ prevContentRef.current = content;
128
+ return;
129
+ }
130
+ if (prevContentRef.current === content) return;
131
+ prevContentRef.current = content;
132
+ if (initializedRef.current && currentContentRef.current !== content) {
133
+ currentContentRef.current = content;
134
+ callEditor(e => e.setValue(content));
135
+ }
136
+ }, [content]);
137
+
138
+ // Push language changes to live editor
139
+ const prevLanguageRef = useRef(null);
140
+ useEffect(() => {
141
+ if (prevLanguageRef.current === null) {
142
+ prevLanguageRef.current = language;
143
+ return;
144
+ }
145
+ if (prevLanguageRef.current === language) return;
146
+ prevLanguageRef.current = language;
147
+ if (language) callEditor(e => e.setLanguage(language));
148
+ }, [language]);
149
+
150
+ // Push theme changes to live editor
151
+ const prevThemeRef = useRef(null);
152
+ useEffect(() => {
153
+ if (prevThemeRef.current === null) {
154
+ prevThemeRef.current = theme;
155
+ return;
156
+ }
157
+ if (prevThemeRef.current === theme) return;
158
+ prevThemeRef.current = theme;
159
+ callEditor(e => e.setTheme(theme));
160
+ }, [theme]);
161
+
162
+ // Push extension changes to live editor
163
+ const prevExtensionsRef = useRef(null);
164
+ useEffect(() => {
165
+ if (prevExtensionsRef.current === null) {
166
+ prevExtensionsRef.current = extensions;
167
+ return;
168
+ }
169
+ if (prevExtensionsRef.current === extensions) return;
170
+ prevExtensionsRef.current = extensions;
171
+ callEditor(e => e.setExtensions(extensions));
172
+ }, [extensions]);
173
+
174
+ // Push viewport changes to live editor
175
+ const prevViewportRef = useRef(null);
176
+ useEffect(() => {
177
+ if (prevViewportRef.current === null) {
178
+ prevViewportRef.current = viewport;
179
+ return;
180
+ }
181
+ if (prevViewportRef.current === viewport) return;
182
+ prevViewportRef.current = viewport;
183
+ if (viewport) callEditor(e => e.setViewport(viewport));
184
+ }, [viewport]);
185
+ const handleWebViewReference = useCallback(webView => {
186
+ setInitialized(false);
187
+ initializedRef.current = false;
188
+ if (webView) {
189
+ const {
190
+ content: c,
191
+ language: l,
192
+ extensions: e,
193
+ theme: t,
194
+ viewport: v
195
+ } = propsRef.current;
196
+ currentContentRef.current = c;
197
+ apiRef.current.setInitialConfig({
198
+ content: c,
199
+ language: l,
200
+ extensions: e,
201
+ theme: t,
202
+ viewport: v
203
+ });
204
+ apiRef.current.initialize(webView);
205
+ }
206
+ callbacksRef.current.onWebViewRefUpdated?.(webView);
207
+ }, []);
208
+ const handleMessage = useCallback(event => {
209
+ apiRef.current.onMessage(event);
210
+ }, []);
211
+ const handleLoadError = useCallback((...args) => {
212
+ console.log("WebView Load Error:", ...args);
213
+ }, []);
214
+ return /*#__PURE__*/_jsxs(View, {
215
+ style: styles.container,
216
+ children: [/*#__PURE__*/_jsx(WebView, {
217
+ ref: handleWebViewReference,
218
+ onMessage: handleMessage,
219
+ onError: handleLoadError,
220
+ onLoad: onLoad,
221
+ onLoadStart: onLoadStart,
222
+ onLoadProgress: onLoadProgress,
223
+ onLoadEnd: onLoadEnd,
224
+ onNavigationStateChange: onNavigationStateChange,
225
+ allowFileAccess: allowFileAccess,
226
+ allowFileAccessFromFileURLs: true,
227
+ allowUniversalAccessFromFileURLs: true,
228
+ allowingReadAccessToURL: Platform.OS === "ios" ? "file://" : undefined,
229
+ source: {
230
+ uri: editorUri
231
+ },
232
+ style: styles.webView,
233
+ javaScriptEnabled: true,
234
+ originWhitelist: ["file://*", "about:*"]
235
+ }), !initialized && renderBlockingView()]
236
+ });
237
+ };
238
+ export default CodeEditor;
239
+ //# sourceMappingURL=CodeEditor.js.map
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=EditorAPI.js.map
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+
3
+ import { initializeHost } from '@actualwave/webview-interface';
4
+ /**
5
+ * WebViewAPI wires the DDA bridge between React Native and the WebView editor.
6
+ * After onInitialized fires, call api.editor to reach the full EditorAPI proxy.
7
+ * api.focus() is the only method kept here directly — it additionally calls
8
+ * requestFocus() on the native WebView ref to trigger the Android soft keyboard.
9
+ */
10
+ class WebViewAPI {
11
+ webView = null;
12
+ _editor = null;
13
+ stopFn = null;
14
+ _onMessage = null;
15
+ _initialConfig = {};
16
+ constructor(handlers) {
17
+ this.handlers = handlers;
18
+ }
19
+
20
+ /** DDA proxy to the WebView's EditorController. Available after onInitialized fires. */
21
+ get editor() {
22
+ return this._editor;
23
+ }
24
+ setInitialConfig(config) {
25
+ this._initialConfig = config;
26
+ }
27
+ initialize(webView) {
28
+ this.webView = webView;
29
+ this._editor = null;
30
+ this.stopFn?.();
31
+ this.stopFn = null;
32
+
33
+ // Methods exposed to the GUEST via DDA. The GUEST calls these on nativeApi.
34
+ const hostRoot = {
35
+ getInitialConfig: () => this._initialConfig,
36
+ onLog: (...args) => this.handlers.onLog(...args),
37
+ onError: error => this.handlers.onError(error)
38
+ };
39
+ const {
40
+ onMessage,
41
+ connection
42
+ } = initializeHost({
43
+ webView,
44
+ root: hostRoot,
45
+ handshakeTimeout: 30000
46
+ });
47
+ this._onMessage = onMessage;
48
+ void connection.then(({
49
+ root: pageApi,
50
+ stop
51
+ }) => {
52
+ this._editor = pageApi;
53
+ this.stopFn = stop;
54
+ // onInitialized is called when __editorReady__ arrives (after createEditor completes)
55
+ });
56
+ }
57
+
58
+ // Intercepts out-of-band messages before DDA sees them:
59
+ // __editorLog__ — window.log() calls from the WebView
60
+ // __editorError__ — window.onerror / unhandledrejection from the WebView
61
+ // __editorReady__ — sent after createEditor + theme/language load; fires onInitialized
62
+ // Everything else is forwarded to the DDA subscriber.
63
+ onMessage = event => {
64
+ const raw = event?.nativeEvent?.data ?? event?.data;
65
+ if (typeof raw === 'string') {
66
+ try {
67
+ const parsed = JSON.parse(raw);
68
+ if (parsed?.type === '__editorError__') {
69
+ this.handlers.onError(parsed.data);
70
+ return;
71
+ }
72
+ if (parsed?.type === '__editorLog__') {
73
+ this.handlers.onLog(...(Array.isArray(parsed.data) ? parsed.data : [parsed.data]));
74
+ return;
75
+ }
76
+ if (parsed?.type === '__editorReady__') {
77
+ // Fires only after the GUEST finishes createEditor (theme + language applied),
78
+ // so the BlockingView is removed only when the editor is visually complete.
79
+ this.handlers.onInitialized(this);
80
+ return;
81
+ }
82
+ if (parsed?.type === '__contentChange__') {
83
+ // One-way notification — no DDA round trip, no injectJavaScript response.
84
+ // Keeps content updates off the DDA channel so injectJavaScript is never
85
+ // called while the user is typing (avoids disrupting Android IME composition).
86
+ const {
87
+ value,
88
+ undo,
89
+ redo
90
+ } = parsed.data ?? {};
91
+ this.handlers.onContentUpdate(value ?? '');
92
+ this.handlers.onHistorySizeUpdate({
93
+ undo: undo ?? 0,
94
+ redo: redo ?? 0
95
+ });
96
+ return;
97
+ }
98
+ if (parsed?.type === '__selectionChange__') {
99
+ this.handlers.onSelectionChange?.(typeof parsed.data === 'string' ? parsed.data : '');
100
+ return;
101
+ }
102
+ } catch {
103
+ // not JSON — fall through to DDA
104
+ }
105
+ }
106
+ this._onMessage?.(event);
107
+ };
108
+ stop() {
109
+ this.stopFn?.();
110
+ this.stopFn = null;
111
+ this._onMessage = null;
112
+ this._editor = null;
113
+ }
114
+ injectJavaScript(code) {
115
+ this.webView?.injectJavaScript(code);
116
+ }
117
+ requestFocus() {
118
+ this.webView?.requestFocus?.();
119
+ }
120
+
121
+ // focus() is kept here rather than on editor because it must also call
122
+ // requestFocus() on the native WebView ref to raise the Android soft keyboard.
123
+ focus = () => {
124
+ try {
125
+ this.webView?.requestFocus?.();
126
+ } catch {
127
+ // requestFocus is best-effort on Android
128
+ }
129
+ return this._editor.focus();
130
+ };
131
+ }
132
+ export default WebViewAPI;
133
+ //# sourceMappingURL=WebViewAPI.js.map
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ export { default } from "./CodeEditor.js";
4
+ export { default as CodeEditor } from "./CodeEditor.js";
5
+ export { default as WebViewAPI } from "./WebViewAPI.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,3 @@
1
+ export = withCodeditorAssets;
2
+ declare function withCodeditorAssets(config: any): any;
3
+ //# sourceMappingURL=app.plugin.d.ts.map
@@ -0,0 +1,10 @@
1
+ export let overrides: ({
2
+ exclude: RegExp;
3
+ presets: string[];
4
+ include?: undefined;
5
+ } | {
6
+ include: RegExp;
7
+ presets: string[];
8
+ exclude?: undefined;
9
+ })[];
10
+ //# sourceMappingURL=babel.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,2 @@
1
+ export let assets: string[];
2
+ //# sourceMappingURL=react-native.config.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=copy-assets.d.ts.map
@@ -0,0 +1,3 @@
1
+ declare const BlockingView: () => import("react/jsx-runtime").JSX.Element;
2
+ export default BlockingView;
3
+ //# sourceMappingURL=BlockingView.d.ts.map
@@ -0,0 +1,33 @@
1
+ import React from "react";
2
+ import WebView from "react-native-webview";
3
+ import WebViewAPI from "./WebViewAPI";
4
+ import type { ExtensionSpec, HistorySize, ViewportSettings } from "./EditorAPI";
5
+ export interface CodeEditorProps {
6
+ onInitialized: (api: WebViewAPI) => void;
7
+ onHistorySizeUpdate: (size: HistorySize) => void;
8
+ onLog: (...args: unknown[]) => void;
9
+ onError: (error: unknown) => void;
10
+ onContentUpdate: (content: string) => void;
11
+ onSelectionChange?: (text: string) => void;
12
+ onWebViewRefUpdated?: (webView: WebView | null) => void;
13
+ onLoad?: (event: unknown) => void;
14
+ onLoadStart?: (event: unknown) => void;
15
+ onLoadProgress?: (event: unknown) => void;
16
+ onLoadEnd?: (event: unknown) => void;
17
+ onNavigationStateChange?: (event: unknown) => void;
18
+ renderBlockingView?: () => React.ReactNode;
19
+ /** Language name for syntax highlighting, e.g. 'javascript', 'python'. */
20
+ language?: string;
21
+ /** Additional CodeMirror extension specs loaded on top of the language. */
22
+ extensions?: ExtensionSpec[];
23
+ /** Theme name from the @uiw/codemirror-themes collection, e.g. 'darcula', 'monokai'. */
24
+ theme?: string;
25
+ content?: string;
26
+ viewport?: ViewportSettings;
27
+ allowFileAccess?: boolean;
28
+ /** Override the default editor HTML URI (useful on iOS where the bundle path varies). */
29
+ editorUri?: string;
30
+ }
31
+ declare const CodeEditor: ({ onInitialized, onHistorySizeUpdate, onLog, onError, onContentUpdate, onSelectionChange, onWebViewRefUpdated, onLoad, onLoadStart, onLoadProgress, onLoadEnd, onNavigationStateChange, renderBlockingView, language, extensions, theme, content, viewport, allowFileAccess, editorUri, }: CodeEditorProps) => import("react/jsx-runtime").JSX.Element;
32
+ export default CodeEditor;
33
+ //# sourceMappingURL=CodeEditor.d.ts.map
@@ -0,0 +1,66 @@
1
+ export interface ViewportSettings {
2
+ maximumScale?: number;
3
+ minimumScale?: number;
4
+ intialScale?: number;
5
+ userScalable?: boolean;
6
+ viewportWidth?: string | number;
7
+ }
8
+ export interface CursorPosition {
9
+ line: number;
10
+ ch: number;
11
+ index: number;
12
+ }
13
+ export interface HistorySize {
14
+ undo: number;
15
+ redo: number;
16
+ }
17
+ /**
18
+ * Extension spec forms accepted by createEditor / setExtensions / setTheme:
19
+ * - string → package name loaded via the registry, e.g. '@codemirror/autocomplete'
20
+ * - [string, string] → [packageName, exportName], e.g. ['@uiw/codemirror-theme-darcula', 'darcula']
21
+ * - [string, object] → [packageName, options] passed to the registered resolver
22
+ * - anything else → treated as a pre-built CodeMirror Extension and used as-is
23
+ */
24
+ export type ExtensionSpec = string | [string, unknown] | unknown;
25
+ export interface CompletionItem {
26
+ label: string;
27
+ type?: 'function' | 'class' | 'variable' | 'keyword' | 'namespace' | 'type' | 'text';
28
+ detail?: string;
29
+ info?: string;
30
+ }
31
+ export interface EditorAPI {
32
+ getValue(): Promise<string>;
33
+ setValue(value: string): Promise<void>;
34
+ resetValue(value?: string): Promise<void>;
35
+ setLanguage(name: string): Promise<void>;
36
+ setExtensions(specs: ExtensionSpec[]): Promise<void>;
37
+ setTheme(themeName?: string): Promise<void>;
38
+ setFontSize(size: number): Promise<void>;
39
+ setViewport(options: ViewportSettings): Promise<void>;
40
+ focus(): Promise<void>;
41
+ getCursor(where?: 'from' | 'to' | 'head'): Promise<CursorPosition>;
42
+ setCursor(line: number, ch?: number): Promise<void>;
43
+ getSelection(): Promise<string>;
44
+ setSelection(anchor: number, head?: number): Promise<void>;
45
+ replaceSelection(text: string): Promise<void>;
46
+ cancelSelection(): Promise<void>;
47
+ indentMore(): Promise<boolean>;
48
+ indentLess(): Promise<boolean>;
49
+ toggleComment(): Promise<boolean>;
50
+ moveLineUp(): Promise<boolean>;
51
+ moveLineDown(): Promise<boolean>;
52
+ deleteLine(): Promise<boolean>;
53
+ selectLine(): Promise<boolean>;
54
+ selectParentSyntax(): Promise<boolean>;
55
+ historyUndo(): Promise<boolean>;
56
+ historyRedo(): Promise<boolean>;
57
+ historyClear(): Promise<void>;
58
+ historySize(): Promise<HistorySize>;
59
+ scrollToCursor(margin?: number): Promise<void>;
60
+ startCompletion(): Promise<void>;
61
+ setCompletions(items: CompletionItem[]): Promise<void>;
62
+ setSoftKeyboard(enabled: boolean): Promise<void>;
63
+ loadExtension(moduleName: string): Promise<object>;
64
+ destroy(): Promise<void>;
65
+ }
66
+ //# sourceMappingURL=EditorAPI.d.ts.map