nitrogen 0.2.23 → 0.29.4

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 (333) hide show
  1. package/README.md +15 -109
  2. package/lib/Logger.d.ts +10 -0
  3. package/lib/Logger.js +56 -0
  4. package/lib/autolinking/Autolinking.d.ts +8 -0
  5. package/lib/autolinking/Autolinking.js +1 -0
  6. package/lib/autolinking/android/createCMakeExtension.d.ts +6 -0
  7. package/lib/autolinking/android/createCMakeExtension.js +106 -0
  8. package/lib/autolinking/android/createGradleExtension.d.ts +5 -0
  9. package/lib/autolinking/android/createGradleExtension.js +36 -0
  10. package/lib/autolinking/android/createHybridObjectInitializer.d.ts +2 -0
  11. package/lib/autolinking/android/createHybridObjectInitializer.js +159 -0
  12. package/lib/autolinking/createAndroidAutolinking.d.ts +11 -0
  13. package/lib/autolinking/createAndroidAutolinking.js +13 -0
  14. package/lib/autolinking/createIOSAutolinking.d.ts +5 -0
  15. package/lib/autolinking/createIOSAutolinking.js +19 -0
  16. package/lib/autolinking/ios/createHybridObjectInitializer.d.ts +9 -0
  17. package/lib/autolinking/ios/createHybridObjectInitializer.js +97 -0
  18. package/lib/autolinking/ios/createPodspecRubyExtension.d.ts +5 -0
  19. package/lib/autolinking/ios/createPodspecRubyExtension.js +69 -0
  20. package/lib/autolinking/ios/createSwiftCxxBridge.d.ts +2 -0
  21. package/lib/autolinking/ios/createSwiftCxxBridge.js +117 -0
  22. package/lib/autolinking/ios/createSwiftUmbrellaHeader.d.ts +3 -0
  23. package/lib/autolinking/ios/createSwiftUmbrellaHeader.js +74 -0
  24. package/lib/config/NitroConfig.d.ts +52 -0
  25. package/lib/config/NitroConfig.js +112 -0
  26. package/lib/config/NitroUserConfig.d.ts +22 -0
  27. package/lib/config/NitroUserConfig.js +88 -0
  28. package/lib/config/getConfig.d.ts +2 -0
  29. package/lib/config/getConfig.js +84 -0
  30. package/lib/createGitAttributes.d.ts +1 -0
  31. package/lib/createGitAttributes.js +11 -0
  32. package/lib/createPlatformSpec.d.ts +4 -0
  33. package/lib/createPlatformSpec.js +127 -0
  34. package/lib/getFiles.d.ts +1 -0
  35. package/lib/getFiles.js +28 -0
  36. package/lib/getPlatformSpecs.d.ts +17 -0
  37. package/lib/getPlatformSpecs.js +153 -0
  38. package/lib/index.d.ts +2 -0
  39. package/lib/index.js +113 -10
  40. package/lib/init.d.ts +1 -0
  41. package/lib/init.js +123 -0
  42. package/lib/nitrogen.d.ts +11 -0
  43. package/lib/nitrogen.js +165 -0
  44. package/lib/prettifyDirectory.d.ts +1 -0
  45. package/lib/prettifyDirectory.js +27 -0
  46. package/lib/syntax/BridgedType.d.ts +41 -0
  47. package/lib/syntax/BridgedType.js +1 -0
  48. package/lib/syntax/CodeNode.d.ts +23 -0
  49. package/lib/syntax/CodeNode.js +1 -0
  50. package/lib/syntax/HybridObjectSpec.d.ts +13 -0
  51. package/lib/syntax/HybridObjectSpec.js +1 -0
  52. package/lib/syntax/Method.d.ts +41 -0
  53. package/lib/syntax/Method.js +108 -0
  54. package/lib/syntax/Parameter.d.ts +15 -0
  55. package/lib/syntax/Parameter.js +65 -0
  56. package/lib/syntax/Property.d.ts +50 -0
  57. package/lib/syntax/Property.js +147 -0
  58. package/lib/syntax/SourceFile.d.ts +70 -0
  59. package/lib/syntax/SourceFile.js +7 -0
  60. package/lib/syntax/c++/CppEnum.d.ts +6 -0
  61. package/lib/syntax/c++/CppEnum.js +110 -0
  62. package/lib/syntax/c++/CppHybridObject.d.ts +3 -0
  63. package/lib/syntax/c++/CppHybridObject.js +146 -0
  64. package/lib/syntax/c++/CppHybridObjectRegistration.d.ts +17 -0
  65. package/lib/syntax/c++/CppHybridObjectRegistration.js +18 -0
  66. package/lib/syntax/c++/CppStruct.d.ts +3 -0
  67. package/lib/syntax/c++/CppStruct.js +108 -0
  68. package/lib/syntax/c++/CppUnion.d.ts +6 -0
  69. package/lib/syntax/c++/CppUnion.js +88 -0
  70. package/lib/syntax/c++/getForwardDeclaration.d.ts +3 -0
  71. package/lib/syntax/c++/getForwardDeclaration.js +14 -0
  72. package/lib/syntax/c++/includeNitroHeader.d.ts +7 -0
  73. package/lib/syntax/c++/includeNitroHeader.js +34 -0
  74. package/lib/syntax/createType.d.ts +15 -0
  75. package/lib/syntax/createType.js +303 -0
  76. package/lib/syntax/getAllTypes.d.ts +3 -0
  77. package/lib/syntax/getAllTypes.js +11 -0
  78. package/lib/syntax/getCustomTypeConfig.d.ts +8 -0
  79. package/lib/syntax/getCustomTypeConfig.js +53 -0
  80. package/lib/syntax/getHybridObjectName.d.ts +36 -0
  81. package/lib/syntax/getHybridObjectName.js +10 -0
  82. package/lib/syntax/getInterfaceProperties.d.ts +4 -0
  83. package/lib/syntax/getInterfaceProperties.js +9 -0
  84. package/lib/syntax/getReferencedTypes.d.ts +2 -0
  85. package/lib/syntax/getReferencedTypes.js +47 -0
  86. package/lib/syntax/helpers.d.ts +13 -0
  87. package/lib/syntax/helpers.js +53 -0
  88. package/lib/syntax/isCoreType.d.ts +9 -0
  89. package/lib/syntax/isCoreType.js +47 -0
  90. package/lib/syntax/kotlin/FbjniHybridObject.d.ts +3 -0
  91. package/lib/syntax/kotlin/FbjniHybridObject.js +261 -0
  92. package/lib/syntax/kotlin/JNINativeRegistrations.d.ts +8 -0
  93. package/lib/syntax/kotlin/JNINativeRegistrations.js +7 -0
  94. package/lib/syntax/kotlin/KotlinBoxedPrimitive.d.ts +7 -0
  95. package/lib/syntax/kotlin/KotlinBoxedPrimitive.js +17 -0
  96. package/lib/syntax/kotlin/KotlinCxxBridgedType.d.ts +19 -0
  97. package/lib/syntax/kotlin/KotlinCxxBridgedType.js +893 -0
  98. package/lib/syntax/kotlin/KotlinEnum.d.ts +3 -0
  99. package/lib/syntax/kotlin/KotlinEnum.js +113 -0
  100. package/lib/syntax/kotlin/KotlinFunction.d.ts +3 -0
  101. package/lib/syntax/kotlin/KotlinFunction.js +256 -0
  102. package/lib/syntax/kotlin/KotlinHybridObject.d.ts +3 -0
  103. package/lib/syntax/kotlin/KotlinHybridObject.js +177 -0
  104. package/lib/syntax/kotlin/KotlinHybridObjectRegistration.d.ts +17 -0
  105. package/lib/syntax/kotlin/KotlinHybridObjectRegistration.js +26 -0
  106. package/lib/syntax/kotlin/KotlinStruct.d.ts +3 -0
  107. package/lib/syntax/kotlin/KotlinStruct.js +172 -0
  108. package/lib/syntax/kotlin/KotlinVariant.d.ts +3 -0
  109. package/lib/syntax/kotlin/KotlinVariant.js +191 -0
  110. package/lib/syntax/swift/SwiftCxxBridgedType.d.ts +21 -0
  111. package/lib/syntax/swift/SwiftCxxBridgedType.js +819 -0
  112. package/lib/syntax/swift/SwiftCxxTypeHelper.d.ts +17 -0
  113. package/lib/syntax/swift/SwiftCxxTypeHelper.js +613 -0
  114. package/lib/syntax/swift/SwiftEnum.d.ts +3 -0
  115. package/lib/syntax/swift/SwiftEnum.js +52 -0
  116. package/lib/syntax/swift/SwiftFunction.d.ts +3 -0
  117. package/lib/syntax/swift/SwiftFunction.js +83 -0
  118. package/lib/syntax/swift/SwiftHybridObject.d.ts +3 -0
  119. package/lib/syntax/swift/SwiftHybridObject.js +103 -0
  120. package/lib/syntax/swift/SwiftHybridObjectBridge.d.ts +11 -0
  121. package/lib/syntax/swift/SwiftHybridObjectBridge.js +451 -0
  122. package/lib/syntax/swift/SwiftHybridObjectRegistration.d.ts +19 -0
  123. package/lib/syntax/swift/SwiftHybridObjectRegistration.js +42 -0
  124. package/lib/syntax/swift/SwiftStruct.d.ts +3 -0
  125. package/lib/syntax/swift/SwiftStruct.js +75 -0
  126. package/lib/syntax/swift/SwiftVariant.d.ts +3 -0
  127. package/lib/syntax/swift/SwiftVariant.js +58 -0
  128. package/lib/syntax/types/ArrayBufferType.d.ts +10 -0
  129. package/lib/syntax/types/ArrayBufferType.js +37 -0
  130. package/lib/syntax/types/ArrayType.d.ts +12 -0
  131. package/lib/syntax/types/ArrayType.js +52 -0
  132. package/lib/syntax/types/BigIntType.d.ts +10 -0
  133. package/lib/syntax/types/BigIntType.js +27 -0
  134. package/lib/syntax/types/BooleanType.d.ts +10 -0
  135. package/lib/syntax/types/BooleanType.js +27 -0
  136. package/lib/syntax/types/CustomType.d.ts +14 -0
  137. package/lib/syntax/types/CustomType.js +36 -0
  138. package/lib/syntax/types/DateType.d.ts +10 -0
  139. package/lib/syntax/types/DateType.js +35 -0
  140. package/lib/syntax/types/EnumType.d.ts +23 -0
  141. package/lib/syntax/types/EnumType.js +101 -0
  142. package/lib/syntax/types/ErrorType.d.ts +11 -0
  143. package/lib/syntax/types/ErrorType.js +37 -0
  144. package/lib/syntax/types/FunctionType.d.ts +29 -0
  145. package/lib/syntax/types/FunctionType.js +147 -0
  146. package/lib/syntax/types/HybridObjectBaseType.d.ts +11 -0
  147. package/lib/syntax/types/HybridObjectBaseType.js +38 -0
  148. package/lib/syntax/types/HybridObjectType.d.ts +23 -0
  149. package/lib/syntax/types/HybridObjectType.js +131 -0
  150. package/lib/syntax/types/MapType.d.ts +10 -0
  151. package/lib/syntax/types/MapType.js +37 -0
  152. package/lib/syntax/types/NamedWrappingType.d.ts +14 -0
  153. package/lib/syntax/types/NamedWrappingType.js +27 -0
  154. package/lib/syntax/types/NullType.d.ts +10 -0
  155. package/lib/syntax/types/NullType.js +23 -0
  156. package/lib/syntax/types/NumberType.d.ts +10 -0
  157. package/lib/syntax/types/NumberType.js +27 -0
  158. package/lib/syntax/types/OptionalType.d.ts +13 -0
  159. package/lib/syntax/types/OptionalType.js +59 -0
  160. package/lib/syntax/types/PromiseType.d.ts +16 -0
  161. package/lib/syntax/types/PromiseType.js +62 -0
  162. package/lib/syntax/types/RecordType.d.ts +13 -0
  163. package/lib/syntax/types/RecordType.js +47 -0
  164. package/lib/syntax/types/ResultWrappingType.d.ts +13 -0
  165. package/lib/syntax/types/ResultWrappingType.js +44 -0
  166. package/lib/syntax/types/StringType.d.ts +10 -0
  167. package/lib/syntax/types/StringType.js +35 -0
  168. package/lib/syntax/types/StructType.d.ts +14 -0
  169. package/lib/syntax/types/StructType.js +61 -0
  170. package/lib/syntax/types/TupleType.d.ts +12 -0
  171. package/lib/syntax/types/TupleType.js +39 -0
  172. package/lib/syntax/types/Type.d.ts +55 -0
  173. package/lib/syntax/types/Type.js +1 -0
  174. package/lib/syntax/types/VariantType.d.ts +19 -0
  175. package/lib/syntax/types/VariantType.js +75 -0
  176. package/lib/syntax/types/VoidType.d.ts +10 -0
  177. package/lib/syntax/types/VoidType.js +27 -0
  178. package/lib/syntax/types/getTypeAs.d.ts +2 -0
  179. package/lib/syntax/types/getTypeAs.js +12 -0
  180. package/lib/utils.d.ts +22 -0
  181. package/lib/utils.js +126 -0
  182. package/lib/views/CppHybridViewComponent.d.ts +14 -0
  183. package/lib/views/CppHybridViewComponent.js +254 -0
  184. package/lib/views/createHostComponentJs.d.ts +3 -0
  185. package/lib/views/createHostComponentJs.js +27 -0
  186. package/lib/views/kotlin/KotlinHybridViewManager.d.ts +3 -0
  187. package/lib/views/kotlin/KotlinHybridViewManager.js +229 -0
  188. package/lib/views/swift/SwiftHybridViewManager.d.ts +3 -0
  189. package/lib/views/swift/SwiftHybridViewManager.js +131 -0
  190. package/lib/writeFile.d.ts +5 -0
  191. package/lib/writeFile.js +19 -0
  192. package/package.json +58 -29
  193. package/src/Logger.ts +63 -0
  194. package/src/autolinking/Autolinking.ts +9 -0
  195. package/src/autolinking/android/createCMakeExtension.ts +123 -0
  196. package/src/autolinking/android/createGradleExtension.ts +43 -0
  197. package/src/autolinking/android/createHybridObjectInitializer.ts +174 -0
  198. package/src/autolinking/createAndroidAutolinking.ts +28 -0
  199. package/src/autolinking/createIOSAutolinking.ts +24 -0
  200. package/src/autolinking/ios/createHybridObjectInitializer.ts +112 -0
  201. package/src/autolinking/ios/createPodspecRubyExtension.ts +76 -0
  202. package/src/autolinking/ios/createSwiftCxxBridge.ts +137 -0
  203. package/src/autolinking/ios/createSwiftUmbrellaHeader.ts +90 -0
  204. package/src/config/NitroConfig.ts +139 -0
  205. package/src/config/NitroUserConfig.ts +105 -0
  206. package/src/config/getConfig.ts +91 -0
  207. package/src/createGitAttributes.ts +15 -0
  208. package/src/createPlatformSpec.ts +176 -0
  209. package/src/getFiles.ts +31 -0
  210. package/src/getPlatformSpecs.ts +202 -0
  211. package/src/index.ts +146 -0
  212. package/src/init.ts +186 -0
  213. package/src/nitrogen.ts +246 -0
  214. package/src/prettifyDirectory.ts +32 -0
  215. package/src/syntax/BridgedType.ts +59 -0
  216. package/src/syntax/CodeNode.ts +24 -0
  217. package/src/syntax/HybridObjectSpec.ts +14 -0
  218. package/src/syntax/Method.ts +154 -0
  219. package/src/syntax/Parameter.ts +81 -0
  220. package/src/syntax/Property.ts +203 -0
  221. package/src/syntax/SourceFile.ts +80 -0
  222. package/src/syntax/c++/CppEnum.ts +128 -0
  223. package/src/syntax/c++/CppHybridObject.ts +165 -0
  224. package/src/syntax/c++/CppHybridObjectRegistration.ts +39 -0
  225. package/src/syntax/c++/CppStruct.ts +129 -0
  226. package/src/syntax/c++/CppUnion.ts +105 -0
  227. package/src/syntax/c++/getForwardDeclaration.ts +19 -0
  228. package/src/syntax/c++/includeNitroHeader.ts +40 -0
  229. package/src/syntax/createType.ts +365 -0
  230. package/src/syntax/getAllTypes.ts +18 -0
  231. package/src/syntax/getCustomTypeConfig.ts +71 -0
  232. package/src/syntax/getHybridObjectName.ts +48 -0
  233. package/src/syntax/getInterfaceProperties.ts +21 -0
  234. package/src/syntax/getReferencedTypes.ts +57 -0
  235. package/src/syntax/helpers.ts +79 -0
  236. package/src/syntax/isCoreType.ts +60 -0
  237. package/src/syntax/kotlin/FbjniHybridObject.ts +313 -0
  238. package/src/syntax/kotlin/JNINativeRegistrations.ts +19 -0
  239. package/src/syntax/kotlin/KotlinBoxedPrimitive.ts +19 -0
  240. package/src/syntax/kotlin/KotlinCxxBridgedType.ts +942 -0
  241. package/src/syntax/kotlin/KotlinEnum.ts +130 -0
  242. package/src/syntax/kotlin/KotlinFunction.ts +277 -0
  243. package/src/syntax/kotlin/KotlinHybridObject.ts +205 -0
  244. package/src/syntax/kotlin/KotlinHybridObjectRegistration.ts +51 -0
  245. package/src/syntax/kotlin/KotlinStruct.ts +198 -0
  246. package/src/syntax/kotlin/KotlinVariant.ts +212 -0
  247. package/src/syntax/swift/SwiftCxxBridgedType.ts +874 -0
  248. package/src/syntax/swift/SwiftCxxTypeHelper.ts +674 -0
  249. package/src/syntax/swift/SwiftEnum.ts +65 -0
  250. package/src/syntax/swift/SwiftFunction.ts +91 -0
  251. package/src/syntax/swift/SwiftHybridObject.ts +121 -0
  252. package/src/syntax/swift/SwiftHybridObjectBridge.ts +522 -0
  253. package/src/syntax/swift/SwiftHybridObjectRegistration.ts +75 -0
  254. package/src/syntax/swift/SwiftStruct.ts +85 -0
  255. package/src/syntax/swift/SwiftVariant.ts +67 -0
  256. package/src/syntax/types/ArrayBufferType.ts +49 -0
  257. package/src/syntax/types/ArrayType.ts +62 -0
  258. package/src/syntax/types/BigIntType.ts +35 -0
  259. package/src/syntax/types/BooleanType.ts +35 -0
  260. package/src/syntax/types/CustomType.ts +47 -0
  261. package/src/syntax/types/DateType.ts +43 -0
  262. package/src/syntax/types/EnumType.ts +130 -0
  263. package/src/syntax/types/ErrorType.ts +44 -0
  264. package/src/syntax/types/FunctionType.ts +167 -0
  265. package/src/syntax/types/HybridObjectBaseType.ts +54 -0
  266. package/src/syntax/types/HybridObjectType.ts +198 -0
  267. package/src/syntax/types/MapType.ts +49 -0
  268. package/src/syntax/types/NamedWrappingType.ts +33 -0
  269. package/src/syntax/types/NullType.ts +30 -0
  270. package/src/syntax/types/NumberType.ts +34 -0
  271. package/src/syntax/types/OptionalType.ts +66 -0
  272. package/src/syntax/types/PromiseType.ts +72 -0
  273. package/src/syntax/types/RecordType.ts +56 -0
  274. package/src/syntax/types/ResultWrappingType.ts +53 -0
  275. package/src/syntax/types/StringType.ts +44 -0
  276. package/src/syntax/types/StructType.ts +83 -0
  277. package/src/syntax/types/TupleType.ts +53 -0
  278. package/src/syntax/types/Type.ts +82 -0
  279. package/src/syntax/types/VariantType.ts +92 -0
  280. package/src/syntax/types/VoidType.ts +34 -0
  281. package/src/syntax/types/getTypeAs.ts +15 -0
  282. package/src/utils.ts +162 -0
  283. package/src/views/CppHybridViewComponent.ts +301 -0
  284. package/src/views/createHostComponentJs.ts +34 -0
  285. package/src/views/kotlin/KotlinHybridViewManager.ts +258 -0
  286. package/src/views/swift/SwiftHybridViewManager.ts +153 -0
  287. package/src/writeFile.ts +27 -0
  288. package/.jshintignore +0 -6
  289. package/.jshintrc +0 -3
  290. package/.npmignore +0 -3
  291. package/.travis.yml +0 -13
  292. package/LICENSE +0 -13
  293. package/browser/nitrogen-min.js +0 -3
  294. package/browser/nitrogen.js +0 -6369
  295. package/lib/apiKey.js +0 -67
  296. package/lib/blob.js +0 -57
  297. package/lib/commandManager.js +0 -350
  298. package/lib/device.js +0 -19
  299. package/lib/memoryStore.js +0 -24
  300. package/lib/message.js +0 -298
  301. package/lib/permission.js +0 -121
  302. package/lib/principal.js +0 -330
  303. package/lib/service.js +0 -349
  304. package/lib/session.js +0 -494
  305. package/lib/user.js +0 -20
  306. package/publish +0 -2
  307. package/scripts/build-documentation +0 -4
  308. package/scripts/build-module +0 -27
  309. package/scripts/module.js +0 -12
  310. package/scripts/postamble.js +0 -1
  311. package/scripts/preamble.js +0 -2
  312. package/scripts/run-test-server +0 -9
  313. package/test/config.js +0 -12
  314. package/test/fixtures/images/image.jpg +0 -0
  315. package/test/fixtures/images/motion0.jpg +0 -0
  316. package/test/fixtures/images/motion1.jpg +0 -0
  317. package/test/fixtures/images/motion2.jpg +0 -0
  318. package/test/fixtures/index.js +0 -76
  319. package/test/main.js +0 -5
  320. package/test/memoryStore.js +0 -22
  321. package/test/mocha.opts +0 -3
  322. package/test/units/apiKey.js +0 -46
  323. package/test/units/blob.js +0 -35
  324. package/test/units/commandManager.js +0 -67
  325. package/test/units/device.js +0 -26
  326. package/test/units/heartbeat.js +0 -28
  327. package/test/units/message.js +0 -79
  328. package/test/units/permissions.js +0 -43
  329. package/test/units/principal.js +0 -116
  330. package/test/units/service.js +0 -92
  331. package/test/units/session.js +0 -97
  332. package/test/units/user.js +0 -48
  333. package/yuidoc.json +0 -8
package/lib/utils.js ADDED
@@ -0,0 +1,126 @@
1
+ import path from 'path';
2
+ import fs from 'fs';
3
+ import { isNotDuplicate } from './syntax/helpers.js';
4
+ import { readUserConfig } from './config/getConfig.js';
5
+ import { NitroConfig } from './config/NitroConfig.js';
6
+ export const NITROGEN_VERSION = process.env.npm_package_version ?? '?.?.?';
7
+ export function capitalizeName(name) {
8
+ if (name.length === 0)
9
+ return name;
10
+ return name.charAt(0).toUpperCase() + name.slice(1);
11
+ }
12
+ export function createIndentation(spacesCount) {
13
+ return Array.from(Array(spacesCount)).fill(' ').join('');
14
+ }
15
+ export function indent(string, indentation) {
16
+ let spaces;
17
+ if (typeof indentation === 'number') {
18
+ spaces = createIndentation(indentation);
19
+ }
20
+ else {
21
+ spaces = indentation;
22
+ }
23
+ return string.replaceAll('\n', `\n${spaces}`);
24
+ }
25
+ export function errorToString(error) {
26
+ if (error == null) {
27
+ return `null`;
28
+ }
29
+ if (typeof error !== 'object') {
30
+ return `${error}`;
31
+ }
32
+ if (error instanceof Error) {
33
+ let message = `${error.name}: ${error.message}`;
34
+ if (error.cause != null) {
35
+ message += ` (cause: ${JSON.stringify(error.cause)})`;
36
+ }
37
+ return message;
38
+ }
39
+ if ('toString' in error) {
40
+ return error.toString();
41
+ }
42
+ return JSON.stringify(error);
43
+ }
44
+ export function escapeComments(string) {
45
+ return string
46
+ .replace(/\/\*/g, '/ *') // Escape start of comment
47
+ .replace(/\*\//g, '* /') // Escape end of comment
48
+ .replace(/\/\//g, '/ /'); // Escape single-line comment
49
+ }
50
+ const HAS_UNIX_PATHS = path.join('a', 'b').includes('/');
51
+ export function toUnixPath(p) {
52
+ if (HAS_UNIX_PATHS)
53
+ return p;
54
+ return p.replaceAll('\\', '/');
55
+ }
56
+ const sep = path.sep;
57
+ export function unsafeFastJoin(...segments) {
58
+ // this function should really not take any unsafe strings like `/` or `\`.
59
+ return segments.join(sep);
60
+ }
61
+ function getFullPath(file) {
62
+ return unsafeFastJoin(file.platform, file.language, ...file.subdirectory, file.name);
63
+ }
64
+ /**
65
+ * Deduplicates all files via their full path.
66
+ * If content differs, you are f*cked.
67
+ */
68
+ export function deduplicateFiles(files) {
69
+ const map = new Map();
70
+ for (const file of files) {
71
+ const filePath = getFullPath(file);
72
+ if (!map.has(filePath)) {
73
+ map.set(filePath, file);
74
+ }
75
+ }
76
+ return [...map.values()];
77
+ }
78
+ export function filterDuplicateHelperBridges(bridge, i, array) {
79
+ const otherIndex = array.findIndex((f2) => bridge.specializationName === f2.specializationName);
80
+ return otherIndex === i;
81
+ }
82
+ export function toLowerCamelCase(string) {
83
+ const parts = string.split('_').filter((part) => part !== '');
84
+ if (parts.length === 0)
85
+ return '';
86
+ const camelCaseString = parts[0].toLowerCase();
87
+ const camelCased = parts
88
+ .slice(1)
89
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase());
90
+ return camelCaseString + camelCased.join('');
91
+ }
92
+ export function getBaseTypes(type) {
93
+ const baseTypes = type.getBaseTypes();
94
+ const symbol = type.getSymbol();
95
+ if (symbol != null) {
96
+ baseTypes.push(...symbol.getDeclaredType().getBaseTypes());
97
+ }
98
+ const recursive = baseTypes.flatMap((b) => [b, ...getBaseTypes(b)]);
99
+ return recursive.filter(isNotDuplicate);
100
+ }
101
+ export function getHybridObjectNitroModuleConfig(type) {
102
+ const symbol = type.getSymbol() ?? type.getAliasSymbol();
103
+ if (!symbol)
104
+ return undefined;
105
+ const declarations = symbol.getValueDeclaration() || symbol.getDeclarations()[0];
106
+ if (!declarations)
107
+ return undefined;
108
+ const sourceFile = declarations.getSourceFile();
109
+ let filePath = sourceFile.getFilePath();
110
+ while (true) {
111
+ // go up one dir
112
+ const newFilePath = path.resolve(path.join(filePath, '..'));
113
+ if (filePath === newFilePath) {
114
+ // going 'cd ..' in that path didn't change a thing - so we
115
+ // reached the root directory. we didn't find a nitro.json anywhere.
116
+ return undefined;
117
+ }
118
+ filePath = newFilePath;
119
+ const nitroJsonPath = path.join(filePath, 'nitro.json');
120
+ const hasNitroJson = fs.existsSync(nitroJsonPath);
121
+ if (hasNitroJson) {
122
+ const config = readUserConfig(nitroJsonPath);
123
+ return new NitroConfig(config);
124
+ }
125
+ }
126
+ }
@@ -0,0 +1,14 @@
1
+ import type { SourceFile } from '../syntax/SourceFile.js';
2
+ import type { HybridObjectSpec } from '../syntax/HybridObjectSpec.js';
3
+ interface ViewComponentNames {
4
+ propsClassName: `${string}Props`;
5
+ stateClassName: `${string}State`;
6
+ nameVariable: `${string}ComponentName`;
7
+ shadowNodeClassName: `${string}ShadowNode`;
8
+ descriptorClassName: `${string}ComponentDescriptor`;
9
+ component: `${string}Component`;
10
+ manager: `${string}Manager`;
11
+ }
12
+ export declare function getViewComponentNames(spec: HybridObjectSpec): ViewComponentNames;
13
+ export declare function createViewComponentShadowNodeFiles(spec: HybridObjectSpec): SourceFile[];
14
+ export {};
@@ -0,0 +1,254 @@
1
+ import { createIndentation, indent } from '../utils.js';
2
+ import { createFileMetadataString, escapeCppName, isFunction, } from '../syntax/helpers.js';
3
+ import { getHybridObjectName } from '../syntax/getHybridObjectName.js';
4
+ import { includeHeader } from '../syntax/c++/includeNitroHeader.js';
5
+ import { createHostComponentJs } from './createHostComponentJs.js';
6
+ import { Property } from '../syntax/Property.js';
7
+ import { FunctionType } from '../syntax/types/FunctionType.js';
8
+ import { VoidType } from '../syntax/types/VoidType.js';
9
+ import { HybridObjectType } from '../syntax/types/HybridObjectType.js';
10
+ import { NamedWrappingType } from '../syntax/types/NamedWrappingType.js';
11
+ import { OptionalType } from '../syntax/types/OptionalType.js';
12
+ export function getViewComponentNames(spec) {
13
+ const name = getHybridObjectName(spec.name);
14
+ return {
15
+ propsClassName: `${name.HybridT}Props`,
16
+ stateClassName: `${name.HybridT}State`,
17
+ nameVariable: `${name.HybridT}ComponentName`,
18
+ shadowNodeClassName: `${name.HybridT}ShadowNode`,
19
+ descriptorClassName: `${name.HybridT}ComponentDescriptor`,
20
+ component: `${name.HybridT}Component`,
21
+ manager: `${name.HybridT}Manager`,
22
+ };
23
+ }
24
+ function getHybridRefProperty(spec) {
25
+ const hybrid = new HybridObjectType(spec);
26
+ const type = new FunctionType(new VoidType(), [
27
+ new NamedWrappingType('ref', hybrid),
28
+ ]);
29
+ return new Property('hybridRef', new OptionalType(type), false);
30
+ }
31
+ export function createViewComponentShadowNodeFiles(spec) {
32
+ if (!spec.isHybridView) {
33
+ throw new Error(`Cannot create View Component ShadowNode code for ${spec.name} - it's not a HybridView!`);
34
+ }
35
+ const { T, HybridT } = getHybridObjectName(spec.name);
36
+ const { propsClassName, stateClassName, nameVariable, shadowNodeClassName, descriptorClassName, component, } = getViewComponentNames(spec);
37
+ const namespace = spec.config.getCxxNamespace('c++', 'views');
38
+ const props = [...spec.properties, getHybridRefProperty(spec)];
39
+ const properties = props.map((p) => `CachedProp<${p.type.getCode('c++')}> ${escapeCppName(p.name)};`);
40
+ const cases = props.map((p) => `case hashString("${p.name}"): return true;`);
41
+ const includes = props.flatMap((p) => p.getRequiredImports('c++').map((i) => includeHeader(i, true)));
42
+ // .hpp code
43
+ const shadowIndent = createIndentation(shadowNodeClassName.length);
44
+ const componentHeaderCode = `
45
+ ${createFileMetadataString(`${component}.hpp`)}
46
+
47
+ #pragma once
48
+
49
+ #include <optional>
50
+ #include <NitroModules/NitroDefines.hpp>
51
+ #include <NitroModules/NitroHash.hpp>
52
+ #include <NitroModules/CachedProp.hpp>
53
+ #include <react/renderer/core/ConcreteComponentDescriptor.h>
54
+ #include <react/renderer/core/PropsParserContext.h>
55
+ #include <react/renderer/components/view/ConcreteViewShadowNode.h>
56
+ #include <react/renderer/components/view/ViewProps.h>
57
+
58
+ ${includes.join('\n')}
59
+
60
+ namespace ${namespace} {
61
+
62
+ using namespace facebook;
63
+
64
+ /**
65
+ * The name of the actual native View.
66
+ */
67
+ extern const char ${nameVariable}[];
68
+
69
+ /**
70
+ * Props for the "${spec.name}" View.
71
+ */
72
+ class ${propsClassName} final: public react::ViewProps {
73
+ public:
74
+ ${propsClassName}() = default;
75
+ ${propsClassName}(const ${propsClassName}&);
76
+ ${propsClassName}(const react::PropsParserContext& context,
77
+ ${createIndentation(propsClassName.length)} const ${propsClassName}& sourceProps,
78
+ ${createIndentation(propsClassName.length)} const react::RawProps& rawProps);
79
+
80
+ public:
81
+ ${indent(properties.join('\n'), ' ')}
82
+
83
+ private:
84
+ static bool filterObjectKeys(const std::string& propName);
85
+ };
86
+
87
+ /**
88
+ * State for the "${spec.name}" View.
89
+ */
90
+ class ${stateClassName} final {
91
+ public:
92
+ ${stateClassName}() = default;
93
+
94
+ public:
95
+ void setProps(const ${propsClassName}& props) { _props.emplace(props); }
96
+ const std::optional<${propsClassName}>& getProps() const { return _props; }
97
+
98
+ public:
99
+ #ifdef ANDROID
100
+ ${stateClassName}(const ${stateClassName}& /* previousState */, folly::dynamic /* data */) {}
101
+ folly::dynamic getDynamic() const {
102
+ throw std::runtime_error("${stateClassName} does not support folly!");
103
+ }
104
+ react::MapBuffer getMapBuffer() const {
105
+ throw std::runtime_error("${stateClassName} does not support MapBuffer!");
106
+ };
107
+ #endif
108
+
109
+ private:
110
+ std::optional<${propsClassName}> _props;
111
+ };
112
+
113
+ /**
114
+ * The Shadow Node for the "${spec.name}" View.
115
+ */
116
+ using ${shadowNodeClassName} = react::ConcreteViewShadowNode<${nameVariable} /* "${HybridT}" */,
117
+ ${shadowIndent} ${propsClassName} /* custom props */,
118
+ ${shadowIndent} react::ViewEventEmitter /* default */,
119
+ ${shadowIndent} ${stateClassName} /* custom state */>;
120
+
121
+ /**
122
+ * The Component Descriptor for the "${spec.name}" View.
123
+ */
124
+ class ${descriptorClassName} final: public react::ConcreteComponentDescriptor<${shadowNodeClassName}> {
125
+ public:
126
+ ${descriptorClassName}(const react::ComponentDescriptorParameters& parameters);
127
+
128
+ public:
129
+ /**
130
+ * A faster path for cloning props - reuses the caching logic from \`${propsClassName}\`.
131
+ */
132
+ std::shared_ptr<const react::Props> cloneProps(const react::PropsParserContext& context,
133
+ const std::shared_ptr<const react::Props>& props,
134
+ react::RawProps rawProps) const override;
135
+ #ifdef ANDROID
136
+ void adopt(react::ShadowNode& shadowNode) const override;
137
+ #endif
138
+ };
139
+
140
+ /* The actual view for "${spec.name}" needs to be implemented in platform-specific code. */
141
+
142
+ } // namespace ${namespace}
143
+ `.trim();
144
+ // .cpp code
145
+ const propInitializers = [
146
+ 'react::ViewProps(context, sourceProps, rawProps, filterObjectKeys)',
147
+ ];
148
+ const propCopyInitializers = ['react::ViewProps()'];
149
+ for (const prop of props) {
150
+ const name = escapeCppName(prop.name);
151
+ const type = prop.type.getCode('c++');
152
+ let valueConversion = `value`;
153
+ if (isFunction(prop.type)) {
154
+ // Due to a React limitation, functions cannot be passed to native directly,
155
+ // because RN converts them to booleans (`true`). Nitro knows this and just
156
+ // wraps functions as objects - the original function is stored in `f`.
157
+ valueConversion = `value.asObject(*runtime).getProperty(*runtime, "f")`;
158
+ }
159
+ propInitializers.push(`
160
+ ${name}([&]() -> CachedProp<${type}> {
161
+ try {
162
+ const react::RawValue* rawValue = rawProps.at("${prop.name}", nullptr, nullptr);
163
+ if (rawValue == nullptr) return sourceProps.${name};
164
+ const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
165
+ return CachedProp<${type}>::fromRawValue(*runtime, ${valueConversion}, sourceProps.${name});
166
+ } catch (const std::exception& exc) {
167
+ throw std::runtime_error(std::string("${spec.name}.${prop.name}: ") + exc.what());
168
+ }
169
+ }())`.trim());
170
+ propCopyInitializers.push(`${name}(other.${name})`);
171
+ }
172
+ const ctorIndent = createIndentation(propsClassName.length * 2);
173
+ const descriptorIndent = createIndentation(descriptorClassName.length);
174
+ const componentCode = `
175
+ ${createFileMetadataString(`${component}.cpp`)}
176
+
177
+ #include "${component}.hpp"
178
+
179
+ #include <string>
180
+ #include <exception>
181
+ #include <utility>
182
+ #include <NitroModules/NitroDefines.hpp>
183
+ #include <NitroModules/JSIConverter.hpp>
184
+ #include <react/renderer/core/RawValue.h>
185
+ #include <react/renderer/core/ShadowNode.h>
186
+ #include <react/renderer/core/ComponentDescriptor.h>
187
+ #include <react/renderer/components/view/ViewProps.h>
188
+
189
+ namespace ${namespace} {
190
+
191
+ extern const char ${nameVariable}[] = "${T}";
192
+
193
+ ${propsClassName}::${propsClassName}(const react::PropsParserContext& context,
194
+ ${ctorIndent} const ${propsClassName}& sourceProps,
195
+ ${ctorIndent} const react::RawProps& rawProps):
196
+ ${indent(propInitializers.join(',\n'), ' ')} { }
197
+
198
+ ${propsClassName}::${propsClassName}(const ${propsClassName}& other):
199
+ ${indent(propCopyInitializers.join(',\n'), ' ')} { }
200
+
201
+ bool ${propsClassName}::filterObjectKeys(const std::string& propName) {
202
+ switch (hashString(propName)) {
203
+ ${indent(cases.join('\n'), ' ')}
204
+ default: return false;
205
+ }
206
+ }
207
+
208
+ ${descriptorClassName}::${descriptorClassName}(const react::ComponentDescriptorParameters& parameters)
209
+ : ConcreteComponentDescriptor(parameters,
210
+ react::RawPropsParser(/* enableJsiParser */ true)) {}
211
+
212
+ std::shared_ptr<const react::Props> ${descriptorClassName}::cloneProps(const react::PropsParserContext& context,
213
+ ${descriptorIndent} const std::shared_ptr<const react::Props>& props,
214
+ ${descriptorIndent} react::RawProps rawProps) const {
215
+ // 1. Prepare raw props parser
216
+ rawProps.parse(rawPropsParser_);
217
+ // 2. Copy props with Nitro's cached copy constructor
218
+ return ${shadowNodeClassName}::Props(context, /* & */ rawProps, props);
219
+ }
220
+
221
+ #ifdef ANDROID
222
+ void ${descriptorClassName}::adopt(react::ShadowNode& shadowNode) const {
223
+ // This is called immediately after \`ShadowNode\` is created, cloned or in progress.
224
+ // On Android, we need to wrap props in our state, which gets routed through Java and later unwrapped in JNI/C++.
225
+ auto& concreteShadowNode = dynamic_cast<${shadowNodeClassName}&>(shadowNode);
226
+ const ${propsClassName}& props = concreteShadowNode.getConcreteProps();
227
+ ${stateClassName} state;
228
+ state.setProps(props);
229
+ concreteShadowNode.setStateData(std::move(state));
230
+ }
231
+ #endif
232
+
233
+ } // namespace ${namespace}
234
+ `.trim();
235
+ const files = [
236
+ {
237
+ name: `${component}.hpp`,
238
+ content: componentHeaderCode,
239
+ language: 'c++',
240
+ platform: 'shared',
241
+ subdirectory: ['views'],
242
+ },
243
+ {
244
+ name: `${component}.cpp`,
245
+ content: componentCode,
246
+ language: 'c++',
247
+ platform: 'shared',
248
+ subdirectory: ['views'],
249
+ },
250
+ ];
251
+ const jsFiles = createHostComponentJs(spec);
252
+ files.push(...jsFiles);
253
+ return files;
254
+ }
@@ -0,0 +1,3 @@
1
+ import type { HybridObjectSpec } from '../syntax/HybridObjectSpec.js';
2
+ import type { SourceFile } from '../syntax/SourceFile.js';
3
+ export declare function createHostComponentJs(spec: HybridObjectSpec): SourceFile[];
@@ -0,0 +1,27 @@
1
+ import { getHybridObjectName } from '../syntax/getHybridObjectName.js';
2
+ import { indent } from '../utils.js';
3
+ export function createHostComponentJs(spec) {
4
+ const { T } = getHybridObjectName(spec.name);
5
+ const props = spec.properties.map((p) => `"${p.name}": true`);
6
+ props.push(`"hybridRef": true`);
7
+ const code = `
8
+ {
9
+ "uiViewClassName": "${T}",
10
+ "supportsRawText": false,
11
+ "bubblingEventTypes": {},
12
+ "directEventTypes": {},
13
+ "validAttributes": {
14
+ ${indent(props.join(',\n'), ' ')}
15
+ }
16
+ }
17
+ `.trim();
18
+ return [
19
+ {
20
+ content: code,
21
+ language: 'json',
22
+ name: `${T}Config.json`,
23
+ platform: 'shared',
24
+ subdirectory: [],
25
+ },
26
+ ];
27
+ }
@@ -0,0 +1,3 @@
1
+ import type { SourceFile } from '../../syntax/SourceFile.js';
2
+ import type { HybridObjectSpec } from '../../syntax/HybridObjectSpec.js';
3
+ export declare function createKotlinHybridViewManager(spec: HybridObjectSpec): SourceFile[];
@@ -0,0 +1,229 @@
1
+ import { createViewComponentShadowNodeFiles, getViewComponentNames, } from '../CppHybridViewComponent.js';
2
+ import { createFileMetadataString, escapeCppName, } from '../../syntax/helpers.js';
3
+ import { getHybridObjectName } from '../../syntax/getHybridObjectName.js';
4
+ import { addJNINativeRegistration } from '../../syntax/kotlin/JNINativeRegistrations.js';
5
+ import { indent } from '../../utils.js';
6
+ export function createKotlinHybridViewManager(spec) {
7
+ const cppFiles = createViewComponentShadowNodeFiles(spec);
8
+ const javaSubNamespace = spec.config.getAndroidPackage('java/kotlin', 'views');
9
+ const javaNamespace = spec.config.getAndroidPackage('java/kotlin');
10
+ const cxxNamespace = spec.config.getCxxNamespace('c++', 'views');
11
+ const { JHybridTSpec, HybridTSpec } = getHybridObjectName(spec.name);
12
+ const { manager, stateClassName, component, propsClassName, descriptorClassName, } = getViewComponentNames(spec);
13
+ const stateUpdaterName = `${stateClassName}Updater`;
14
+ const autolinking = spec.config.getAutolinkedHybridObjects();
15
+ const viewImplementation = autolinking[spec.name]?.kotlin;
16
+ if (viewImplementation == null) {
17
+ throw new Error(`Cannot create Kotlin HybridView ViewManager for ${spec.name} - it is not autolinked in nitro.json!`);
18
+ }
19
+ const viewManagerCode = `
20
+ ${createFileMetadataString(`${manager}.kt`)}
21
+
22
+ package ${javaSubNamespace}
23
+
24
+ import android.view.View
25
+ import com.facebook.react.uimanager.ReactStylesDiffMap
26
+ import com.facebook.react.uimanager.SimpleViewManager
27
+ import com.facebook.react.uimanager.StateWrapper
28
+ import com.facebook.react.uimanager.ThemedReactContext
29
+ import ${javaNamespace}.*
30
+
31
+ /**
32
+ * Represents the React Native \`ViewManager\` for the "${spec.name}" Nitro HybridView.
33
+ */
34
+ class ${manager}: SimpleViewManager<View>() {
35
+ private val views = hashMapOf<View, ${viewImplementation}>()
36
+
37
+ override fun getName(): String {
38
+ return "${spec.name}"
39
+ }
40
+
41
+ override fun createViewInstance(reactContext: ThemedReactContext): View {
42
+ val hybridView = ${viewImplementation}(reactContext)
43
+ val view = hybridView.view
44
+ views[view] = hybridView
45
+ return view
46
+ }
47
+
48
+ override fun onDropViewInstance(view: View) {
49
+ super.onDropViewInstance(view)
50
+ views.remove(view)
51
+ }
52
+
53
+ override fun updateState(view: View, props: ReactStylesDiffMap, stateWrapper: StateWrapper): Any? {
54
+ val hybridView = views[view] ?: throw Error("Couldn't find view $view in local views table!")
55
+
56
+ // 1. Update each prop individually
57
+ hybridView.beforeUpdate()
58
+ ${stateUpdaterName}.updateViewProps(hybridView, stateWrapper)
59
+ hybridView.afterUpdate()
60
+
61
+ // 2. Continue in base View props
62
+ return super.updateState(view, props, stateWrapper)
63
+ }
64
+ }
65
+ `.trim();
66
+ const updaterKotlinCode = `
67
+ ${createFileMetadataString(`${stateUpdaterName}.kt`)}
68
+
69
+ package ${javaSubNamespace}
70
+
71
+ import com.facebook.react.uimanager.StateWrapper
72
+ import ${javaNamespace}.*
73
+
74
+ internal class ${stateUpdaterName} {
75
+ companion object {
76
+ /**
77
+ * Updates the props for [view] through C++.
78
+ * The [state] prop is expected to contain [view]'s props as wrapped Fabric state.
79
+ */
80
+ @Suppress("KotlinJniMissingFunction")
81
+ @JvmStatic
82
+ external fun updateViewProps(view: ${HybridTSpec}, state: StateWrapper)
83
+ }
84
+ }
85
+ `.trim();
86
+ const updaterJniDescriptor = spec.config.getAndroidPackage('c++/jni', 'views', stateUpdaterName);
87
+ const updaterJniHeaderCode = `
88
+ ${createFileMetadataString(`J${stateUpdaterName}.hpp`)}
89
+
90
+ #pragma once
91
+
92
+ #include <fbjni/fbjni.h>
93
+ #include <react/fabric/StateWrapperImpl.h>
94
+ #include <react/fabric/CoreComponentsRegistry.h>
95
+ #include <react/renderer/core/ConcreteComponentDescriptor.h>
96
+ #include <NitroModules/NitroDefines.hpp>
97
+ #include <NitroModules/JStateWrapper.hpp>
98
+ #include "${JHybridTSpec}.hpp"
99
+ #include "views/${component}.hpp"
100
+
101
+ namespace ${cxxNamespace} {
102
+
103
+ using namespace facebook;
104
+
105
+ class J${stateUpdaterName}: public jni::JavaClass<J${stateUpdaterName}> {
106
+ public:
107
+ static constexpr auto kJavaDescriptor = "L${updaterJniDescriptor};";
108
+
109
+ public:
110
+ static void updateViewProps(jni::alias_ref<jni::JClass> /* class */,
111
+ jni::alias_ref<${JHybridTSpec}::javaobject> view,
112
+ jni::alias_ref<JStateWrapper::javaobject> stateWrapperInterface);
113
+
114
+ public:
115
+ static void registerNatives() {
116
+ // Register JNI calls
117
+ javaClassStatic()->registerNatives({
118
+ makeNativeMethod("updateViewProps", J${stateUpdaterName}::updateViewProps),
119
+ });
120
+ // Register React Native view component descriptor
121
+ auto provider = react::concreteComponentDescriptorProvider<${descriptorClassName}>();
122
+ auto providerRegistry = react::CoreComponentsRegistry::sharedProviderRegistry();
123
+ providerRegistry->add(provider);
124
+ }
125
+ };
126
+
127
+ } // namespace ${cxxNamespace}
128
+ `.trim();
129
+ const propsUpdaterCalls = spec.properties.map((p) => {
130
+ const name = escapeCppName(p.name);
131
+ const setter = p.getSetterName('other');
132
+ return `
133
+ if (props.${name}.isDirty) {
134
+ view->${setter}(props.${name}.value);
135
+ // TODO: Set isDirty = false
136
+ }
137
+ `.trim();
138
+ });
139
+ const updaterJniCppCode = `
140
+ ${createFileMetadataString(`J${stateUpdaterName}.cpp`)}
141
+
142
+ #include "J${stateUpdaterName}.hpp"
143
+ #include "views/${component}.hpp"
144
+ #include <NitroModules/NitroDefines.hpp>
145
+
146
+ namespace ${cxxNamespace} {
147
+
148
+ using namespace facebook;
149
+ using ConcreteStateData = react::ConcreteState<${stateClassName}>;
150
+
151
+ void J${stateUpdaterName}::updateViewProps(jni::alias_ref<jni::JClass> /* class */,
152
+ jni::alias_ref<${JHybridTSpec}::javaobject> javaView,
153
+ jni::alias_ref<JStateWrapper::javaobject> stateWrapperInterface) {
154
+ ${JHybridTSpec}* view = javaView->cthis();
155
+
156
+ // Get concrete StateWrapperImpl from passed StateWrapper interface object
157
+ jobject rawStateWrapper = stateWrapperInterface.get();
158
+ if (!stateWrapperInterface->isInstanceOf(react::StateWrapperImpl::javaClassStatic())) {
159
+ throw std::runtime_error("StateWrapper is not a StateWrapperImpl");
160
+ }
161
+ auto stateWrapper = jni::alias_ref<react::StateWrapperImpl::javaobject>{
162
+ static_cast<react::StateWrapperImpl::javaobject>(rawStateWrapper)};
163
+
164
+ std::shared_ptr<const react::State> state = stateWrapper->cthis()->getState();
165
+ auto concreteState = std::dynamic_pointer_cast<const ConcreteStateData>(state);
166
+ const ${stateClassName}& data = concreteState->getData();
167
+ const std::optional<${propsClassName}>& maybeProps = data.getProps();
168
+ if (!maybeProps.has_value()) {
169
+ // Props aren't set yet!
170
+ throw std::runtime_error("${stateClassName}'s data doesn't contain any props!");
171
+ }
172
+ const ${propsClassName}& props = maybeProps.value();
173
+ ${indent(propsUpdaterCalls.join('\n'), ' ')}
174
+
175
+ // Update hybridRef if it changed
176
+ if (props.hybridRef.isDirty) {
177
+ // hybridRef changed - call it with new this
178
+ const auto& maybeFunc = props.hybridRef.value;
179
+ if (maybeFunc.has_value()) {
180
+ std::shared_ptr<${JHybridTSpec}> shared = javaView->cthis()->shared_cast<${JHybridTSpec}>();
181
+ maybeFunc.value()(shared);
182
+ }
183
+ // TODO: Set isDirty = false
184
+ }
185
+ }
186
+
187
+ } // namespace ${cxxNamespace}
188
+ `.trim();
189
+ addJNINativeRegistration({
190
+ namespace: cxxNamespace,
191
+ className: `J${stateUpdaterName}`,
192
+ import: {
193
+ name: `views/J${stateUpdaterName}.hpp`,
194
+ space: 'user',
195
+ language: 'c++',
196
+ },
197
+ });
198
+ return [
199
+ ...cppFiles,
200
+ {
201
+ content: viewManagerCode,
202
+ language: 'kotlin',
203
+ name: `${manager}.kt`,
204
+ platform: 'android',
205
+ subdirectory: [...javaSubNamespace.split('.')],
206
+ },
207
+ {
208
+ content: updaterKotlinCode,
209
+ language: 'kotlin',
210
+ name: `${stateUpdaterName}.kt`,
211
+ platform: 'android',
212
+ subdirectory: [...javaSubNamespace.split('.')],
213
+ },
214
+ {
215
+ content: updaterJniHeaderCode,
216
+ language: 'c++',
217
+ name: `J${stateUpdaterName}.hpp`,
218
+ platform: 'android',
219
+ subdirectory: ['views'],
220
+ },
221
+ {
222
+ content: updaterJniCppCode,
223
+ language: 'c++',
224
+ name: `J${stateUpdaterName}.cpp`,
225
+ platform: 'android',
226
+ subdirectory: ['views'],
227
+ },
228
+ ];
229
+ }
@@ -0,0 +1,3 @@
1
+ import type { SourceFile } from '../../syntax/SourceFile.js';
2
+ import type { HybridObjectSpec } from '../../syntax/HybridObjectSpec.js';
3
+ export declare function createSwiftHybridViewManager(spec: HybridObjectSpec): SourceFile[];