react-native-nobodywho 1.0.1 → 2.0.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.
- package/Nobodywho.podspec +2 -2
- package/README.md +16 -13
- package/generated/cpp/nobodywho.cpp +496 -3
- package/generated/cpp/nobodywho.hpp +8 -0
- package/generated/ts/nobodywho-ffi.ts +10 -1
- package/generated/ts/nobodywho.ts +180 -102
- package/package.json +1 -1
- package/src/chat.ts +5 -3
- package/src/cross_encoder.ts +6 -1
- package/src/encoder.ts +6 -1
- package/src/message.ts +49 -35
- package/src/model.ts +7 -0
- package/src/wrapper.ts +3 -4
package/Nobodywho.podspec
CHANGED
|
@@ -10,7 +10,7 @@ framework_name = "NobodywhoFramework.xcframework"
|
|
|
10
10
|
framework_dir = File.join(__dir__, framework_name)
|
|
11
11
|
zip_name = "#{framework_name}.zip"
|
|
12
12
|
zip_path = File.join(__dir__, zip_name)
|
|
13
|
-
url = "https://github.com/nobodywho-ooo/nobodywho/releases/download/nobodywho-react-native
|
|
13
|
+
url = "https://github.com/nobodywho-ooo/nobodywho/releases/download/nobodywho-react-native-v#{version}/#{zip_name}"
|
|
14
14
|
|
|
15
15
|
# Always download a fresh xcframework to ensure it matches the package version.
|
|
16
16
|
FileUtils.rm_rf(framework_dir) if File.exist?(framework_dir)
|
|
@@ -20,7 +20,7 @@ puts "[NobodyWho] Downloading xcframework from #{url}"
|
|
|
20
20
|
system("curl", "-L", "-f", "-o", zip_path, url) or
|
|
21
21
|
raise "Failed to download NobodyWho xcframework.\n" \
|
|
22
22
|
"URL: #{url}\n" \
|
|
23
|
-
"Check that the release exists: https://github.com/nobodywho-ooo/nobodywho/releases/tag/nobodywho-react-native
|
|
23
|
+
"Check that the release exists: https://github.com/nobodywho-ooo/nobodywho/releases/tag/nobodywho-react-native-v#{version}\n" \
|
|
24
24
|
"For local development, manually place the xcframework at: #{framework_dir}"
|
|
25
25
|
|
|
26
26
|
puts "[NobodyWho] Extracting xcframework..."
|
package/README.md
CHANGED
|
@@ -119,14 +119,14 @@ See the [Sampling documentation](https://docs.nobodywho.ooo/react-native/samplin
|
|
|
119
119
|
|
|
120
120
|
---
|
|
121
121
|
|
|
122
|
-
## Vision
|
|
122
|
+
## Vision & Hearing
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
Provide image and audio information to your LLM.
|
|
125
125
|
|
|
126
126
|
To enable this, you need two model files:
|
|
127
127
|
|
|
128
|
-
- A
|
|
129
|
-
- A matching
|
|
128
|
+
- A multimodal LLM, so the LLM can consume image-tokens or/and audio-tokens
|
|
129
|
+
- A matching projection model, which converts images to image-tokens or/and audio to audio-tokens (usually has `mmproj` in the name)
|
|
130
130
|
|
|
131
131
|
Pass the projection model when loading your model, then use `Prompt` to compose prompts that mix text and images:
|
|
132
132
|
|
|
@@ -135,17 +135,20 @@ import { Chat, Prompt } from "react-native-nobodywho";
|
|
|
135
135
|
|
|
136
136
|
const chat = await Chat.fromPath({
|
|
137
137
|
modelPath: "/path/to/vision-model.gguf",
|
|
138
|
-
|
|
138
|
+
projectionModelPath: "/path/to/mmproj.gguf",
|
|
139
139
|
});
|
|
140
140
|
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
141
|
+
const response = await chat
|
|
142
|
+
.ask(
|
|
143
|
+
new Prompt([
|
|
144
|
+
Prompt.Text("Tell me what you see in the image and what you hear in the audio."),
|
|
145
|
+
Prompt.Image("/path/to/dog.png"),
|
|
146
|
+
Prompt.Audio("/path/to/sound.mp3"),
|
|
147
|
+
]),
|
|
148
|
+
)
|
|
149
|
+
.completed();
|
|
147
150
|
```
|
|
148
151
|
|
|
149
|
-
You can pass multiple images and interleave text between them. If the model performs poorly, try reordering the text and image parts — this can make a noticeable difference. If images consume too much context, increase `contextSize` or preprocess images with compression.
|
|
152
|
+
You can pass multiple images/audio files and interleave text between them. If the model performs poorly, try reordering the text, audio and image parts — this can make a noticeable difference. If images consume too much context, increase `contextSize` or preprocess images with compression.
|
|
150
153
|
|
|
151
|
-
See the [Vision documentation](https://docs.nobodywho.ooo/react-native/vision/) for model recommendations and advanced tips.
|
|
154
|
+
See the [Vision & Hearing documentation](https://docs.nobodywho.ooo/react-native/vision/) for model recommendations and advanced tips.
|
|
@@ -95,9 +95,18 @@ typedef struct UniffiForeignFutureResultVoid {
|
|
|
95
95
|
} UniffiForeignFutureResultVoid;
|
|
96
96
|
typedef void (*UniffiForeignFutureCompleteVoid)(
|
|
97
97
|
uint64_t callback_data, UniffiForeignFutureResultVoid result);
|
|
98
|
+
typedef void (*UniffiCallbackInterfaceRustDownloadProgressCallbackMethod0)(
|
|
99
|
+
uint64_t uniffi_handle, uint64_t downloaded, uint64_t total,
|
|
100
|
+
void *uniffi_out_return, RustCallStatus *rust_call_status);
|
|
98
101
|
typedef void (*UniffiCallbackInterfaceRustToolCallbackMethod0)(
|
|
99
102
|
uint64_t uniffi_handle, RustBuffer arguments_json,
|
|
100
103
|
RustBuffer *uniffi_out_return, RustCallStatus *rust_call_status);
|
|
104
|
+
typedef struct UniffiVTableCallbackInterfaceRustDownloadProgressCallback {
|
|
105
|
+
UniffiCallbackInterfaceFree uniffi_free;
|
|
106
|
+
UniffiCallbackInterfaceClone uniffi_clone;
|
|
107
|
+
UniffiCallbackInterfaceRustDownloadProgressCallbackMethod0
|
|
108
|
+
on_download_progress;
|
|
109
|
+
} UniffiVTableCallbackInterfaceRustDownloadProgressCallback;
|
|
101
110
|
typedef struct UniffiVTableCallbackInterfaceRustToolCallback {
|
|
102
111
|
UniffiCallbackInterfaceFree uniffi_free;
|
|
103
112
|
UniffiCallbackInterfaceClone uniffi_clone;
|
|
@@ -253,12 +262,15 @@ uniffi_nobodywho_uniffi_fn_constructor_samplerconfig_from_json(
|
|
|
253
262
|
RustBuffer json_str, RustCallStatus *uniffi_out_err);
|
|
254
263
|
RustBuffer uniffi_nobodywho_uniffi_fn_method_samplerconfig_to_json(
|
|
255
264
|
/*handle*/ uint64_t ptr, RustCallStatus *uniffi_out_err);
|
|
265
|
+
void uniffi_nobodywho_uniffi_fn_init_callback_vtable_rustdownloadprogresscallback(
|
|
266
|
+
UniffiVTableCallbackInterfaceRustDownloadProgressCallback *vtable);
|
|
256
267
|
void uniffi_nobodywho_uniffi_fn_init_callback_vtable_rusttoolcallback(
|
|
257
268
|
UniffiVTableCallbackInterfaceRustToolCallback *vtable);
|
|
258
269
|
float uniffi_nobodywho_uniffi_fn_func_cosine_similarity(
|
|
259
270
|
RustBuffer a, RustBuffer b, RustCallStatus *uniffi_out_err);
|
|
260
271
|
/*handle*/ uint64_t uniffi_nobodywho_uniffi_fn_func_load_model(
|
|
261
|
-
RustBuffer model_path, int8_t use_gpu, RustBuffer projection_model_path
|
|
272
|
+
RustBuffer model_path, int8_t use_gpu, RustBuffer projection_model_path,
|
|
273
|
+
RustBuffer on_download_progress);
|
|
262
274
|
/*handle*/ uint64_t uniffi_nobodywho_uniffi_fn_func_sampler_preset_default(
|
|
263
275
|
RustCallStatus *uniffi_out_err);
|
|
264
276
|
/*handle*/ uint64_t uniffi_nobodywho_uniffi_fn_func_sampler_preset_dry(
|
|
@@ -452,6 +464,8 @@ uint16_t uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new();
|
|
|
452
464
|
uint16_t uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new_async();
|
|
453
465
|
uint16_t uniffi_nobodywho_uniffi_checksum_constructor_samplerbuilder_new();
|
|
454
466
|
uint16_t uniffi_nobodywho_uniffi_checksum_constructor_samplerconfig_from_json();
|
|
467
|
+
uint16_t
|
|
468
|
+
uniffi_nobodywho_uniffi_checksum_method_rustdownloadprogresscallback_on_download_progress();
|
|
455
469
|
uint16_t uniffi_nobodywho_uniffi_checksum_method_rusttoolcallback_call();
|
|
456
470
|
uint32_t ffi_nobodywho_uniffi_uniffi_contract_version();
|
|
457
471
|
}
|
|
@@ -890,6 +904,119 @@ static void cleanup() {
|
|
|
890
904
|
} // namespace uniffi::nobodywho::cb::foreignfuturedroppedcallback
|
|
891
905
|
// Implementation of free callback function CallbackInterfaceFree
|
|
892
906
|
|
|
907
|
+
// Callback function:
|
|
908
|
+
// uniffi::nobodywho::st::vtablecallbackinterfacerustdownloadprogresscallback::vtablecallbackinterfacerustdownloadprogresscallback::free::UniffiCallbackInterfaceFree
|
|
909
|
+
//
|
|
910
|
+
// We have the following constraints:
|
|
911
|
+
// - we need to pass a function pointer to Rust.
|
|
912
|
+
// - we need a jsi::Runtime and jsi::Function to call into JS.
|
|
913
|
+
// - function pointers can't store state, so we can't use a lamda.
|
|
914
|
+
//
|
|
915
|
+
// For this, we store a lambda as a global, as `rsLambda`. The `callback`
|
|
916
|
+
// function calls the lambda, which itself calls the `body` which then calls
|
|
917
|
+
// into JS.
|
|
918
|
+
//
|
|
919
|
+
// We then give the `callback` function pointer to Rust which will call the
|
|
920
|
+
// lambda sometime in the future.
|
|
921
|
+
namespace uniffi::nobodywho::st::
|
|
922
|
+
vtablecallbackinterfacerustdownloadprogresscallback::
|
|
923
|
+
vtablecallbackinterfacerustdownloadprogresscallback::free {
|
|
924
|
+
using namespace facebook;
|
|
925
|
+
|
|
926
|
+
// We need to store a lambda in a global so we can call it from
|
|
927
|
+
// a function pointer. The function pointer is passed to Rust.
|
|
928
|
+
static std::function<void(uint64_t)> rsLambda = nullptr;
|
|
929
|
+
|
|
930
|
+
// This is the main body of the callback. It's called from the lambda,
|
|
931
|
+
// which itself is called from the callback function which is passed to Rust.
|
|
932
|
+
static void body(jsi::Runtime &rt,
|
|
933
|
+
std::shared_ptr<uniffi_runtime::UniffiCallInvoker> callInvoker,
|
|
934
|
+
std::shared_ptr<jsi::Value> callbackValue,
|
|
935
|
+
uint64_t rs_handle) {
|
|
936
|
+
|
|
937
|
+
// Convert the arguments from Rust, into jsi::Values.
|
|
938
|
+
// We'll use the Bridging class to do this…
|
|
939
|
+
auto js_handle =
|
|
940
|
+
uniffi_jsi::Bridging<uint64_t>::toJs(rt, callInvoker, rs_handle);
|
|
941
|
+
|
|
942
|
+
// Now we are ready to call the callback.
|
|
943
|
+
// We are already on the JS thread, because this `body` function was
|
|
944
|
+
// invoked from the CallInvoker.
|
|
945
|
+
try {
|
|
946
|
+
// Getting the callback function
|
|
947
|
+
auto cb = callbackValue->asObject(rt).asFunction(rt);
|
|
948
|
+
auto uniffiResult = cb.call(rt, js_handle);
|
|
949
|
+
|
|
950
|
+
} catch (const jsi::JSError &error) {
|
|
951
|
+
std::cout << "Error in callback UniffiCallbackInterfaceFree: "
|
|
952
|
+
<< error.what() << std::endl;
|
|
953
|
+
throw error;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
static void callback(uint64_t rs_handle) {
|
|
958
|
+
// If the runtime has shutdown, then there is no point in trying to
|
|
959
|
+
// call into Javascript. BUT how do we tell if the runtime has shutdown?
|
|
960
|
+
//
|
|
961
|
+
// Answer: the module destructor calls into callback `cleanup` method,
|
|
962
|
+
// which nulls out the rsLamda.
|
|
963
|
+
//
|
|
964
|
+
// If rsLamda is null, then there is no runtime to call into.
|
|
965
|
+
if (rsLambda == nullptr) {
|
|
966
|
+
// This only occurs when destructors are calling into Rust free/drop,
|
|
967
|
+
// which causes the JS callback to be dropped.
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
// The runtime, the actual callback jsi::funtion, and the callInvoker
|
|
972
|
+
// are all in the lambda.
|
|
973
|
+
rsLambda(rs_handle);
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
[[maybe_unused]] static UniffiCallbackInterfaceFree
|
|
977
|
+
makeCallbackFunction( // uniffi::nobodywho::st::vtablecallbackinterfacerustdownloadprogresscallback::vtablecallbackinterfacerustdownloadprogresscallback::free
|
|
978
|
+
jsi::Runtime &rt,
|
|
979
|
+
std::shared_ptr<uniffi_runtime::UniffiCallInvoker> callInvoker,
|
|
980
|
+
const jsi::Value &value) {
|
|
981
|
+
if (rsLambda != nullptr) {
|
|
982
|
+
// `makeCallbackFunction` is called in two circumstances:
|
|
983
|
+
//
|
|
984
|
+
// 1. at startup, when initializing callback interface vtables.
|
|
985
|
+
// 2. when polling futures. This happens at least once per future that is
|
|
986
|
+
// exposed to Javascript. We know that this is always the same function,
|
|
987
|
+
// `uniffiFutureContinuationCallback` in `async-rust-calls.ts`.
|
|
988
|
+
//
|
|
989
|
+
// We can therefore return the callback function without making anything
|
|
990
|
+
// new if we've been initialized already.
|
|
991
|
+
return callback;
|
|
992
|
+
}
|
|
993
|
+
auto callbackFunction = value.asObject(rt).asFunction(rt);
|
|
994
|
+
auto callbackValue = std::make_shared<jsi::Value>(rt, callbackFunction);
|
|
995
|
+
rsLambda = [&rt, callInvoker, callbackValue](uint64_t rs_handle) {
|
|
996
|
+
// We immediately make a lambda which will do the work of transforming the
|
|
997
|
+
// arguments into JSI values and calling the callback.
|
|
998
|
+
uniffi_runtime::UniffiCallFunc jsLambda =
|
|
999
|
+
[callInvoker, callbackValue, rs_handle](jsi::Runtime &rt) mutable {
|
|
1000
|
+
body(rt, callInvoker, callbackValue, rs_handle);
|
|
1001
|
+
};
|
|
1002
|
+
// We'll then call that lambda from the callInvoker which will
|
|
1003
|
+
// look after calling it on the correct thread.
|
|
1004
|
+
|
|
1005
|
+
callInvoker->invokeNonBlocking(rt, jsLambda);
|
|
1006
|
+
};
|
|
1007
|
+
return callback;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
// This method is called from the destructor of NativeNobodywho, which only
|
|
1011
|
+
// happens when the jsi::Runtime is being destroyed.
|
|
1012
|
+
static void cleanup() {
|
|
1013
|
+
// The lambda holds a reference to the the Runtime, so when this is nulled
|
|
1014
|
+
// out, then the pointer will no longer be left dangling.
|
|
1015
|
+
rsLambda = nullptr;
|
|
1016
|
+
}
|
|
1017
|
+
} // namespace
|
|
1018
|
+
// uniffi::nobodywho::st::vtablecallbackinterfacerustdownloadprogresscallback::vtablecallbackinterfacerustdownloadprogresscallback::free
|
|
1019
|
+
|
|
893
1020
|
// Callback function:
|
|
894
1021
|
// uniffi::nobodywho::st::vtablecallbackinterfacerusttoolcallback::vtablecallbackinterfacerusttoolcallback::free::UniffiCallbackInterfaceFree
|
|
895
1022
|
//
|
|
@@ -1822,6 +1949,314 @@ template <> struct Bridging<UniffiForeignFutureCompleteVoid> {
|
|
|
1822
1949
|
return jsi::Value::undefined();
|
|
1823
1950
|
}
|
|
1824
1951
|
};
|
|
1952
|
+
} // namespace uniffi::nobodywho
|
|
1953
|
+
// Implementation of CallbackInterfaceClone for vtable field uniffi_clone in
|
|
1954
|
+
// VTableCallbackInterfaceRustDownloadProgressCallback
|
|
1955
|
+
|
|
1956
|
+
// Callback function:
|
|
1957
|
+
// uniffi::nobodywho::cb::callbackinterfaceclone::vtablecallbackinterfacerustdownloadprogresscallback::UniffiCallbackInterfaceClone
|
|
1958
|
+
//
|
|
1959
|
+
// We have the following constraints:
|
|
1960
|
+
// - we need to pass a function pointer to Rust.
|
|
1961
|
+
// - we need a jsi::Runtime and jsi::Function to call into JS.
|
|
1962
|
+
// - function pointers can't store state, so we can't use a lamda.
|
|
1963
|
+
//
|
|
1964
|
+
// For this, we store a lambda as a global, as `rsLambda`. The `callback`
|
|
1965
|
+
// function calls the lambda, which itself calls the `body` which then calls
|
|
1966
|
+
// into JS.
|
|
1967
|
+
//
|
|
1968
|
+
// We then give the `callback` function pointer to Rust which will call the
|
|
1969
|
+
// lambda sometime in the future.
|
|
1970
|
+
namespace uniffi::nobodywho::cb::callbackinterfaceclone::
|
|
1971
|
+
vtablecallbackinterfacerustdownloadprogresscallback {
|
|
1972
|
+
using namespace facebook;
|
|
1973
|
+
|
|
1974
|
+
// We need to store a lambda in a global so we can call it from
|
|
1975
|
+
// a function pointer. The function pointer is passed to Rust.
|
|
1976
|
+
static std::function<void(uint64_t, uint64_t *)> rsLambda = nullptr;
|
|
1977
|
+
|
|
1978
|
+
// This is the main body of the callback. It's called from the lambda,
|
|
1979
|
+
// which itself is called from the callback function which is passed to Rust.
|
|
1980
|
+
static void body(jsi::Runtime &rt,
|
|
1981
|
+
std::shared_ptr<uniffi_runtime::UniffiCallInvoker> callInvoker,
|
|
1982
|
+
std::shared_ptr<jsi::Value> callbackValue, uint64_t rs_handle,
|
|
1983
|
+
uint64_t *uniffi_direct_return) {
|
|
1984
|
+
|
|
1985
|
+
// Convert the arguments from Rust, into jsi::Values.
|
|
1986
|
+
// We'll use the Bridging class to do this…
|
|
1987
|
+
auto js_handle =
|
|
1988
|
+
uniffi_jsi::Bridging<uint64_t>::toJs(rt, callInvoker, rs_handle);
|
|
1989
|
+
|
|
1990
|
+
// Now we are ready to call the callback.
|
|
1991
|
+
// We are already on the JS thread, because this `body` function was
|
|
1992
|
+
// invoked from the CallInvoker.
|
|
1993
|
+
try {
|
|
1994
|
+
// Getting the callback function
|
|
1995
|
+
auto cb = callbackValue->asObject(rt).asFunction(rt);
|
|
1996
|
+
auto uniffiResult = cb.call(rt, js_handle);
|
|
1997
|
+
|
|
1998
|
+
// Write the direct return value back to the caller.
|
|
1999
|
+
if (uniffi_direct_return != nullptr) {
|
|
2000
|
+
*uniffi_direct_return =
|
|
2001
|
+
uniffi_jsi::Bridging<uint64_t>::fromJs(rt, callInvoker, uniffiResult);
|
|
2002
|
+
}
|
|
2003
|
+
} catch (const jsi::JSError &error) {
|
|
2004
|
+
std::cout << "Error in callback UniffiCallbackInterfaceClone: "
|
|
2005
|
+
<< error.what() << std::endl;
|
|
2006
|
+
throw error;
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
static uint64_t callback(uint64_t rs_handle) {
|
|
2011
|
+
// If the runtime has shutdown, then there is no point in trying to
|
|
2012
|
+
// call into Javascript. BUT how do we tell if the runtime has shutdown?
|
|
2013
|
+
//
|
|
2014
|
+
// Answer: the module destructor calls into callback `cleanup` method,
|
|
2015
|
+
// which nulls out the rsLamda.
|
|
2016
|
+
//
|
|
2017
|
+
// If rsLamda is null, then there is no runtime to call into.
|
|
2018
|
+
if (rsLambda == nullptr) {
|
|
2019
|
+
// This only occurs when destructors are calling into Rust free/drop,
|
|
2020
|
+
// which causes the JS callback to be dropped.
|
|
2021
|
+
return 0;
|
|
2022
|
+
}
|
|
2023
|
+
uint64_t uniffi_result = 0;
|
|
2024
|
+
|
|
2025
|
+
// The runtime, the actual callback jsi::funtion, and the callInvoker
|
|
2026
|
+
// are all in the lambda.
|
|
2027
|
+
rsLambda(rs_handle, &uniffi_result);
|
|
2028
|
+
return uniffi_result;
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
[[maybe_unused]] static UniffiCallbackInterfaceClone
|
|
2032
|
+
makeCallbackFunction( // uniffi::nobodywho::cb::callbackinterfaceclone::vtablecallbackinterfacerustdownloadprogresscallback
|
|
2033
|
+
jsi::Runtime &rt,
|
|
2034
|
+
std::shared_ptr<uniffi_runtime::UniffiCallInvoker> callInvoker,
|
|
2035
|
+
const jsi::Value &value) {
|
|
2036
|
+
if (rsLambda != nullptr) {
|
|
2037
|
+
// `makeCallbackFunction` is called in two circumstances:
|
|
2038
|
+
//
|
|
2039
|
+
// 1. at startup, when initializing callback interface vtables.
|
|
2040
|
+
// 2. when polling futures. This happens at least once per future that is
|
|
2041
|
+
// exposed to Javascript. We know that this is always the same function,
|
|
2042
|
+
// `uniffiFutureContinuationCallback` in `async-rust-calls.ts`.
|
|
2043
|
+
//
|
|
2044
|
+
// We can therefore return the callback function without making anything
|
|
2045
|
+
// new if we've been initialized already.
|
|
2046
|
+
return callback;
|
|
2047
|
+
}
|
|
2048
|
+
auto callbackFunction = value.asObject(rt).asFunction(rt);
|
|
2049
|
+
auto callbackValue = std::make_shared<jsi::Value>(rt, callbackFunction);
|
|
2050
|
+
rsLambda = [&rt, callInvoker, callbackValue](uint64_t rs_handle,
|
|
2051
|
+
uint64_t *uniffi_direct_return) {
|
|
2052
|
+
// We immediately make a lambda which will do the work of transforming the
|
|
2053
|
+
// arguments into JSI values and calling the callback.
|
|
2054
|
+
uniffi_runtime::UniffiCallFunc jsLambda =
|
|
2055
|
+
[callInvoker, callbackValue, rs_handle,
|
|
2056
|
+
uniffi_direct_return](jsi::Runtime &rt) mutable {
|
|
2057
|
+
body(rt, callInvoker, callbackValue, rs_handle, uniffi_direct_return);
|
|
2058
|
+
};
|
|
2059
|
+
// We'll then call that lambda from the callInvoker which will
|
|
2060
|
+
// look after calling it on the correct thread.
|
|
2061
|
+
callInvoker->invokeBlocking(rt, jsLambda);
|
|
2062
|
+
};
|
|
2063
|
+
return callback;
|
|
2064
|
+
}
|
|
2065
|
+
|
|
2066
|
+
// This method is called from the destructor of NativeNobodywho, which only
|
|
2067
|
+
// happens when the jsi::Runtime is being destroyed.
|
|
2068
|
+
static void cleanup() {
|
|
2069
|
+
// The lambda holds a reference to the the Runtime, so when this is nulled
|
|
2070
|
+
// out, then the pointer will no longer be left dangling.
|
|
2071
|
+
rsLambda = nullptr;
|
|
2072
|
+
}
|
|
2073
|
+
} // namespace
|
|
2074
|
+
// uniffi::nobodywho::cb::callbackinterfaceclone::vtablecallbackinterfacerustdownloadprogresscallback
|
|
2075
|
+
// Implementation of CallbackInterfaceRustDownloadProgressCallbackMethod0 for
|
|
2076
|
+
// vtable field on_download_progress in
|
|
2077
|
+
// VTableCallbackInterfaceRustDownloadProgressCallback
|
|
2078
|
+
|
|
2079
|
+
// Callback function:
|
|
2080
|
+
// uniffi::nobodywho::cb::callbackinterfacerustdownloadprogresscallbackmethod0::vtablecallbackinterfacerustdownloadprogresscallback::UniffiCallbackInterfaceRustDownloadProgressCallbackMethod0
|
|
2081
|
+
//
|
|
2082
|
+
// We have the following constraints:
|
|
2083
|
+
// - we need to pass a function pointer to Rust.
|
|
2084
|
+
// - we need a jsi::Runtime and jsi::Function to call into JS.
|
|
2085
|
+
// - function pointers can't store state, so we can't use a lamda.
|
|
2086
|
+
//
|
|
2087
|
+
// For this, we store a lambda as a global, as `rsLambda`. The `callback`
|
|
2088
|
+
// function calls the lambda, which itself calls the `body` which then calls
|
|
2089
|
+
// into JS.
|
|
2090
|
+
//
|
|
2091
|
+
// We then give the `callback` function pointer to Rust which will call the
|
|
2092
|
+
// lambda sometime in the future.
|
|
2093
|
+
namespace uniffi::nobodywho::cb::
|
|
2094
|
+
callbackinterfacerustdownloadprogresscallbackmethod0::
|
|
2095
|
+
vtablecallbackinterfacerustdownloadprogresscallback {
|
|
2096
|
+
using namespace facebook;
|
|
2097
|
+
|
|
2098
|
+
// We need to store a lambda in a global so we can call it from
|
|
2099
|
+
// a function pointer. The function pointer is passed to Rust.
|
|
2100
|
+
static std::function<void(uint64_t, uint64_t, uint64_t, void *,
|
|
2101
|
+
RustCallStatus *)>
|
|
2102
|
+
rsLambda = nullptr;
|
|
2103
|
+
|
|
2104
|
+
// This is the main body of the callback. It's called from the lambda,
|
|
2105
|
+
// which itself is called from the callback function which is passed to Rust.
|
|
2106
|
+
static void body(jsi::Runtime &rt,
|
|
2107
|
+
std::shared_ptr<uniffi_runtime::UniffiCallInvoker> callInvoker,
|
|
2108
|
+
std::shared_ptr<jsi::Value> callbackValue,
|
|
2109
|
+
uint64_t rs_uniffiHandle, uint64_t rs_downloaded,
|
|
2110
|
+
uint64_t rs_total, void *rs_uniffiOutReturn,
|
|
2111
|
+
RustCallStatus *uniffi_call_status) {
|
|
2112
|
+
|
|
2113
|
+
// Convert the arguments from Rust, into jsi::Values.
|
|
2114
|
+
// We'll use the Bridging class to do this…
|
|
2115
|
+
auto js_uniffiHandle =
|
|
2116
|
+
uniffi_jsi::Bridging<uint64_t>::toJs(rt, callInvoker, rs_uniffiHandle);
|
|
2117
|
+
auto js_downloaded =
|
|
2118
|
+
uniffi_jsi::Bridging<uint64_t>::toJs(rt, callInvoker, rs_downloaded);
|
|
2119
|
+
auto js_total =
|
|
2120
|
+
uniffi_jsi::Bridging<uint64_t>::toJs(rt, callInvoker, rs_total);
|
|
2121
|
+
|
|
2122
|
+
// Now we are ready to call the callback.
|
|
2123
|
+
// We are already on the JS thread, because this `body` function was
|
|
2124
|
+
// invoked from the CallInvoker.
|
|
2125
|
+
try {
|
|
2126
|
+
// Getting the callback function
|
|
2127
|
+
auto cb = callbackValue->asObject(rt).asFunction(rt);
|
|
2128
|
+
auto uniffiResult = cb.call(rt, js_uniffiHandle, js_downloaded, js_total);
|
|
2129
|
+
|
|
2130
|
+
// Now copy the result back from JS into the RustCallStatus object.
|
|
2131
|
+
uniffi::nobodywho::Bridging<RustCallStatus>::copyFromJs(
|
|
2132
|
+
rt, callInvoker, uniffiResult, uniffi_call_status);
|
|
2133
|
+
|
|
2134
|
+
if (uniffi_call_status->code != UNIFFI_CALL_STATUS_OK) {
|
|
2135
|
+
// The JS callback finished abnormally, so we cannot retrieve the return
|
|
2136
|
+
// value.
|
|
2137
|
+
return;
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
} catch (const jsi::JSError &error) {
|
|
2141
|
+
std::cout << "Error in callback "
|
|
2142
|
+
"UniffiCallbackInterfaceRustDownloadProgressCallbackMethod0: "
|
|
2143
|
+
<< error.what() << std::endl;
|
|
2144
|
+
throw error;
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
|
|
2148
|
+
static void callback(uint64_t rs_uniffiHandle, uint64_t rs_downloaded,
|
|
2149
|
+
uint64_t rs_total, void *rs_uniffiOutReturn,
|
|
2150
|
+
RustCallStatus *uniffi_call_status) {
|
|
2151
|
+
// If the runtime has shutdown, then there is no point in trying to
|
|
2152
|
+
// call into Javascript. BUT how do we tell if the runtime has shutdown?
|
|
2153
|
+
//
|
|
2154
|
+
// Answer: the module destructor calls into callback `cleanup` method,
|
|
2155
|
+
// which nulls out the rsLamda.
|
|
2156
|
+
//
|
|
2157
|
+
// If rsLamda is null, then there is no runtime to call into.
|
|
2158
|
+
if (rsLambda == nullptr) {
|
|
2159
|
+
// This only occurs when destructors are calling into Rust free/drop,
|
|
2160
|
+
// which causes the JS callback to be dropped.
|
|
2161
|
+
return;
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
// The runtime, the actual callback jsi::funtion, and the callInvoker
|
|
2165
|
+
// are all in the lambda.
|
|
2166
|
+
rsLambda(rs_uniffiHandle, rs_downloaded, rs_total, rs_uniffiOutReturn,
|
|
2167
|
+
uniffi_call_status);
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2170
|
+
[[maybe_unused]] static UniffiCallbackInterfaceRustDownloadProgressCallbackMethod0
|
|
2171
|
+
makeCallbackFunction( // uniffi::nobodywho::cb::callbackinterfacerustdownloadprogresscallbackmethod0::vtablecallbackinterfacerustdownloadprogresscallback
|
|
2172
|
+
jsi::Runtime &rt,
|
|
2173
|
+
std::shared_ptr<uniffi_runtime::UniffiCallInvoker> callInvoker,
|
|
2174
|
+
const jsi::Value &value) {
|
|
2175
|
+
if (rsLambda != nullptr) {
|
|
2176
|
+
// `makeCallbackFunction` is called in two circumstances:
|
|
2177
|
+
//
|
|
2178
|
+
// 1. at startup, when initializing callback interface vtables.
|
|
2179
|
+
// 2. when polling futures. This happens at least once per future that is
|
|
2180
|
+
// exposed to Javascript. We know that this is always the same function,
|
|
2181
|
+
// `uniffiFutureContinuationCallback` in `async-rust-calls.ts`.
|
|
2182
|
+
//
|
|
2183
|
+
// We can therefore return the callback function without making anything
|
|
2184
|
+
// new if we've been initialized already.
|
|
2185
|
+
return callback;
|
|
2186
|
+
}
|
|
2187
|
+
auto callbackFunction = value.asObject(rt).asFunction(rt);
|
|
2188
|
+
auto callbackValue = std::make_shared<jsi::Value>(rt, callbackFunction);
|
|
2189
|
+
rsLambda = [&rt, callInvoker,
|
|
2190
|
+
callbackValue](uint64_t rs_uniffiHandle, uint64_t rs_downloaded,
|
|
2191
|
+
uint64_t rs_total, void *rs_uniffiOutReturn,
|
|
2192
|
+
RustCallStatus *uniffi_call_status) {
|
|
2193
|
+
// We immediately make a lambda which will do the work of transforming the
|
|
2194
|
+
// arguments into JSI values and calling the callback.
|
|
2195
|
+
uniffi_runtime::UniffiCallFunc jsLambda =
|
|
2196
|
+
[callInvoker, callbackValue, rs_uniffiHandle, rs_downloaded, rs_total,
|
|
2197
|
+
rs_uniffiOutReturn, uniffi_call_status](jsi::Runtime &rt) mutable {
|
|
2198
|
+
body(rt, callInvoker, callbackValue, rs_uniffiHandle, rs_downloaded,
|
|
2199
|
+
rs_total, rs_uniffiOutReturn, uniffi_call_status);
|
|
2200
|
+
};
|
|
2201
|
+
// We'll then call that lambda from the callInvoker which will
|
|
2202
|
+
// look after calling it on the correct thread.
|
|
2203
|
+
callInvoker->invokeBlocking(rt, jsLambda);
|
|
2204
|
+
};
|
|
2205
|
+
return callback;
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
// This method is called from the destructor of NativeNobodywho, which only
|
|
2209
|
+
// happens when the jsi::Runtime is being destroyed.
|
|
2210
|
+
static void cleanup() {
|
|
2211
|
+
// The lambda holds a reference to the the Runtime, so when this is nulled
|
|
2212
|
+
// out, then the pointer will no longer be left dangling.
|
|
2213
|
+
rsLambda = nullptr;
|
|
2214
|
+
}
|
|
2215
|
+
} // namespace
|
|
2216
|
+
// uniffi::nobodywho::cb::callbackinterfacerustdownloadprogresscallbackmethod0::vtablecallbackinterfacerustdownloadprogresscallback
|
|
2217
|
+
namespace uniffi::nobodywho {
|
|
2218
|
+
using namespace facebook;
|
|
2219
|
+
using CallInvoker = uniffi_runtime::UniffiCallInvoker;
|
|
2220
|
+
|
|
2221
|
+
template <>
|
|
2222
|
+
struct Bridging<UniffiVTableCallbackInterfaceRustDownloadProgressCallback> {
|
|
2223
|
+
static UniffiVTableCallbackInterfaceRustDownloadProgressCallback
|
|
2224
|
+
fromJs(jsi::Runtime &rt, std::shared_ptr<CallInvoker> callInvoker,
|
|
2225
|
+
const jsi::Value &jsValue) {
|
|
2226
|
+
// Check if the input is an object
|
|
2227
|
+
if (!jsValue.isObject()) {
|
|
2228
|
+
throw jsi::JSError(
|
|
2229
|
+
rt, "Expected an object for "
|
|
2230
|
+
"UniffiVTableCallbackInterfaceRustDownloadProgressCallback");
|
|
2231
|
+
}
|
|
2232
|
+
|
|
2233
|
+
// Get the object from the jsi::Value
|
|
2234
|
+
auto jsObject = jsValue.getObject(rt);
|
|
2235
|
+
|
|
2236
|
+
// Create the vtable struct
|
|
2237
|
+
UniffiVTableCallbackInterfaceRustDownloadProgressCallback rsObject;
|
|
2238
|
+
|
|
2239
|
+
// Create the vtable from the js callbacks.
|
|
2240
|
+
rsObject.uniffi_free = uniffi::nobodywho::st::
|
|
2241
|
+
vtablecallbackinterfacerustdownloadprogresscallback::
|
|
2242
|
+
vtablecallbackinterfacerustdownloadprogresscallback::free::
|
|
2243
|
+
makeCallbackFunction(rt, callInvoker,
|
|
2244
|
+
jsObject.getProperty(rt, "uniffiFree"));
|
|
2245
|
+
rsObject.uniffi_clone = uniffi::nobodywho::cb::callbackinterfaceclone::
|
|
2246
|
+
vtablecallbackinterfacerustdownloadprogresscallback::
|
|
2247
|
+
makeCallbackFunction(rt, callInvoker,
|
|
2248
|
+
jsObject.getProperty(rt, "uniffiClone"));
|
|
2249
|
+
rsObject.on_download_progress = uniffi::nobodywho::cb::
|
|
2250
|
+
callbackinterfacerustdownloadprogresscallbackmethod0::
|
|
2251
|
+
vtablecallbackinterfacerustdownloadprogresscallback::
|
|
2252
|
+
makeCallbackFunction(
|
|
2253
|
+
rt, callInvoker,
|
|
2254
|
+
jsObject.getProperty(rt, "onDownloadProgress"));
|
|
2255
|
+
|
|
2256
|
+
return rsObject;
|
|
2257
|
+
}
|
|
2258
|
+
};
|
|
2259
|
+
|
|
1825
2260
|
} // namespace uniffi::nobodywho
|
|
1826
2261
|
// Implementation of CallbackInterfaceClone for vtable field uniffi_clone in
|
|
1827
2262
|
// VTableCallbackInterfaceRustToolCallback
|
|
@@ -2886,6 +3321,19 @@ NativeNobodywho::NativeNobodywho(
|
|
|
2886
3321
|
->cpp_uniffi_nobodywho_uniffi_fn_method_samplerconfig_to_json(
|
|
2887
3322
|
rt, thisVal, args, count);
|
|
2888
3323
|
});
|
|
3324
|
+
props["ubrn_uniffi_nobodywho_uniffi_fn_init_callback_vtable_"
|
|
3325
|
+
"rustdownloadprogresscallback"] = jsi::Function::createFromHostFunction(
|
|
3326
|
+
rt,
|
|
3327
|
+
jsi::PropNameID::forAscii(rt,
|
|
3328
|
+
"ubrn_uniffi_nobodywho_uniffi_fn_init_callback_"
|
|
3329
|
+
"vtable_rustdownloadprogresscallback"),
|
|
3330
|
+
1,
|
|
3331
|
+
[this](jsi::Runtime &rt, const jsi::Value &thisVal,
|
|
3332
|
+
const jsi::Value *args, size_t count) -> jsi::Value {
|
|
3333
|
+
return this
|
|
3334
|
+
->cpp_uniffi_nobodywho_uniffi_fn_init_callback_vtable_rustdownloadprogresscallback(
|
|
3335
|
+
rt, thisVal, args, count);
|
|
3336
|
+
});
|
|
2889
3337
|
props["ubrn_uniffi_nobodywho_uniffi_fn_init_callback_vtable_"
|
|
2890
3338
|
"rusttoolcallback"] = jsi::Function::createFromHostFunction(
|
|
2891
3339
|
rt,
|
|
@@ -2914,7 +3362,7 @@ NativeNobodywho::NativeNobodywho(
|
|
|
2914
3362
|
rt,
|
|
2915
3363
|
jsi::PropNameID::forAscii(
|
|
2916
3364
|
rt, "ubrn_uniffi_nobodywho_uniffi_fn_func_load_model"),
|
|
2917
|
-
|
|
3365
|
+
4,
|
|
2918
3366
|
[this](jsi::Runtime &rt, const jsi::Value &thisVal,
|
|
2919
3367
|
const jsi::Value *args, size_t count) -> jsi::Value {
|
|
2920
3368
|
return this->cpp_uniffi_nobodywho_uniffi_fn_func_load_model(
|
|
@@ -4188,6 +4636,20 @@ NativeNobodywho::NativeNobodywho(
|
|
|
4188
4636
|
->cpp_uniffi_nobodywho_uniffi_checksum_constructor_samplerconfig_from_json(
|
|
4189
4637
|
rt, thisVal, args, count);
|
|
4190
4638
|
});
|
|
4639
|
+
props["ubrn_uniffi_nobodywho_uniffi_checksum_method_"
|
|
4640
|
+
"rustdownloadprogresscallback_on_download_progress"] =
|
|
4641
|
+
jsi::Function::createFromHostFunction(
|
|
4642
|
+
rt,
|
|
4643
|
+
jsi::PropNameID::forAscii(
|
|
4644
|
+
rt, "ubrn_uniffi_nobodywho_uniffi_checksum_method_"
|
|
4645
|
+
"rustdownloadprogresscallback_on_download_progress"),
|
|
4646
|
+
0,
|
|
4647
|
+
[this](jsi::Runtime &rt, const jsi::Value &thisVal,
|
|
4648
|
+
const jsi::Value *args, size_t count) -> jsi::Value {
|
|
4649
|
+
return this
|
|
4650
|
+
->cpp_uniffi_nobodywho_uniffi_checksum_method_rustdownloadprogresscallback_on_download_progress(
|
|
4651
|
+
rt, thisVal, args, count);
|
|
4652
|
+
});
|
|
4191
4653
|
props["ubrn_uniffi_nobodywho_uniffi_checksum_method_rusttoolcallback_call"] =
|
|
4192
4654
|
jsi::Function::createFromHostFunction(
|
|
4193
4655
|
rt,
|
|
@@ -4352,8 +4814,14 @@ NativeNobodywho::~NativeNobodywho() {
|
|
|
4352
4814
|
// Cleanup for callback function ForeignFutureDroppedCallback
|
|
4353
4815
|
uniffi::nobodywho::cb::foreignfuturedroppedcallback::cleanup();
|
|
4354
4816
|
// Cleanup for "free" callback function CallbackInterfaceFree
|
|
4817
|
+
uniffi::nobodywho::st::vtablecallbackinterfacerustdownloadprogresscallback::
|
|
4818
|
+
vtablecallbackinterfacerustdownloadprogresscallback::free::cleanup();
|
|
4355
4819
|
uniffi::nobodywho::st::vtablecallbackinterfacerusttoolcallback::
|
|
4356
4820
|
vtablecallbackinterfacerusttoolcallback::free::cleanup();
|
|
4821
|
+
uniffi::nobodywho::cb::callbackinterfaceclone::
|
|
4822
|
+
vtablecallbackinterfacerustdownloadprogresscallback::cleanup();
|
|
4823
|
+
uniffi::nobodywho::cb::callbackinterfacerustdownloadprogresscallbackmethod0::
|
|
4824
|
+
vtablecallbackinterfacerustdownloadprogresscallback::cleanup();
|
|
4357
4825
|
uniffi::nobodywho::cb::callbackinterfaceclone::
|
|
4358
4826
|
vtablecallbackinterfacerusttoolcallback::cleanup();
|
|
4359
4827
|
uniffi::nobodywho::cb::callbackinterfacerusttoolcallbackmethod0::
|
|
@@ -5395,6 +5863,21 @@ NativeNobodywho::cpp_uniffi_nobodywho_uniffi_fn_method_samplerconfig_to_json(
|
|
|
5395
5863
|
|
|
5396
5864
|
return uniffi::nobodywho::Bridging<RustBuffer>::toJs(rt, callInvoker, value);
|
|
5397
5865
|
}
|
|
5866
|
+
jsi::Value NativeNobodywho::
|
|
5867
|
+
cpp_uniffi_nobodywho_uniffi_fn_init_callback_vtable_rustdownloadprogresscallback(
|
|
5868
|
+
jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
|
|
5869
|
+
size_t count) {
|
|
5870
|
+
auto vtableInstance = uniffi::nobodywho::Bridging<
|
|
5871
|
+
UniffiVTableCallbackInterfaceRustDownloadProgressCallback>::
|
|
5872
|
+
fromJs(rt, callInvoker, args[0]);
|
|
5873
|
+
|
|
5874
|
+
std::lock_guard<std::mutex> lock(uniffi::nobodywho::registry::vtableMutex);
|
|
5875
|
+
uniffi_nobodywho_uniffi_fn_init_callback_vtable_rustdownloadprogresscallback(
|
|
5876
|
+
uniffi::nobodywho::registry::putTable(
|
|
5877
|
+
"UniffiVTableCallbackInterfaceRustDownloadProgressCallback",
|
|
5878
|
+
vtableInstance));
|
|
5879
|
+
return jsi::Value::undefined();
|
|
5880
|
+
}
|
|
5398
5881
|
jsi::Value NativeNobodywho::
|
|
5399
5882
|
cpp_uniffi_nobodywho_uniffi_fn_init_callback_vtable_rusttoolcallback(
|
|
5400
5883
|
jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
|
|
@@ -5430,8 +5913,9 @@ jsi::Value NativeNobodywho::cpp_uniffi_nobodywho_uniffi_fn_func_load_model(
|
|
|
5430
5913
|
auto value = uniffi_nobodywho_uniffi_fn_func_load_model(
|
|
5431
5914
|
uniffi::nobodywho::Bridging<RustBuffer>::fromJs(rt, callInvoker, args[0]),
|
|
5432
5915
|
uniffi_jsi::Bridging<int8_t>::fromJs(rt, callInvoker, args[1]),
|
|
5916
|
+
uniffi::nobodywho::Bridging<RustBuffer>::fromJs(rt, callInvoker, args[2]),
|
|
5433
5917
|
uniffi::nobodywho::Bridging<RustBuffer>::fromJs(rt, callInvoker,
|
|
5434
|
-
args[
|
|
5918
|
+
args[3]));
|
|
5435
5919
|
|
|
5436
5920
|
return uniffi_jsi::Bridging</*handle*/ uint64_t>::toJs(rt, callInvoker,
|
|
5437
5921
|
value);
|
|
@@ -6539,6 +7023,15 @@ jsi::Value NativeNobodywho::
|
|
|
6539
7023
|
|
|
6540
7024
|
return uniffi_jsi::Bridging<uint16_t>::toJs(rt, callInvoker, value);
|
|
6541
7025
|
}
|
|
7026
|
+
jsi::Value NativeNobodywho::
|
|
7027
|
+
cpp_uniffi_nobodywho_uniffi_checksum_method_rustdownloadprogresscallback_on_download_progress(
|
|
7028
|
+
jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
|
|
7029
|
+
size_t count) {
|
|
7030
|
+
auto value =
|
|
7031
|
+
uniffi_nobodywho_uniffi_checksum_method_rustdownloadprogresscallback_on_download_progress();
|
|
7032
|
+
|
|
7033
|
+
return uniffi_jsi::Bridging<uint16_t>::toJs(rt, callInvoker, value);
|
|
7034
|
+
}
|
|
6542
7035
|
jsi::Value NativeNobodywho::
|
|
6543
7036
|
cpp_uniffi_nobodywho_uniffi_checksum_method_rusttoolcallback_call(
|
|
6544
7037
|
jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
|