react-native-nitro-modules 0.21.0 → 0.22.1

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 (76) hide show
  1. package/NitroModules.podspec +4 -1
  2. package/README.md +1 -1
  3. package/android/CMakeLists.txt +1 -0
  4. package/android/build.gradle +4 -2
  5. package/android/gradle.properties +2 -2
  6. package/android/src/main/cpp/platform/ThreadUtils.cpp +4 -4
  7. package/android/src/main/cpp/registry/JHybridObjectRegistry.hpp +2 -0
  8. package/android/src/main/java/com/margelo/nitro/core/HybridObject.kt +10 -9
  9. package/android/src/main/java/com/margelo/nitro/core/HybridObjectInitializer.java +4 -0
  10. package/android/src/main/java/com/margelo/nitro/core/HybridObjectRegistry.java +2 -0
  11. package/android/src/main/java/com/margelo/nitro/views/HybridView.kt +23 -0
  12. package/cpp/core/ArrayBuffer.cpp +2 -2
  13. package/cpp/core/ArrayBuffer.hpp +3 -3
  14. package/cpp/core/HybridFunction.hpp +1 -1
  15. package/cpp/core/HybridObject.cpp +7 -6
  16. package/cpp/core/HybridObject.hpp +3 -3
  17. package/cpp/core/Promise.hpp +1 -1
  18. package/cpp/entrypoint/HybridNitroModulesProxy.cpp +8 -0
  19. package/cpp/entrypoint/HybridNitroModulesProxy.hpp +1 -0
  20. package/cpp/jsi/JSICache.cpp +5 -4
  21. package/cpp/jsi/JSICache.hpp +21 -15
  22. package/cpp/jsi/JSIConverter+Exception.hpp +1 -1
  23. package/cpp/jsi/JSIConverter+Function.hpp +3 -2
  24. package/cpp/jsi/JSIConverter+HostObject.hpp +1 -1
  25. package/cpp/jsi/JSIConverter+HybridObject.hpp +1 -1
  26. package/cpp/jsi/JSIConverter+Tuple.hpp +1 -1
  27. package/cpp/jsi/JSIConverter+Variant.hpp +1 -1
  28. package/cpp/jsi/JSIHelpers.hpp +1 -1
  29. package/cpp/prototype/HybridObjectPrototype.cpp +3 -3
  30. package/cpp/prototype/HybridObjectPrototype.hpp +2 -2
  31. package/cpp/registry/HybridObjectRegistry.cpp +25 -12
  32. package/cpp/registry/HybridObjectRegistry.hpp +1 -0
  33. package/cpp/utils/AssertPromiseState.hpp +1 -1
  34. package/cpp/utils/BorrowingReference.hpp +163 -54
  35. package/cpp/utils/NitroDefines.hpp +10 -1
  36. package/cpp/utils/NitroHash.hpp +17 -0
  37. package/cpp/utils/{TypeInfo.hpp → NitroTypeInfo.hpp} +1 -1
  38. package/cpp/utils/OwningLock.hpp +14 -14
  39. package/cpp/utils/ReferenceState.hpp +40 -0
  40. package/cpp/utils/WeakReference+Owning.hpp +33 -0
  41. package/cpp/utils/WeakReference.hpp +102 -0
  42. package/cpp/views/CachedProp.hpp +43 -0
  43. package/ios/core/AnyMapHolder.swift +8 -8
  44. package/ios/core/HybridContext.hpp +1 -1
  45. package/ios/core/{HybridObjectSpec.swift → HybridObject.swift} +10 -2
  46. package/ios/turbomodule/NativeNitroModules+NewArch.mm +1 -1
  47. package/ios/utils/RuntimeError.hpp +1 -1
  48. package/ios/views/HybridView.swift +41 -0
  49. package/lib/commonjs/index.js +11 -0
  50. package/lib/commonjs/index.js.map +1 -1
  51. package/lib/commonjs/views/HybridView.js +17 -0
  52. package/lib/commonjs/views/HybridView.js.map +1 -0
  53. package/lib/commonjs/views/getHostComponent.js +22 -0
  54. package/lib/commonjs/views/getHostComponent.js.map +1 -0
  55. package/lib/module/index.js +1 -0
  56. package/lib/module/index.js.map +1 -1
  57. package/lib/module/views/HybridView.js +30 -0
  58. package/lib/module/views/HybridView.js.map +1 -0
  59. package/lib/module/views/getHostComponent.js +15 -0
  60. package/lib/module/views/getHostComponent.js.map +1 -0
  61. package/lib/tsconfig.build.tsbuildinfo +1 -1
  62. package/lib/typescript/NitroModulesProxy.d.ts +7 -0
  63. package/lib/typescript/NitroModulesProxy.d.ts.map +1 -1
  64. package/lib/typescript/index.d.ts +1 -0
  65. package/lib/typescript/index.d.ts.map +1 -1
  66. package/lib/typescript/views/HybridView.d.ts +35 -0
  67. package/lib/typescript/views/HybridView.d.ts.map +1 -0
  68. package/lib/typescript/views/getHostComponent.d.ts +13 -0
  69. package/lib/typescript/views/getHostComponent.d.ts.map +1 -0
  70. package/package.json +3 -2
  71. package/src/NitroModulesProxy.ts +8 -0
  72. package/src/index.ts +1 -0
  73. package/src/views/HybridView.ts +37 -0
  74. package/src/views/getHostComponent.ts +26 -0
  75. package/cpp/utils/BorrowingReference+Owning.hpp +0 -36
  76. package/cpp/utils/OwningReference.hpp +0 -237
@@ -0,0 +1,35 @@
1
+ import type { HybridObject } from '../HybridObject';
2
+ /**
3
+ * Describes the languages this view will be implemented in.
4
+ */
5
+ export interface ViewPlatformSpec {
6
+ ios?: 'swift';
7
+ android?: 'kotlin';
8
+ }
9
+ /**
10
+ * Represents a Nitro `HybridView` which is implemented in a native language
11
+ * like Swift or Kotlin.
12
+ *
13
+ * `HybridViews`s use the Nitro Tunnel for efficient, low-overhead JS <-> Native communication.
14
+ *
15
+ * All `HybridViews`s have a C++ Fabric View base with a backing Shadow Node.
16
+ *
17
+ * - TypeScript Properties (`name: Type`) will be React Props
18
+ * - TypeScript Methods (`name(): Type`) will be Ref Methods
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * export interface Camera extends HybridView {
23
+ * zoom: number
24
+ * flash: boolean
25
+ * takePhoto(): Image
26
+ * }
27
+ * ```
28
+ */
29
+ export interface HybridView<Platforms extends ViewPlatformSpec = {
30
+ ios: 'swift';
31
+ android: 'kotlin';
32
+ }> extends HybridObject<Platforms> {
33
+ }
34
+ export * from './getHostComponent';
35
+ //# sourceMappingURL=HybridView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HybridView.d.ts","sourceRoot":"","sources":["../../../src/views/HybridView.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAEnD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,OAAO,CAAC,EAAE,QAAQ,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,UAAU,CACzB,SAAS,SAAS,gBAAgB,GAAG;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,CACxE,SAAQ,YAAY,CAAC,SAAS,CAAC;CAEhC;AAED,cAAc,oBAAoB,CAAA"}
@@ -0,0 +1,13 @@
1
+ import { type HostComponent } from 'react-native';
2
+ export interface ViewConfig<Props> {
3
+ uiViewClassName: string;
4
+ supportsRawText?: boolean;
5
+ bubblingEventTypes: Record<string, unknown>;
6
+ directEventTypes: Record<string, unknown>;
7
+ validAttributes: Record<keyof Props, boolean>;
8
+ }
9
+ /**
10
+ * Finds and returns a native view (aka {@linkcode HostComponent}) via the given {@linkcode name}.
11
+ */
12
+ export declare function getHostComponent<Props>(name: string, getViewConfig: () => ViewConfig<Props>): HostComponent<Props>;
13
+ //# sourceMappingURL=getHostComponent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getHostComponent.d.ts","sourceRoot":"","sources":["../../../src/views/getHostComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AAI3D,MAAM,WAAW,UAAU,CAAC,KAAK;IAC/B,eAAe,EAAE,MAAM,CAAA;IACvB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC3C,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACzC,eAAe,EAAE,MAAM,CAAC,MAAM,KAAK,EAAE,OAAO,CAAC,CAAA;CAC9C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EACpC,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,UAAU,CAAC,KAAK,CAAC,GACrC,aAAa,CAAC,KAAK,CAAC,CAOtB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-modules",
3
- "version": "0.21.0",
3
+ "version": "0.22.1",
4
4
  "description": "Insanely fast native C++, Swift or Kotlin modules with a statically compiled binding layer to JSI.",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -20,6 +20,7 @@
20
20
  "cpp/",
21
21
  "app.plugin.js",
22
22
  "*.podspec",
23
+ "nitro_pod_utils.rb",
23
24
  "README.md"
24
25
  ],
25
26
  "keywords": [
@@ -73,7 +74,7 @@
73
74
  "@types/react": "*",
74
75
  "jest": "*",
75
76
  "react": "18.3.1",
76
- "react-native": "0.76.5",
77
+ "react-native": "0.77.0",
77
78
  "react-native-builder-bob": "^0.35.0"
78
79
  },
79
80
  "peerDependencies": {
@@ -69,4 +69,12 @@ export interface NitroModulesProxy extends HybridObject {
69
69
  * Returns whether the given {@linkcode object} has NativeState or not.
70
70
  */
71
71
  hasNativeState(object: unknown): boolean
72
+
73
+ /**
74
+ * Re-calculates `memorySize` of the given {@linkcode HybridObject} and notifies
75
+ * the JS VM about the newly updated memory footprint.
76
+ *
77
+ * This is achieved by just doing a round-trip from JS -> native -> JS.
78
+ */
79
+ updateMemorySize(obj: HybridObject): HybridObject
72
80
  }
package/src/index.ts CHANGED
@@ -2,3 +2,4 @@ export * from './HybridObject'
2
2
  export * from './NitroModules'
3
3
  export * from './AnyMap'
4
4
  export * from './Constructor'
5
+ export * from './views/HybridView'
@@ -0,0 +1,37 @@
1
+ import type { HybridObject } from '../HybridObject'
2
+
3
+ /**
4
+ * Describes the languages this view will be implemented in.
5
+ */
6
+ export interface ViewPlatformSpec {
7
+ ios?: 'swift'
8
+ android?: 'kotlin'
9
+ }
10
+
11
+ /**
12
+ * Represents a Nitro `HybridView` which is implemented in a native language
13
+ * like Swift or Kotlin.
14
+ *
15
+ * `HybridViews`s use the Nitro Tunnel for efficient, low-overhead JS <-> Native communication.
16
+ *
17
+ * All `HybridViews`s have a C++ Fabric View base with a backing Shadow Node.
18
+ *
19
+ * - TypeScript Properties (`name: Type`) will be React Props
20
+ * - TypeScript Methods (`name(): Type`) will be Ref Methods
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * export interface Camera extends HybridView {
25
+ * zoom: number
26
+ * flash: boolean
27
+ * takePhoto(): Image
28
+ * }
29
+ * ```
30
+ */
31
+ export interface HybridView<
32
+ Platforms extends ViewPlatformSpec = { ios: 'swift'; android: 'kotlin' },
33
+ > extends HybridObject<Platforms> {
34
+ /* empty interface for now */
35
+ }
36
+
37
+ export * from './getHostComponent'
@@ -0,0 +1,26 @@
1
+ import { Platform, type HostComponent } from 'react-native'
2
+ // @ts-expect-error this unfortunately isn't typed or default-exported.
3
+ import * as NativeComponentRegistry from 'react-native/Libraries/NativeComponent/NativeComponentRegistry'
4
+
5
+ export interface ViewConfig<Props> {
6
+ uiViewClassName: string
7
+ supportsRawText?: boolean
8
+ bubblingEventTypes: Record<string, unknown>
9
+ directEventTypes: Record<string, unknown>
10
+ validAttributes: Record<keyof Props, boolean>
11
+ }
12
+
13
+ /**
14
+ * Finds and returns a native view (aka {@linkcode HostComponent}) via the given {@linkcode name}.
15
+ */
16
+ export function getHostComponent<Props>(
17
+ name: string,
18
+ getViewConfig: () => ViewConfig<Props>
19
+ ): HostComponent<Props> {
20
+ if (NativeComponentRegistry == null) {
21
+ throw new Error(
22
+ `NativeComponentRegistry is not available on ${Platform.OS}!`
23
+ )
24
+ }
25
+ return NativeComponentRegistry.get<Props>(name, getViewConfig)
26
+ }
@@ -1,36 +0,0 @@
1
- //
2
- // BorrowingReference+Owning.hpp
3
- // react-native-nitro
4
- //
5
- // Created by Marc Rousavy on 23.06.24.
6
- //
7
-
8
- #pragma once
9
-
10
- #include "OwningReference.hpp"
11
-
12
- namespace margelo::nitro {
13
-
14
- template <typename T>
15
- BorrowingReference<T>::BorrowingReference(const OwningReference<T>& ref) {
16
- _value = ref._value;
17
- _isDeleted = ref._isDeleted;
18
- _strongRefCount = ref._strongRefCount;
19
- _weakRefCount = ref._weakRefCount;
20
- _mutex = ref._mutex;
21
- (*_weakRefCount)++;
22
- }
23
-
24
- template <typename T>
25
- OwningReference<T> BorrowingReference<T>::lock() const {
26
- std::unique_lock lock(*_mutex);
27
-
28
- if (*_isDeleted) {
29
- // return nullptr
30
- return OwningReference<T>();
31
- }
32
-
33
- return OwningReference(*this);
34
- }
35
-
36
- } // namespace margelo::nitro
@@ -1,237 +0,0 @@
1
- //
2
- // OwningReference.hpp
3
- // react-native-nitro
4
- //
5
- // Created by Marc Rousavy on 23.06.24.
6
- //
7
-
8
- #pragma once
9
-
10
- #include "BorrowingReference.hpp"
11
- #include "OwningLock.hpp"
12
- #include <atomic>
13
- #include <cstddef>
14
- #include <mutex>
15
-
16
- namespace margelo::nitro {
17
-
18
- /**
19
- An `OwningReference<T>` is a smart-pointer that holds a strong reference to a pointer.
20
- You can have multiple `OwningReference<T>` instances point to the same pointer, as they internally keep a ref-count.
21
- As opposed to a `shared_ptr<T>`, an `OwningReference<T>` can also be imperatively manually deleted, even if there
22
- are multiple strong references still holding onto the pointer.
23
-
24
- An `OwningReference<T>` can be weakified, which gives the user a `BorrowingReference<T>`.
25
- A `BorrowingReference<T>` can be locked to get an `OwningReference<T>` again, assuming it has not been deleted yet.
26
- */
27
- template <typename T>
28
- class OwningReference final {
29
- public:
30
- using Pointee = T;
31
-
32
- public:
33
- OwningReference() : _value(nullptr), _isDeleted(nullptr), _strongRefCount(nullptr), _weakRefCount(nullptr), _mutex(nullptr) {}
34
-
35
- explicit OwningReference(T* value)
36
- : _value(value), _isDeleted(new bool(false)), _strongRefCount(new std::atomic_size_t(1)), _weakRefCount(new std::atomic_size_t(0)),
37
- _mutex(new std::recursive_mutex()) {}
38
-
39
- OwningReference(const OwningReference& ref)
40
- : _value(ref._value), _isDeleted(ref._isDeleted), _strongRefCount(ref._strongRefCount), _weakRefCount(ref._weakRefCount),
41
- _mutex(ref._mutex) {
42
- // increment ref count after copy
43
- (*_strongRefCount)++;
44
- }
45
-
46
- OwningReference(OwningReference&& ref)
47
- : _value(ref._value), _isDeleted(ref._isDeleted), _strongRefCount(ref._strongRefCount), _weakRefCount(ref._weakRefCount),
48
- _mutex(ref._mutex) {
49
- ref._value = nullptr;
50
- ref._isDeleted = nullptr;
51
- ref._strongRefCount = nullptr;
52
- ref._weakRefCount = nullptr;
53
- }
54
-
55
- OwningReference& operator=(const OwningReference& ref) {
56
- if (this == &ref)
57
- return *this;
58
-
59
- if (_strongRefCount != nullptr) {
60
- // destroy previous pointer
61
- (*_strongRefCount)--;
62
- maybeDestroy();
63
- }
64
-
65
- _value = ref._value;
66
- _isDeleted = ref._isDeleted;
67
- _strongRefCount = ref._strongRefCount;
68
- _weakRefCount = ref._weakRefCount;
69
- _mutex = ref._mutex;
70
- if (_strongRefCount != nullptr) {
71
- // increment new pointer
72
- (*_strongRefCount)++;
73
- }
74
-
75
- return *this;
76
- }
77
-
78
- private:
79
- // BorrowingReference<T> -> OwningReference<T> Lock-constructor
80
- OwningReference(const BorrowingReference<T>& ref)
81
- : _value(ref._value), _isDeleted(ref._isDeleted), _strongRefCount(ref._strongRefCount), _weakRefCount(ref._weakRefCount),
82
- _mutex(ref._mutex) {
83
- (*_strongRefCount)++;
84
- }
85
-
86
- private:
87
- // OwningReference<C> -> OwningReference<T> Cast-constructor
88
- template <typename OldT>
89
- OwningReference(T* value, const OwningReference<OldT>& originalRef)
90
- : _value(value), _isDeleted(originalRef._isDeleted), _strongRefCount(originalRef._strongRefCount),
91
- _weakRefCount(originalRef._weakRefCount), _mutex(originalRef._mutex) {
92
- (*_strongRefCount)++;
93
- }
94
-
95
- template <typename C>
96
- friend class OwningReference;
97
-
98
- public:
99
- ~OwningReference() {
100
- if (_strongRefCount == nullptr) {
101
- // we are just a dangling nullptr.
102
- return;
103
- }
104
-
105
- // decrement strong ref count on destroy
106
- --(*_strongRefCount);
107
- maybeDestroy();
108
- }
109
-
110
- public:
111
- /**
112
- Casts this `OwningReference<T>` to a `OwningReference<C>`.
113
- */
114
- template <typename C>
115
- OwningReference<C> as() {
116
- return OwningReference<C>(static_cast<C*>(_value), *this);
117
- }
118
-
119
- public:
120
- /**
121
- Creates an `OwningLock<T>` for the given `OwningReference<T>` to guarantee safe
122
- safe access to `OwningReference<T>`.
123
- Other threads (e.g. the Hermes garbage collector) cannot delete the `OwningReference<T>`
124
- as long as the `OwningLock<T>` is still alive.
125
- */
126
- [[nodiscard]]
127
- OwningLock<T> lock() const {
128
- return OwningLock<T>(*this);
129
- }
130
-
131
- /**
132
- Get whether the `OwningReference<T>` is still pointing to a valid value, or not.
133
- */
134
- inline bool hasValue() const {
135
- return _value != nullptr && !(*_isDeleted);
136
- }
137
-
138
- /**
139
- Get a borrowing (or "weak") reference to this owning reference
140
- */
141
- [[nodiscard]]
142
- BorrowingReference<T> weak() const {
143
- return BorrowingReference(*this);
144
- }
145
-
146
- /**
147
- Delete and destroy the value this OwningReference is pointing to.
148
- This can even be called if there are still multiple strong references to the value.
149
-
150
- This will block as long as one or more `OwningLock<T>`s of this `OwningReference<T>` are still alive.
151
- */
152
- void destroy() {
153
- std::unique_lock lock(*_mutex);
154
-
155
- forceDestroy();
156
- }
157
-
158
- public:
159
- explicit inline operator bool() const {
160
- return hasValue();
161
- }
162
-
163
- inline T& operator*() const {
164
- return *_value;
165
- }
166
-
167
- inline T* operator->() const {
168
- return _value;
169
- }
170
-
171
- inline bool operator==(T* other) const {
172
- std::unique_lock lock(*_mutex);
173
-
174
- if (*_isDeleted) {
175
- return other == nullptr;
176
- } else {
177
- return other == _value;
178
- }
179
- }
180
-
181
- inline bool operator!=(T* other) const {
182
- return !(this == other);
183
- }
184
-
185
- inline bool operator==(const OwningReference<T>& other) const {
186
- return _value == other._value;
187
- }
188
-
189
- inline bool operator!=(const OwningReference<T>& other) const {
190
- return !(this == other);
191
- }
192
-
193
- private:
194
- void maybeDestroy() {
195
- _mutex->lock();
196
-
197
- if (*_strongRefCount == 0) {
198
- // after no strong references exist anymore
199
- forceDestroy();
200
- }
201
-
202
- if (*_strongRefCount == 0 && *_weakRefCount == 0) {
203
- // free the full memory if there are no more references at all
204
- delete _isDeleted;
205
- delete _strongRefCount;
206
- delete _weakRefCount;
207
- _mutex->unlock();
208
- return;
209
- }
210
-
211
- _mutex->unlock();
212
- }
213
-
214
- void forceDestroy() {
215
- if (*_isDeleted) {
216
- // it has already been destroyed.
217
- return;
218
- }
219
- delete _value;
220
- *_isDeleted = true;
221
- }
222
-
223
- public:
224
- friend class BorrowingReference<T>;
225
- friend class OwningLock<T>;
226
-
227
- private:
228
- T* _value;
229
- bool* _isDeleted;
230
- std::atomic_size_t* _strongRefCount;
231
- std::atomic_size_t* _weakRefCount;
232
- std::recursive_mutex* _mutex;
233
- };
234
-
235
- } // namespace margelo::nitro
236
-
237
- #include "BorrowingReference+Owning.hpp"