basalt-core 0.0.0-rc5

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 (325) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cli/basalt.d.ts +3 -0
  3. package/dist/cli/basalt.d.ts.map +1 -0
  4. package/dist/cli/basalt.js +47 -0
  5. package/dist/cli/basalt.js.map +1 -0
  6. package/dist/cli/bundle-cli.d.ts +12 -0
  7. package/dist/cli/bundle-cli.d.ts.map +1 -0
  8. package/dist/cli/bundle-cli.js +124 -0
  9. package/dist/cli/bundle-cli.js.map +1 -0
  10. package/dist/cli/bundleWithAssets.d.ts +79 -0
  11. package/dist/cli/bundleWithAssets.d.ts.map +1 -0
  12. package/dist/cli/bundleWithAssets.js +198 -0
  13. package/dist/cli/bundleWithAssets.js.map +1 -0
  14. package/dist/cli/desktop.d.ts +339 -0
  15. package/dist/cli/desktop.d.ts.map +1 -0
  16. package/dist/cli/desktop.js +1029 -0
  17. package/dist/cli/desktop.js.map +1 -0
  18. package/dist/cli/doctor.d.ts +31 -0
  19. package/dist/cli/doctor.d.ts.map +1 -0
  20. package/dist/cli/doctor.js +283 -0
  21. package/dist/cli/doctor.js.map +1 -0
  22. package/dist/cli/init.d.ts +77 -0
  23. package/dist/cli/init.d.ts.map +1 -0
  24. package/dist/cli/init.js +442 -0
  25. package/dist/cli/init.js.map +1 -0
  26. package/dist/cli/metro.d.ts +49 -0
  27. package/dist/cli/metro.d.ts.map +1 -0
  28. package/dist/cli/metro.js +148 -0
  29. package/dist/cli/metro.js.map +1 -0
  30. package/dist/cli/packageApp.d.ts +102 -0
  31. package/dist/cli/packageApp.d.ts.map +1 -0
  32. package/dist/cli/packageApp.js +319 -0
  33. package/dist/cli/packageApp.js.map +1 -0
  34. package/dist/cli/steps.d.ts +34 -0
  35. package/dist/cli/steps.d.ts.map +1 -0
  36. package/dist/cli/steps.js +53 -0
  37. package/dist/cli/steps.js.map +1 -0
  38. package/dist/metro-config.d.ts +168 -0
  39. package/dist/metro-config.d.ts.map +1 -0
  40. package/dist/metro-config.js +671 -0
  41. package/dist/metro-config.js.map +1 -0
  42. package/dist/react-native.config.d.ts +7 -0
  43. package/dist/react-native.config.d.ts.map +1 -0
  44. package/dist/react-native.config.js +80 -0
  45. package/dist/react-native.config.js.map +1 -0
  46. package/dist/src/DragSource.d.ts +52 -0
  47. package/dist/src/DragSource.d.ts.map +1 -0
  48. package/dist/src/DragSource.js +97 -0
  49. package/dist/src/DragSource.js.map +1 -0
  50. package/dist/src/DropTarget.d.ts +58 -0
  51. package/dist/src/DropTarget.d.ts.map +1 -0
  52. package/dist/src/DropTarget.js +131 -0
  53. package/dist/src/DropTarget.js.map +1 -0
  54. package/dist/src/KeyHandler.d.ts +57 -0
  55. package/dist/src/KeyHandler.d.ts.map +1 -0
  56. package/dist/src/KeyHandler.js +48 -0
  57. package/dist/src/KeyHandler.js.map +1 -0
  58. package/dist/src/Menu.d.ts +72 -0
  59. package/dist/src/Menu.d.ts.map +1 -0
  60. package/dist/src/Menu.js +179 -0
  61. package/dist/src/Menu.js.map +1 -0
  62. package/dist/src/TitleBar.d.ts +75 -0
  63. package/dist/src/TitleBar.d.ts.map +1 -0
  64. package/dist/src/TitleBar.js +236 -0
  65. package/dist/src/TitleBar.js.map +1 -0
  66. package/dist/src/Window.d.ts +87 -0
  67. package/dist/src/Window.d.ts.map +1 -0
  68. package/dist/src/Window.js +248 -0
  69. package/dist/src/Window.js.map +1 -0
  70. package/dist/src/closeRequest.d.ts +55 -0
  71. package/dist/src/closeRequest.d.ts.map +1 -0
  72. package/dist/src/closeRequest.js +134 -0
  73. package/dist/src/closeRequest.js.map +1 -0
  74. package/dist/src/index.d.ts +45 -0
  75. package/dist/src/index.d.ts.map +1 -0
  76. package/dist/src/index.js +92 -0
  77. package/dist/src/index.js.map +1 -0
  78. package/dist/src/overrides/Alert.d.ts +69 -0
  79. package/dist/src/overrides/Alert.d.ts.map +1 -0
  80. package/dist/src/overrides/Alert.js +112 -0
  81. package/dist/src/overrides/Alert.js.map +1 -0
  82. package/dist/src/overrides/BaseViewConfig.d.ts +28 -0
  83. package/dist/src/overrides/BaseViewConfig.d.ts.map +1 -0
  84. package/dist/src/overrides/BaseViewConfig.js +72 -0
  85. package/dist/src/overrides/BaseViewConfig.js.map +1 -0
  86. package/dist/src/overrides/Platform.linux.d.ts +10 -0
  87. package/dist/src/overrides/Platform.linux.d.ts.map +1 -0
  88. package/dist/src/overrides/Platform.linux.js +15 -0
  89. package/dist/src/overrides/Platform.linux.js.map +1 -0
  90. package/dist/src/overrides/Platform.macos.d.ts +10 -0
  91. package/dist/src/overrides/Platform.macos.d.ts.map +1 -0
  92. package/dist/src/overrides/Platform.macos.js +15 -0
  93. package/dist/src/overrides/Platform.macos.js.map +1 -0
  94. package/dist/src/overrides/Platform.windows.d.ts +10 -0
  95. package/dist/src/overrides/Platform.windows.d.ts.map +1 -0
  96. package/dist/src/overrides/Platform.windows.js +15 -0
  97. package/dist/src/overrides/Platform.windows.js.map +1 -0
  98. package/dist/src/overrides/ReactDevToolsSettingsManager.d.ts +24 -0
  99. package/dist/src/overrides/ReactDevToolsSettingsManager.d.ts.map +1 -0
  100. package/dist/src/overrides/ReactDevToolsSettingsManager.js +30 -0
  101. package/dist/src/overrides/ReactDevToolsSettingsManager.js.map +1 -0
  102. package/dist/src/overrides/RefreshControl.d.ts +52 -0
  103. package/dist/src/overrides/RefreshControl.d.ts.map +1 -0
  104. package/dist/src/overrides/RefreshControl.js +92 -0
  105. package/dist/src/overrides/RefreshControl.js.map +1 -0
  106. package/dist/src/overrides/ScrollView.d.ts +39 -0
  107. package/dist/src/overrides/ScrollView.d.ts.map +1 -0
  108. package/dist/src/overrides/ScrollView.js +59 -0
  109. package/dist/src/overrides/ScrollView.js.map +1 -0
  110. package/dist/src/overrides/Share.d.ts +96 -0
  111. package/dist/src/overrides/Share.d.ts.map +1 -0
  112. package/dist/src/overrides/Share.js +97 -0
  113. package/dist/src/overrides/Share.js.map +1 -0
  114. package/dist/src/overrides/TextInput.d.ts +81 -0
  115. package/dist/src/overrides/TextInput.d.ts.map +1 -0
  116. package/dist/src/overrides/TextInput.js +213 -0
  117. package/dist/src/overrides/TextInput.js.map +1 -0
  118. package/dist/src/overrides/View.d.ts +36 -0
  119. package/dist/src/overrides/View.d.ts.map +1 -0
  120. package/dist/src/overrides/View.js +99 -0
  121. package/dist/src/overrides/View.js.map +1 -0
  122. package/dist/src/overrides/createPlatform.d.ts +32 -0
  123. package/dist/src/overrides/createPlatform.d.ts.map +1 -0
  124. package/dist/src/overrides/createPlatform.js +84 -0
  125. package/dist/src/overrides/createPlatform.js.map +1 -0
  126. package/dist/src/overrides/setUpDeveloperTools.d.ts +28 -0
  127. package/dist/src/overrides/setUpDeveloperTools.d.ts.map +1 -0
  128. package/dist/src/overrides/setUpDeveloperTools.js +84 -0
  129. package/dist/src/overrides/setUpDeveloperTools.js.map +1 -0
  130. package/dist/src/overrides/setUpXHR.d.ts +46 -0
  131. package/dist/src/overrides/setUpXHR.d.ts.map +1 -0
  132. package/dist/src/overrides/setUpXHR.js +236 -0
  133. package/dist/src/overrides/setUpXHR.js.map +1 -0
  134. package/dist/src/quitRequest.d.ts +55 -0
  135. package/dist/src/quitRequest.d.ts.map +1 -0
  136. package/dist/src/quitRequest.js +121 -0
  137. package/dist/src/quitRequest.js.map +1 -0
  138. package/dist/src/resourcePath.d.ts +18 -0
  139. package/dist/src/resourcePath.d.ts.map +1 -0
  140. package/dist/src/resourcePath.js +31 -0
  141. package/dist/src/resourcePath.js.map +1 -0
  142. package/dist/src/responseBody.d.ts +76 -0
  143. package/dist/src/responseBody.d.ts.map +1 -0
  144. package/dist/src/responseBody.js +94 -0
  145. package/dist/src/responseBody.js.map +1 -0
  146. package/dist/src/responseHeaders.d.ts +40 -0
  147. package/dist/src/responseHeaders.d.ts.map +1 -0
  148. package/dist/src/responseHeaders.js +75 -0
  149. package/dist/src/responseHeaders.js.map +1 -0
  150. package/dist/src/titleBarState.d.ts +43 -0
  151. package/dist/src/titleBarState.d.ts.map +1 -0
  152. package/dist/src/titleBarState.js +77 -0
  153. package/dist/src/titleBarState.js.map +1 -0
  154. package/dist/src/useContextMenu.d.ts +113 -0
  155. package/dist/src/useContextMenu.d.ts.map +1 -0
  156. package/dist/src/useContextMenu.js +109 -0
  157. package/dist/src/useContextMenu.js.map +1 -0
  158. package/dist/src/useDialog.d.ts +98 -0
  159. package/dist/src/useDialog.d.ts.map +1 -0
  160. package/dist/src/useDialog.js +112 -0
  161. package/dist/src/useDialog.js.map +1 -0
  162. package/dist/src/useDisplays.d.ts +70 -0
  163. package/dist/src/useDisplays.d.ts.map +1 -0
  164. package/dist/src/useDisplays.js +118 -0
  165. package/dist/src/useDisplays.js.map +1 -0
  166. package/dist/src/useHandledKeys.d.ts +38 -0
  167. package/dist/src/useHandledKeys.d.ts.map +1 -0
  168. package/dist/src/useHandledKeys.js +70 -0
  169. package/dist/src/useHandledKeys.js.map +1 -0
  170. package/dist/src/useWindow.d.ts +140 -0
  171. package/dist/src/useWindow.d.ts.map +1 -0
  172. package/dist/src/useWindow.js +233 -0
  173. package/dist/src/useWindow.js.map +1 -0
  174. package/dist/tsconfig.tsbuildinfo +1 -0
  175. package/native/CMakeLists.txt +355 -0
  176. package/native/bootstrap.sh +613 -0
  177. package/native/cmake/CompilerFlags.cmake +49 -0
  178. package/native/cmake/Expo.cmake +125 -0
  179. package/native/cmake/ReactNativeCore.cmake +612 -0
  180. package/native/cmake/Reanimated.cmake +108 -0
  181. package/native/cmake/Skia.cmake +379 -0
  182. package/native/cmake/ThirdParty.cmake +290 -0
  183. package/native/cmake/Worklets.cmake +67 -0
  184. package/native/cmake/codegen/CMakeLists.txt +32 -0
  185. package/native/core/AppIdentity.cpp +85 -0
  186. package/native/core/AppIdentity.h +59 -0
  187. package/native/core/AppPaths.cpp +96 -0
  188. package/native/core/AppPaths.h +53 -0
  189. package/native/core/AppearanceModule.cpp +60 -0
  190. package/native/core/AppearanceModule.h +40 -0
  191. package/native/core/Backface.h +59 -0
  192. package/native/core/BlobModule.cpp +283 -0
  193. package/native/core/BlobModule.h +76 -0
  194. package/native/core/BlobRegistry.cpp +75 -0
  195. package/native/core/BlobRegistry.h +44 -0
  196. package/native/core/ColorScheme.cpp +105 -0
  197. package/native/core/ColorScheme.h +59 -0
  198. package/native/core/ComponentRegistry.h +30 -0
  199. package/native/core/ControlMetrics.h +37 -0
  200. package/native/core/CoreModules.cpp +592 -0
  201. package/native/core/CoreModules.h +308 -0
  202. package/native/core/DebuggingOverlay.cpp +106 -0
  203. package/native/core/DebuggingOverlay.h +65 -0
  204. package/native/core/DesktopControls.cpp +232 -0
  205. package/native/core/DesktopControls.h +170 -0
  206. package/native/core/DevBundle.cpp +108 -0
  207. package/native/core/DevBundle.h +69 -0
  208. package/native/core/DevMenu.cpp +99 -0
  209. package/native/core/DevMenu.h +75 -0
  210. package/native/core/DialogModule.cpp +150 -0
  211. package/native/core/DialogModule.h +51 -0
  212. package/native/core/DragAndDrop.cpp +45 -0
  213. package/native/core/DragAndDrop.h +225 -0
  214. package/native/core/ExpoImageComponent.cpp +79 -0
  215. package/native/core/ExpoImageComponent.h +80 -0
  216. package/native/core/ExpoModules.cpp +415 -0
  217. package/native/core/ExpoModules.h +115 -0
  218. package/native/core/ExpoRuntime.cpp +366 -0
  219. package/native/core/ExpoRuntime.h +42 -0
  220. package/native/core/FocusRing.h +36 -0
  221. package/native/core/FontRegistry.h +51 -0
  222. package/native/core/GestureHandlerModule.cpp +136 -0
  223. package/native/core/GestureHandlerModule.h +71 -0
  224. package/native/core/Gestures.cpp +533 -0
  225. package/native/core/Gestures.h +145 -0
  226. package/native/core/HoverTracker.cpp +69 -0
  227. package/native/core/HoverTracker.h +109 -0
  228. package/native/core/HttpClient.cpp +282 -0
  229. package/native/core/ImageBytes.cpp +205 -0
  230. package/native/core/ImageBytes.h +29 -0
  231. package/native/core/ImageCache.cpp +51 -0
  232. package/native/core/ImageCache.h +89 -0
  233. package/native/core/JsRuntimeAccess.cpp +70 -0
  234. package/native/core/JsRuntimeAccess.h +60 -0
  235. package/native/core/JsiPromise.h +51 -0
  236. package/native/core/KeyEvents.cpp +116 -0
  237. package/native/core/KeyEvents.h +144 -0
  238. package/native/core/LogBoxSurface.cpp +46 -0
  239. package/native/core/LogBoxSurface.h +68 -0
  240. package/native/core/MenuModel.h +117 -0
  241. package/native/core/MenuModule.cpp +209 -0
  242. package/native/core/MenuModule.h +66 -0
  243. package/native/core/MountingWalk.h +524 -0
  244. package/native/core/PackageModules.cpp.in +25 -0
  245. package/native/core/PackageModules.h +50 -0
  246. package/native/core/PlatformConstantsModule.cpp +63 -0
  247. package/native/core/PlatformConstantsModule.h +64 -0
  248. package/native/core/PlatformServices.h +213 -0
  249. package/native/core/PointerButtons.h +63 -0
  250. package/native/core/PullToRefresh.cpp +57 -0
  251. package/native/core/PullToRefresh.h +73 -0
  252. package/native/core/ReanimatedCompat.h +47 -0
  253. package/native/core/ReanimatedModule.cpp +203 -0
  254. package/native/core/ReanimatedModule.h +55 -0
  255. package/native/core/ScrollAnimation.cpp +59 -0
  256. package/native/core/ScrollAnimation.h +70 -0
  257. package/native/core/ScrollBounds.cpp +26 -0
  258. package/native/core/ScrollBounds.h +68 -0
  259. package/native/core/ScrollIndicator.cpp +50 -0
  260. package/native/core/ScrollIndicator.h +69 -0
  261. package/native/core/ScrollMomentum.cpp +71 -0
  262. package/native/core/ScrollMomentum.h +73 -0
  263. package/native/core/ScrollSnap.cpp +123 -0
  264. package/native/core/ScrollSnap.h +80 -0
  265. package/native/core/ShareFallback.cpp +101 -0
  266. package/native/core/ShareFallback.h +45 -0
  267. package/native/core/SkiaPictureViewComponent.cpp +11 -0
  268. package/native/core/SkiaPictureViewComponent.h +47 -0
  269. package/native/core/SourceCodeModule.cpp +55 -0
  270. package/native/core/SourceCodeModule.h +53 -0
  271. package/native/core/StatusBarModule.cpp +23 -0
  272. package/native/core/StatusBarModule.h +42 -0
  273. package/native/core/TestDialog.cpp +148 -0
  274. package/native/core/TestDialog.h +96 -0
  275. package/native/core/TestKeys.cpp +78 -0
  276. package/native/core/TestKeys.h +50 -0
  277. package/native/core/TestQuitFile.cpp +33 -0
  278. package/native/core/TestQuitFile.h +60 -0
  279. package/native/core/TestSettle.h +192 -0
  280. package/native/core/TitleBarRegions.h +31 -0
  281. package/native/core/TurboModuleProxy.cpp +51 -0
  282. package/native/core/TurboModuleProxy.h +46 -0
  283. package/native/core/UIManagerAccess.cpp +43 -0
  284. package/native/core/UIManagerAccess.h +43 -0
  285. package/native/core/WindowBoundsCache.cpp +319 -0
  286. package/native/core/WindowControl.h +235 -0
  287. package/native/core/WindowHost.h +158 -0
  288. package/native/core/WindowMethods.cpp +167 -0
  289. package/native/core/WindowMethods.h +84 -0
  290. package/native/core/WindowsModule.cpp +448 -0
  291. package/native/core/WindowsModule.h +133 -0
  292. package/native/core/WorkletsModule.cpp +199 -0
  293. package/native/core/WorkletsModule.h +57 -0
  294. package/native/core/portability_probe.cpp +210 -0
  295. package/native/tests/EventRecorder.h +124 -0
  296. package/native/tests/TestHarness.cpp +109 -0
  297. package/native/tests/TestHarness.h +89 -0
  298. package/native/tests/TreeDump.h +49 -0
  299. package/native/tests/test_app_identity.cpp +114 -0
  300. package/native/tests/test_app_paths.cpp +48 -0
  301. package/native/tests/test_appearance.cpp +107 -0
  302. package/native/tests/test_backface.cpp +79 -0
  303. package/native/tests/test_blobs.cpp +157 -0
  304. package/native/tests/test_controls.cpp +185 -0
  305. package/native/tests/test_devbundle.cpp +103 -0
  306. package/native/tests/test_drag_and_drop.cpp +143 -0
  307. package/native/tests/test_gestures.cpp +331 -0
  308. package/native/tests/test_hover.cpp +92 -0
  309. package/native/tests/test_image_cache.cpp +109 -0
  310. package/native/tests/test_js_runtime_access.cpp +137 -0
  311. package/native/tests/test_key_events.cpp +235 -0
  312. package/native/tests/test_momentum.cpp +138 -0
  313. package/native/tests/test_quit_file.cpp +104 -0
  314. package/native/tests/test_scroll_animation.cpp +120 -0
  315. package/native/tests/test_scroll_bounds.cpp +66 -0
  316. package/native/tests/test_scroll_indicator.cpp +149 -0
  317. package/native/tests/test_scroll_snap.cpp +112 -0
  318. package/native/tests/test_settle.cpp +115 -0
  319. package/native/tests/test_share.cpp +75 -0
  320. package/native/tests/test_sourcecode.cpp +62 -0
  321. package/native/tests/test_window_close.cpp +119 -0
  322. package/native/tests/test_window_limits.cpp +123 -0
  323. package/package.json +43 -0
  324. package/react-native.config.js +86 -0
  325. package/supported-versions.json +66 -0
@@ -0,0 +1,290 @@
1
+ # Provides the third-party CMake target *names* React Native's own CMakeLists
2
+ # link against, backed by system packages where possible and by vendored
3
+ # sources where not.
4
+ #
5
+ # React Native normally gets these from its Android build (gradle downloads and
6
+ # unpacks each one under third-party-ndk). A host build has no such step, so we
7
+ # supply equivalents here. Fantom does the same thing for its tester.
8
+ #
9
+ # Two ways of finding the same four libraries, and the split is Windows.
10
+ #
11
+ # On Linux and macOS they come from the system -- apt or Homebrew -- and
12
+ # `find_library` is the right tool, because a distro's package installs a bare
13
+ # `libglog.so` in a directory the linker already searches. On Windows there is
14
+ # no system to install them into. vcpkg is the equivalent, and it ships proper
15
+ # CMake config packages, which is a better answer than `find_library` even
16
+ # where both would work: a config package carries the include directories, the
17
+ # transitive dependencies and the debug/release split, and a bare
18
+ # `find_library` on `boost_regex` would not even match the name vcpkg gives it
19
+ # (`boost_regex-vc143-mt-x64-1_89.lib`).
20
+ #
21
+ # The target names below -- `glog`, `boost`, `double-conversion`, `fmt` -- are
22
+ # not ours to choose either way. They are what React Native's own CMakeLists
23
+ # link against.
24
+ if(WIN32)
25
+ find_package(glog CONFIG REQUIRED)
26
+ find_package(Boost CONFIG REQUIRED COMPONENTS regex thread)
27
+ find_package(double-conversion CONFIG REQUIRED)
28
+ find_package(fmt CONFIG REQUIRED)
29
+
30
+ # React Native's CMakeLists link the bare names; vcpkg's config packages
31
+ # define namespaced ones. These INTERFACE targets stand in the middle.
32
+ # Guarded on the name not already existing, because a config package is
33
+ # entitled to define the bare name too and CMake refuses a duplicate.
34
+ if(NOT TARGET glog)
35
+ add_library(glog INTERFACE)
36
+ target_link_libraries(glog INTERFACE glog::glog)
37
+ endif()
38
+ target_compile_definitions(glog INTERFACE GLOG_USE_GLOG_EXPORT)
39
+
40
+ add_library(boost INTERFACE)
41
+ # Boost::thread as well as regex: folly's Windows PThread.cpp is written over
42
+ # boost::thread, and its thread-local storage needs the compiled library
43
+ # rather than the headers.
44
+ target_link_libraries(boost INTERFACE Boost::regex Boost::thread Boost::headers)
45
+
46
+ if(NOT TARGET double-conversion)
47
+ add_library(double-conversion INTERFACE)
48
+ target_link_libraries(double-conversion INTERFACE double-conversion::double-conversion)
49
+ endif()
50
+
51
+ if(NOT TARGET fmt)
52
+ add_library(fmt INTERFACE)
53
+ target_link_libraries(fmt INTERFACE fmt::fmt)
54
+ endif()
55
+
56
+ # As on the other platforms: nothing on a host build needs glog's signal
57
+ # handlers, and React Native's Android build is the only thing that has them.
58
+ add_library(glog_init INTERFACE)
59
+ else()
60
+
61
+ # --- glog ------------------------------------------------------------------
62
+ # RN pins glog 0.3.5; distros ship 0.7.x, which added a guard requiring
63
+ # GLOG_USE_GLOG_EXPORT when the headers are not consumed via glog's own CMake
64
+ # target. Without it every glog header hard-errors.
65
+ find_library(GLOG_LIBRARY glog REQUIRED)
66
+ find_path(GLOG_INCLUDE_DIR glog/logging.h REQUIRED)
67
+ add_library(glog INTERFACE)
68
+ target_link_libraries(glog INTERFACE ${GLOG_LIBRARY})
69
+ # Distros put headers in /usr/include; Homebrew does not, so carry the path.
70
+ target_include_directories(glog INTERFACE ${GLOG_INCLUDE_DIR})
71
+ target_compile_definitions(glog INTERFACE GLOG_USE_GLOG_EXPORT)
72
+
73
+ # RN's Android build has a glog_init target that installs signal handlers.
74
+ # Nothing on a host build needs it; Fantom stubs it the same way.
75
+ add_library(glog_init INTERFACE)
76
+
77
+ # --- boost -----------------------------------------------------------------
78
+ # Headers only, with one exception: folly's Uri parser uses boost::regex, which
79
+ # is a compiled library. Uri is pulled in by React Native's websocket client
80
+ # (see rn_websocket in ReactNativeCore.cmake), so it is needed as soon as the
81
+ # dev server is. boost::asio and boost::beast, which that client also uses, are
82
+ # header-only.
83
+ find_path(BOOST_INCLUDE_DIR boost/version.hpp REQUIRED)
84
+ find_library(BOOST_REGEX_LIBRARY NAMES boost_regex boost_regex-mt REQUIRED)
85
+ add_library(boost INTERFACE)
86
+ target_include_directories(boost INTERFACE ${BOOST_INCLUDE_DIR})
87
+ target_link_libraries(boost INTERFACE ${BOOST_REGEX_LIBRARY})
88
+
89
+ # --- double-conversion -----------------------------------------------------
90
+ find_library(DOUBLE_CONVERSION_LIBRARY double-conversion REQUIRED)
91
+ find_path(DOUBLE_CONVERSION_INCLUDE_DIR double-conversion/double-conversion.h REQUIRED)
92
+ add_library(double-conversion INTERFACE)
93
+ target_link_libraries(double-conversion INTERFACE ${DOUBLE_CONVERSION_LIBRARY})
94
+ target_include_directories(double-conversion INTERFACE ${DOUBLE_CONVERSION_INCLUDE_DIR})
95
+
96
+ # --- fmt -------------------------------------------------------------------
97
+ find_library(FMT_LIBRARY fmt REQUIRED)
98
+ find_path(FMT_INCLUDE_DIR fmt/format.h REQUIRED)
99
+ add_library(fmt INTERFACE)
100
+ target_link_libraries(fmt INTERFACE ${FMT_LIBRARY})
101
+ target_include_directories(fmt INTERFACE ${FMT_INCLUDE_DIR})
102
+
103
+ endif() # WIN32 -- everything below is the same on all three platforms.
104
+
105
+ # --- fast_float (vendored, header-only) ------------------------------------
106
+ add_library(fast_float INTERFACE)
107
+ target_include_directories(fast_float INTERFACE ${FAST_FLOAT_DIR}/include)
108
+
109
+ # --- folly_runtime ---------------------------------------------------------
110
+ # The trimmed folly RN actually builds: ~30 translation units, no config step,
111
+ # no coroutines. Source list and flags mirror
112
+ # private/react-native-fantom/tester/third-party/folly/CMakeLists.txt.
113
+ # Three of these are claims about POSIX and are false on Windows. folly reads
114
+ # them as "the platform has this", not as "please provide it", so leaving them
115
+ # defined on Windows makes it call recvmmsg, pthread_setname_np and the XSI
116
+ # strerror_r, none of which exist -- and it fails at link rather than at
117
+ # configure, which is a worse place to find out.
118
+ #
119
+ # FOLLY_HAVE_CLOCK_GETTIME is the interesting one. Windows has no
120
+ # clock_gettime, but folly's portability layer *provides* one, and defining the
121
+ # flag is how folly is told to use its own rather than expect the system's.
122
+ set(folly_FLAGS
123
+ -DFOLLY_NO_CONFIG=1
124
+ -DFOLLY_HAVE_CLOCK_GETTIME=1
125
+ -DFOLLY_CFG_NO_COROUTINES=1
126
+ -DFOLLY_MOBILE=0)
127
+ if(NOT WIN32)
128
+ list(APPEND folly_FLAGS
129
+ -DFOLLY_HAVE_RECVMMSG=1
130
+ -DFOLLY_HAVE_PTHREAD=1
131
+ -DFOLLY_HAVE_XSI_STRERROR_R=1)
132
+ endif()
133
+
134
+ set(folly_runtime_SRC
135
+ Conv.cpp Demangle.cpp FileUtil.cpp Format.cpp ScopeGuard.cpp
136
+ SharedMutex.cpp String.cpp Unicode.cpp
137
+ concurrency/CacheLocality.cpp
138
+ container/detail/F14Table.cpp
139
+ detail/FileUtilDetail.cpp detail/Futex.cpp
140
+ detail/SplitStringSimd.cpp detail/UniqueInstance.cpp
141
+ hash/SpookyHashV2.cpp
142
+ io/IOBuf.cpp
143
+ json/dynamic.cpp json/json_pointer.cpp json/json.cpp
144
+ # Not in React Native's own folly source list. Its websocket client
145
+ # parses the packager URL with folly::Uri, so a host that talks to the
146
+ # dev server needs it.
147
+ Uri.cpp
148
+ lang/CString.cpp lang/Exception.cpp lang/SafeAssert.cpp lang/ToAscii.cpp
149
+ memory/SanitizeAddress.cpp memory/detail/MallocImpl.cpp
150
+ net/NetOps.cpp
151
+ portability/SysUio.cpp
152
+ synchronization/SanitizeThread.cpp synchronization/ParkingLot.cpp
153
+ system/AtFork.cpp system/ThreadId.cpp system/ThreadName.cpp)
154
+ # folly's Windows portability layer, which React Native's own source list does
155
+ # not carry because React Native does not build folly on Windows -- it consumes
156
+ # a prebuilt one. These are not shims this project wrote: nineteen of folly's
157
+ # twenty-one portability sources already have `_WIN32` branches, and this is the
158
+ # subset the translation units above reach. Without them the build gets all the
159
+ # way to the linker and fails on `open`, `pthread_key_create`, `gettimeofday`
160
+ # and thirty more.
161
+ if(WIN32)
162
+ list(APPEND folly_runtime_SRC
163
+ portability/Dirent.cpp
164
+ portability/Fcntl.cpp
165
+ portability/Malloc.cpp
166
+ portability/PThread.cpp
167
+ portability/Sched.cpp
168
+ portability/Sockets.cpp
169
+ portability/Stdio.cpp
170
+ portability/Stdlib.cpp
171
+ portability/String.cpp
172
+ portability/SysFile.cpp
173
+ portability/SysMembarrier.cpp
174
+ portability/SysMman.cpp
175
+ portability/SysResource.cpp
176
+ portability/SysStat.cpp
177
+ portability/SysTime.cpp
178
+ portability/Time.cpp
179
+ portability/Unistd.cpp
180
+ # Not under portability/: folly keeps its Windows socket-handle table in
181
+ # net/detail. Without it the link fails on SocketFileDescriptorMap, which
182
+ # is what folly::netops uses to make a SOCKET look like an fd.
183
+ net/detail/SocketFileDescriptorMap.cpp)
184
+ endif()
185
+
186
+ list(TRANSFORM folly_runtime_SRC PREPEND ${FOLLY_DIR}/folly/)
187
+
188
+ add_library(folly_runtime STATIC ${folly_runtime_SRC})
189
+ target_compile_options(folly_runtime PRIVATE
190
+ ${BASALT_EXCEPTIONS_FLAG} ${BASALT_FRAME_POINTER_FLAG} ${BASALT_RTTI_FLAG}
191
+ ${BASALT_NO_SIGN_COMPARE_FLAG} ${folly_FLAGS})
192
+ target_compile_options(folly_runtime PUBLIC ${folly_FLAGS})
193
+ if(WIN32)
194
+ # ws2_32 for the sockets folly's net layer wraps, and NOMINMAX because folly
195
+ # uses std::min and std::max in headers that windows.h has already redefined
196
+ # as macros by the time they are reached.
197
+ # winmm for timeBeginPeriod/timeEndPeriod, which folly's Windows clock uses to
198
+ # ask for a finer timer resolution.
199
+ target_link_libraries(folly_runtime ws2_32 winmm)
200
+ target_compile_definitions(folly_runtime PUBLIC NOMINMAX WIN32_LEAN_AND_MEAN)
201
+ endif()
202
+ target_include_directories(folly_runtime PUBLIC ${FOLLY_DIR})
203
+ target_link_libraries(folly_runtime glog double-conversion boost fmt fast_float)
204
+
205
+ # --- nlohmann_json (vendored, header-only) ---------------------------------
206
+ # Needed by ReactCxxPlatform's devsupport (PackagerConnection).
207
+ add_library(nlohmann_json INTERFACE)
208
+ target_include_directories(nlohmann_json INTERFACE ${NLOHMANN_JSON_DIR}/include)
209
+
210
+ # --- OpenSSL ---------------------------------------------------------------
211
+ # Also devsupport: the packager connection speaks WebSocket over TLS.
212
+ find_package(OpenSSL REQUIRED)
213
+
214
+ # --- libcurl ---------------------------------------------------------------
215
+ # Backs src/LinuxNetworking.cpp's IHttpClient: the dev server bundle fetch and
216
+ # NetworkingModule (fetch/XHR) both go through it. Present on macOS in the SDK;
217
+ # on Linux it is the curl development package.
218
+ find_package(CURL REQUIRED)
219
+
220
+ # --- Hermes ----------------------------------------------------------------
221
+ # Built separately from RN's pinned tarball; see README. Fantom locates the
222
+ # same library out of its Android hermes-engine build dir.
223
+ # Two names, because Hermes renamed the library. React Native 0.81's Hermes
224
+ # builds `libhermes`; the one 0.87 and main use builds `libhermesvm`. Which one
225
+ # is present follows from the version in supported-versions.json, so this looks
226
+ # for either rather than being told.
227
+ find_library(HERMES_VM_LIBRARY NAMES hermesvm hermes
228
+ HINTS ${HERMES_BUILD_DIR}/API/hermes ${HERMES_BUILD_DIR}/lib
229
+ REQUIRED)
230
+
231
+ # Two things about Hermes on Windows that follow from static archives not
232
+ # behaving like shared libraries, and neither of which is visible elsewhere.
233
+ #
234
+ # First, the name found above is wrong here. Hermes' `hermesvm` target builds a
235
+ # DLL, and a Windows DLL exports nothing without __declspec(dllexport), which
236
+ # Hermes does not annotate -- so `hermesvm.lib` is a one-kilobyte import library
237
+ # for a DLL with nothing in it, next to a thirty-megabyte `hermesvm_a.lib` that
238
+ # has the engine. On Linux the shared object works because ELF exports
239
+ # everything by default; that default is the only reason the name is right
240
+ # there.
241
+ #
242
+ # Second, jsi has to be named separately. `-DJSI_DIR` makes the Hermes build
243
+ # compile React Native's jsi, and on Linux libhermesvm.so absorbs it the way a
244
+ # shared library absorbs its static dependencies. A static archive absorbs
245
+ # nothing, so on Windows jsi.lib is a second file and the link fails on
246
+ # jsi::Value and jsi::JSError without it.
247
+ if(WIN32)
248
+ find_library(HERMES_VM_STATIC_LIBRARY NAMES hermesvm_a
249
+ HINTS ${HERMES_BUILD_DIR}/lib REQUIRED)
250
+ find_library(HERMES_JSI_LIBRARY NAMES jsi
251
+ HINTS ${HERMES_BUILD_DIR}/jsi REQUIRED)
252
+ # And ICU. Hermes reports "Using Windows 10 built-in ICU" at configure time
253
+ # and defines USE_WIN10_ICU, which means it calls u_strToUpper, ucol_strcoll
254
+ # and friends out of the operating system's own icu.dll rather than vendoring
255
+ # a copy. `icu.lib` is that DLL's import library and ships with the Windows
256
+ # SDK. Nothing names it for us: on Linux the equivalent arrives through
257
+ # pkg-config, and on a shared-library platform it would have been recorded as
258
+ # a dependency of libhermesvm.so.
259
+ set(HERMES_LINK_LIBRARIES
260
+ ${HERMES_VM_STATIC_LIBRARY} ${HERMES_JSI_LIBRARY} icu)
261
+ else()
262
+ set(HERMES_LINK_LIBRARIES ${HERMES_VM_LIBRARY})
263
+ endif()
264
+ # Both names, for the same reason the find_library above takes both: React
265
+ # Native 0.81's own CMakeLists link hermes-engine::libhermes, and 0.87 and main
266
+ # link hermes-engine::hermesvm. Only one of them is ever referenced by a given
267
+ # React Native, and defining the other costs nothing.
268
+ # GLOBAL because the platform packages are separate directories now: an
269
+ # imported target is visible only in the directory that created it and below,
270
+ # and basalt-gtk adds this one as a *sibling* subdirectory rather
271
+ # than containing it. Without GLOBAL the failure is "target was not found" at
272
+ # generate time, naming the target and not the scope.
273
+ foreach(hermes_alias hermesvm libhermes)
274
+ add_library(hermes-engine::${hermes_alias} INTERFACE IMPORTED GLOBAL)
275
+ # Quoted, because on Windows this is two libraries rather than one and an
276
+ # unquoted list would arrive as extra arguments to set_target_properties.
277
+ set_target_properties(hermes-engine::${hermes_alias} PROPERTIES
278
+ INTERFACE_LINK_LIBRARIES "${HERMES_LINK_LIBRARIES}")
279
+ endforeach()
280
+
281
+ # Hermes' public headers must be globally visible: RN's own hermes/executor and
282
+ # hermes/inspector-modern targets include <hermes/hermes.h> without declaring a
283
+ # dependency that would carry the path. Fantom does the same with a global
284
+ # include_directories() over its prefab-headers dir.
285
+ #
286
+ # RN's jsi is used rather than Hermes' vendored copy, so API/ and public/ only.
287
+ include_directories(
288
+ ${HERMES_DIR}/API
289
+ ${HERMES_DIR}/public
290
+ ${HERMES_BUILD_DIR}/lib/config)
@@ -0,0 +1,67 @@
1
+ # react-native-worklets, compiled from the app's own copy.
2
+ #
3
+ # The same arrangement as Expo.cmake and for the same reason: the package ships
4
+ # its portable half as C++ in `Common/cpp`, depending on jsi, Hermes, a call
5
+ # invoker and nothing else, so the app's own copy compiles at the app's own
6
+ # version. Nothing is vendored and nothing is pinned.
7
+ #
8
+ # What the package does *not* ship for a desktop is the host half -- the
9
+ # TurboModule, the UI scheduler, the frame queue and the platform logger are
10
+ # written per platform, and iOS's and Android's are a few hundred lines each.
11
+ # Those are core/Worklets*.{h,cpp} here.
12
+ #
13
+ # Reanimated sits on top of this and is the same shape again; see
14
+
15
+ if(NOT DEFINED BASALT_WORKLETS)
16
+ return()
17
+ endif()
18
+
19
+ get_filename_component(WORKLETS_DIR "${BASALT_WORKLETS}" ABSOLUTE)
20
+ set(WORKLETS_CPP_DIR ${WORKLETS_DIR}/Common/cpp)
21
+
22
+ if(NOT EXISTS ${WORKLETS_CPP_DIR}/worklets/WorkletRuntime/WorkletRuntime.cpp)
23
+ message(FATAL_ERROR
24
+ "no react-native-worklets C++ at ${WORKLETS_CPP_DIR}.\n"
25
+ "BASALT_WORKLETS should name an installed react-native-worklets, "
26
+ "the one in the app's node_modules.")
27
+ endif()
28
+
29
+ # The version the package declares, which its C++ compares against the version
30
+ # its JavaScript declares and warns about when they differ. Read from the
31
+ # package rather than pinned, for the same reason everything else here is.
32
+ file(READ ${WORKLETS_DIR}/package.json WORKLETS_PACKAGE_JSON)
33
+ string(JSON WORKLETS_VERSION GET "${WORKLETS_PACKAGE_JSON}" version)
34
+
35
+ file(GLOB_RECURSE WORKLETS_SRC CONFIGURE_DEPENDS ${WORKLETS_CPP_DIR}/worklets/*.cpp)
36
+
37
+ add_library(worklets_core OBJECT ${WORKLETS_SRC})
38
+ # SYSTEM, and warnings off: somebody else's sources held to somebody else's
39
+ # warning set. This project's -Wall -Wextra -Werror is about its own code.
40
+ target_include_directories(worklets_core SYSTEM PUBLIC
41
+ ${WORKLETS_CPP_DIR}
42
+ ${RN_DIR}/ReactCommon
43
+ ${RN_DIR}/ReactCommon/jsi
44
+ ${RN_DIR}/ReactCommon/callinvoker
45
+ ${RN_DIR}/ReactCommon/cxxreact
46
+ ${RN_DIR}/ReactCommon/jsiexecutor
47
+ ${RN_DIR}/ReactCommon/runtimeexecutor
48
+ ${FOLLY_DIR})
49
+ target_compile_options(worklets_core PRIVATE -w)
50
+ target_compile_definitions(worklets_core PUBLIC
51
+ WORKLETS_VERSION=${WORKLETS_VERSION}
52
+ WORKLETS_FEATURE_FLAGS=\"\")
53
+ target_link_libraries(worklets_core folly_runtime glog hermes-engine::hermesvm)
54
+ if(APPLE)
55
+ # AsyncQueueImpl wraps each job in an autorelease pool on Apple platforms,
56
+ # which is right and needs the Objective-C runtime -- even for the GTK host,
57
+ # which is built on macOS here and is otherwise pure C++.
58
+ target_link_libraries(worklets_core "-framework Foundation")
59
+ endif()
60
+
61
+ message(STATUS "Worklets from ${WORKLETS_DIR}")
62
+
63
+ # Not add_compile_definitions: that is directory-scoped, and the hosts are
64
+ # sibling directories since the packages were split, so they would compile
65
+ # without it and quietly not offer the module. It goes on basalt_core as PUBLIC
66
+ # instead, where linking carries it -- the same fix BASALT_RN_MINOR needed.
67
+ # See the target_compile_definitions beside basalt_core in ../CMakeLists.txt.
@@ -0,0 +1,32 @@
1
+ # Replaces the CMakeLists that generate-codegen-artifacts.js emits alongside
2
+ # the generated sources, which links Android-only targets (fbjni,
3
+ # turbomodulejsijni). Mirrors private/react-native-fantom/tester/codegen/
4
+ # CMakeLists.txt. bootstrap.sh regenerates the sources around this file and
5
+ # must not overwrite it.
6
+
7
+ cmake_minimum_required(VERSION 3.13)
8
+
9
+ # Only the Fabric component specs. The top-level FBReactNativeSpec-generated.cpp
10
+ # is the JNI TurboModule binding and includes ReactCommon/JavaTurboModule.h,
11
+ # which is Android-only. Fantom excludes it the same way.
12
+ file(GLOB react_codegen_SRCS CONFIGURE_DEPENDS
13
+ react/renderer/components/FBReactNativeSpec/*.cpp)
14
+
15
+ add_library(react_codegen_rncore OBJECT ${react_codegen_SRCS})
16
+
17
+ target_include_directories(react_codegen_rncore PUBLIC
18
+ ${CMAKE_CURRENT_SOURCE_DIR}
19
+ ${CMAKE_CURRENT_SOURCE_DIR}/react/renderer/components/FBReactNativeSpec
20
+ ${CMAKE_CURRENT_SOURCE_DIR}/react/renderer/components)
21
+
22
+ target_link_libraries(react_codegen_rncore
23
+ jsi
24
+ react_nativemodule_core
25
+ rrc_view)
26
+
27
+ target_compile_options(react_codegen_rncore PRIVATE
28
+ -DLOG_TAG=\"ReactNative\"
29
+ -fexceptions
30
+ -frtti
31
+ -std=c++20
32
+ -Wall)
@@ -0,0 +1,85 @@
1
+ #include "AppIdentity.h"
2
+
3
+ #include <folly/json.h>
4
+
5
+ #include <filesystem>
6
+ #include <fstream>
7
+ #include <mutex>
8
+ #include <sstream>
9
+
10
+ namespace basalt {
11
+
12
+ namespace {
13
+
14
+ AppIdentity &storage() {
15
+ static AppIdentity identity;
16
+ return identity;
17
+ }
18
+
19
+ std::once_flag &readOnce() {
20
+ static std::once_flag flag;
21
+ return flag;
22
+ }
23
+
24
+ AppIdentity readFrom(const std::string &bundlePath) {
25
+ AppIdentity identity;
26
+
27
+ std::error_code error;
28
+ const std::filesystem::path bundle(bundlePath);
29
+ const std::filesystem::path file =
30
+ (bundle.has_parent_path() ? bundle.parent_path() : std::filesystem::current_path(error)) /
31
+ "app.identity.json";
32
+
33
+ std::ifstream stream(file);
34
+ if (!stream) {
35
+ return identity;
36
+ }
37
+ std::stringstream contents;
38
+ contents << stream.rdbuf();
39
+
40
+ try {
41
+ const folly::dynamic parsed = folly::parseJson(contents.str());
42
+ if (!parsed.isObject()) {
43
+ return identity;
44
+ }
45
+ if (const auto *name = parsed.get_ptr("name"); name != nullptr && name->isString()) {
46
+ identity.name = name->asString();
47
+ }
48
+ if (const auto *id = parsed.get_ptr("identifier"); id != nullptr && id->isString()) {
49
+ identity.identifier = id->asString();
50
+ }
51
+ if (const auto *version = parsed.get_ptr("version"); version != nullptr && version->isString()) {
52
+ identity.version = version->asString();
53
+ }
54
+ if (const auto *schemes = parsed.get_ptr("schemes"); schemes != nullptr && schemes->isArray()) {
55
+ for (const auto &scheme : *schemes) {
56
+ if (scheme.isString()) {
57
+ identity.schemes.push_back(scheme.asString());
58
+ }
59
+ }
60
+ }
61
+ } catch (const std::exception &) {
62
+ // A malformed file is the same as none. It is written by this project's own
63
+ // CLI, so a parse failure means somebody edited it by hand -- and refusing
64
+ // to start over it would be a worse answer than starting without an icon.
65
+ return AppIdentity{};
66
+ }
67
+ return identity;
68
+ }
69
+
70
+ } // namespace
71
+
72
+ AppIdentity readAppIdentity(const std::string &bundlePath) {
73
+ return readFrom(bundlePath);
74
+ }
75
+
76
+ const AppIdentity &appIdentity(const std::string &bundlePath) {
77
+ std::call_once(readOnce(), [&bundlePath] { storage() = readFrom(bundlePath); });
78
+ return storage();
79
+ }
80
+
81
+ const AppIdentity &appIdentity() {
82
+ return storage();
83
+ }
84
+
85
+ } // namespace basalt
@@ -0,0 +1,59 @@
1
+ // What the app calls itself, as the desktop needs to know it.
2
+ //
3
+ // A host is a generic binary: it is handed a bundle and a module name and has
4
+ // no idea what application it is. That is fine for drawing and not fine for
5
+ // anything the operating system keys on identity -- a notification's name and
6
+ // icon, a taskbar group, a registered URL scheme.
7
+ //
8
+ // `cli/packageApp.js` writes the answer beside the bundle as `app.identity.json`
9
+ // and this reads it. Beside the bundle rather than beside the executable
10
+ // because the executable is shared by every app on the machine, and beside it
11
+ // rather than passed as an argument because a shortcut the person clicks in a
12
+ // month has no environment to carry one.
13
+ //
14
+ // Everything here degrades rather than fails: an app built by hand, with no
15
+ // identity file, gets an empty identity, and each caller decides what that
16
+ // means. Windows treats it as "no AppUserModelID, so no toasts", which is the
17
+ // same answer it gave before any of this existed.
18
+
19
+ #pragma once
20
+
21
+ #include <string>
22
+ #include <vector>
23
+
24
+ namespace basalt {
25
+
26
+ struct AppIdentity {
27
+ // What a person sees: "The Demo".
28
+ std::string name;
29
+ // Reverse-DNS, and on Windows also the AppUserModelID: "com.example.demo".
30
+ std::string identifier;
31
+ // URL schemes the app claims, without the "://".
32
+ std::vector<std::string> schemes;
33
+ std::string version;
34
+
35
+ bool empty() const {
36
+ return identifier.empty();
37
+ }
38
+ };
39
+
40
+ // Reads `app.identity.json` from beside `bundlePath`, with no caching. Returns
41
+ // an empty identity when there is none, when it cannot be parsed, or when it
42
+ // says nothing useful -- none of which is an error.
43
+ //
44
+ // Separate from the cached reader below so that it can be tested: the cache is
45
+ // process-wide and answers once, which a test cannot work with.
46
+ AppIdentity readAppIdentity(const std::string &bundlePath);
47
+
48
+ // Reads `app.identity.json` from beside `bundlePath`. Returns an empty identity
49
+ // when there is none, which is not an error.
50
+ //
51
+ // Read once and cached: it is consulted from startup and from the notification
52
+ // path, and it cannot change under a running process.
53
+ const AppIdentity &appIdentity(const std::string &bundlePath);
54
+
55
+ // The identity read earlier, or an empty one when nothing has read it yet.
56
+ // For the callers that have no bundle path in reach.
57
+ const AppIdentity &appIdentity();
58
+
59
+ } // namespace basalt
@@ -0,0 +1,96 @@
1
+ #include "AppPaths.h"
2
+
3
+ #include <cstdint>
4
+ #include <filesystem>
5
+ #include <string>
6
+ #include <utility>
7
+
8
+ #if defined(__APPLE__)
9
+ #include <mach-o/dyld.h>
10
+ #elif defined(_WIN32)
11
+ #include <windows.h>
12
+ #endif
13
+
14
+ namespace basalt {
15
+
16
+ namespace {
17
+
18
+ // The running executable, by each platform's own way of asking. There is no
19
+ // portable one: argv[0] is whatever the caller passed and may be a bare name.
20
+ std::string executablePath() {
21
+ #if defined(__APPLE__)
22
+ uint32_t size = 0;
23
+ _NSGetExecutablePath(nullptr, &size);
24
+ std::string buffer(size, '\0');
25
+ if (_NSGetExecutablePath(buffer.data(), &size) != 0) {
26
+ return {};
27
+ }
28
+ // Sized to include the terminator, so the string has one inside it.
29
+ return buffer.c_str();
30
+ #elif defined(_WIN32)
31
+ std::wstring buffer(MAX_PATH, L'\0');
32
+ DWORD length = GetModuleFileNameW(nullptr, buffer.data(), static_cast<DWORD>(buffer.size()));
33
+ while (length == buffer.size()) {
34
+ // The path was longer than the buffer, which GetModuleFileNameW reports by
35
+ // filling it exactly; there is no other way to ask how long it is.
36
+ buffer.resize(buffer.size() * 2);
37
+ length = GetModuleFileNameW(nullptr, buffer.data(), static_cast<DWORD>(buffer.size()));
38
+ }
39
+ if (length == 0) {
40
+ return {};
41
+ }
42
+ buffer.resize(length);
43
+ const int bytes = WideCharToMultiByte(
44
+ CP_UTF8, 0, buffer.c_str(), static_cast<int>(buffer.size()), nullptr, 0, nullptr, nullptr);
45
+ if (bytes <= 0) {
46
+ return {};
47
+ }
48
+ std::string utf8(static_cast<size_t>(bytes), '\0');
49
+ WideCharToMultiByte(
50
+ CP_UTF8, 0, buffer.c_str(), static_cast<int>(buffer.size()), utf8.data(), bytes, nullptr,
51
+ nullptr);
52
+ return utf8;
53
+ #else
54
+ std::error_code code;
55
+ const std::filesystem::path resolved = std::filesystem::read_symlink("/proc/self/exe", code);
56
+ return code ? std::string{} : resolved.string();
57
+ #endif
58
+ }
59
+
60
+ } // namespace
61
+
62
+ std::string applicationResourcePath() {
63
+ const std::string executable = executablePath();
64
+ if (executable.empty()) {
65
+ return {};
66
+ }
67
+
68
+ std::error_code ignored;
69
+ const std::filesystem::path directory =
70
+ std::filesystem::weakly_canonical(std::filesystem::path(executable).parent_path(), ignored);
71
+
72
+ // `Foo.app/Contents/MacOS/basalt_appkit` -> `Foo.app/Contents/Resources`,
73
+ // which is where cli/packageApp.ts puts an app's files and where
74
+ // NSBundle.mainBundle.resourcePath would point. Recognised by the layout
75
+ // rather than by the platform, because a macOS host run straight out of a
76
+ // build directory is not in a bundle and should answer that directory.
77
+ if (directory.filename() == "MacOS" && directory.parent_path().filename() == "Contents") {
78
+ return (directory.parent_path() / "Resources").string();
79
+ }
80
+ return directory.string();
81
+ }
82
+
83
+ DesktopAppModule::DesktopAppModule(std::shared_ptr<facebook::react::CallInvoker> jsInvoker)
84
+ : TurboModule(kModuleName, std::move(jsInvoker)) {
85
+ methodMap_["getResourcePath"] = MethodMetadata{0, getResourcePath};
86
+ }
87
+
88
+ facebook::jsi::Value DesktopAppModule::getResourcePath(
89
+ facebook::jsi::Runtime &runtime,
90
+ facebook::react::TurboModule & /*module*/,
91
+ const facebook::jsi::Value * /*args*/,
92
+ size_t /*count*/) {
93
+ return facebook::jsi::String::createFromUtf8(runtime, applicationResourcePath());
94
+ }
95
+
96
+ } // namespace basalt
@@ -0,0 +1,53 @@
1
+ // Where the application's own files are.
2
+ //
3
+ // A packaged desktop application has somewhere its build put the things it
4
+ // ships with -- a script it runs, a model it loads, a binary it drives -- and
5
+ // where that is differs by desktop. This project's packager is what decides it:
6
+ // `Foo.app/Contents/Resources` beside `Contents/MacOS/basalt_appkit` on macOS,
7
+ // and beside the executable on Linux and Windows, where there is no separate
8
+ // resources directory. See cli/packageApp.ts.
9
+ //
10
+ // So it is this platform's to answer, not the app's. An app working it out for
11
+ // itself is an app that has to know the layout of a bundle it did not build --
12
+ // which is exactly the knowledge that is supposed to live here, and which
13
+ // changes the day the packager changes.
14
+ //
15
+ // Derived from the running executable rather than asked of a toolkit.
16
+ // `NSBundle.mainBundle.resourcePath` is the authoritative answer on macOS and
17
+ // there is no equivalent on the other two, so one portable derivation beats one
18
+ // real answer and two approximations -- and the layout it derives from is this
19
+ // project's own.
20
+
21
+ #pragma once
22
+
23
+ #include <FBReactNativeSpec/FBReactNativeSpecJSI.h>
24
+
25
+ #include <memory>
26
+ #include <string>
27
+
28
+ namespace basalt {
29
+
30
+ // The directory holding what the build put beside the application, or empty
31
+ // when the running executable's path cannot be determined at all.
32
+ //
33
+ // A development run, where the host is started straight out of a build
34
+ // directory, answers that directory: there is no bundle, and the honest answer
35
+ // to "where are my resources" is "where the binary is".
36
+ std::string applicationResourcePath();
37
+
38
+ // `NativeModules.BasaltApp`, which is how JavaScript asks.
39
+ class DesktopAppModule : public facebook::react::TurboModule {
40
+ public:
41
+ static constexpr auto kModuleName = "BasaltApp";
42
+
43
+ explicit DesktopAppModule(std::shared_ptr<facebook::react::CallInvoker> jsInvoker);
44
+
45
+ private:
46
+ static facebook::jsi::Value getResourcePath(
47
+ facebook::jsi::Runtime &runtime,
48
+ facebook::react::TurboModule &module,
49
+ const facebook::jsi::Value *args,
50
+ size_t count);
51
+ };
52
+
53
+ } // namespace basalt