nitrogen 0.2.24 → 0.29.5

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 (241) hide show
  1. package/README.md +18 -108
  2. package/lib/Logger.js +56 -0
  3. package/lib/autolinking/Autolinking.js +1 -0
  4. package/lib/autolinking/android/createCMakeExtension.js +109 -0
  5. package/lib/autolinking/android/createGradleExtension.js +36 -0
  6. package/lib/autolinking/android/createHybridObjectInitializer.js +159 -0
  7. package/lib/autolinking/createAndroidAutolinking.js +13 -0
  8. package/lib/autolinking/createIOSAutolinking.js +19 -0
  9. package/lib/autolinking/ios/createHybridObjectInitializer.js +97 -0
  10. package/lib/autolinking/ios/createPodspecRubyExtension.js +69 -0
  11. package/lib/autolinking/ios/createSwiftCxxBridge.js +117 -0
  12. package/lib/autolinking/ios/createSwiftUmbrellaHeader.js +74 -0
  13. package/lib/config/NitroConfig.js +112 -0
  14. package/lib/config/NitroUserConfig.js +88 -0
  15. package/lib/config/getConfig.js +84 -0
  16. package/lib/createGitAttributes.js +11 -0
  17. package/lib/createPlatformSpec.js +127 -0
  18. package/lib/getFiles.js +28 -0
  19. package/lib/getPlatformSpecs.js +153 -0
  20. package/lib/index.js +113 -10
  21. package/lib/init.js +123 -0
  22. package/lib/nitrogen.js +165 -0
  23. package/lib/prettifyDirectory.js +27 -0
  24. package/lib/syntax/BridgedType.js +1 -0
  25. package/lib/syntax/CodeNode.js +1 -0
  26. package/lib/syntax/HybridObjectSpec.js +1 -0
  27. package/lib/syntax/Method.js +108 -0
  28. package/lib/syntax/Parameter.js +65 -0
  29. package/lib/syntax/Property.js +147 -0
  30. package/lib/syntax/SourceFile.js +7 -0
  31. package/lib/syntax/c++/CppEnum.js +110 -0
  32. package/lib/syntax/c++/CppHybridObject.js +146 -0
  33. package/lib/syntax/c++/CppHybridObjectRegistration.js +18 -0
  34. package/lib/syntax/c++/CppStruct.js +108 -0
  35. package/lib/syntax/c++/CppUnion.js +88 -0
  36. package/lib/syntax/c++/getForwardDeclaration.js +14 -0
  37. package/lib/syntax/c++/includeNitroHeader.js +34 -0
  38. package/lib/syntax/createType.js +303 -0
  39. package/lib/syntax/getAllTypes.js +11 -0
  40. package/lib/syntax/getCustomTypeConfig.js +53 -0
  41. package/lib/syntax/getHybridObjectName.d.ts +36 -0
  42. package/lib/syntax/getHybridObjectName.js +10 -0
  43. package/lib/syntax/getInterfaceProperties.js +9 -0
  44. package/lib/syntax/getReferencedTypes.js +47 -0
  45. package/lib/syntax/helpers.js +53 -0
  46. package/lib/syntax/isCoreType.js +47 -0
  47. package/lib/syntax/kotlin/FbjniHybridObject.js +261 -0
  48. package/lib/syntax/kotlin/JNINativeRegistrations.js +7 -0
  49. package/lib/syntax/kotlin/KotlinBoxedPrimitive.js +17 -0
  50. package/lib/syntax/kotlin/KotlinCxxBridgedType.js +893 -0
  51. package/lib/syntax/kotlin/KotlinEnum.js +113 -0
  52. package/lib/syntax/kotlin/KotlinFunction.js +256 -0
  53. package/lib/syntax/kotlin/KotlinHybridObject.js +177 -0
  54. package/lib/syntax/kotlin/KotlinHybridObjectRegistration.js +26 -0
  55. package/lib/syntax/kotlin/KotlinStruct.js +172 -0
  56. package/lib/syntax/kotlin/KotlinVariant.js +191 -0
  57. package/lib/syntax/swift/SwiftCxxBridgedType.js +819 -0
  58. package/lib/syntax/swift/SwiftCxxTypeHelper.js +613 -0
  59. package/lib/syntax/swift/SwiftEnum.js +52 -0
  60. package/lib/syntax/swift/SwiftFunction.js +83 -0
  61. package/lib/syntax/swift/SwiftHybridObject.js +103 -0
  62. package/lib/syntax/swift/SwiftHybridObjectBridge.js +451 -0
  63. package/lib/syntax/swift/SwiftHybridObjectRegistration.js +42 -0
  64. package/lib/syntax/swift/SwiftStruct.js +75 -0
  65. package/lib/syntax/swift/SwiftVariant.js +58 -0
  66. package/lib/syntax/types/ArrayBufferType.js +37 -0
  67. package/lib/syntax/types/ArrayType.d.ts +12 -0
  68. package/lib/syntax/types/ArrayType.js +52 -0
  69. package/lib/syntax/types/BigIntType.js +27 -0
  70. package/lib/syntax/types/BooleanType.js +27 -0
  71. package/lib/syntax/types/CustomType.d.ts +14 -0
  72. package/lib/syntax/types/CustomType.js +36 -0
  73. package/lib/syntax/types/DateType.js +35 -0
  74. package/lib/syntax/types/EnumType.js +101 -0
  75. package/lib/syntax/types/ErrorType.js +37 -0
  76. package/lib/syntax/types/FunctionType.js +147 -0
  77. package/lib/syntax/types/HybridObjectBaseType.js +38 -0
  78. package/lib/syntax/types/HybridObjectType.js +131 -0
  79. package/lib/syntax/types/MapType.js +37 -0
  80. package/lib/syntax/types/NamedWrappingType.js +27 -0
  81. package/lib/syntax/types/NullType.js +23 -0
  82. package/lib/syntax/types/NumberType.js +27 -0
  83. package/lib/syntax/types/OptionalType.js +59 -0
  84. package/lib/syntax/types/PromiseType.js +62 -0
  85. package/lib/syntax/types/RecordType.js +47 -0
  86. package/lib/syntax/types/ResultWrappingType.js +44 -0
  87. package/lib/syntax/types/StringType.js +35 -0
  88. package/lib/syntax/types/StructType.js +61 -0
  89. package/lib/syntax/types/TupleType.js +39 -0
  90. package/lib/syntax/types/Type.js +1 -0
  91. package/lib/syntax/types/VariantType.js +75 -0
  92. package/lib/syntax/types/VoidType.js +27 -0
  93. package/lib/syntax/types/getTypeAs.js +12 -0
  94. package/lib/utils.js +126 -0
  95. package/lib/views/CppHybridViewComponent.js +256 -0
  96. package/lib/views/createHostComponentJs.js +27 -0
  97. package/lib/views/kotlin/KotlinHybridViewManager.js +229 -0
  98. package/lib/views/swift/SwiftHybridViewManager.js +131 -0
  99. package/lib/writeFile.js +19 -0
  100. package/package.json +58 -29
  101. package/src/Logger.ts +63 -0
  102. package/src/autolinking/Autolinking.ts +9 -0
  103. package/src/autolinking/android/createCMakeExtension.ts +126 -0
  104. package/src/autolinking/android/createGradleExtension.ts +43 -0
  105. package/src/autolinking/android/createHybridObjectInitializer.ts +174 -0
  106. package/src/autolinking/createAndroidAutolinking.ts +28 -0
  107. package/src/autolinking/createIOSAutolinking.ts +24 -0
  108. package/src/autolinking/ios/createHybridObjectInitializer.ts +112 -0
  109. package/src/autolinking/ios/createPodspecRubyExtension.ts +76 -0
  110. package/src/autolinking/ios/createSwiftCxxBridge.ts +137 -0
  111. package/src/autolinking/ios/createSwiftUmbrellaHeader.ts +90 -0
  112. package/src/config/NitroConfig.ts +139 -0
  113. package/src/config/NitroUserConfig.ts +105 -0
  114. package/src/config/getConfig.ts +91 -0
  115. package/src/createGitAttributes.ts +15 -0
  116. package/src/createPlatformSpec.ts +176 -0
  117. package/src/getFiles.ts +31 -0
  118. package/src/getPlatformSpecs.ts +202 -0
  119. package/src/index.ts +146 -0
  120. package/src/init.ts +186 -0
  121. package/src/nitrogen.ts +246 -0
  122. package/src/prettifyDirectory.ts +32 -0
  123. package/src/syntax/BridgedType.ts +59 -0
  124. package/src/syntax/CodeNode.ts +24 -0
  125. package/src/syntax/HybridObjectSpec.ts +14 -0
  126. package/src/syntax/Method.ts +154 -0
  127. package/src/syntax/Parameter.ts +81 -0
  128. package/src/syntax/Property.ts +203 -0
  129. package/src/syntax/SourceFile.ts +80 -0
  130. package/src/syntax/c++/CppEnum.ts +128 -0
  131. package/src/syntax/c++/CppHybridObject.ts +165 -0
  132. package/src/syntax/c++/CppHybridObjectRegistration.ts +39 -0
  133. package/src/syntax/c++/CppStruct.ts +129 -0
  134. package/src/syntax/c++/CppUnion.ts +105 -0
  135. package/src/syntax/c++/getForwardDeclaration.ts +19 -0
  136. package/src/syntax/c++/includeNitroHeader.ts +40 -0
  137. package/src/syntax/createType.ts +365 -0
  138. package/src/syntax/getAllTypes.ts +18 -0
  139. package/src/syntax/getCustomTypeConfig.ts +71 -0
  140. package/src/syntax/getHybridObjectName.ts +48 -0
  141. package/src/syntax/getInterfaceProperties.ts +21 -0
  142. package/src/syntax/getReferencedTypes.ts +57 -0
  143. package/src/syntax/helpers.ts +79 -0
  144. package/src/syntax/isCoreType.ts +60 -0
  145. package/src/syntax/kotlin/FbjniHybridObject.ts +313 -0
  146. package/src/syntax/kotlin/JNINativeRegistrations.ts +19 -0
  147. package/src/syntax/kotlin/KotlinBoxedPrimitive.ts +19 -0
  148. package/src/syntax/kotlin/KotlinCxxBridgedType.ts +942 -0
  149. package/src/syntax/kotlin/KotlinEnum.ts +130 -0
  150. package/src/syntax/kotlin/KotlinFunction.ts +277 -0
  151. package/src/syntax/kotlin/KotlinHybridObject.ts +205 -0
  152. package/src/syntax/kotlin/KotlinHybridObjectRegistration.ts +51 -0
  153. package/src/syntax/kotlin/KotlinStruct.ts +198 -0
  154. package/src/syntax/kotlin/KotlinVariant.ts +212 -0
  155. package/src/syntax/swift/SwiftCxxBridgedType.ts +874 -0
  156. package/src/syntax/swift/SwiftCxxTypeHelper.ts +674 -0
  157. package/src/syntax/swift/SwiftEnum.ts +65 -0
  158. package/src/syntax/swift/SwiftFunction.ts +91 -0
  159. package/src/syntax/swift/SwiftHybridObject.ts +121 -0
  160. package/src/syntax/swift/SwiftHybridObjectBridge.ts +522 -0
  161. package/src/syntax/swift/SwiftHybridObjectRegistration.ts +75 -0
  162. package/src/syntax/swift/SwiftStruct.ts +85 -0
  163. package/src/syntax/swift/SwiftVariant.ts +67 -0
  164. package/src/syntax/types/ArrayBufferType.ts +49 -0
  165. package/src/syntax/types/ArrayType.ts +62 -0
  166. package/src/syntax/types/BigIntType.ts +35 -0
  167. package/src/syntax/types/BooleanType.ts +35 -0
  168. package/src/syntax/types/CustomType.ts +47 -0
  169. package/src/syntax/types/DateType.ts +43 -0
  170. package/src/syntax/types/EnumType.ts +130 -0
  171. package/src/syntax/types/ErrorType.ts +44 -0
  172. package/src/syntax/types/FunctionType.ts +167 -0
  173. package/src/syntax/types/HybridObjectBaseType.ts +54 -0
  174. package/src/syntax/types/HybridObjectType.ts +198 -0
  175. package/src/syntax/types/MapType.ts +49 -0
  176. package/src/syntax/types/NamedWrappingType.ts +33 -0
  177. package/src/syntax/types/NullType.ts +30 -0
  178. package/src/syntax/types/NumberType.ts +34 -0
  179. package/src/syntax/types/OptionalType.ts +66 -0
  180. package/src/syntax/types/PromiseType.ts +72 -0
  181. package/src/syntax/types/RecordType.ts +56 -0
  182. package/src/syntax/types/ResultWrappingType.ts +53 -0
  183. package/src/syntax/types/StringType.ts +44 -0
  184. package/src/syntax/types/StructType.ts +83 -0
  185. package/src/syntax/types/TupleType.ts +53 -0
  186. package/src/syntax/types/Type.ts +82 -0
  187. package/src/syntax/types/VariantType.ts +92 -0
  188. package/src/syntax/types/VoidType.ts +34 -0
  189. package/src/syntax/types/getTypeAs.ts +15 -0
  190. package/src/utils.ts +162 -0
  191. package/src/views/CppHybridViewComponent.ts +304 -0
  192. package/src/views/createHostComponentJs.ts +34 -0
  193. package/src/views/kotlin/KotlinHybridViewManager.ts +258 -0
  194. package/src/views/swift/SwiftHybridViewManager.ts +153 -0
  195. package/src/writeFile.ts +27 -0
  196. package/.jshintignore +0 -6
  197. package/.jshintrc +0 -3
  198. package/.npmignore +0 -3
  199. package/.travis.yml +0 -13
  200. package/LICENSE +0 -13
  201. package/browser/nitrogen-min.js +0 -3
  202. package/browser/nitrogen.js +0 -6369
  203. package/lib/apiKey.js +0 -67
  204. package/lib/blob.js +0 -57
  205. package/lib/commandManager.js +0 -350
  206. package/lib/device.js +0 -19
  207. package/lib/memoryStore.js +0 -24
  208. package/lib/message.js +0 -298
  209. package/lib/permission.js +0 -121
  210. package/lib/principal.js +0 -330
  211. package/lib/service.js +0 -347
  212. package/lib/session.js +0 -494
  213. package/lib/user.js +0 -20
  214. package/publish +0 -2
  215. package/scripts/build-documentation +0 -4
  216. package/scripts/build-module +0 -27
  217. package/scripts/module.js +0 -12
  218. package/scripts/postamble.js +0 -1
  219. package/scripts/preamble.js +0 -2
  220. package/scripts/run-test-server +0 -9
  221. package/test/config.js +0 -12
  222. package/test/fixtures/images/image.jpg +0 -0
  223. package/test/fixtures/images/motion0.jpg +0 -0
  224. package/test/fixtures/images/motion1.jpg +0 -0
  225. package/test/fixtures/images/motion2.jpg +0 -0
  226. package/test/fixtures/index.js +0 -76
  227. package/test/main.js +0 -5
  228. package/test/memoryStore.js +0 -22
  229. package/test/mocha.opts +0 -3
  230. package/test/units/apiKey.js +0 -46
  231. package/test/units/blob.js +0 -35
  232. package/test/units/commandManager.js +0 -67
  233. package/test/units/device.js +0 -26
  234. package/test/units/heartbeat.js +0 -28
  235. package/test/units/message.js +0 -79
  236. package/test/units/permissions.js +0 -43
  237. package/test/units/principal.js +0 -116
  238. package/test/units/service.js +0 -92
  239. package/test/units/session.js +0 -97
  240. package/test/units/user.js +0 -48
  241. package/yuidoc.json +0 -8
@@ -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,131 @@
1
+ import { createViewComponentShadowNodeFiles, getViewComponentNames, } from '../CppHybridViewComponent.js';
2
+ import { createFileMetadataString, escapeCppName, } from '../../syntax/helpers.js';
3
+ import { getUmbrellaHeaderName } from '../../autolinking/ios/createSwiftUmbrellaHeader.js';
4
+ import { getHybridObjectName } from '../../syntax/getHybridObjectName.js';
5
+ import { getHybridObjectConstructorCall } from '../../syntax/swift/SwiftHybridObjectRegistration.js';
6
+ import { indent } from '../../utils.js';
7
+ import { SwiftCxxBridgedType } from '../../syntax/swift/SwiftCxxBridgedType.js';
8
+ export function createSwiftHybridViewManager(spec) {
9
+ const cppFiles = createViewComponentShadowNodeFiles(spec);
10
+ const namespace = spec.config.getCxxNamespace('c++');
11
+ const swiftNamespace = spec.config.getIosModuleName();
12
+ const { HybridTSpec, HybridTSpecSwift, HybridTSpecCxx } = getHybridObjectName(spec.name);
13
+ const { component, descriptorClassName, propsClassName } = getViewComponentNames(spec);
14
+ const autolinking = spec.config.getAutolinkedHybridObjects();
15
+ const viewImplementation = autolinking[spec.name]?.swift;
16
+ if (viewImplementation == null) {
17
+ throw new Error(`Cannot create Swift HybridView ViewManager for ${spec.name} - it is not autolinked in nitro.json!`);
18
+ }
19
+ const propAssignments = spec.properties.map((p) => {
20
+ const name = escapeCppName(p.name);
21
+ const setter = p.getSetterName('swift');
22
+ const bridge = new SwiftCxxBridgedType(p.type, false);
23
+ const parse = bridge.parseFromCppToSwift(`newViewProps.${name}.value`, 'c++');
24
+ return `
25
+ // ${p.jsSignature}
26
+ if (newViewProps.${name}.isDirty) {
27
+ swiftPart.${setter}(${indent(parse, ' ')});
28
+ newViewProps.${name}.isDirty = false;
29
+ }
30
+ `.trim();
31
+ });
32
+ const mmFile = `
33
+ ${createFileMetadataString(`${component}.mm`)}
34
+
35
+ #import "${component}.hpp"
36
+ #import <memory>
37
+ #import <react/renderer/componentregistry/ComponentDescriptorProvider.h>
38
+ #import <React/RCTViewComponentView.h>
39
+ #import <React/RCTComponentViewFactory.h>
40
+ #import <React/UIView+ComponentViewProtocol.h>
41
+ #import <NitroModules/NitroDefines.hpp>
42
+ #import <UIKit/UIKit.h>
43
+
44
+ #import "${HybridTSpecSwift}.hpp"
45
+ #import "${getUmbrellaHeaderName()}"
46
+
47
+ using namespace facebook;
48
+ using namespace ${namespace};
49
+ using namespace ${namespace}::views;
50
+
51
+ /**
52
+ * Represents the React Native View holder for the Nitro "${spec.name}" HybridView.
53
+ */
54
+ @interface ${component}: RCTViewComponentView
55
+ @end
56
+
57
+ @implementation ${component} {
58
+ std::shared_ptr<${HybridTSpecSwift}> _hybridView;
59
+ }
60
+
61
+ + (void) load {
62
+ [super load];
63
+ [RCTComponentViewFactory.currentComponentViewFactory registerComponentViewClass:[${component} class]];
64
+ }
65
+
66
+ + (react::ComponentDescriptorProvider) componentDescriptorProvider {
67
+ return react::concreteComponentDescriptorProvider<${descriptorClassName}>();
68
+ }
69
+
70
+ - (instancetype) init {
71
+ if (self = [super init]) {
72
+ std::shared_ptr<${HybridTSpec}> hybridView = ${getHybridObjectConstructorCall(spec.name)}
73
+ _hybridView = std::dynamic_pointer_cast<${HybridTSpecSwift}>(hybridView);
74
+ [self updateView];
75
+ }
76
+ return self;
77
+ }
78
+
79
+ - (void) updateView {
80
+ // 1. Get Swift part
81
+ ${swiftNamespace}::${HybridTSpecCxx}& swiftPart = _hybridView->getSwiftPart();
82
+
83
+ // 2. Get UIView*
84
+ void* viewUnsafe = swiftPart.getView();
85
+ UIView* view = (__bridge_transfer UIView*) viewUnsafe;
86
+
87
+ // 3. Update RCTViewComponentView's [contentView]
88
+ [self setContentView:view];
89
+ }
90
+
91
+ - (void) updateProps:(const std::shared_ptr<const react::Props>&)props
92
+ oldProps:(const std::shared_ptr<const react::Props>&)oldProps {
93
+ // 1. Downcast props
94
+ const auto& newViewPropsConst = *std::static_pointer_cast<${propsClassName} const>(props);
95
+ auto& newViewProps = const_cast<${propsClassName}&>(newViewPropsConst);
96
+ ${swiftNamespace}::${HybridTSpecCxx}& swiftPart = _hybridView->getSwiftPart();
97
+
98
+ // 2. Update each prop individually
99
+ swiftPart.beforeUpdate();
100
+
101
+ ${indent(propAssignments.join('\n'), ' ')}
102
+
103
+ swiftPart.afterUpdate();
104
+
105
+ // 3. Update hybridRef if it changed
106
+ if (newViewProps.hybridRef.isDirty) {
107
+ // hybridRef changed - call it with new this
108
+ const auto& maybeFunc = newViewProps.hybridRef.value;
109
+ if (maybeFunc.has_value()) {
110
+ maybeFunc.value()(_hybridView);
111
+ }
112
+ newViewProps.hybridRef.isDirty = false;
113
+ }
114
+
115
+ // 4. Continue in base class
116
+ [super updateProps:props oldProps:oldProps];
117
+ }
118
+
119
+ @end
120
+ `;
121
+ return [
122
+ ...cppFiles,
123
+ {
124
+ content: mmFile,
125
+ language: 'c++',
126
+ name: `${component}.mm`,
127
+ platform: 'ios',
128
+ subdirectory: ['views'],
129
+ },
130
+ ];
131
+ }
@@ -0,0 +1,19 @@
1
+ import path from 'path';
2
+ import { promises as fs } from 'fs';
3
+ import { capitalizeName } from './utils.js';
4
+ import chalk from 'chalk';
5
+ import { Logger } from './Logger.js';
6
+ /**
7
+ * Writes the given file to disk and returns it's actual path.
8
+ */
9
+ export async function writeFile(basePath, file) {
10
+ const filepath = path.join(basePath, ...file.subdirectory, file.name);
11
+ const language = capitalizeName(file.language);
12
+ Logger.debug(` ${chalk.dim(language)}: Creating ${file.name}...`);
13
+ const dir = path.dirname(filepath);
14
+ // Create directory if it doesn't exist yet
15
+ await fs.mkdir(dir, { recursive: true });
16
+ // Write file
17
+ await fs.writeFile(filepath, file.content.trim() + '\n', 'utf8');
18
+ return filepath;
19
+ }
package/package.json CHANGED
@@ -1,40 +1,69 @@
1
1
  {
2
2
  "name": "nitrogen",
3
- "homepage": "https://github.com/nitrogenjs/client",
4
- "author": "Tim Park <timfpark@gmail.com>",
5
- "licenses": [
6
- {
7
- "type": "Apache",
8
- "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
9
- }
3
+ "version": "0.29.5",
4
+ "description": "The code-generator for react-native-nitro-modules.",
5
+ "main": "lib/index",
6
+ "types": "lib/index.d.ts",
7
+ "source": "src/index",
8
+ "type": "module",
9
+ "files": [
10
+ "lib",
11
+ "src",
12
+ "README.md"
10
13
  ],
11
- "main": "./lib",
14
+ "bin": "./lib/index.js",
12
15
  "repository": {
13
16
  "type": "git",
14
- "url": "https://github.com/nitrogenjs/client.git"
17
+ "url": "git+https://github.com/mrousavy/nitro.git"
15
18
  },
16
- "version": "0.2.24",
17
- "dependencies": {
18
- "async": "~0.2.10",
19
- "request": "~2.36.0",
20
- "socket.io-client": "~0.9.16"
19
+ "author": "Marc Rousavy <me@mrousavy.com> (https://github.com/mrousavy)",
20
+ "license": "MIT",
21
+ "bugs": {
22
+ "url": "https://github.com/mrousavy/nitro/issues"
21
23
  },
22
- "devDependencies": {
23
- "nitrogen-browser-request": "~0.3.2",
24
- "mocha": "~1.17.1",
25
- "uglify-js": "~2.4.13",
26
- "jsdox": "~0.2.6"
24
+ "homepage": "https://github.com/mrousavy/nitro#readme",
25
+ "publishConfig": {
26
+ "registry": "https://registry.npmjs.org/"
27
27
  },
28
28
  "scripts": {
29
- "test": "mocha",
30
- "postpublish": "scripts/build-documentation"
29
+ "postinstall": "bun build || exit 0;",
30
+ "build": "bun tsc",
31
+ "start": "tsc && node lib/index.js",
32
+ "typecheck": "tsc --noEmit",
33
+ "lint": "eslint \"**/*.{js,ts,tsx}\" --fix",
34
+ "lint-ci": "eslint \"**/*.{js,ts,tsx}\" -f @jamesacarr/github-actions",
35
+ "release": "release-it"
36
+ },
37
+ "dependencies": {
38
+ "chalk": "^5.3.0",
39
+ "react-native-nitro-modules": "^0.29.5",
40
+ "ts-morph": "^25.0.0",
41
+ "yargs": "^17.7.2",
42
+ "zod": "^4.0.5"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^22.8.4"
31
46
  },
32
- "keywords": [
33
- "devices",
34
- "iot",
35
- "nitrogen",
36
- "pi",
37
- "raspberry",
38
- "raspberry pi"
39
- ]
47
+ "release-it": {
48
+ "npm": {
49
+ "publish": true
50
+ },
51
+ "git": false,
52
+ "github": {
53
+ "release": false
54
+ },
55
+ "hooks": {
56
+ "before:init": "bun typecheck && bun lint",
57
+ "after:bump": "bun run build"
58
+ },
59
+ "plugins": {
60
+ "@release-it/bumper": {
61
+ "out": {
62
+ "file": "package.json",
63
+ "path": "dependencies.react-native-nitro-modules",
64
+ "versionPrefix": "^"
65
+ }
66
+ }
67
+ }
68
+ }
40
69
  }
package/src/Logger.ts ADDED
@@ -0,0 +1,63 @@
1
+ export type LogLevel = 'debug' | 'info' | 'warning' | 'error'
2
+ const levelMap = {
3
+ debug: 0,
4
+ info: 1,
5
+ warning: 2,
6
+ error: 3,
7
+ } as const
8
+ let currentLogLevel: LogLevel = 'info'
9
+
10
+ export function isValidLogLevel(level: unknown): level is LogLevel {
11
+ // @ts-expect-error
12
+ return typeof levelMap[level] === 'number'
13
+ }
14
+
15
+ export function setLogLevel(level: LogLevel) {
16
+ currentLogLevel = level
17
+ }
18
+
19
+ function isAtLeast(level: LogLevel): boolean {
20
+ return levelMap[level] >= levelMap[currentLogLevel]
21
+ }
22
+
23
+ let indentation = 0
24
+
25
+ function getIndentation(): string {
26
+ let string = ''
27
+ for (let i = 0; i < indentation; i++) {
28
+ string += ' '
29
+ }
30
+ return string
31
+ }
32
+
33
+ export const Logger = {
34
+ withIndented(callback: () => void) {
35
+ try {
36
+ indentation++
37
+ callback()
38
+ } finally {
39
+ indentation--
40
+ }
41
+ },
42
+
43
+ debug(message: string, ...extra: unknown[]) {
44
+ if (isAtLeast('debug')) {
45
+ console.debug(getIndentation() + message, ...extra)
46
+ }
47
+ },
48
+ info(message: string, ...extra: unknown[]) {
49
+ if (isAtLeast('info')) {
50
+ console.info(getIndentation() + message, ...extra)
51
+ }
52
+ },
53
+ warn(message: string, ...extra: unknown[]) {
54
+ if (isAtLeast('warning')) {
55
+ console.warn(getIndentation() + message, ...extra)
56
+ }
57
+ },
58
+ error(message: string, ...extra: unknown[]) {
59
+ if (isAtLeast('error')) {
60
+ console.error(getIndentation() + message, ...extra)
61
+ }
62
+ },
63
+ }
@@ -0,0 +1,9 @@
1
+ import type { Platform } from '../getPlatformSpecs.js'
2
+ import type { SourceFile } from '../syntax/SourceFile.js'
3
+
4
+ type AutolinkingFile = Omit<SourceFile, 'language'>
5
+
6
+ export interface Autolinking {
7
+ platform: Platform
8
+ sourceFiles: AutolinkingFile[]
9
+ }
@@ -0,0 +1,126 @@
1
+ import { NitroConfig } from '../../config/NitroConfig.js'
2
+ import { indent, toLowerCamelCase, toUnixPath } from '../../utils.js'
3
+ import {
4
+ createFileMetadataString,
5
+ getRelativeDirectory,
6
+ getRelativeDirectoryGenerated,
7
+ isCppFile,
8
+ isNotDuplicate,
9
+ } from '../../syntax/helpers.js'
10
+ import type { SourceFile } from '../../syntax/SourceFile.js'
11
+
12
+ export interface CMakeFile extends Omit<SourceFile, 'language'> {
13
+ language: 'cmake'
14
+ }
15
+
16
+ export function getBuildingWithGeneratedCmakeDefinition(): string {
17
+ const moduleName = NitroConfig.current.getAndroidCxxLibName()
18
+ const upper = toLowerCamelCase(moduleName).toUpperCase()
19
+ return `BUILDING_${upper}_WITH_GENERATED_CMAKE_PROJECT`
20
+ }
21
+
22
+ export function createCMakeExtension(files: SourceFile[]): CMakeFile {
23
+ const name = NitroConfig.current.getAndroidCxxLibName()
24
+ const sharedFiles = files
25
+ .filter((f) => f.platform === 'shared' && isCppFile(f))
26
+ .map((f) => getRelativeDirectory(f))
27
+ .map((p) => toUnixPath(p))
28
+ .filter(isNotDuplicate)
29
+ const androidFiles = files
30
+ .filter((f) => f.platform === 'android' && isCppFile(f))
31
+ .map((f) => getRelativeDirectory(f))
32
+ .map((p) => toUnixPath(p))
33
+ .filter(isNotDuplicate)
34
+ const autolinkingFilePath = getRelativeDirectoryGenerated(
35
+ 'android',
36
+ `${name}OnLoad.cpp`
37
+ )
38
+ const autolinkingFile = toUnixPath(autolinkingFilePath)
39
+ const buildingWithDefinition = getBuildingWithGeneratedCmakeDefinition()
40
+
41
+ const code = `
42
+ ${createFileMetadataString(`${name}+autolinking.cmake`, '#')}
43
+
44
+ # This is a CMake file that adds all files generated by Nitrogen
45
+ # to the current CMake project.
46
+ #
47
+ # To use it, add this to your CMakeLists.txt:
48
+ # \`\`\`cmake
49
+ # include(\${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/${name}+autolinking.cmake)
50
+ # \`\`\`
51
+
52
+ # Add all headers that were generated by Nitrogen
53
+ include_directories(
54
+ "../nitrogen/generated/shared/c++"
55
+ "../nitrogen/generated/android/c++"
56
+ "../nitrogen/generated/android/"
57
+ )
58
+
59
+ # Add all .cpp sources that were generated by Nitrogen
60
+ target_sources(
61
+ # CMake project name (Android C++ library name)
62
+ ${name} PRIVATE
63
+ # Autolinking Setup
64
+ ${autolinkingFile}
65
+ # Shared Nitrogen C++ sources
66
+ ${indent(sharedFiles.join('\n'), ' ')}
67
+ # Android-specific Nitrogen C++ sources
68
+ ${indent(androidFiles.join('\n'), ' ')}
69
+ )
70
+
71
+ # Define a flag to check if we are building properly
72
+ add_definitions(-D${buildingWithDefinition})
73
+
74
+ # Enable Raw Props parsing in react-native (for Nitro Views)
75
+ add_compile_options(-DRN_SERIALIZABLE_STATE=1)
76
+
77
+ # From node_modules/react-native/ReactAndroid/cmake-utils/folly-flags.cmake
78
+ # Used in node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake
79
+ target_compile_definitions(
80
+ ${name} PRIVATE
81
+ -DFOLLY_NO_CONFIG=1
82
+ -DFOLLY_HAVE_CLOCK_GETTIME=1
83
+ -DFOLLY_USE_LIBCPP=1
84
+ -DFOLLY_CFG_NO_COROUTINES=1
85
+ -DFOLLY_MOBILE=1
86
+ -DFOLLY_HAVE_RECVMMSG=1
87
+ -DFOLLY_HAVE_PTHREAD=1
88
+ # Once we target android-23 above, we can comment
89
+ # the following line. NDK uses GNU style stderror_r() after API 23.
90
+ -DFOLLY_HAVE_XSI_STRERROR_R=1
91
+ )
92
+
93
+ # Add all libraries required by the generated specs
94
+ find_package(fbjni REQUIRED) # <-- Used for communication between Java <-> C++
95
+ find_package(ReactAndroid REQUIRED) # <-- Used to set up React Native bindings (e.g. CallInvoker/TurboModule)
96
+ find_package(react-native-nitro-modules REQUIRED) # <-- Used to create all HybridObjects and use the Nitro core library
97
+
98
+ # Link all libraries together
99
+ target_link_libraries(
100
+ ${name}
101
+ fbjni::fbjni # <-- Facebook C++ JNI helpers
102
+ ReactAndroid::jsi # <-- RN: JSI
103
+ react-native-nitro-modules::NitroModules # <-- NitroModules Core :)
104
+ )
105
+
106
+ # Link react-native (different prefab between RN 0.75 and RN 0.76)
107
+ if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
108
+ target_link_libraries(
109
+ ${name}
110
+ ReactAndroid::reactnative # <-- RN: Native Modules umbrella prefab
111
+ )
112
+ else()
113
+ target_link_libraries(
114
+ ${name}
115
+ ReactAndroid::react_nativemodule_core # <-- RN: TurboModules Core
116
+ )
117
+ endif()
118
+ `.trim()
119
+ return {
120
+ content: code,
121
+ language: 'cmake',
122
+ name: `${name}+autolinking.cmake`,
123
+ platform: 'android',
124
+ subdirectory: [],
125
+ }
126
+ }