react-native-litert-lm 0.2.1 → 0.3.0

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 (43) hide show
  1. package/README.md +331 -150
  2. package/android/build.gradle +1 -1
  3. package/android/src/main/java/com/margelo/nitro/dev/litert/litertlm/HybridLiteRTLM.kt +140 -37
  4. package/app.plugin.js +33 -0
  5. package/cpp/HybridLiteRTLM.cpp +577 -378
  6. package/cpp/HybridLiteRTLM.hpp +66 -23
  7. package/cpp/IOSDownloadHelper.h +24 -0
  8. package/cpp/cpp-adapter.cpp +10 -2
  9. package/cpp/include/litert_lm_engine.h +502 -0
  10. package/ios/IOSDownloadHelper.mm +129 -0
  11. package/ios/LiteRTLMAutolinking.mm +30 -0
  12. package/lib/hooks.d.ts +33 -3
  13. package/lib/hooks.js +54 -23
  14. package/lib/index.d.ts +4 -1
  15. package/lib/index.js +6 -6
  16. package/lib/memoryTracker.d.ts +128 -0
  17. package/lib/memoryTracker.js +155 -0
  18. package/lib/modelFactory.d.ts +21 -2
  19. package/lib/modelFactory.js +78 -11
  20. package/lib/specs/LiteRTLM.nitro.d.ts +19 -0
  21. package/nitrogen/generated/android/LiteRTLMOnLoad.cpp +28 -18
  22. package/nitrogen/generated/android/LiteRTLMOnLoad.hpp +13 -4
  23. package/nitrogen/generated/android/c++/JHybridLiteRTLMSpec.cpp +39 -36
  24. package/nitrogen/generated/android/c++/JHybridLiteRTLMSpec.hpp +20 -22
  25. package/nitrogen/generated/android/c++/JMemoryUsage.hpp +69 -0
  26. package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/HybridLiteRTLMSpec.kt +19 -18
  27. package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/MemoryUsage.kt +47 -0
  28. package/nitrogen/generated/shared/c++/HybridLiteRTLMSpec.cpp +1 -0
  29. package/nitrogen/generated/shared/c++/HybridLiteRTLMSpec.hpp +4 -0
  30. package/nitrogen/generated/shared/c++/MemoryUsage.hpp +95 -0
  31. package/package.json +12 -5
  32. package/react-native-litert-lm.podspec +20 -7
  33. package/scripts/build-ios-engine.sh +283 -0
  34. package/scripts/download-ios-frameworks.sh +72 -0
  35. package/scripts/postinstall.js +116 -0
  36. package/scripts/stubs/cxx_bridge_stubs.cc +224 -0
  37. package/scripts/stubs/gemma_model_constraint_provider.cc +46 -0
  38. package/scripts/stubs/llguidance_stubs.c +101 -0
  39. package/src/hooks.ts +107 -41
  40. package/src/index.ts +13 -6
  41. package/src/memoryTracker.ts +268 -0
  42. package/src/modelFactory.ts +107 -11
  43. package/src/specs/LiteRTLM.nitro.ts +21 -0
@@ -88,6 +88,20 @@ export interface GenerationStats {
88
88
  /** Tokens per second */
89
89
  tokensPerSecond: number;
90
90
  }
91
+ /**
92
+ * Real memory usage statistics from the native runtime.
93
+ * Measured from OS-level APIs, not estimated.
94
+ */
95
+ export interface MemoryUsage {
96
+ /** Native heap allocated bytes (Debug.getNativeHeapAllocatedSize on Android, malloc_size on iOS) */
97
+ nativeHeapBytes: number;
98
+ /** Total process resident set size (RSS) in bytes */
99
+ residentBytes: number;
100
+ /** Available system memory in bytes */
101
+ availableMemoryBytes: number;
102
+ /** Whether the system considers memory low */
103
+ isLowMemory: boolean;
104
+ }
91
105
  /**
92
106
  * LiteRT-LM: High-performance LLM inference engine.
93
107
  * Supports Gemma 3n, Phi-4, Qwen, and other .litertlm models.
@@ -175,6 +189,11 @@ export interface LiteRTLM extends HybridObject<{
175
189
  * Get the last generation statistics.
176
190
  */
177
191
  getStats(): GenerationStats;
192
+ /**
193
+ * Get real memory usage from the native runtime.
194
+ * Uses OS-level APIs to report actual memory consumption.
195
+ */
196
+ getMemoryUsage(): MemoryUsage;
178
197
  /**
179
198
  * Release all native resources.
180
199
  * Call this when done with the LLM instance.
@@ -23,26 +23,36 @@
23
23
  namespace margelo::nitro::litertlm {
24
24
 
25
25
  int initialize(JavaVM* vm) {
26
+ return facebook::jni::initialize(vm, []() {
27
+ ::margelo::nitro::litertlm::registerAllNatives();
28
+ });
29
+ }
30
+
31
+ struct JHybridLiteRTLMSpecImpl: public jni::JavaClass<JHybridLiteRTLMSpecImpl, JHybridLiteRTLMSpec::JavaPart> {
32
+ static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/dev/litert/litertlm/HybridLiteRTLM;";
33
+ static std::shared_ptr<JHybridLiteRTLMSpec> create() {
34
+ static auto constructorFn = javaClassStatic()->getConstructor<JHybridLiteRTLMSpecImpl::javaobject()>();
35
+ jni::local_ref<JHybridLiteRTLMSpec::JavaPart> javaPart = javaClassStatic()->newObject(constructorFn);
36
+ return javaPart->getJHybridLiteRTLMSpec();
37
+ }
38
+ };
39
+
40
+ void registerAllNatives() {
26
41
  using namespace margelo::nitro;
27
42
  using namespace margelo::nitro::litertlm;
28
- using namespace facebook;
29
-
30
- return facebook::jni::initialize(vm, [] {
31
- // Register native JNI methods
32
- margelo::nitro::litertlm::JHybridLiteRTLMSpec::registerNatives();
33
- margelo::nitro::litertlm::JFunc_void_double_cxx::registerNatives();
34
- margelo::nitro::litertlm::JFunc_void_std__string_bool_cxx::registerNatives();
35
-
36
- // Register Nitro Hybrid Objects
37
- HybridObjectRegistry::registerHybridObjectConstructor(
38
- "LiteRTLM",
39
- []() -> std::shared_ptr<HybridObject> {
40
- static DefaultConstructableObject<JHybridLiteRTLMSpec::javaobject> object("com/margelo/nitro/dev/litert/litertlm/HybridLiteRTLM");
41
- auto instance = object.create();
42
- return instance->cthis()->shared();
43
- }
44
- );
45
- });
43
+
44
+ // Register native JNI methods
45
+ margelo::nitro::litertlm::JHybridLiteRTLMSpec::CxxPart::registerNatives();
46
+ margelo::nitro::litertlm::JFunc_void_double_cxx::registerNatives();
47
+ margelo::nitro::litertlm::JFunc_void_std__string_bool_cxx::registerNatives();
48
+
49
+ // Register Nitro Hybrid Objects
50
+ HybridObjectRegistry::registerHybridObjectConstructor(
51
+ "LiteRTLM",
52
+ []() -> std::shared_ptr<HybridObject> {
53
+ return JHybridLiteRTLMSpecImpl::create();
54
+ }
55
+ );
46
56
  }
47
57
 
48
58
  } // namespace margelo::nitro::litertlm
@@ -6,20 +6,29 @@
6
6
  ///
7
7
 
8
8
  #include <jni.h>
9
+ #include <functional>
9
10
  #include <NitroModules/NitroDefines.hpp>
10
11
 
11
12
  namespace margelo::nitro::litertlm {
12
13
 
14
+ [[deprecated("Use registerNatives() instead.")]]
15
+ int initialize(JavaVM* vm);
16
+
13
17
  /**
14
- * Initializes the native (C++) part of LiteRTLM, and autolinks all Hybrid Objects.
15
- * Call this in your `JNI_OnLoad` function (probably inside `cpp-adapter.cpp`).
18
+ * Register the native (C++) part of LiteRTLM, and autolinks all Hybrid Objects.
19
+ * Call this in your `JNI_OnLoad` function (probably inside `cpp-adapter.cpp`),
20
+ * inside a `facebook::jni::initialize(vm, ...)` call.
16
21
  * Example:
17
22
  * ```cpp (cpp-adapter.cpp)
18
23
  * JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
19
- * return margelo::nitro::litertlm::initialize(vm);
24
+ * return facebook::jni::initialize(vm, []() {
25
+ * // register all LiteRTLM HybridObjects
26
+ * margelo::nitro::litertlm::registerNatives();
27
+ * // any other custom registrations go here.
28
+ * });
20
29
  * }
21
30
  * ```
22
31
  */
23
- int initialize(JavaVM* vm);
32
+ void registerAllNatives();
24
33
 
25
34
  } // namespace margelo::nitro::litertlm
@@ -13,6 +13,8 @@ namespace margelo::nitro::litertlm { struct Message; }
13
13
  namespace margelo::nitro::litertlm { enum class Role; }
14
14
  // Forward declaration of `GenerationStats` to properly resolve imports.
15
15
  namespace margelo::nitro::litertlm { struct GenerationStats; }
16
+ // Forward declaration of `MemoryUsage` to properly resolve imports.
17
+ namespace margelo::nitro::litertlm { struct MemoryUsage; }
16
18
  // Forward declaration of `LLMConfig` to properly resolve imports.
17
19
  namespace margelo::nitro::litertlm { struct LLMConfig; }
18
20
  // Forward declaration of `Backend` to properly resolve imports.
@@ -29,6 +31,8 @@ namespace margelo::nitro::litertlm { enum class Backend; }
29
31
  #include "JRole.hpp"
30
32
  #include "GenerationStats.hpp"
31
33
  #include "JGenerationStats.hpp"
34
+ #include "MemoryUsage.hpp"
35
+ #include "JMemoryUsage.hpp"
32
36
  #include "LLMConfig.hpp"
33
37
  #include <optional>
34
38
  #include "JLLMConfig.hpp"
@@ -41,37 +45,31 @@ namespace margelo::nitro::litertlm { enum class Backend; }
41
45
 
42
46
  namespace margelo::nitro::litertlm {
43
47
 
44
- jni::local_ref<JHybridLiteRTLMSpec::jhybriddata> JHybridLiteRTLMSpec::initHybrid(jni::alias_ref<jhybridobject> jThis) {
45
- return makeCxxInstance(jThis);
46
- }
47
-
48
- void JHybridLiteRTLMSpec::registerNatives() {
49
- registerHybrid({
50
- makeNativeMethod("initHybrid", JHybridLiteRTLMSpec::initHybrid),
51
- });
48
+ std::shared_ptr<JHybridLiteRTLMSpec> JHybridLiteRTLMSpec::JavaPart::getJHybridLiteRTLMSpec() {
49
+ auto hybridObject = JHybridObject::JavaPart::getJHybridObject();
50
+ auto castHybridObject = std::dynamic_pointer_cast<JHybridLiteRTLMSpec>(hybridObject);
51
+ if (castHybridObject == nullptr) [[unlikely]] {
52
+ throw std::runtime_error("Failed to downcast JHybridObject to JHybridLiteRTLMSpec!");
53
+ }
54
+ return castHybridObject;
52
55
  }
53
56
 
54
- size_t JHybridLiteRTLMSpec::getExternalMemorySize() noexcept {
55
- static const auto method = javaClassStatic()->getMethod<jlong()>("getMemorySize");
56
- return method(_javaPart);
57
+ jni::local_ref<JHybridLiteRTLMSpec::CxxPart::jhybriddata> JHybridLiteRTLMSpec::CxxPart::initHybrid(jni::alias_ref<jhybridobject> jThis) {
58
+ return makeCxxInstance(jThis);
57
59
  }
58
60
 
59
- bool JHybridLiteRTLMSpec::equals(const std::shared_ptr<HybridObject>& other) {
60
- if (auto otherCast = std::dynamic_pointer_cast<JHybridLiteRTLMSpec>(other)) {
61
- return _javaPart == otherCast->_javaPart;
61
+ std::shared_ptr<JHybridObject> JHybridLiteRTLMSpec::CxxPart::createHybridObject(const jni::local_ref<JHybridObject::JavaPart>& javaPart) {
62
+ auto castJavaPart = jni::dynamic_ref_cast<JHybridLiteRTLMSpec::JavaPart>(javaPart);
63
+ if (castJavaPart == nullptr) [[unlikely]] {
64
+ throw std::runtime_error("Failed to cast JHybridObject::JavaPart to JHybridLiteRTLMSpec::JavaPart!");
62
65
  }
63
- return false;
66
+ return std::make_shared<JHybridLiteRTLMSpec>(castJavaPart);
64
67
  }
65
68
 
66
- void JHybridLiteRTLMSpec::dispose() noexcept {
67
- static const auto method = javaClassStatic()->getMethod<void()>("dispose");
68
- method(_javaPart);
69
- }
70
-
71
- std::string JHybridLiteRTLMSpec::toString() {
72
- static const auto method = javaClassStatic()->getMethod<jni::JString()>("toString");
73
- auto javaString = method(_javaPart);
74
- return javaString->toStdString();
69
+ void JHybridLiteRTLMSpec::CxxPart::registerNatives() {
70
+ registerHybrid({
71
+ makeNativeMethod("initHybrid", JHybridLiteRTLMSpec::CxxPart::initHybrid),
72
+ });
75
73
  }
76
74
 
77
75
  // Properties
@@ -79,7 +77,7 @@ namespace margelo::nitro::litertlm {
79
77
 
80
78
  // Methods
81
79
  std::shared_ptr<Promise<void>> JHybridLiteRTLMSpec::loadModel(const std::string& modelPath, const std::optional<LLMConfig>& config) {
82
- static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* modelPath */, jni::alias_ref<JLLMConfig> /* config */)>("loadModel");
80
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* modelPath */, jni::alias_ref<JLLMConfig> /* config */)>("loadModel");
83
81
  auto __result = method(_javaPart, jni::make_jstring(modelPath), config.has_value() ? JLLMConfig::fromCpp(config.value()) : nullptr);
84
82
  return [&]() {
85
83
  auto __promise = Promise<void>::create();
@@ -94,7 +92,7 @@ namespace margelo::nitro::litertlm {
94
92
  }();
95
93
  }
96
94
  std::shared_ptr<Promise<std::string>> JHybridLiteRTLMSpec::sendMessage(const std::string& message) {
97
- static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* message */)>("sendMessage");
95
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* message */)>("sendMessage");
98
96
  auto __result = method(_javaPart, jni::make_jstring(message));
99
97
  return [&]() {
100
98
  auto __promise = Promise<std::string>::create();
@@ -110,7 +108,7 @@ namespace margelo::nitro::litertlm {
110
108
  }();
111
109
  }
112
110
  std::shared_ptr<Promise<std::string>> JHybridLiteRTLMSpec::sendMessageWithImage(const std::string& message, const std::string& imagePath) {
113
- static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* message */, jni::alias_ref<jni::JString> /* imagePath */)>("sendMessageWithImage");
111
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* message */, jni::alias_ref<jni::JString> /* imagePath */)>("sendMessageWithImage");
114
112
  auto __result = method(_javaPart, jni::make_jstring(message), jni::make_jstring(imagePath));
115
113
  return [&]() {
116
114
  auto __promise = Promise<std::string>::create();
@@ -126,7 +124,7 @@ namespace margelo::nitro::litertlm {
126
124
  }();
127
125
  }
128
126
  std::shared_ptr<Promise<std::string>> JHybridLiteRTLMSpec::downloadModel(const std::string& url, const std::string& fileName, const std::optional<std::function<void(double /* progress */)>>& onProgress) {
129
- static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* url */, jni::alias_ref<jni::JString> /* fileName */, jni::alias_ref<JFunc_void_double::javaobject> /* onProgress */)>("downloadModel_cxx");
127
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* url */, jni::alias_ref<jni::JString> /* fileName */, jni::alias_ref<JFunc_void_double::javaobject> /* onProgress */)>("downloadModel_cxx");
130
128
  auto __result = method(_javaPart, jni::make_jstring(url), jni::make_jstring(fileName), onProgress.has_value() ? JFunc_void_double_cxx::fromCpp(onProgress.value()) : nullptr);
131
129
  return [&]() {
132
130
  auto __promise = Promise<std::string>::create();
@@ -142,7 +140,7 @@ namespace margelo::nitro::litertlm {
142
140
  }();
143
141
  }
144
142
  std::shared_ptr<Promise<void>> JHybridLiteRTLMSpec::deleteModel(const std::string& fileName) {
145
- static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* fileName */)>("deleteModel");
143
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* fileName */)>("deleteModel");
146
144
  auto __result = method(_javaPart, jni::make_jstring(fileName));
147
145
  return [&]() {
148
146
  auto __promise = Promise<void>::create();
@@ -157,7 +155,7 @@ namespace margelo::nitro::litertlm {
157
155
  }();
158
156
  }
159
157
  std::shared_ptr<Promise<std::string>> JHybridLiteRTLMSpec::sendMessageWithAudio(const std::string& message, const std::string& audioPath) {
160
- static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* message */, jni::alias_ref<jni::JString> /* audioPath */)>("sendMessageWithAudio");
158
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* message */, jni::alias_ref<jni::JString> /* audioPath */)>("sendMessageWithAudio");
161
159
  auto __result = method(_javaPart, jni::make_jstring(message), jni::make_jstring(audioPath));
162
160
  return [&]() {
163
161
  auto __promise = Promise<std::string>::create();
@@ -173,11 +171,11 @@ namespace margelo::nitro::litertlm {
173
171
  }();
174
172
  }
175
173
  void JHybridLiteRTLMSpec::sendMessageAsync(const std::string& message, const std::function<void(const std::string& /* token */, bool /* done */)>& onToken) {
176
- static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* message */, jni::alias_ref<JFunc_void_std__string_bool::javaobject> /* onToken */)>("sendMessageAsync_cxx");
174
+ static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* message */, jni::alias_ref<JFunc_void_std__string_bool::javaobject> /* onToken */)>("sendMessageAsync_cxx");
177
175
  method(_javaPart, jni::make_jstring(message), JFunc_void_std__string_bool_cxx::fromCpp(onToken));
178
176
  }
179
177
  std::vector<Message> JHybridLiteRTLMSpec::getHistory() {
180
- static const auto method = javaClassStatic()->getMethod<jni::local_ref<jni::JArrayClass<JMessage>>()>("getHistory");
178
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JArrayClass<JMessage>>()>("getHistory");
181
179
  auto __result = method(_javaPart);
182
180
  return [&]() {
183
181
  size_t __size = __result->size();
@@ -191,21 +189,26 @@ namespace margelo::nitro::litertlm {
191
189
  }();
192
190
  }
193
191
  void JHybridLiteRTLMSpec::resetConversation() {
194
- static const auto method = javaClassStatic()->getMethod<void()>("resetConversation");
192
+ static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("resetConversation");
195
193
  method(_javaPart);
196
194
  }
197
195
  bool JHybridLiteRTLMSpec::isReady() {
198
- static const auto method = javaClassStatic()->getMethod<jboolean()>("isReady");
196
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean()>("isReady");
199
197
  auto __result = method(_javaPart);
200
198
  return static_cast<bool>(__result);
201
199
  }
202
200
  GenerationStats JHybridLiteRTLMSpec::getStats() {
203
- static const auto method = javaClassStatic()->getMethod<jni::local_ref<JGenerationStats>()>("getStats");
201
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JGenerationStats>()>("getStats");
202
+ auto __result = method(_javaPart);
203
+ return __result->toCpp();
204
+ }
205
+ MemoryUsage JHybridLiteRTLMSpec::getMemoryUsage() {
206
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JMemoryUsage>()>("getMemoryUsage");
204
207
  auto __result = method(_javaPart);
205
208
  return __result->toCpp();
206
209
  }
207
210
  void JHybridLiteRTLMSpec::close() {
208
- static const auto method = javaClassStatic()->getMethod<void()>("close");
211
+ static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("close");
209
212
  method(_javaPart);
210
213
  }
211
214
 
@@ -18,34 +18,33 @@ namespace margelo::nitro::litertlm {
18
18
 
19
19
  using namespace facebook;
20
20
 
21
- class JHybridLiteRTLMSpec: public jni::HybridClass<JHybridLiteRTLMSpec, JHybridObject>,
22
- public virtual HybridLiteRTLMSpec {
21
+ class JHybridLiteRTLMSpec: public virtual HybridLiteRTLMSpec, public virtual JHybridObject {
23
22
  public:
24
- static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/dev/litert/litertlm/HybridLiteRTLMSpec;";
25
- static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);
26
- static void registerNatives();
27
-
28
- protected:
29
- // C++ constructor (called from Java via `initHybrid()`)
30
- explicit JHybridLiteRTLMSpec(jni::alias_ref<jhybridobject> jThis) :
31
- HybridObject(HybridLiteRTLMSpec::TAG),
32
- HybridBase(jThis),
33
- _javaPart(jni::make_global(jThis)) {}
23
+ struct JavaPart: public jni::JavaClass<JavaPart, JHybridObject::JavaPart> {
24
+ static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/dev/litert/litertlm/HybridLiteRTLMSpec;";
25
+ std::shared_ptr<JHybridLiteRTLMSpec> getJHybridLiteRTLMSpec();
26
+ };
27
+ struct CxxPart: public jni::HybridClass<CxxPart, JHybridObject::CxxPart> {
28
+ static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/dev/litert/litertlm/HybridLiteRTLMSpec$CxxPart;";
29
+ static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);
30
+ static void registerNatives();
31
+ using HybridBase::HybridBase;
32
+ protected:
33
+ std::shared_ptr<JHybridObject> createHybridObject(const jni::local_ref<JHybridObject::JavaPart>& javaPart) override;
34
+ };
34
35
 
35
36
  public:
37
+ explicit JHybridLiteRTLMSpec(const jni::local_ref<JHybridLiteRTLMSpec::JavaPart>& javaPart):
38
+ HybridObject(HybridLiteRTLMSpec::TAG),
39
+ JHybridObject(javaPart),
40
+ _javaPart(jni::make_global(javaPart)) {}
36
41
  ~JHybridLiteRTLMSpec() override {
37
42
  // Hermes GC can destroy JS objects on a non-JNI Thread.
38
43
  jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); });
39
44
  }
40
45
 
41
46
  public:
42
- size_t getExternalMemorySize() noexcept override;
43
- bool equals(const std::shared_ptr<HybridObject>& other) override;
44
- void dispose() noexcept override;
45
- std::string toString() override;
46
-
47
- public:
48
- inline const jni::global_ref<JHybridLiteRTLMSpec::javaobject>& getJavaPart() const noexcept {
47
+ inline const jni::global_ref<JHybridLiteRTLMSpec::JavaPart>& getJavaPart() const noexcept {
49
48
  return _javaPart;
50
49
  }
51
50
 
@@ -66,12 +65,11 @@ namespace margelo::nitro::litertlm {
66
65
  void resetConversation() override;
67
66
  bool isReady() override;
68
67
  GenerationStats getStats() override;
68
+ MemoryUsage getMemoryUsage() override;
69
69
  void close() override;
70
70
 
71
71
  private:
72
- friend HybridBase;
73
- using HybridBase::HybridBase;
74
- jni::global_ref<JHybridLiteRTLMSpec::javaobject> _javaPart;
72
+ jni::global_ref<JHybridLiteRTLMSpec::JavaPart> _javaPart;
75
73
  };
76
74
 
77
75
  } // namespace margelo::nitro::litertlm
@@ -0,0 +1,69 @@
1
+ ///
2
+ /// JMemoryUsage.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #include <fbjni/fbjni.h>
11
+ #include "MemoryUsage.hpp"
12
+
13
+
14
+
15
+ namespace margelo::nitro::litertlm {
16
+
17
+ using namespace facebook;
18
+
19
+ /**
20
+ * The C++ JNI bridge between the C++ struct "MemoryUsage" and the the Kotlin data class "MemoryUsage".
21
+ */
22
+ struct JMemoryUsage final: public jni::JavaClass<JMemoryUsage> {
23
+ public:
24
+ static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/dev/litert/litertlm/MemoryUsage;";
25
+
26
+ public:
27
+ /**
28
+ * Convert this Java/Kotlin-based struct to the C++ struct MemoryUsage by copying all values to C++.
29
+ */
30
+ [[maybe_unused]]
31
+ [[nodiscard]]
32
+ MemoryUsage toCpp() const {
33
+ static const auto clazz = javaClassStatic();
34
+ static const auto fieldNativeHeapBytes = clazz->getField<double>("nativeHeapBytes");
35
+ double nativeHeapBytes = this->getFieldValue(fieldNativeHeapBytes);
36
+ static const auto fieldResidentBytes = clazz->getField<double>("residentBytes");
37
+ double residentBytes = this->getFieldValue(fieldResidentBytes);
38
+ static const auto fieldAvailableMemoryBytes = clazz->getField<double>("availableMemoryBytes");
39
+ double availableMemoryBytes = this->getFieldValue(fieldAvailableMemoryBytes);
40
+ static const auto fieldIsLowMemory = clazz->getField<jboolean>("isLowMemory");
41
+ jboolean isLowMemory = this->getFieldValue(fieldIsLowMemory);
42
+ return MemoryUsage(
43
+ nativeHeapBytes,
44
+ residentBytes,
45
+ availableMemoryBytes,
46
+ static_cast<bool>(isLowMemory)
47
+ );
48
+ }
49
+
50
+ public:
51
+ /**
52
+ * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.
53
+ */
54
+ [[maybe_unused]]
55
+ static jni::local_ref<JMemoryUsage::javaobject> fromCpp(const MemoryUsage& value) {
56
+ using JSignature = JMemoryUsage(double, double, double, jboolean);
57
+ static const auto clazz = javaClassStatic();
58
+ static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
59
+ return create(
60
+ clazz,
61
+ value.nativeHeapBytes,
62
+ value.residentBytes,
63
+ value.availableMemoryBytes,
64
+ value.isLowMemory
65
+ );
66
+ }
67
+ };
68
+
69
+ } // namespace margelo::nitro::litertlm
@@ -25,23 +25,6 @@ import com.margelo.nitro.core.HybridObject
25
25
  "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName"
26
26
  )
27
27
  abstract class HybridLiteRTLMSpec: HybridObject() {
28
- @DoNotStrip
29
- private var mHybridData: HybridData = initHybrid()
30
-
31
- init {
32
- super.updateNative(mHybridData)
33
- }
34
-
35
- override fun updateNative(hybridData: HybridData) {
36
- mHybridData = hybridData
37
- super.updateNative(hybridData)
38
- }
39
-
40
- // Default implementation of `HybridObject.toString()`
41
- override fun toString(): String {
42
- return "[HybridObject LiteRTLM]"
43
- }
44
-
45
28
  // Properties
46
29
 
47
30
 
@@ -100,11 +83,29 @@ abstract class HybridLiteRTLMSpec: HybridObject() {
100
83
  @Keep
101
84
  abstract fun getStats(): GenerationStats
102
85
 
86
+ @DoNotStrip
87
+ @Keep
88
+ abstract fun getMemoryUsage(): MemoryUsage
89
+
103
90
  @DoNotStrip
104
91
  @Keep
105
92
  abstract fun close(): Unit
106
93
 
107
- private external fun initHybrid(): HybridData
94
+ // Default implementation of `HybridObject.toString()`
95
+ override fun toString(): String {
96
+ return "[HybridObject LiteRTLM]"
97
+ }
98
+
99
+ // C++ backing class
100
+ @DoNotStrip
101
+ @Keep
102
+ protected open class CxxPart(javaPart: HybridLiteRTLMSpec): HybridObject.CxxPart(javaPart) {
103
+ // C++ JHybridLiteRTLMSpec::CxxPart::initHybrid(...)
104
+ external override fun initHybrid(): HybridData
105
+ }
106
+ override fun createCxxPart(): CxxPart {
107
+ return CxxPart(this)
108
+ }
108
109
 
109
110
  companion object {
110
111
  protected const val TAG = "HybridLiteRTLMSpec"
@@ -0,0 +1,47 @@
1
+ ///
2
+ /// MemoryUsage.kt
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ package com.margelo.nitro.dev.litert.litertlm
9
+
10
+ import androidx.annotation.Keep
11
+ import com.facebook.proguard.annotations.DoNotStrip
12
+
13
+
14
+ /**
15
+ * Represents the JavaScript object/struct "MemoryUsage".
16
+ */
17
+ @DoNotStrip
18
+ @Keep
19
+ data class MemoryUsage(
20
+ @DoNotStrip
21
+ @Keep
22
+ val nativeHeapBytes: Double,
23
+ @DoNotStrip
24
+ @Keep
25
+ val residentBytes: Double,
26
+ @DoNotStrip
27
+ @Keep
28
+ val availableMemoryBytes: Double,
29
+ @DoNotStrip
30
+ @Keep
31
+ val isLowMemory: Boolean
32
+ ) {
33
+ /* primary constructor */
34
+
35
+ companion object {
36
+ /**
37
+ * Constructor called from C++
38
+ */
39
+ @DoNotStrip
40
+ @Keep
41
+ @Suppress("unused")
42
+ @JvmStatic
43
+ private fun fromCpp(nativeHeapBytes: Double, residentBytes: Double, availableMemoryBytes: Double, isLowMemory: Boolean): MemoryUsage {
44
+ return MemoryUsage(nativeHeapBytes, residentBytes, availableMemoryBytes, isLowMemory)
45
+ }
46
+ }
47
+ }
@@ -25,6 +25,7 @@ namespace margelo::nitro::litertlm {
25
25
  prototype.registerHybridMethod("resetConversation", &HybridLiteRTLMSpec::resetConversation);
26
26
  prototype.registerHybridMethod("isReady", &HybridLiteRTLMSpec::isReady);
27
27
  prototype.registerHybridMethod("getStats", &HybridLiteRTLMSpec::getStats);
28
+ prototype.registerHybridMethod("getMemoryUsage", &HybridLiteRTLMSpec::getMemoryUsage);
28
29
  prototype.registerHybridMethod("close", &HybridLiteRTLMSpec::close);
29
30
  });
30
31
  }
@@ -19,6 +19,8 @@ namespace margelo::nitro::litertlm { struct LLMConfig; }
19
19
  namespace margelo::nitro::litertlm { struct Message; }
20
20
  // Forward declaration of `GenerationStats` to properly resolve imports.
21
21
  namespace margelo::nitro::litertlm { struct GenerationStats; }
22
+ // Forward declaration of `MemoryUsage` to properly resolve imports.
23
+ namespace margelo::nitro::litertlm { struct MemoryUsage; }
22
24
 
23
25
  #include <NitroModules/Promise.hpp>
24
26
  #include <string>
@@ -28,6 +30,7 @@ namespace margelo::nitro::litertlm { struct GenerationStats; }
28
30
  #include "Message.hpp"
29
31
  #include <vector>
30
32
  #include "GenerationStats.hpp"
33
+ #include "MemoryUsage.hpp"
31
34
 
32
35
  namespace margelo::nitro::litertlm {
33
36
 
@@ -71,6 +74,7 @@ namespace margelo::nitro::litertlm {
71
74
  virtual void resetConversation() = 0;
72
75
  virtual bool isReady() = 0;
73
76
  virtual GenerationStats getStats() = 0;
77
+ virtual MemoryUsage getMemoryUsage() = 0;
74
78
  virtual void close() = 0;
75
79
 
76
80
  protected: