@onekeyfe/react-native-perf-stats 3.0.35 → 3.0.37

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 (35) hide show
  1. package/android/src/main/java/com/margelo/nitro/reactnativeperfstats/PerfStatsInitProvider.kt +11 -4
  2. package/android/src/main/java/com/margelo/nitro/reactnativeperfstats/ReactNativePerfStats.kt +333 -24
  3. package/ios/ReactNativePerfStats.swift +360 -15
  4. package/lib/module/index.js +77 -5
  5. package/lib/module/index.js.map +1 -1
  6. package/lib/typescript/src/ReactNativePerfStats.nitro.d.ts +109 -1
  7. package/lib/typescript/src/ReactNativePerfStats.nitro.d.ts.map +1 -1
  8. package/lib/typescript/src/index.d.ts +31 -0
  9. package/lib/typescript/src/index.d.ts.map +1 -1
  10. package/nitrogen/generated/android/c++/JFunc_void_MemoryWarningEvent.hpp +79 -0
  11. package/nitrogen/generated/android/c++/JHybridReactNativePerfStatsSpec.cpp +24 -0
  12. package/nitrogen/generated/android/c++/JHybridReactNativePerfStatsSpec.hpp +3 -0
  13. package/nitrogen/generated/android/c++/JMemoryWarningEvent.hpp +66 -0
  14. package/nitrogen/generated/android/c++/JMemoryWarningLevel.hpp +59 -0
  15. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativeperfstats/Func_void_MemoryWarningEvent.kt +80 -0
  16. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativeperfstats/HybridReactNativePerfStatsSpec.kt +17 -0
  17. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativeperfstats/MemoryWarningEvent.kt +44 -0
  18. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativeperfstats/MemoryWarningLevel.kt +21 -0
  19. package/nitrogen/generated/android/reactnativeperfstatsOnLoad.cpp +2 -0
  20. package/nitrogen/generated/ios/ReactNativePerfStats-Swift-Cxx-Bridge.cpp +8 -0
  21. package/nitrogen/generated/ios/ReactNativePerfStats-Swift-Cxx-Bridge.hpp +37 -0
  22. package/nitrogen/generated/ios/ReactNativePerfStats-Swift-Cxx-Umbrella.hpp +7 -0
  23. package/nitrogen/generated/ios/c++/HybridReactNativePerfStatsSpecSwift.hpp +27 -0
  24. package/nitrogen/generated/ios/swift/Func_void_MemoryWarningEvent.swift +47 -0
  25. package/nitrogen/generated/ios/swift/HybridReactNativePerfStatsSpec.swift +3 -0
  26. package/nitrogen/generated/ios/swift/HybridReactNativePerfStatsSpec_cxx.swift +39 -0
  27. package/nitrogen/generated/ios/swift/MemoryWarningEvent.swift +58 -0
  28. package/nitrogen/generated/ios/swift/MemoryWarningLevel.swift +40 -0
  29. package/nitrogen/generated/shared/c++/HybridReactNativePerfStatsSpec.cpp +3 -0
  30. package/nitrogen/generated/shared/c++/HybridReactNativePerfStatsSpec.hpp +7 -0
  31. package/nitrogen/generated/shared/c++/MemoryWarningEvent.hpp +84 -0
  32. package/nitrogen/generated/shared/c++/MemoryWarningLevel.hpp +76 -0
  33. package/package.json +1 -1
  34. package/src/ReactNativePerfStats.nitro.ts +114 -1
  35. package/src/index.tsx +90 -5
@@ -10,6 +10,10 @@
10
10
  // Forward declarations of C++ defined types
11
11
  // Forward declaration of `HybridReactNativePerfStatsSpec` to properly resolve imports.
12
12
  namespace margelo::nitro::reactnativeperfstats { class HybridReactNativePerfStatsSpec; }
13
+ // Forward declaration of `MemoryWarningEvent` to properly resolve imports.
14
+ namespace margelo::nitro::reactnativeperfstats { struct MemoryWarningEvent; }
15
+ // Forward declaration of `MemoryWarningLevel` to properly resolve imports.
16
+ namespace margelo::nitro::reactnativeperfstats { enum class MemoryWarningLevel; }
13
17
  // Forward declaration of `PerfSample` to properly resolve imports.
14
18
  namespace margelo::nitro::reactnativeperfstats { struct PerfSample; }
15
19
 
@@ -19,6 +23,8 @@ namespace ReactNativePerfStats { class HybridReactNativePerfStatsSpec_cxx; }
19
23
 
20
24
  // Include C++ defined types
21
25
  #include "HybridReactNativePerfStatsSpec.hpp"
26
+ #include "MemoryWarningEvent.hpp"
27
+ #include "MemoryWarningLevel.hpp"
22
28
  #include "PerfSample.hpp"
23
29
  #include <NitroModules/Promise.hpp>
24
30
  #include <NitroModules/PromiseHolder.hpp>
@@ -89,6 +95,28 @@ namespace margelo::nitro::reactnativeperfstats::bridge::swift {
89
95
  return Func_void_std__exception_ptr_Wrapper(std::move(value));
90
96
  }
91
97
 
98
+ // pragma MARK: std::function<void(const MemoryWarningEvent& /* event */)>
99
+ /**
100
+ * Specialized version of `std::function<void(const MemoryWarningEvent&)>`.
101
+ */
102
+ using Func_void_MemoryWarningEvent = std::function<void(const MemoryWarningEvent& /* event */)>;
103
+ /**
104
+ * Wrapper class for a `std::function<void(const MemoryWarningEvent& / * event * /)>`, this can be used from Swift.
105
+ */
106
+ class Func_void_MemoryWarningEvent_Wrapper final {
107
+ public:
108
+ explicit Func_void_MemoryWarningEvent_Wrapper(std::function<void(const MemoryWarningEvent& /* event */)>&& func): _function(std::make_unique<std::function<void(const MemoryWarningEvent& /* event */)>>(std::move(func))) {}
109
+ inline void call(MemoryWarningEvent event) const noexcept {
110
+ _function->operator()(event);
111
+ }
112
+ private:
113
+ std::unique_ptr<std::function<void(const MemoryWarningEvent& /* event */)>> _function;
114
+ } SWIFT_NONCOPYABLE;
115
+ Func_void_MemoryWarningEvent create_Func_void_MemoryWarningEvent(void* NON_NULL swiftClosureWrapper) noexcept;
116
+ inline Func_void_MemoryWarningEvent_Wrapper wrap_Func_void_MemoryWarningEvent(Func_void_MemoryWarningEvent value) noexcept {
117
+ return Func_void_MemoryWarningEvent_Wrapper(std::move(value));
118
+ }
119
+
92
120
  // pragma MARK: std::shared_ptr<HybridReactNativePerfStatsSpec>
93
121
  /**
94
122
  * Specialized version of `std::shared_ptr<HybridReactNativePerfStatsSpec>`.
@@ -118,5 +146,14 @@ namespace margelo::nitro::reactnativeperfstats::bridge::swift {
118
146
  inline Result_std__shared_ptr_Promise_PerfSample___ create_Result_std__shared_ptr_Promise_PerfSample___(const std::exception_ptr& error) noexcept {
119
147
  return Result<std::shared_ptr<Promise<PerfSample>>>::withError(error);
120
148
  }
149
+
150
+ // pragma MARK: Result<double>
151
+ using Result_double_ = Result<double>;
152
+ inline Result_double_ create_Result_double_(double value) noexcept {
153
+ return Result<double>::withValue(std::move(value));
154
+ }
155
+ inline Result_double_ create_Result_double_(const std::exception_ptr& error) noexcept {
156
+ return Result<double>::withError(error);
157
+ }
121
158
 
122
159
  } // namespace margelo::nitro::reactnativeperfstats::bridge::swift
@@ -10,15 +10,22 @@
10
10
  // Forward declarations of C++ defined types
11
11
  // Forward declaration of `HybridReactNativePerfStatsSpec` to properly resolve imports.
12
12
  namespace margelo::nitro::reactnativeperfstats { class HybridReactNativePerfStatsSpec; }
13
+ // Forward declaration of `MemoryWarningEvent` to properly resolve imports.
14
+ namespace margelo::nitro::reactnativeperfstats { struct MemoryWarningEvent; }
15
+ // Forward declaration of `MemoryWarningLevel` to properly resolve imports.
16
+ namespace margelo::nitro::reactnativeperfstats { enum class MemoryWarningLevel; }
13
17
  // Forward declaration of `PerfSample` to properly resolve imports.
14
18
  namespace margelo::nitro::reactnativeperfstats { struct PerfSample; }
15
19
 
16
20
  // Include C++ defined types
17
21
  #include "HybridReactNativePerfStatsSpec.hpp"
22
+ #include "MemoryWarningEvent.hpp"
23
+ #include "MemoryWarningLevel.hpp"
18
24
  #include "PerfSample.hpp"
19
25
  #include <NitroModules/Promise.hpp>
20
26
  #include <NitroModules/Result.hpp>
21
27
  #include <exception>
28
+ #include <functional>
22
29
  #include <memory>
23
30
 
24
31
  // C++ helpers for Swift
@@ -14,9 +14,16 @@ namespace ReactNativePerfStats { class HybridReactNativePerfStatsSpec_cxx; }
14
14
 
15
15
  // Forward declaration of `PerfSample` to properly resolve imports.
16
16
  namespace margelo::nitro::reactnativeperfstats { struct PerfSample; }
17
+ // Forward declaration of `MemoryWarningEvent` to properly resolve imports.
18
+ namespace margelo::nitro::reactnativeperfstats { struct MemoryWarningEvent; }
19
+ // Forward declaration of `MemoryWarningLevel` to properly resolve imports.
20
+ namespace margelo::nitro::reactnativeperfstats { enum class MemoryWarningLevel; }
17
21
 
18
22
  #include "PerfSample.hpp"
19
23
  #include <NitroModules/Promise.hpp>
24
+ #include "MemoryWarningEvent.hpp"
25
+ #include <functional>
26
+ #include "MemoryWarningLevel.hpp"
20
27
 
21
28
  #include "ReactNativePerfStats-Swift-Cxx-Umbrella.hpp"
22
29
 
@@ -100,6 +107,26 @@ namespace margelo::nitro::reactnativeperfstats {
100
107
  std::rethrow_exception(__result.error());
101
108
  }
102
109
  }
110
+ inline double addMemoryWarningListener(const std::function<void(const MemoryWarningEvent& /* event */)>& callback) override {
111
+ auto __result = _swiftPart.addMemoryWarningListener(callback);
112
+ if (__result.hasError()) [[unlikely]] {
113
+ std::rethrow_exception(__result.error());
114
+ }
115
+ auto __value = std::move(__result.value());
116
+ return __value;
117
+ }
118
+ inline void removeMemoryWarningListener(double id) override {
119
+ auto __result = _swiftPart.removeMemoryWarningListener(std::forward<decltype(id)>(id));
120
+ if (__result.hasError()) [[unlikely]] {
121
+ std::rethrow_exception(__result.error());
122
+ }
123
+ }
124
+ inline void cleanupNativeCaches() override {
125
+ auto __result = _swiftPart.cleanupNativeCaches();
126
+ if (__result.hasError()) [[unlikely]] {
127
+ std::rethrow_exception(__result.error());
128
+ }
129
+ }
103
130
 
104
131
  private:
105
132
  ReactNativePerfStats::HybridReactNativePerfStatsSpec_cxx _swiftPart;
@@ -0,0 +1,47 @@
1
+ ///
2
+ /// Func_void_MemoryWarningEvent.swift
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ import Foundation
9
+ import NitroModules
10
+
11
+ /**
12
+ * Wraps a Swift `(_ event: MemoryWarningEvent) -> Void` as a class.
13
+ * This class can be used from C++, e.g. to wrap the Swift closure as a `std::function`.
14
+ */
15
+ public final class Func_void_MemoryWarningEvent {
16
+ public typealias bridge = margelo.nitro.reactnativeperfstats.bridge.swift
17
+
18
+ private let closure: (_ event: MemoryWarningEvent) -> Void
19
+
20
+ public init(_ closure: @escaping (_ event: MemoryWarningEvent) -> Void) {
21
+ self.closure = closure
22
+ }
23
+
24
+ @inline(__always)
25
+ public func call(event: MemoryWarningEvent) -> Void {
26
+ self.closure(event)
27
+ }
28
+
29
+ /**
30
+ * Casts this instance to a retained unsafe raw pointer.
31
+ * This acquires one additional strong reference on the object!
32
+ */
33
+ @inline(__always)
34
+ public func toUnsafe() -> UnsafeMutableRawPointer {
35
+ return Unmanaged.passRetained(self).toOpaque()
36
+ }
37
+
38
+ /**
39
+ * Casts an unsafe pointer to a `Func_void_MemoryWarningEvent`.
40
+ * The pointer has to be a retained opaque `Unmanaged<Func_void_MemoryWarningEvent>`.
41
+ * This removes one strong reference from the object!
42
+ */
43
+ @inline(__always)
44
+ public static func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> Func_void_MemoryWarningEvent {
45
+ return Unmanaged<Func_void_MemoryWarningEvent>.fromOpaque(pointer).takeRetainedValue()
46
+ }
47
+ }
@@ -20,6 +20,9 @@ public protocol HybridReactNativePerfStatsSpec_protocol: HybridObject {
20
20
  func hideOverlay() throws -> Void
21
21
  func sample() throws -> Promise<PerfSample>
22
22
  func setJsFpsHint(fps: Double) throws -> Void
23
+ func addMemoryWarningListener(callback: @escaping (_ event: MemoryWarningEvent) -> Void) throws -> Double
24
+ func removeMemoryWarningListener(id: Double) throws -> Void
25
+ func cleanupNativeCaches() throws -> Void
23
26
  }
24
27
 
25
28
  public extension HybridReactNativePerfStatsSpec_protocol {
@@ -190,4 +190,43 @@ open class HybridReactNativePerfStatsSpec_cxx {
190
190
  return bridge.create_Result_void_(__exceptionPtr)
191
191
  }
192
192
  }
193
+
194
+ @inline(__always)
195
+ public final func addMemoryWarningListener(callback: bridge.Func_void_MemoryWarningEvent) -> bridge.Result_double_ {
196
+ do {
197
+ let __result = try self.__implementation.addMemoryWarningListener(callback: { () -> (MemoryWarningEvent) -> Void in
198
+ let __wrappedFunction = bridge.wrap_Func_void_MemoryWarningEvent(callback)
199
+ return { (__event: MemoryWarningEvent) -> Void in
200
+ __wrappedFunction.call(__event)
201
+ }
202
+ }())
203
+ let __resultCpp = __result
204
+ return bridge.create_Result_double_(__resultCpp)
205
+ } catch (let __error) {
206
+ let __exceptionPtr = __error.toCpp()
207
+ return bridge.create_Result_double_(__exceptionPtr)
208
+ }
209
+ }
210
+
211
+ @inline(__always)
212
+ public final func removeMemoryWarningListener(id: Double) -> bridge.Result_void_ {
213
+ do {
214
+ try self.__implementation.removeMemoryWarningListener(id: id)
215
+ return bridge.create_Result_void_()
216
+ } catch (let __error) {
217
+ let __exceptionPtr = __error.toCpp()
218
+ return bridge.create_Result_void_(__exceptionPtr)
219
+ }
220
+ }
221
+
222
+ @inline(__always)
223
+ public final func cleanupNativeCaches() -> bridge.Result_void_ {
224
+ do {
225
+ try self.__implementation.cleanupNativeCaches()
226
+ return bridge.create_Result_void_()
227
+ } catch (let __error) {
228
+ let __exceptionPtr = __error.toCpp()
229
+ return bridge.create_Result_void_(__exceptionPtr)
230
+ }
231
+ }
193
232
  }
@@ -0,0 +1,58 @@
1
+ ///
2
+ /// MemoryWarningEvent.swift
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ import Foundation
9
+ import NitroModules
10
+
11
+ /**
12
+ * Represents an instance of `MemoryWarningEvent`, backed by a C++ struct.
13
+ */
14
+ public typealias MemoryWarningEvent = margelo.nitro.reactnativeperfstats.MemoryWarningEvent
15
+
16
+ public extension MemoryWarningEvent {
17
+ private typealias bridge = margelo.nitro.reactnativeperfstats.bridge.swift
18
+
19
+ /**
20
+ * Create a new instance of `MemoryWarningEvent`.
21
+ */
22
+ init(level: MemoryWarningLevel, rss: Double, timestamp: Double) {
23
+ self.init(level, rss, timestamp)
24
+ }
25
+
26
+ var level: MemoryWarningLevel {
27
+ @inline(__always)
28
+ get {
29
+ return self.__level
30
+ }
31
+ @inline(__always)
32
+ set {
33
+ self.__level = newValue
34
+ }
35
+ }
36
+
37
+ var rss: Double {
38
+ @inline(__always)
39
+ get {
40
+ return self.__rss
41
+ }
42
+ @inline(__always)
43
+ set {
44
+ self.__rss = newValue
45
+ }
46
+ }
47
+
48
+ var timestamp: Double {
49
+ @inline(__always)
50
+ get {
51
+ return self.__timestamp
52
+ }
53
+ @inline(__always)
54
+ set {
55
+ self.__timestamp = newValue
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,40 @@
1
+ ///
2
+ /// MemoryWarningLevel.swift
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ /**
9
+ * Represents the JS union `MemoryWarningLevel`, backed by a C++ enum.
10
+ */
11
+ public typealias MemoryWarningLevel = margelo.nitro.reactnativeperfstats.MemoryWarningLevel
12
+
13
+ public extension MemoryWarningLevel {
14
+ /**
15
+ * Get a MemoryWarningLevel for the given String value, or
16
+ * return `nil` if the given value was invalid/unknown.
17
+ */
18
+ init?(fromString string: String) {
19
+ switch string {
20
+ case "low":
21
+ self = .low
22
+ case "critical":
23
+ self = .critical
24
+ default:
25
+ return nil
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Get the String value this MemoryWarningLevel represents.
31
+ */
32
+ var stringValue: String {
33
+ switch self {
34
+ case .low:
35
+ return "low"
36
+ case .critical:
37
+ return "critical"
38
+ }
39
+ }
40
+ }
@@ -20,6 +20,9 @@ namespace margelo::nitro::reactnativeperfstats {
20
20
  prototype.registerHybridMethod("hideOverlay", &HybridReactNativePerfStatsSpec::hideOverlay);
21
21
  prototype.registerHybridMethod("sample", &HybridReactNativePerfStatsSpec::sample);
22
22
  prototype.registerHybridMethod("setJsFpsHint", &HybridReactNativePerfStatsSpec::setJsFpsHint);
23
+ prototype.registerHybridMethod("addMemoryWarningListener", &HybridReactNativePerfStatsSpec::addMemoryWarningListener);
24
+ prototype.registerHybridMethod("removeMemoryWarningListener", &HybridReactNativePerfStatsSpec::removeMemoryWarningListener);
25
+ prototype.registerHybridMethod("cleanupNativeCaches", &HybridReactNativePerfStatsSpec::cleanupNativeCaches);
23
26
  });
24
27
  }
25
28
 
@@ -15,9 +15,13 @@
15
15
 
16
16
  // Forward declaration of `PerfSample` to properly resolve imports.
17
17
  namespace margelo::nitro::reactnativeperfstats { struct PerfSample; }
18
+ // Forward declaration of `MemoryWarningEvent` to properly resolve imports.
19
+ namespace margelo::nitro::reactnativeperfstats { struct MemoryWarningEvent; }
18
20
 
19
21
  #include "PerfSample.hpp"
20
22
  #include <NitroModules/Promise.hpp>
23
+ #include "MemoryWarningEvent.hpp"
24
+ #include <functional>
21
25
 
22
26
  namespace margelo::nitro::reactnativeperfstats {
23
27
 
@@ -56,6 +60,9 @@ namespace margelo::nitro::reactnativeperfstats {
56
60
  virtual void hideOverlay() = 0;
57
61
  virtual std::shared_ptr<Promise<PerfSample>> sample() = 0;
58
62
  virtual void setJsFpsHint(double fps) = 0;
63
+ virtual double addMemoryWarningListener(const std::function<void(const MemoryWarningEvent& /* event */)>& callback) = 0;
64
+ virtual void removeMemoryWarningListener(double id) = 0;
65
+ virtual void cleanupNativeCaches() = 0;
59
66
 
60
67
  protected:
61
68
  // Hybrid Setup
@@ -0,0 +1,84 @@
1
+ ///
2
+ /// MemoryWarningEvent.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #if __has_include(<NitroModules/JSIConverter.hpp>)
11
+ #include <NitroModules/JSIConverter.hpp>
12
+ #else
13
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
14
+ #endif
15
+ #if __has_include(<NitroModules/NitroDefines.hpp>)
16
+ #include <NitroModules/NitroDefines.hpp>
17
+ #else
18
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
19
+ #endif
20
+ #if __has_include(<NitroModules/JSIHelpers.hpp>)
21
+ #include <NitroModules/JSIHelpers.hpp>
22
+ #else
23
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
24
+ #endif
25
+
26
+ // Forward declaration of `MemoryWarningLevel` to properly resolve imports.
27
+ namespace margelo::nitro::reactnativeperfstats { enum class MemoryWarningLevel; }
28
+
29
+ #include "MemoryWarningLevel.hpp"
30
+
31
+ namespace margelo::nitro::reactnativeperfstats {
32
+
33
+ /**
34
+ * A struct which can be represented as a JavaScript object (MemoryWarningEvent).
35
+ */
36
+ struct MemoryWarningEvent {
37
+ public:
38
+ MemoryWarningLevel level SWIFT_PRIVATE;
39
+ double rss SWIFT_PRIVATE;
40
+ double timestamp SWIFT_PRIVATE;
41
+
42
+ public:
43
+ MemoryWarningEvent() = default;
44
+ explicit MemoryWarningEvent(MemoryWarningLevel level, double rss, double timestamp): level(level), rss(rss), timestamp(timestamp) {}
45
+ };
46
+
47
+ } // namespace margelo::nitro::reactnativeperfstats
48
+
49
+ namespace margelo::nitro {
50
+
51
+ // C++ MemoryWarningEvent <> JS MemoryWarningEvent (object)
52
+ template <>
53
+ struct JSIConverter<margelo::nitro::reactnativeperfstats::MemoryWarningEvent> final {
54
+ static inline margelo::nitro::reactnativeperfstats::MemoryWarningEvent fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
55
+ jsi::Object obj = arg.asObject(runtime);
56
+ return margelo::nitro::reactnativeperfstats::MemoryWarningEvent(
57
+ JSIConverter<margelo::nitro::reactnativeperfstats::MemoryWarningLevel>::fromJSI(runtime, obj.getProperty(runtime, "level")),
58
+ JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, "rss")),
59
+ JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, "timestamp"))
60
+ );
61
+ }
62
+ static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::reactnativeperfstats::MemoryWarningEvent& arg) {
63
+ jsi::Object obj(runtime);
64
+ obj.setProperty(runtime, "level", JSIConverter<margelo::nitro::reactnativeperfstats::MemoryWarningLevel>::toJSI(runtime, arg.level));
65
+ obj.setProperty(runtime, "rss", JSIConverter<double>::toJSI(runtime, arg.rss));
66
+ obj.setProperty(runtime, "timestamp", JSIConverter<double>::toJSI(runtime, arg.timestamp));
67
+ return obj;
68
+ }
69
+ static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
70
+ if (!value.isObject()) {
71
+ return false;
72
+ }
73
+ jsi::Object obj = value.getObject(runtime);
74
+ if (!nitro::isPlainObject(runtime, obj)) {
75
+ return false;
76
+ }
77
+ if (!JSIConverter<margelo::nitro::reactnativeperfstats::MemoryWarningLevel>::canConvert(runtime, obj.getProperty(runtime, "level"))) return false;
78
+ if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, "rss"))) return false;
79
+ if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, "timestamp"))) return false;
80
+ return true;
81
+ }
82
+ };
83
+
84
+ } // namespace margelo::nitro
@@ -0,0 +1,76 @@
1
+ ///
2
+ /// MemoryWarningLevel.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #if __has_include(<NitroModules/NitroHash.hpp>)
11
+ #include <NitroModules/NitroHash.hpp>
12
+ #else
13
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
14
+ #endif
15
+ #if __has_include(<NitroModules/JSIConverter.hpp>)
16
+ #include <NitroModules/JSIConverter.hpp>
17
+ #else
18
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
19
+ #endif
20
+ #if __has_include(<NitroModules/NitroDefines.hpp>)
21
+ #include <NitroModules/NitroDefines.hpp>
22
+ #else
23
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
24
+ #endif
25
+
26
+ namespace margelo::nitro::reactnativeperfstats {
27
+
28
+ /**
29
+ * An enum which can be represented as a JavaScript union (MemoryWarningLevel).
30
+ */
31
+ enum class MemoryWarningLevel {
32
+ LOW SWIFT_NAME(low) = 0,
33
+ CRITICAL SWIFT_NAME(critical) = 1,
34
+ } CLOSED_ENUM;
35
+
36
+ } // namespace margelo::nitro::reactnativeperfstats
37
+
38
+ namespace margelo::nitro {
39
+
40
+ // C++ MemoryWarningLevel <> JS MemoryWarningLevel (union)
41
+ template <>
42
+ struct JSIConverter<margelo::nitro::reactnativeperfstats::MemoryWarningLevel> final {
43
+ static inline margelo::nitro::reactnativeperfstats::MemoryWarningLevel fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
44
+ std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);
45
+ switch (hashString(unionValue.c_str(), unionValue.size())) {
46
+ case hashString("low"): return margelo::nitro::reactnativeperfstats::MemoryWarningLevel::LOW;
47
+ case hashString("critical"): return margelo::nitro::reactnativeperfstats::MemoryWarningLevel::CRITICAL;
48
+ default: [[unlikely]]
49
+ throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum MemoryWarningLevel - invalid value!");
50
+ }
51
+ }
52
+ static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::reactnativeperfstats::MemoryWarningLevel arg) {
53
+ switch (arg) {
54
+ case margelo::nitro::reactnativeperfstats::MemoryWarningLevel::LOW: return JSIConverter<std::string>::toJSI(runtime, "low");
55
+ case margelo::nitro::reactnativeperfstats::MemoryWarningLevel::CRITICAL: return JSIConverter<std::string>::toJSI(runtime, "critical");
56
+ default: [[unlikely]]
57
+ throw std::invalid_argument("Cannot convert MemoryWarningLevel to JS - invalid value: "
58
+ + std::to_string(static_cast<int>(arg)) + "!");
59
+ }
60
+ }
61
+ static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
62
+ if (!value.isString()) {
63
+ return false;
64
+ }
65
+ std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);
66
+ switch (hashString(unionValue.c_str(), unionValue.size())) {
67
+ case hashString("low"):
68
+ case hashString("critical"):
69
+ return true;
70
+ default:
71
+ return false;
72
+ }
73
+ }
74
+ };
75
+
76
+ } // namespace margelo::nitro
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/react-native-perf-stats",
3
- "version": "3.0.35",
3
+ "version": "3.0.37",
4
4
  "description": "react-native-perf-stats",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -13,19 +13,56 @@ export interface PerfSample {
13
13
  /**
14
14
  * UI thread frame rate, frames per second over the last 1 s window.
15
15
  * Measured on the platform's main thread via Choreographer (Android)
16
- * or CADisplayLink (iOS). `0` until at least one window has elapsed.
16
+ * or CADisplayLink (iOS). `0` until at least one window has elapsed
17
+ * **and the sampler is running** — the underlying frame monitor only
18
+ * runs between `start()` and `stop()`, so one-shot `sample()` calls
19
+ * issued outside that window always report `0` here.
17
20
  */
18
21
  uiFps: number;
19
22
  /**
20
23
  * JS thread frame rate, frames per second reported by the JS-side
21
24
  * `requestAnimationFrame` ticker (see `startJsFpsTracker`). `0` if
22
25
  * the tracker has not been started or no hint has been received yet.
26
+ * Same caveat as `uiFps`: one-shot `sample()` calls issued before
27
+ * `start()` (or after `stop()`) report `0` here.
23
28
  */
24
29
  jsFps: number;
25
30
  /** Wall-clock timestamp (ms since unix epoch) when the sample was taken. */
26
31
  timestamp: number;
27
32
  }
28
33
 
34
+ /**
35
+ * Severity of a system-emitted memory pressure event, normalised across
36
+ * platforms.
37
+ *
38
+ * - `low`: Android `TRIM_MEMORY_RUNNING_MODERATE` /
39
+ * `TRIM_MEMORY_RUNNING_LOW`. iOS does not emit this level (iOS only
40
+ * fires the critical warning), so JS code should treat the absence of
41
+ * `low` events on iOS as expected, not a missing signal.
42
+ * - `critical`: iOS `UIApplicationDidReceiveMemoryWarningNotification`;
43
+ * Android `TRIM_MEMORY_RUNNING_CRITICAL` or `onLowMemory()`. Indicates
44
+ * the OS is about to start killing background apps (Android) or the
45
+ * app itself (iOS jetsam). Subscribers should drop everything that
46
+ * can be rebuilt on demand.
47
+ */
48
+ export type MemoryWarningLevel = 'low' | 'critical';
49
+
50
+ export interface MemoryWarningEvent {
51
+ level: MemoryWarningLevel;
52
+ /**
53
+ * Process RSS in bytes at the moment the warning fired. `0` if the
54
+ * lookup failed.
55
+ *
56
+ * On iOS the primary source is `phys_footprint`; if that fails, the
57
+ * fallback path reads `resident_size`, which is semantically smaller
58
+ * and noisier. The two values are not directly comparable, so treat
59
+ * unexpected magnitude differences across reports cautiously.
60
+ */
61
+ rss: number;
62
+ /** Wall-clock timestamp (ms since unix epoch). */
63
+ timestamp: number;
64
+ }
65
+
29
66
  export interface ReactNativePerfStats
30
67
  extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> {
31
68
  /**
@@ -78,4 +115,80 @@ export interface ReactNativePerfStats
78
115
  * than calling this directly.
79
116
  */
80
117
  setJsFpsHint(fps: number): void;
118
+
119
+ /**
120
+ * Subscribe to OS-emitted memory pressure events.
121
+ *
122
+ * - iOS: `UIApplicationDidReceiveMemoryWarningNotification`, mapped to
123
+ * `critical`. Fires on the main thread.
124
+ * - Android: `ComponentCallbacks2.onTrimMemory` filtered to
125
+ * `TRIM_MEMORY_RUNNING_*` (foreground process pressure), plus
126
+ * `onLowMemory()` as `critical`. Fires on the main thread.
127
+ *
128
+ * The native listener is registered process-wide on first call and
129
+ * survives `stop()` — memory pressure is independent of the perf
130
+ * sampler being active. Callbacks are invoked on the JS thread.
131
+ *
132
+ * **Always pair this with `removeMemoryWarningListener`** (e.g. in a
133
+ * React effect cleanup): the callback closure is retained for the life
134
+ * of the subscription, and forgetting to remove leaks every object the
135
+ * closure transitively captures — typically the React component instance
136
+ * that registered it. This matters in dev too: the native listener
137
+ * table is a process-wide singleton that **does not clear on RN
138
+ * reload**, so a Fast-Refresh / dev reload that drops the JS realm
139
+ * without first calling `removeMemoryWarningListener` will leave the
140
+ * pre-reload callback in the table, pointing at a dead JS context.
141
+ * The cleanest fix is the same effect-cleanup pattern.
142
+ *
143
+ * The relative order in which subscribed callbacks fire for a single
144
+ * event is **not guaranteed** — iOS iterates a hash dictionary, Android
145
+ * iterates a LinkedHashMap, and either may change. Don't take a
146
+ * cross-listener dependency.
147
+ *
148
+ * Dispatch: when a warning arrives, the native module walks all
149
+ * registered callbacks **serially on the main thread** before each
150
+ * one hops to the JS thread. Cost scales with the number of
151
+ * subscribers — keep N small (single-digit) and avoid registering one
152
+ * listener per render-tree branch.
153
+ *
154
+ * Side effects of the warning itself (before your callback fires):
155
+ * - **iOS** runs the same reclaim path as `cleanupNativeCaches`,
156
+ * which drops the process-wide `URLCache.shared`, the WK HTTP /
157
+ * AppCache / Service-Worker stores, and triggers a libmalloc
158
+ * pressure relief. If any code path in the app depends on
159
+ * URLCache for offline HTTP content, or on a Service Worker for
160
+ * offline WebView fallback, that state is dropped here — don't
161
+ * register this listener if either is load-bearing.
162
+ * - **Android** runs `Runtime.gc()` on every warning (LOW and
163
+ * CRITICAL). ART treats it as a hint.
164
+ *
165
+ * Returns an opaque id; pass it to `removeMemoryWarningListener` to
166
+ * unsubscribe.
167
+ */
168
+ addMemoryWarningListener(callback: (event: MemoryWarningEvent) => void): number;
169
+
170
+ /** Unsubscribe a previously-registered memory warning listener. No-op for unknown ids. */
171
+ removeMemoryWarningListener(id: number): void;
172
+
173
+ /**
174
+ * Trigger the same native reclaim path the OS memory-warning observer
175
+ * runs, on demand. Use when the JS layer has reason to believe pressure
176
+ * is building before the OS posts a warning (e.g. backgrounding, a
177
+ * heavy route transition, jotai cache invalidation, post-import).
178
+ *
179
+ * - **iOS** clears `URLCache.shared` (process-wide HTTP response cache;
180
+ * any consumer that relies on URLCache for offline content loses
181
+ * it until the next request) and the WK HTTP / AppCache / Service-
182
+ * Worker stores (auth-related cookies / localStorage / IndexedDB
183
+ * are preserved). Then dispatches `malloc_zone_pressure_relief` on
184
+ * a background queue — the call returns to JS immediately, but the
185
+ * zone walk that actually frees pages can take 100-500 ms.
186
+ * - **Android** asks ART to GC via `Runtime.gc()` (hint only; the
187
+ * runtime decides whether to honour it). Returns quickly.
188
+ *
189
+ * Cheap on Android, cheap-to-return on iOS (heavy work runs async).
190
+ * Pair with `forceGarbageCollection()` if you also want the JS engine
191
+ * to participate.
192
+ */
193
+ cleanupNativeCaches(): void;
81
194
  }