nitrogen 0.33.2 → 0.33.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.
@@ -34,7 +34,6 @@ return ${returnType.parseFromSwiftToCpp('__result', 'swift')}
34
34
  const code = `
35
35
  ${createFileMetadataString(`${swiftClassName}.swift`)}
36
36
 
37
- import Foundation
38
37
  ${imports.join('\n')}
39
38
 
40
39
  /**
@@ -58,7 +58,6 @@ public ${hasBaseClass ? 'override func' : 'func'} getCxxWrapper() -> ${name.Hybr
58
58
  const protocolCode = `
59
59
  ${createFileMetadataString(`${protocolName}.swift`)}
60
60
 
61
- import Foundation
62
61
  ${imports.join('\n')}
63
62
 
64
63
  /// See \`\`${protocolName}\`\`
@@ -43,7 +43,7 @@ public final func afterUpdate() {
43
43
  }
44
44
  `.trim(), `
45
45
  public final func maybePrepareForRecycle() {
46
- guard let recyclable = __implementation as? RecyclableView else { return }
46
+ guard let recyclable = __implementation as? any RecyclableView else { return }
47
47
  recyclable.prepareForRecycle()
48
48
  }
49
49
  `.trim());
@@ -82,7 +82,6 @@ public override func getCxxPart() -> bridge.${baseBridge.specializationName} {
82
82
  const swiftCxxWrapperCode = `
83
83
  ${createFileMetadataString(`${name.HybridTSpecCxx}.swift`)}
84
84
 
85
- import Foundation
86
85
  ${imports.join('\n')}
87
86
 
88
87
  /**
@@ -28,7 +28,6 @@ var ${p.escapedName}: ${p.getCode('swift')} {
28
28
  const code = `
29
29
  ${createFileMetadataString(`${struct.structName}.swift`)}
30
30
 
31
- import Foundation
32
31
  ${imports.join('\n')}
33
32
 
34
33
  /**
@@ -74,7 +74,6 @@ namespace ${namespace} {
74
74
  class ${propsClassName} final: public react::ViewProps {
75
75
  public:
76
76
  ${propsClassName}() = default;
77
- ${propsClassName}(const ${propsClassName}&);
78
77
  ${propsClassName}(const react::PropsParserContext& context,
79
78
  ${createIndentation(propsClassName.length)} const ${propsClassName}& sourceProps,
80
79
  ${createIndentation(propsClassName.length)} const react::RawProps& rawProps);
@@ -92,10 +91,14 @@ namespace ${namespace} {
92
91
  class ${stateClassName} final {
93
92
  public:
94
93
  ${stateClassName}() = default;
94
+ explicit ${stateClassName}(const std::shared_ptr<${propsClassName}>& props):
95
+ _props(props) {}
95
96
 
96
97
  public:
97
- void setProps(const ${propsClassName}& props) { _props.emplace(props); }
98
- const std::optional<${propsClassName}>& getProps() const { return _props; }
98
+ [[nodiscard]]
99
+ const std::shared_ptr<${propsClassName}>& getProps() const {
100
+ return _props;
101
+ }
99
102
 
100
103
  public:
101
104
  #ifdef ANDROID
@@ -109,7 +112,7 @@ namespace ${namespace} {
109
112
  #endif
110
113
 
111
114
  private:
112
- std::optional<${propsClassName}> _props;
115
+ std::shared_ptr<${propsClassName}> _props;
113
116
  };
114
117
 
115
118
  /**
@@ -125,7 +128,7 @@ namespace ${namespace} {
125
128
  */
126
129
  class ${descriptorClassName} final: public react::ConcreteComponentDescriptor<${shadowNodeClassName}> {
127
130
  public:
128
- ${descriptorClassName}(const react::ComponentDescriptorParameters& parameters);
131
+ explicit ${descriptorClassName}(const react::ComponentDescriptorParameters& parameters);
129
132
 
130
133
  public:
131
134
  /**
@@ -198,9 +201,6 @@ namespace ${namespace} {
198
201
  ${ctorIndent} const react::RawProps& rawProps):
199
202
  ${indent(propInitializers.join(',\n'), ' ')} { }
200
203
 
201
- ${propsClassName}::${propsClassName}(const ${propsClassName}& other):
202
- ${indent(propCopyInitializers.join(',\n'), ' ')} { }
203
-
204
204
  bool ${propsClassName}::filterObjectKeys(const std::string& propName) {
205
205
  switch (hashString(propName)) {
206
206
  ${indent(cases.join('\n'), ' ')}
@@ -225,10 +225,10 @@ namespace ${namespace} {
225
225
  void ${descriptorClassName}::adopt(react::ShadowNode& shadowNode) const {
226
226
  // This is called immediately after \`ShadowNode\` is created, cloned or in progress.
227
227
  // On Android, we need to wrap props in our state, which gets routed through Java and later unwrapped in JNI/C++.
228
- auto& concreteShadowNode = dynamic_cast<${shadowNodeClassName}&>(shadowNode);
229
- const ${propsClassName}& props = concreteShadowNode.getConcreteProps();
230
- ${stateClassName} state;
231
- state.setProps(props);
228
+ auto& concreteShadowNode = static_cast<${shadowNodeClassName}&>(shadowNode);
229
+ const std::shared_ptr<const ${propsClassName}>& constProps = concreteShadowNode.getConcreteSharedProps();
230
+ const std::shared_ptr<${propsClassName}>& props = std::const_pointer_cast<${propsClassName}>(constProps);
231
+ ${stateClassName} state{props};
232
232
  concreteShadowNode.setStateData(std::move(state));
233
233
  }
234
234
  #endif
@@ -33,7 +33,7 @@ import ${javaNamespace}.*
33
33
  /**
34
34
  * Represents the React Native \`ViewManager\` for the "${spec.name}" Nitro HybridView.
35
35
  */
36
- open class ${manager}: SimpleViewManager<View>() {
36
+ public class ${manager}: SimpleViewManager<View>() {
37
37
  init {
38
38
  if (RecyclableView::class.java.isAssignableFrom(${viewImplementation}::class.java)) {
39
39
  // Enable view recycling
@@ -114,8 +114,8 @@ ${createFileMetadataString(`J${stateUpdaterName}.hpp`)}
114
114
  #endif
115
115
 
116
116
  #include <fbjni/fbjni.h>
117
- #include <react/fabric/StateWrapperImpl.h>
118
117
  #include <react/fabric/CoreComponentsRegistry.h>
118
+ #include <react/fabric/StateWrapperImpl.h>
119
119
  #include <react/renderer/core/ConcreteComponentDescriptor.h>
120
120
  #include <NitroModules/NitroDefines.hpp>
121
121
  #include <NitroModules/JStateWrapper.hpp>
@@ -126,7 +126,7 @@ namespace ${cxxNamespace} {
126
126
 
127
127
  using namespace facebook;
128
128
 
129
- class J${stateUpdaterName}: public jni::JavaClass<J${stateUpdaterName}> {
129
+ class J${stateUpdaterName} final: public jni::JavaClass<J${stateUpdaterName}> {
130
130
  public:
131
131
  static constexpr auto kJavaDescriptor = "L${updaterJniDescriptor};";
132
132
 
@@ -154,9 +154,9 @@ public:
154
154
  const name = escapeCppName(p.name);
155
155
  const setter = p.getSetterName('other');
156
156
  return `
157
- if (props.${name}.isDirty) {
158
- view->${setter}(props.${name}.value);
159
- // TODO: Set isDirty = false
157
+ if (props->${name}.isDirty) {
158
+ view->${setter}(props->${name}.value);
159
+ props->${name}.isDirty = false;
160
160
  }
161
161
  `.trim();
162
162
  });
@@ -166,6 +166,7 @@ ${createFileMetadataString(`J${stateUpdaterName}.cpp`)}
166
166
  #include "J${stateUpdaterName}.hpp"
167
167
  #include "views/${component}.hpp"
168
168
  #include <NitroModules/NitroDefines.hpp>
169
+ #include <react/fabric/StateWrapperImpl.h>
169
170
 
170
171
  namespace ${cxxNamespace} {
171
172
 
@@ -179,32 +180,32 @@ void J${stateUpdaterName}::updateViewProps(jni::alias_ref<jni::JClass> /* class
179
180
 
180
181
  // Get concrete StateWrapperImpl from passed StateWrapper interface object
181
182
  jobject rawStateWrapper = stateWrapperInterface.get();
182
- if (!stateWrapperInterface->isInstanceOf(react::StateWrapperImpl::javaClassStatic())) {
183
+ if (!stateWrapperInterface->isInstanceOf(react::StateWrapperImpl::javaClassStatic())) [[unlikely]] {
183
184
  throw std::runtime_error("StateWrapper is not a StateWrapperImpl");
184
185
  }
185
186
  auto stateWrapper = jni::alias_ref<react::StateWrapperImpl::javaobject>{
186
187
  static_cast<react::StateWrapperImpl::javaobject>(rawStateWrapper)};
187
-
188
188
  std::shared_ptr<const react::State> state = stateWrapper->cthis()->getState();
189
- auto concreteState = std::dynamic_pointer_cast<const ConcreteStateData>(state);
189
+ auto concreteState = std::static_pointer_cast<const ConcreteStateData>(state);
190
190
  const ${stateClassName}& data = concreteState->getData();
191
- const std::optional<${propsClassName}>& maybeProps = data.getProps();
192
- if (!maybeProps.has_value()) {
191
+ const std::shared_ptr<${propsClassName}>& props = data.getProps();
192
+ if (props == nullptr) [[unlikely]] {
193
193
  // Props aren't set yet!
194
194
  throw std::runtime_error("${stateClassName}'s data doesn't contain any props!");
195
195
  }
196
- const ${propsClassName}& props = maybeProps.value();
196
+
197
+ // Update all props if they are dirty
197
198
  ${indent(propsUpdaterCalls.join('\n'), ' ')}
198
199
 
199
200
  // Update hybridRef if it changed
200
- if (props.hybridRef.isDirty) {
201
+ if (props->hybridRef.isDirty) {
201
202
  // hybridRef changed - call it with new this
202
- const auto& maybeFunc = props.hybridRef.value;
203
+ const auto& maybeFunc = props->hybridRef.value;
203
204
  if (maybeFunc.has_value()) {
204
205
  std::shared_ptr<${JHybridTSpec}> shared = javaView->cthis()->shared_cast<${JHybridTSpec}>();
205
206
  maybeFunc.value()(shared);
206
207
  }
207
- // TODO: Set isDirty = false
208
+ props->hybridRef.isDirty = false;
208
209
  }
209
210
  }
210
211
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nitrogen",
3
- "version": "0.33.2",
3
+ "version": "0.33.4",
4
4
  "description": "The code-generator for react-native-nitro-modules.",
5
5
  "main": "lib/index",
6
6
  "types": "lib/index.d.ts",
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "chalk": "^5.3.0",
38
- "react-native-nitro-modules": "^0.33.2",
38
+ "react-native-nitro-modules": "^0.33.4",
39
39
  "ts-morph": "^27.0.0",
40
40
  "yargs": "^18.0.0",
41
41
  "zod": "^4.0.5"
@@ -41,7 +41,6 @@ return ${returnType.parseFromSwiftToCpp('__result', 'swift')}
41
41
  const code = `
42
42
  ${createFileMetadataString(`${swiftClassName}.swift`)}
43
43
 
44
- import Foundation
45
44
  ${imports.join('\n')}
46
45
 
47
46
  /**
@@ -70,7 +70,6 @@ public ${hasBaseClass ? 'override func' : 'func'} getCxxWrapper() -> ${name.Hybr
70
70
  const protocolCode = `
71
71
  ${createFileMetadataString(`${protocolName}.swift`)}
72
72
 
73
- import Foundation
74
73
  ${imports.join('\n')}
75
74
 
76
75
  /// See \`\`${protocolName}\`\`
@@ -66,7 +66,7 @@ public final func afterUpdate() {
66
66
  `.trim(),
67
67
  `
68
68
  public final func maybePrepareForRecycle() {
69
- guard let recyclable = __implementation as? RecyclableView else { return }
69
+ guard let recyclable = __implementation as? any RecyclableView else { return }
70
70
  recyclable.prepareForRecycle()
71
71
  }
72
72
  `.trim()
@@ -130,7 +130,6 @@ public override func getCxxPart() -> bridge.${baseBridge.specializationName} {
130
130
  const swiftCxxWrapperCode = `
131
131
  ${createFileMetadataString(`${name.HybridTSpecCxx}.swift`)}
132
132
 
133
- import Foundation
134
133
  ${imports.join('\n')}
135
134
 
136
135
  /**
@@ -37,7 +37,6 @@ var ${p.escapedName}: ${p.getCode('swift')} {
37
37
  const code = `
38
38
  ${createFileMetadataString(`${struct.structName}.swift`)}
39
39
 
40
- import Foundation
41
40
  ${imports.join('\n')}
42
41
 
43
42
  /**
@@ -115,7 +115,6 @@ namespace ${namespace} {
115
115
  class ${propsClassName} final: public react::ViewProps {
116
116
  public:
117
117
  ${propsClassName}() = default;
118
- ${propsClassName}(const ${propsClassName}&);
119
118
  ${propsClassName}(const react::PropsParserContext& context,
120
119
  ${createIndentation(propsClassName.length)} const ${propsClassName}& sourceProps,
121
120
  ${createIndentation(propsClassName.length)} const react::RawProps& rawProps);
@@ -133,10 +132,14 @@ namespace ${namespace} {
133
132
  class ${stateClassName} final {
134
133
  public:
135
134
  ${stateClassName}() = default;
135
+ explicit ${stateClassName}(const std::shared_ptr<${propsClassName}>& props):
136
+ _props(props) {}
136
137
 
137
138
  public:
138
- void setProps(const ${propsClassName}& props) { _props.emplace(props); }
139
- const std::optional<${propsClassName}>& getProps() const { return _props; }
139
+ [[nodiscard]]
140
+ const std::shared_ptr<${propsClassName}>& getProps() const {
141
+ return _props;
142
+ }
140
143
 
141
144
  public:
142
145
  #ifdef ANDROID
@@ -150,7 +153,7 @@ namespace ${namespace} {
150
153
  #endif
151
154
 
152
155
  private:
153
- std::optional<${propsClassName}> _props;
156
+ std::shared_ptr<${propsClassName}> _props;
154
157
  };
155
158
 
156
159
  /**
@@ -166,7 +169,7 @@ namespace ${namespace} {
166
169
  */
167
170
  class ${descriptorClassName} final: public react::ConcreteComponentDescriptor<${shadowNodeClassName}> {
168
171
  public:
169
- ${descriptorClassName}(const react::ComponentDescriptorParameters& parameters);
172
+ explicit ${descriptorClassName}(const react::ComponentDescriptorParameters& parameters);
170
173
 
171
174
  public:
172
175
  /**
@@ -245,9 +248,6 @@ namespace ${namespace} {
245
248
  ${ctorIndent} const react::RawProps& rawProps):
246
249
  ${indent(propInitializers.join(',\n'), ' ')} { }
247
250
 
248
- ${propsClassName}::${propsClassName}(const ${propsClassName}& other):
249
- ${indent(propCopyInitializers.join(',\n'), ' ')} { }
250
-
251
251
  bool ${propsClassName}::filterObjectKeys(const std::string& propName) {
252
252
  switch (hashString(propName)) {
253
253
  ${indent(cases.join('\n'), ' ')}
@@ -272,10 +272,10 @@ namespace ${namespace} {
272
272
  void ${descriptorClassName}::adopt(react::ShadowNode& shadowNode) const {
273
273
  // This is called immediately after \`ShadowNode\` is created, cloned or in progress.
274
274
  // On Android, we need to wrap props in our state, which gets routed through Java and later unwrapped in JNI/C++.
275
- auto& concreteShadowNode = dynamic_cast<${shadowNodeClassName}&>(shadowNode);
276
- const ${propsClassName}& props = concreteShadowNode.getConcreteProps();
277
- ${stateClassName} state;
278
- state.setProps(props);
275
+ auto& concreteShadowNode = static_cast<${shadowNodeClassName}&>(shadowNode);
276
+ const std::shared_ptr<const ${propsClassName}>& constProps = concreteShadowNode.getConcreteSharedProps();
277
+ const std::shared_ptr<${propsClassName}>& props = std::const_pointer_cast<${propsClassName}>(constProps);
278
+ ${stateClassName} state{props};
279
279
  concreteShadowNode.setStateData(std::move(state));
280
280
  }
281
281
  #endif
@@ -53,7 +53,7 @@ import ${javaNamespace}.*
53
53
  /**
54
54
  * Represents the React Native \`ViewManager\` for the "${spec.name}" Nitro HybridView.
55
55
  */
56
- open class ${manager}: SimpleViewManager<View>() {
56
+ public class ${manager}: SimpleViewManager<View>() {
57
57
  init {
58
58
  if (RecyclableView::class.java.isAssignableFrom(${viewImplementation}::class.java)) {
59
59
  // Enable view recycling
@@ -140,8 +140,8 @@ ${createFileMetadataString(`J${stateUpdaterName}.hpp`)}
140
140
  #endif
141
141
 
142
142
  #include <fbjni/fbjni.h>
143
- #include <react/fabric/StateWrapperImpl.h>
144
143
  #include <react/fabric/CoreComponentsRegistry.h>
144
+ #include <react/fabric/StateWrapperImpl.h>
145
145
  #include <react/renderer/core/ConcreteComponentDescriptor.h>
146
146
  #include <NitroModules/NitroDefines.hpp>
147
147
  #include <NitroModules/JStateWrapper.hpp>
@@ -152,7 +152,7 @@ namespace ${cxxNamespace} {
152
152
 
153
153
  using namespace facebook;
154
154
 
155
- class J${stateUpdaterName}: public jni::JavaClass<J${stateUpdaterName}> {
155
+ class J${stateUpdaterName} final: public jni::JavaClass<J${stateUpdaterName}> {
156
156
  public:
157
157
  static constexpr auto kJavaDescriptor = "L${updaterJniDescriptor};";
158
158
 
@@ -181,9 +181,9 @@ public:
181
181
  const name = escapeCppName(p.name)
182
182
  const setter = p.getSetterName('other')
183
183
  return `
184
- if (props.${name}.isDirty) {
185
- view->${setter}(props.${name}.value);
186
- // TODO: Set isDirty = false
184
+ if (props->${name}.isDirty) {
185
+ view->${setter}(props->${name}.value);
186
+ props->${name}.isDirty = false;
187
187
  }
188
188
  `.trim()
189
189
  })
@@ -193,6 +193,7 @@ ${createFileMetadataString(`J${stateUpdaterName}.cpp`)}
193
193
  #include "J${stateUpdaterName}.hpp"
194
194
  #include "views/${component}.hpp"
195
195
  #include <NitroModules/NitroDefines.hpp>
196
+ #include <react/fabric/StateWrapperImpl.h>
196
197
 
197
198
  namespace ${cxxNamespace} {
198
199
 
@@ -206,32 +207,32 @@ void J${stateUpdaterName}::updateViewProps(jni::alias_ref<jni::JClass> /* class
206
207
 
207
208
  // Get concrete StateWrapperImpl from passed StateWrapper interface object
208
209
  jobject rawStateWrapper = stateWrapperInterface.get();
209
- if (!stateWrapperInterface->isInstanceOf(react::StateWrapperImpl::javaClassStatic())) {
210
+ if (!stateWrapperInterface->isInstanceOf(react::StateWrapperImpl::javaClassStatic())) [[unlikely]] {
210
211
  throw std::runtime_error("StateWrapper is not a StateWrapperImpl");
211
212
  }
212
213
  auto stateWrapper = jni::alias_ref<react::StateWrapperImpl::javaobject>{
213
214
  static_cast<react::StateWrapperImpl::javaobject>(rawStateWrapper)};
214
-
215
215
  std::shared_ptr<const react::State> state = stateWrapper->cthis()->getState();
216
- auto concreteState = std::dynamic_pointer_cast<const ConcreteStateData>(state);
216
+ auto concreteState = std::static_pointer_cast<const ConcreteStateData>(state);
217
217
  const ${stateClassName}& data = concreteState->getData();
218
- const std::optional<${propsClassName}>& maybeProps = data.getProps();
219
- if (!maybeProps.has_value()) {
218
+ const std::shared_ptr<${propsClassName}>& props = data.getProps();
219
+ if (props == nullptr) [[unlikely]] {
220
220
  // Props aren't set yet!
221
221
  throw std::runtime_error("${stateClassName}'s data doesn't contain any props!");
222
222
  }
223
- const ${propsClassName}& props = maybeProps.value();
223
+
224
+ // Update all props if they are dirty
224
225
  ${indent(propsUpdaterCalls.join('\n'), ' ')}
225
226
 
226
227
  // Update hybridRef if it changed
227
- if (props.hybridRef.isDirty) {
228
+ if (props->hybridRef.isDirty) {
228
229
  // hybridRef changed - call it with new this
229
- const auto& maybeFunc = props.hybridRef.value;
230
+ const auto& maybeFunc = props->hybridRef.value;
230
231
  if (maybeFunc.has_value()) {
231
232
  std::shared_ptr<${JHybridTSpec}> shared = javaView->cthis()->shared_cast<${JHybridTSpec}>();
232
233
  maybeFunc.value()(shared);
233
234
  }
234
- // TODO: Set isDirty = false
235
+ props->hybridRef.isDirty = false;
235
236
  }
236
237
  }
237
238