nitrogen 0.29.5 → 0.29.7

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.
@@ -32,6 +32,12 @@ ${createFileMetadataString(`${name}+autolinking.cmake`, '#')}
32
32
  # include(\${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/${name}+autolinking.cmake)
33
33
  # \`\`\`
34
34
 
35
+ # Define a flag to check if we are building properly
36
+ add_definitions(-D${buildingWithDefinition})
37
+
38
+ # Enable Raw Props parsing in react-native (for Nitro Views)
39
+ add_definitions(-DRN_SERIALIZABLE_STATE)
40
+
35
41
  # Add all headers that were generated by Nitrogen
36
42
  include_directories(
37
43
  "../nitrogen/generated/shared/c++"
@@ -51,15 +57,9 @@ target_sources(
51
57
  ${indent(androidFiles.join('\n'), ' ')}
52
58
  )
53
59
 
54
- # Define a flag to check if we are building properly
55
- add_definitions(-D${buildingWithDefinition})
56
-
57
- # Enable Raw Props parsing in react-native (for Nitro Views)
58
- add_compile_options(-DRN_SERIALIZABLE_STATE=1)
59
-
60
60
  # From node_modules/react-native/ReactAndroid/cmake-utils/folly-flags.cmake
61
61
  # Used in node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake
62
- target_compile_definitions(
62
+ target_compile_definitions(
63
63
  ${name} PRIVATE
64
64
  -DFOLLY_NO_CONFIG=1
65
65
  -DFOLLY_HAVE_CLOCK_GETTIME=1
@@ -0,0 +1,13 @@
1
+ import type { NitroConfig } from '../config/NitroConfig.js';
2
+ import type { Language } from '../getPlatformSpecs.js';
3
+ import type { Method } from './Method.js';
4
+ import type { Property } from './Property.js';
5
+ export interface HybridObjectSpec {
6
+ name: string;
7
+ language: Language;
8
+ properties: Property[];
9
+ methods: Method[];
10
+ baseTypes: HybridObjectSpec[];
11
+ isHybridView: boolean;
12
+ config: NitroConfig;
13
+ }
@@ -14,7 +14,7 @@ import { StructType } from '../types/StructType.js';
14
14
  import { TupleType } from '../types/TupleType.js';
15
15
  import { VariantType } from '../types/VariantType.js';
16
16
  import { getReferencedTypes } from '../getReferencedTypes.js';
17
- import { createSwiftCxxHelpers, } from './SwiftCxxTypeHelper.js';
17
+ import { createSwiftCxxHelpers, isPrimitivelyCopyable, } from './SwiftCxxTypeHelper.js';
18
18
  import { createSwiftEnumBridge } from './SwiftEnum.js';
19
19
  import { createSwiftStructBridge } from './SwiftStruct.js';
20
20
  import { createSwiftVariant } from './SwiftVariant.js';
@@ -68,17 +68,11 @@ export class SwiftCxxBridgedType {
68
68
  case 'tuple':
69
69
  // (A, B) <> std::tuple<A, B>
70
70
  return true;
71
- case 'struct':
72
- // SomeStruct (Swift extension) <> SomeStruct (C++)
73
- return true;
74
71
  case 'function':
75
72
  // (@ecaping () -> Void) <> std::function<...>
76
73
  return true;
77
74
  case 'array-buffer':
78
75
  // ArrayBufferHolder <> std::shared_ptr<ArrayBuffer>
79
- if (this.isBridgingToDirectCppTarget) {
80
- return false;
81
- }
82
76
  return true;
83
77
  case 'date':
84
78
  // Date <> double
@@ -452,7 +446,21 @@ export class SwiftCxxBridgedType {
452
446
  const wrapping = new SwiftCxxBridgedType(array.itemType, true);
453
447
  switch (language) {
454
448
  case 'swift':
455
- return `${cppParameterName}.map({ __item in ${wrapping.parseFromCppToSwift('__item', 'swift')} })`.trim();
449
+ if (isPrimitivelyCopyable(array.itemType)) {
450
+ // We can primitively copy the data, raw:
451
+ const bridge = this.getBridgeOrThrow();
452
+ const getDataFunc = `bridge.get_data_${bridge.specializationName}`;
453
+ return `
454
+ { () -> ${array.getCode('swift')} in
455
+ let __data = ${getDataFunc}(${cppParameterName})
456
+ let __size = ${cppParameterName}.size()
457
+ return Array(UnsafeBufferPointer(start: __data, count: __size))
458
+ }()`.trim();
459
+ }
460
+ else {
461
+ // We have to iterate the element one by one to create a resulting Array (mapped)
462
+ return `${cppParameterName}.map({ __item in ${wrapping.parseFromCppToSwift('__item', 'swift')} })`.trim();
463
+ }
456
464
  default:
457
465
  return cppParameterName;
458
466
  }
@@ -698,12 +706,22 @@ case ${i}:
698
706
  }
699
707
  case 'array': {
700
708
  const bridge = this.getBridgeOrThrow();
701
- const makeFunc = `bridge.${bridge.funcName}`;
702
709
  const array = getTypeAs(this.type, ArrayType);
703
710
  const wrapping = new SwiftCxxBridgedType(array.itemType, true);
704
711
  switch (language) {
705
712
  case 'swift':
706
- return `
713
+ if (isPrimitivelyCopyable(array.itemType)) {
714
+ // memory can be copied primitively
715
+ const copyFunc = `bridge.${bridge.funcName}`;
716
+ return `
717
+ ${swiftParameterName}.withUnsafeBufferPointer { __pointer -> bridge.${bridge.specializationName} in
718
+ return ${copyFunc}(__pointer.baseAddress!, ${swiftParameterName}.count)
719
+ }`.trim();
720
+ }
721
+ else {
722
+ // array has to be iterated and converted one-by-one
723
+ const makeFunc = `bridge.${bridge.funcName}`;
724
+ return `
707
725
  { () -> bridge.${bridge.specializationName} in
708
726
  var __vector = ${makeFunc}(${swiftParameterName}.count)
709
727
  for __item in ${swiftParameterName} {
@@ -711,6 +729,7 @@ case ${i}:
711
729
  }
712
730
  return __vector
713
731
  }()`.trim();
732
+ }
714
733
  default:
715
734
  return swiftParameterName;
716
735
  }
@@ -0,0 +1,18 @@
1
+ import type { SourceImport } from '../SourceFile.js';
2
+ import type { Type } from '../types/Type.js';
3
+ export interface SwiftCxxHelper {
4
+ cxxHeader: {
5
+ code: string;
6
+ requiredIncludes: SourceImport[];
7
+ };
8
+ cxxImplementation?: {
9
+ code: string;
10
+ requiredIncludes: SourceImport[];
11
+ };
12
+ funcName: string;
13
+ specializationName: string;
14
+ cxxType: string;
15
+ dependencies: SwiftCxxHelper[];
16
+ }
17
+ export declare function createSwiftCxxHelpers(type: Type): SwiftCxxHelper | undefined;
18
+ export declare function isPrimitivelyCopyable(type: Type): boolean;
@@ -115,17 +115,17 @@ return ${cxxNamespace}::get_${internalName}(cppType);
115
115
  * Specialized version of \`${escapeComments(actualType)}\`.
116
116
  */
117
117
  using ${name} = ${actualType};
118
- ${actualType} create_${name}(void* _Nonnull swiftUnsafePointer) noexcept;
119
- void* _Nonnull get_${name}(${name} cppType) noexcept;
118
+ ${actualType} create_${name}(void* NON_NULL swiftUnsafePointer) noexcept;
119
+ void* NON_NULL get_${name}(${name} cppType) noexcept;
120
120
  `.trim(),
121
121
  requiredIncludes: type.getRequiredImports('c++'),
122
122
  },
123
123
  cxxImplementation: {
124
124
  code: `
125
- ${actualType} create_${name}(void* _Nonnull swiftUnsafePointer) noexcept {
125
+ ${actualType} create_${name}(void* NON_NULL swiftUnsafePointer) noexcept {
126
126
  ${indent(createImplementation, ' ')}
127
127
  }
128
- void* _Nonnull get_${name}(${name} cppType) noexcept {
128
+ void* NON_NULL get_${name}(${name} cppType) noexcept {
129
129
  ${indent(getImplementation, ' ')}
130
130
  }
131
131
  `.trim(),
@@ -219,6 +219,10 @@ inline ${wrappedBridge.getTypeCode('c++')} get_${name}(const ${actualType}& opti
219
219
  dependencies: [],
220
220
  };
221
221
  }
222
+ export function isPrimitivelyCopyable(type) {
223
+ const bridgedType = new SwiftCxxBridgedType(type, true);
224
+ return !bridgedType.needsSpecialHandling;
225
+ }
222
226
  /**
223
227
  * Creates a C++ `create_vector_T<T>(size)` function that can be called from Swift.
224
228
  */
@@ -226,12 +230,27 @@ function createCxxVectorSwiftHelper(type) {
226
230
  const actualType = type.getCode('c++');
227
231
  const bridgedType = new SwiftCxxBridgedType(type);
228
232
  const name = escapeCppName(actualType);
229
- return {
230
- cxxType: actualType,
231
- funcName: `create_${name}`,
232
- specializationName: name,
233
- cxxHeader: {
234
- code: `
233
+ let code;
234
+ let funcName;
235
+ if (isPrimitivelyCopyable(type.itemType)) {
236
+ const itemType = type.itemType.getCode('c++');
237
+ funcName = `copy_${name}`;
238
+ code = `
239
+ /**
240
+ * Specialized version of \`${escapeComments(actualType)}\`.
241
+ */
242
+ using ${name} = ${actualType};
243
+ inline ${actualType} copy_${name}(const ${itemType}* CONTIGUOUS_MEMORY NON_NULL data, size_t size) noexcept {
244
+ return margelo::nitro::FastVectorCopy<${itemType}>(data, size);
245
+ }
246
+ inline const ${itemType}* CONTIGUOUS_MEMORY NON_NULL get_data_${name}(const ${actualType}& vector) noexcept {
247
+ return vector.data();
248
+ }
249
+ `.trim();
250
+ }
251
+ else {
252
+ funcName = `create_${name}`;
253
+ code = `
235
254
  /**
236
255
  * Specialized version of \`${escapeComments(actualType)}\`.
237
256
  */
@@ -240,14 +259,25 @@ inline ${actualType} create_${name}(size_t size) noexcept {
240
259
  ${actualType} vector;
241
260
  vector.reserve(size);
242
261
  return vector;
243
- }
244
- `.trim(),
262
+ }`.trim();
263
+ }
264
+ return {
265
+ cxxType: actualType,
266
+ funcName: funcName,
267
+ specializationName: name,
268
+ cxxHeader: {
269
+ code: code,
245
270
  requiredIncludes: [
246
271
  {
247
272
  name: 'vector',
248
273
  space: 'system',
249
274
  language: 'c++',
250
275
  },
276
+ {
277
+ name: 'NitroModules/FastVectorCopy.hpp',
278
+ space: 'system',
279
+ language: 'c++',
280
+ },
251
281
  ...bridgedType.getRequiredImports('c++'),
252
282
  ],
253
283
  },
@@ -382,7 +412,7 @@ public:
382
412
  private:
383
413
  std::unique_ptr<${actualType}> _function;
384
414
  } SWIFT_NONCOPYABLE;
385
- ${name} create_${name}(void* _Nonnull swiftClosureWrapper) noexcept;
415
+ ${name} create_${name}(void* NON_NULL swiftClosureWrapper) noexcept;
386
416
  inline ${wrapperName} wrap_${name}(${name} value) noexcept {
387
417
  return ${wrapperName}(std::move(value));
388
418
  }
@@ -403,7 +433,7 @@ inline ${wrapperName} wrap_${name}(${name} value) noexcept {
403
433
  },
404
434
  cxxImplementation: {
405
435
  code: `
406
- ${name} create_${name}(void* _Nonnull swiftClosureWrapper) noexcept {
436
+ ${name} create_${name}(void* NON_NULL swiftClosureWrapper) noexcept {
407
437
  auto swiftClosure = ${swiftClassName}::fromUnsafe(swiftClosureWrapper);
408
438
  return [swiftClosure = std::move(swiftClosure)](${paramsSignature.join(', ')}) mutable -> ${type.returnType.getCode('c++')} {
409
439
  ${indent(body, ' ')}
@@ -31,7 +31,7 @@ import ${javaNamespace}.*
31
31
  /**
32
32
  * Represents the React Native \`ViewManager\` for the "${spec.name}" Nitro HybridView.
33
33
  */
34
- class ${manager}: SimpleViewManager<View>() {
34
+ open class ${manager}: SimpleViewManager<View>() {
35
35
  private val views = hashMapOf<View, ${viewImplementation}>()
36
36
 
37
37
  override fun getName(): String {
@@ -89,6 +89,10 @@ ${createFileMetadataString(`J${stateUpdaterName}.hpp`)}
89
89
 
90
90
  #pragma once
91
91
 
92
+ #ifndef RN_SERIALIZABLE_STATE
93
+ #error ${spec.config.getAndroidCxxLibName()} was compiled without the 'RN_SERIALIZABLE_STATE' flag. This flag is required for Nitro Views - set it in your CMakeLists!
94
+ #endif
95
+
92
96
  #include <fbjni/fbjni.h>
93
97
  #include <react/fabric/StateWrapperImpl.h>
94
98
  #include <react/fabric/CoreComponentsRegistry.h>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nitrogen",
3
- "version": "0.29.5",
3
+ "version": "0.29.7",
4
4
  "description": "The code-generator for react-native-nitro-modules.",
5
5
  "main": "lib/index",
6
6
  "types": "lib/index.d.ts",
@@ -36,13 +36,13 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "chalk": "^5.3.0",
39
- "react-native-nitro-modules": "^0.29.5",
40
- "ts-morph": "^25.0.0",
39
+ "react-native-nitro-modules": "^0.29.7",
40
+ "ts-morph": "^27.0.0",
41
41
  "yargs": "^17.7.2",
42
42
  "zod": "^4.0.5"
43
43
  },
44
44
  "devDependencies": {
45
- "@types/node": "^22.8.4"
45
+ "@types/node": "^24.5.2"
46
46
  },
47
47
  "release-it": {
48
48
  "npm": {
@@ -49,6 +49,12 @@ ${createFileMetadataString(`${name}+autolinking.cmake`, '#')}
49
49
  # include(\${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/${name}+autolinking.cmake)
50
50
  # \`\`\`
51
51
 
52
+ # Define a flag to check if we are building properly
53
+ add_definitions(-D${buildingWithDefinition})
54
+
55
+ # Enable Raw Props parsing in react-native (for Nitro Views)
56
+ add_definitions(-DRN_SERIALIZABLE_STATE)
57
+
52
58
  # Add all headers that were generated by Nitrogen
53
59
  include_directories(
54
60
  "../nitrogen/generated/shared/c++"
@@ -68,15 +74,9 @@ target_sources(
68
74
  ${indent(androidFiles.join('\n'), ' ')}
69
75
  )
70
76
 
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
77
  # From node_modules/react-native/ReactAndroid/cmake-utils/folly-flags.cmake
78
78
  # Used in node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake
79
- target_compile_definitions(
79
+ target_compile_definitions(
80
80
  ${name} PRIVATE
81
81
  -DFOLLY_NO_CONFIG=1
82
82
  -DFOLLY_HAVE_CLOCK_GETTIME=1
package/src/getFiles.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { Dirent, promises as fs } from 'fs'
2
2
  import path from 'path'
3
3
 
4
- function getFilePath(file: Dirent, rootDir: string): string {
4
+ type DirentCompat = Dirent & { path?: string }
5
+
6
+ function getFilePath(file: DirentCompat, rootDir: string): string {
5
7
  const dir = file.parentPath ?? file.path ?? rootDir
6
8
  return path.join(dir, file.name)
7
9
  }
@@ -22,6 +22,7 @@ import { VariantType } from '../types/VariantType.js'
22
22
  import { getReferencedTypes } from '../getReferencedTypes.js'
23
23
  import {
24
24
  createSwiftCxxHelpers,
25
+ isPrimitivelyCopyable,
25
26
  type SwiftCxxHelper,
26
27
  } from './SwiftCxxTypeHelper.js'
27
28
  import { createSwiftEnumBridge } from './SwiftEnum.js'
@@ -84,17 +85,11 @@ export class SwiftCxxBridgedType implements BridgedType<'swift', 'c++'> {
84
85
  case 'tuple':
85
86
  // (A, B) <> std::tuple<A, B>
86
87
  return true
87
- case 'struct':
88
- // SomeStruct (Swift extension) <> SomeStruct (C++)
89
- return true
90
88
  case 'function':
91
89
  // (@ecaping () -> Void) <> std::function<...>
92
90
  return true
93
91
  case 'array-buffer':
94
92
  // ArrayBufferHolder <> std::shared_ptr<ArrayBuffer>
95
- if (this.isBridgingToDirectCppTarget) {
96
- return false
97
- }
98
93
  return true
99
94
  case 'date':
100
95
  // Date <> double
@@ -492,7 +487,20 @@ export class SwiftCxxBridgedType implements BridgedType<'swift', 'c++'> {
492
487
  const wrapping = new SwiftCxxBridgedType(array.itemType, true)
493
488
  switch (language) {
494
489
  case 'swift':
495
- return `${cppParameterName}.map({ __item in ${wrapping.parseFromCppToSwift('__item', 'swift')} })`.trim()
490
+ if (isPrimitivelyCopyable(array.itemType)) {
491
+ // We can primitively copy the data, raw:
492
+ const bridge = this.getBridgeOrThrow()
493
+ const getDataFunc = `bridge.get_data_${bridge.specializationName}`
494
+ return `
495
+ { () -> ${array.getCode('swift')} in
496
+ let __data = ${getDataFunc}(${cppParameterName})
497
+ let __size = ${cppParameterName}.size()
498
+ return Array(UnsafeBufferPointer(start: __data, count: __size))
499
+ }()`.trim()
500
+ } else {
501
+ // We have to iterate the element one by one to create a resulting Array (mapped)
502
+ return `${cppParameterName}.map({ __item in ${wrapping.parseFromCppToSwift('__item', 'swift')} })`.trim()
503
+ }
496
504
  default:
497
505
  return cppParameterName
498
506
  }
@@ -749,12 +757,21 @@ case ${i}:
749
757
  }
750
758
  case 'array': {
751
759
  const bridge = this.getBridgeOrThrow()
752
- const makeFunc = `bridge.${bridge.funcName}`
753
760
  const array = getTypeAs(this.type, ArrayType)
754
761
  const wrapping = new SwiftCxxBridgedType(array.itemType, true)
755
762
  switch (language) {
756
763
  case 'swift':
757
- return `
764
+ if (isPrimitivelyCopyable(array.itemType)) {
765
+ // memory can be copied primitively
766
+ const copyFunc = `bridge.${bridge.funcName}`
767
+ return `
768
+ ${swiftParameterName}.withUnsafeBufferPointer { __pointer -> bridge.${bridge.specializationName} in
769
+ return ${copyFunc}(__pointer.baseAddress!, ${swiftParameterName}.count)
770
+ }`.trim()
771
+ } else {
772
+ // array has to be iterated and converted one-by-one
773
+ const makeFunc = `bridge.${bridge.funcName}`
774
+ return `
758
775
  { () -> bridge.${bridge.specializationName} in
759
776
  var __vector = ${makeFunc}(${swiftParameterName}.count)
760
777
  for __item in ${swiftParameterName} {
@@ -762,6 +779,7 @@ case ${i}:
762
779
  }
763
780
  return __vector
764
781
  }()`.trim()
782
+ }
765
783
  default:
766
784
  return swiftParameterName
767
785
  }
@@ -147,17 +147,17 @@ return ${cxxNamespace}::get_${internalName}(cppType);
147
147
  * Specialized version of \`${escapeComments(actualType)}\`.
148
148
  */
149
149
  using ${name} = ${actualType};
150
- ${actualType} create_${name}(void* _Nonnull swiftUnsafePointer) noexcept;
151
- void* _Nonnull get_${name}(${name} cppType) noexcept;
150
+ ${actualType} create_${name}(void* NON_NULL swiftUnsafePointer) noexcept;
151
+ void* NON_NULL get_${name}(${name} cppType) noexcept;
152
152
  `.trim(),
153
153
  requiredIncludes: type.getRequiredImports('c++'),
154
154
  },
155
155
  cxxImplementation: {
156
156
  code: `
157
- ${actualType} create_${name}(void* _Nonnull swiftUnsafePointer) noexcept {
157
+ ${actualType} create_${name}(void* NON_NULL swiftUnsafePointer) noexcept {
158
158
  ${indent(createImplementation, ' ')}
159
159
  }
160
- void* _Nonnull get_${name}(${name} cppType) noexcept {
160
+ void* NON_NULL get_${name}(${name} cppType) noexcept {
161
161
  ${indent(getImplementation, ' ')}
162
162
  }
163
163
  `.trim(),
@@ -260,6 +260,11 @@ inline ${wrappedBridge.getTypeCode('c++')} get_${name}(const ${actualType}& opti
260
260
  }
261
261
  }
262
262
 
263
+ export function isPrimitivelyCopyable(type: Type): boolean {
264
+ const bridgedType = new SwiftCxxBridgedType(type, true)
265
+ return !bridgedType.needsSpecialHandling
266
+ }
267
+
263
268
  /**
264
269
  * Creates a C++ `create_vector_T<T>(size)` function that can be called from Swift.
265
270
  */
@@ -267,12 +272,26 @@ function createCxxVectorSwiftHelper(type: ArrayType): SwiftCxxHelper {
267
272
  const actualType = type.getCode('c++')
268
273
  const bridgedType = new SwiftCxxBridgedType(type)
269
274
  const name = escapeCppName(actualType)
270
- return {
271
- cxxType: actualType,
272
- funcName: `create_${name}`,
273
- specializationName: name,
274
- cxxHeader: {
275
- code: `
275
+ let code: string
276
+ let funcName: string
277
+ if (isPrimitivelyCopyable(type.itemType)) {
278
+ const itemType = type.itemType.getCode('c++')
279
+ funcName = `copy_${name}`
280
+ code = `
281
+ /**
282
+ * Specialized version of \`${escapeComments(actualType)}\`.
283
+ */
284
+ using ${name} = ${actualType};
285
+ inline ${actualType} copy_${name}(const ${itemType}* CONTIGUOUS_MEMORY NON_NULL data, size_t size) noexcept {
286
+ return margelo::nitro::FastVectorCopy<${itemType}>(data, size);
287
+ }
288
+ inline const ${itemType}* CONTIGUOUS_MEMORY NON_NULL get_data_${name}(const ${actualType}& vector) noexcept {
289
+ return vector.data();
290
+ }
291
+ `.trim()
292
+ } else {
293
+ funcName = `create_${name}`
294
+ code = `
276
295
  /**
277
296
  * Specialized version of \`${escapeComments(actualType)}\`.
278
297
  */
@@ -281,14 +300,26 @@ inline ${actualType} create_${name}(size_t size) noexcept {
281
300
  ${actualType} vector;
282
301
  vector.reserve(size);
283
302
  return vector;
284
- }
285
- `.trim(),
303
+ }`.trim()
304
+ }
305
+
306
+ return {
307
+ cxxType: actualType,
308
+ funcName: funcName,
309
+ specializationName: name,
310
+ cxxHeader: {
311
+ code: code,
286
312
  requiredIncludes: [
287
313
  {
288
314
  name: 'vector',
289
315
  space: 'system',
290
316
  language: 'c++',
291
317
  },
318
+ {
319
+ name: 'NitroModules/FastVectorCopy.hpp',
320
+ space: 'system',
321
+ language: 'c++',
322
+ },
292
323
  ...bridgedType.getRequiredImports('c++'),
293
324
  ],
294
325
  },
@@ -426,7 +457,7 @@ public:
426
457
  private:
427
458
  std::unique_ptr<${actualType}> _function;
428
459
  } SWIFT_NONCOPYABLE;
429
- ${name} create_${name}(void* _Nonnull swiftClosureWrapper) noexcept;
460
+ ${name} create_${name}(void* NON_NULL swiftClosureWrapper) noexcept;
430
461
  inline ${wrapperName} wrap_${name}(${name} value) noexcept {
431
462
  return ${wrapperName}(std::move(value));
432
463
  }
@@ -447,7 +478,7 @@ inline ${wrapperName} wrap_${name}(${name} value) noexcept {
447
478
  },
448
479
  cxxImplementation: {
449
480
  code: `
450
- ${name} create_${name}(void* _Nonnull swiftClosureWrapper) noexcept {
481
+ ${name} create_${name}(void* NON_NULL swiftClosureWrapper) noexcept {
451
482
  auto swiftClosure = ${swiftClassName}::fromUnsafe(swiftClosureWrapper);
452
483
  return [swiftClosure = std::move(swiftClosure)](${paramsSignature.join(', ')}) mutable -> ${type.returnType.getCode('c++')} {
453
484
  ${indent(body, ' ')}
@@ -51,7 +51,7 @@ import ${javaNamespace}.*
51
51
  /**
52
52
  * Represents the React Native \`ViewManager\` for the "${spec.name}" Nitro HybridView.
53
53
  */
54
- class ${manager}: SimpleViewManager<View>() {
54
+ open class ${manager}: SimpleViewManager<View>() {
55
55
  private val views = hashMapOf<View, ${viewImplementation}>()
56
56
 
57
57
  override fun getName(): String {
@@ -115,6 +115,10 @@ ${createFileMetadataString(`J${stateUpdaterName}.hpp`)}
115
115
 
116
116
  #pragma once
117
117
 
118
+ #ifndef RN_SERIALIZABLE_STATE
119
+ #error ${spec.config.getAndroidCxxLibName()} was compiled without the 'RN_SERIALIZABLE_STATE' flag. This flag is required for Nitro Views - set it in your CMakeLists!
120
+ #endif
121
+
118
122
  #include <fbjni/fbjni.h>
119
123
  #include <react/fabric/StateWrapperImpl.h>
120
124
  #include <react/fabric/CoreComponentsRegistry.h>