@dittolive/ditto 4.6.0 → 4.7.0-rc.3
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/README.md +2 -2
- package/node/ditto.cjs.js +479 -128
- package/node/ditto.darwin-arm64.node +0 -0
- package/node/ditto.darwin-x64.node +0 -0
- package/node/ditto.linux-arm.node +0 -0
- package/node/ditto.linux-arm64.node +0 -0
- package/node/ditto.linux-x64.node +0 -0
- package/node/ditto.win32-x64.node +0 -0
- package/node/transports.darwin-arm64.node +0 -0
- package/node/transports.darwin-x64.node +0 -0
- package/package.json +1 -1
- package/react-native/android/.project +34 -0
- package/react-native/android/bin/.project +34 -0
- package/react-native/android/bin/src/main/java/com/dittolive/rnsdk/DittoRNSDKModule.class +0 -0
- package/react-native/android/bin/src/main/java/com/dittolive/rnsdk/DittoRNSDKPackage.class +0 -0
- package/react-native/android/build/intermediates/cxx/abi_configuration_4i3a4k2a.json +14 -0
- package/react-native/android/build/intermediates/cxx/abi_configuration_4i3a4k2a.log +1 -0
- package/react-native/android/build/intermediates/cxx/abi_configuration_4i3a4k2a_key.json +23 -0
- package/react-native/android/build/intermediates/cxx/create_cxx_tasks_371_timing.txt +5 -0
- package/react-native/android/build/intermediates/cxx/ndk_locator_record_4q2c3f1f.json +11 -0
- package/react-native/android/build/intermediates/cxx/ndk_locator_record_4q2c3f1f.log +72 -0
- package/react-native/android/build/intermediates/cxx/ndk_locator_record_4q2c3f1f_key.json +10 -0
- package/react-native/android/build.gradle +1 -1
- package/react-native/android/cpp-adapter.cpp +39 -43
- package/react-native/android/src/main/java/com/dittolive/rnsdk/DittoRNSDKModule.java +1 -1
- package/react-native/cpp/include/Arc.hpp +18 -0
- package/react-native/cpp/include/ConnectionRequest.h +18 -0
- package/react-native/cpp/include/FFIUtils.h +2 -0
- package/react-native/cpp/include/Misc.h +1 -1
- package/react-native/cpp/include/Presence.h +4 -0
- package/react-native/cpp/include/Utils.h +14 -3
- package/react-native/cpp/src/Attachment.cpp +5 -6
- package/react-native/cpp/src/Authentication.cpp +1 -1
- package/react-native/cpp/src/Collection.cpp +2 -0
- package/react-native/cpp/src/ConnectionRequest.cpp +123 -0
- package/react-native/cpp/src/DQL.cpp +1 -1
- package/react-native/cpp/src/FFIUtils.cpp +58 -0
- package/react-native/cpp/src/Identity.cpp +2 -3
- package/react-native/cpp/src/LiveQuery.cpp +3 -3
- package/react-native/cpp/src/Misc.cpp +14 -23
- package/react-native/cpp/src/Presence.cpp +87 -0
- package/react-native/cpp/src/Utils.cpp +104 -99
- package/react-native/cpp/src/main.cpp +15 -2
- package/react-native/dittoffi/dittoffi.h +375 -252
- package/react-native/ios/DittoRNSDK.mm +3 -3
- package/react-native/src/ditto.rn.ts +12 -4
- package/react-native/src/index.ts +2 -2
- package/react-native/src/sources/bridge.ts +6 -2
- package/react-native/src/sources/connection-request.ts +139 -0
- package/react-native/src/sources/ditto.ts +31 -28
- package/react-native/src/sources/epilogue.ts +4 -2
- package/react-native/src/sources/error-codes.ts +37 -3
- package/react-native/src/sources/error.ts +30 -1
- package/react-native/src/sources/essentials.ts +6 -0
- package/react-native/src/sources/ffi-error.ts +20 -9
- package/react-native/src/sources/ffi.ts +206 -111
- package/react-native/src/sources/main.ts +1 -0
- package/react-native/src/sources/pending-collections-operation.ts +1 -1
- package/react-native/src/sources/presence.ts +189 -0
- package/react-native/src/sources/query-result-item.ts +4 -4
- package/react-native/src/sources/query-result.ts +6 -6
- package/react-native/src/sources/small-peer-info.ts +1 -12
- package/react-native/src/sources/store-observer.ts +6 -15
- package/react-native/src/sources/store.ts +5 -13
- package/react-native/src/sources/sync.ts +2 -3
- package/types/ditto.d.ts +265 -28
- package/web/ditto.es6.js +1 -1
- package/web/ditto.umd.js +1 -1
- package/web/ditto.wasm +0 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#include "Utils.h"
|
|
2
|
+
#include "ConnectionRequest.h"
|
|
3
|
+
#include <unordered_map>
|
|
4
|
+
|
|
5
|
+
namespace sharedjsi
|
|
6
|
+
{
|
|
7
|
+
|
|
8
|
+
Function dittoffi_connection_request_peer_key_string(Runtime &runtime)
|
|
9
|
+
{
|
|
10
|
+
return Function::createFromHostFunction(runtime,
|
|
11
|
+
PropNameID::forAscii(runtime,
|
|
12
|
+
STRINGIFIED_FUNC_NAME()),
|
|
13
|
+
0,
|
|
14
|
+
[](Runtime &runtime,
|
|
15
|
+
const Value &thisValue,
|
|
16
|
+
const Value *arguments,
|
|
17
|
+
size_t count) -> Value
|
|
18
|
+
{
|
|
19
|
+
auto connection_request = jsPointerObjectToCPointer<dittoffi_connection_request_t>(runtime, arguments[0]);
|
|
20
|
+
char *res = ::dittoffi_connection_request_peer_key_string(connection_request);
|
|
21
|
+
return cPointerToJSPointerObject<char>(runtime, res);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
Function dittoffi_connection_request_peer_metadata_json(Runtime &runtime)
|
|
26
|
+
{
|
|
27
|
+
return Function::createFromHostFunction(runtime,
|
|
28
|
+
PropNameID::forAscii(runtime,
|
|
29
|
+
STRINGIFIED_FUNC_NAME()),
|
|
30
|
+
0,
|
|
31
|
+
[](Runtime &runtime,
|
|
32
|
+
const Value &thisValue,
|
|
33
|
+
const Value *arguments,
|
|
34
|
+
size_t count) -> Value
|
|
35
|
+
{
|
|
36
|
+
auto connection_request = jsPointerObjectToCPointer<dittoffi_connection_request_t>(runtime, arguments[0]);
|
|
37
|
+
slice_ref_uint8_t res = ::dittoffi_connection_request_peer_metadata_json(connection_request);
|
|
38
|
+
return cSlicedBoxToJSSlicedBox(runtime, res);
|
|
39
|
+
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
Function dittoffi_connection_request_identity_service_json(Runtime &runtime)
|
|
44
|
+
{
|
|
45
|
+
return Function::createFromHostFunction(runtime,
|
|
46
|
+
PropNameID::forAscii(runtime,
|
|
47
|
+
STRINGIFIED_FUNC_NAME()),
|
|
48
|
+
0,
|
|
49
|
+
[](Runtime &runtime,
|
|
50
|
+
const Value &thisValue,
|
|
51
|
+
const Value *arguments,
|
|
52
|
+
size_t count) -> Value
|
|
53
|
+
{
|
|
54
|
+
auto connection_request = jsPointerObjectToCPointer<dittoffi_connection_request_t>(runtime, arguments[0]);
|
|
55
|
+
slice_ref_uint8_t res = ::dittoffi_connection_request_identity_service_metadata_json(connection_request);
|
|
56
|
+
return cSlicedBoxToJSSlicedBox(runtime, res);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
Function dittoffi_connection_request_authorize(Runtime &runtime)
|
|
61
|
+
{
|
|
62
|
+
return Function::createFromHostFunction(runtime,
|
|
63
|
+
PropNameID::forAscii(runtime,
|
|
64
|
+
STRINGIFIED_FUNC_NAME()),
|
|
65
|
+
0,
|
|
66
|
+
[](Runtime &runtime,
|
|
67
|
+
const Value &thisValue,
|
|
68
|
+
const Value *arguments,
|
|
69
|
+
size_t count) -> Value
|
|
70
|
+
{
|
|
71
|
+
auto connection_request = jsPointerObjectToCPointer<dittoffi_connection_request_t>(runtime, arguments[0]);
|
|
72
|
+
auto authorized_string = arguments[1].toString(runtime).utf8(runtime);
|
|
73
|
+
auto authorized = authorized_string == "Allow" ? DITTOFFI_CONNECTION_REQUEST_AUTHORIZATION_ALLOW : DITTOFFI_CONNECTION_REQUEST_AUTHORIZATION_DENY;
|
|
74
|
+
|
|
75
|
+
::dittoffi_connection_request_authorize(connection_request, authorized);
|
|
76
|
+
return Value();
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
Function dittoffi_connection_request_connection_type(Runtime &runtime)
|
|
81
|
+
{
|
|
82
|
+
return Function::createFromHostFunction(runtime,
|
|
83
|
+
PropNameID::forAscii(runtime,
|
|
84
|
+
STRINGIFIED_FUNC_NAME()),
|
|
85
|
+
0,
|
|
86
|
+
[](Runtime &runtime,
|
|
87
|
+
const Value &thisValue,
|
|
88
|
+
const Value *arguments,
|
|
89
|
+
size_t count) -> Value
|
|
90
|
+
{
|
|
91
|
+
dittoffi_connection_type_t res = ::dittoffi_connection_request_connection_type(jsPointerObjectToCPointer<dittoffi_connection_request_t>(runtime, arguments[0]));
|
|
92
|
+
|
|
93
|
+
static const std::unordered_map<dittoffi_connection_type_t, std::string> lookup = {
|
|
94
|
+
{DITTOFFI_CONNECTION_TYPE_BLUETOOTH, "Bluetooth"},
|
|
95
|
+
{DITTOFFI_CONNECTION_TYPE_ACCESS_POINT, "AccessPoint"},
|
|
96
|
+
{DITTOFFI_CONNECTION_TYPE_P2_P_WI_FI, "P2PWiFi"},
|
|
97
|
+
{DITTOFFI_CONNECTION_TYPE_WEB_SOCKET, "WebSocket"},
|
|
98
|
+
};
|
|
99
|
+
auto it = lookup.find(res);
|
|
100
|
+
if (it != lookup.end()) {
|
|
101
|
+
return String::createFromUtf8(runtime, it->second);
|
|
102
|
+
} else {
|
|
103
|
+
throw std::invalid_argument("Invalid dittoffi_connection_type_t type");
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
Function dittoffi_connection_request_free(Runtime &runtime)
|
|
109
|
+
{
|
|
110
|
+
return Function::createFromHostFunction(runtime,
|
|
111
|
+
PropNameID::forAscii(runtime,
|
|
112
|
+
STRINGIFIED_FUNC_NAME()),
|
|
113
|
+
0,
|
|
114
|
+
[](Runtime &runtime,
|
|
115
|
+
const Value &thisValue,
|
|
116
|
+
const Value *arguments,
|
|
117
|
+
size_t count) -> Value
|
|
118
|
+
{
|
|
119
|
+
::dittoffi_connection_request_free(jsPointerObjectToCPointer<dittoffi_connection_request_t>(runtime, arguments[0]));
|
|
120
|
+
return Value();
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -147,7 +147,7 @@ Function dittoffi_try_experimental_register_change_observer_str_detached(Runtime
|
|
|
147
147
|
v_change_handler_with_query_result);
|
|
148
148
|
|
|
149
149
|
Object obj(runtime);
|
|
150
|
-
obj.setProperty(runtime, "success",
|
|
150
|
+
obj.setProperty(runtime, "success", int64ToBigIntOrNumber(runtime, res.success));
|
|
151
151
|
obj.setProperty(runtime, "error", cPointerToJSPointerObject(runtime, res.error));
|
|
152
152
|
return obj;
|
|
153
153
|
});
|
|
@@ -15,6 +15,12 @@ Function refCStringToString(Runtime &runtime)
|
|
|
15
15
|
const Value *arguments,
|
|
16
16
|
size_t count) -> Value
|
|
17
17
|
{
|
|
18
|
+
char *str = jsPointerObjectToCPointer<char>(runtime, arguments[0]);
|
|
19
|
+
if (str) {
|
|
20
|
+
return String::createFromUtf8(runtime, str);
|
|
21
|
+
} else {
|
|
22
|
+
return Value::null();
|
|
23
|
+
}
|
|
18
24
|
return String::createFromUtf8(runtime, jsPointerObjectToCPointer<char>(runtime, arguments[0]));
|
|
19
25
|
});
|
|
20
26
|
}
|
|
@@ -40,6 +46,58 @@ Function boxCStringIntoString(Runtime &runtime) {
|
|
|
40
46
|
});
|
|
41
47
|
}
|
|
42
48
|
|
|
49
|
+
Function sliceRefToUInt8Array(Runtime &runtime) {
|
|
50
|
+
return Function::createFromHostFunction(runtime,
|
|
51
|
+
PropNameID::forAscii(runtime, STRINGIFIED_FUNC_NAME()),
|
|
52
|
+
0,
|
|
53
|
+
[](Runtime &runtime,
|
|
54
|
+
const Value &,
|
|
55
|
+
const Value *arguments,
|
|
56
|
+
size_t) -> Value {
|
|
57
|
+
auto fatPtrJs = arguments[0].asObject(runtime);
|
|
58
|
+
auto ptr = jsPointerObjectToCPointer<uint8_t>(runtime, fatPtrJs.getProperty(runtime, "ptr"));
|
|
59
|
+
auto len = static_cast<size_t>(fatPtrJs.getProperty(runtime, "len").asNumber());
|
|
60
|
+
|
|
61
|
+
slice_boxed_uint8 slice = {.ptr = ptr, .len = len};
|
|
62
|
+
if (!slice.ptr) {
|
|
63
|
+
return Value::null();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
TypedArray<TypedArrayKind::Uint8Array> typedArray(runtime, slice.len);
|
|
67
|
+
ArrayBuffer arrayBuffer = typedArray.getBuffer(runtime);
|
|
68
|
+
std::memcpy(arrayBuffer.data(runtime), slice.ptr, slice.len);
|
|
69
|
+
|
|
70
|
+
return typedArray;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
Function sliceBoxedToUInt8Array(Runtime &runtime) {
|
|
75
|
+
return Function::createFromHostFunction(runtime,
|
|
76
|
+
PropNameID::forAscii(runtime, STRINGIFIED_FUNC_NAME()),
|
|
77
|
+
0,
|
|
78
|
+
[](Runtime &runtime,
|
|
79
|
+
const Value &,
|
|
80
|
+
const Value *arguments,
|
|
81
|
+
size_t) -> Value {
|
|
82
|
+
auto fatPtrJs = arguments[0].asObject(runtime);
|
|
83
|
+
auto ptr = jsPointerObjectToCPointer<uint8_t>(runtime, fatPtrJs.getProperty(runtime, "ptr"));
|
|
84
|
+
auto len = static_cast<size_t>(fatPtrJs.getProperty(runtime, "len").asNumber());
|
|
85
|
+
|
|
86
|
+
slice_boxed_uint8 slice = {.ptr = ptr, .len = len};
|
|
87
|
+
if (!slice.ptr) {
|
|
88
|
+
return Value::null();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
TypedArray<TypedArrayKind::Uint8Array> typedArray(runtime, slice.len);
|
|
92
|
+
ArrayBuffer arrayBuffer = typedArray.getBuffer(runtime);
|
|
93
|
+
std::memcpy(arrayBuffer.data(runtime), slice.ptr, slice.len);
|
|
94
|
+
|
|
95
|
+
::ditto_c_bytes_free(slice);
|
|
96
|
+
|
|
97
|
+
return typedArray;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
43
101
|
Function withOutBoxCBytes(Runtime &runtime) {
|
|
44
102
|
return Function::createFromHostFunction(runtime,
|
|
45
103
|
PropNameID::forAscii(runtime,
|
|
@@ -49,7 +49,7 @@ Function ditto_identity_config_make_offline_playground(Runtime &runtime)
|
|
|
49
49
|
{
|
|
50
50
|
std::string app_id_str = jsTypedArrayToCString(runtime, arguments[0]);
|
|
51
51
|
const char *app_id = app_id_str.c_str();
|
|
52
|
-
uint64_t site_id = arguments[1]
|
|
52
|
+
uint64_t site_id = bigIntOrNumberToUint64(runtime, arguments[1]);
|
|
53
53
|
|
|
54
54
|
IdentityConfigResult_t config_result = ::ditto_identity_config_make_offline_playground(app_id, site_id);
|
|
55
55
|
return convertConfigResultToJSIObject(runtime, config_result);
|
|
@@ -91,8 +91,7 @@ Function ditto_identity_config_make_shared_key(Runtime &runtime)
|
|
|
91
91
|
|
|
92
92
|
std::string shared_key_str = jsTypedArrayToCString(runtime, arguments[1]);
|
|
93
93
|
const char *shared_key = shared_key_str.c_str();
|
|
94
|
-
|
|
95
|
-
uint64_t site_id = arguments[2].asBigInt(runtime).asUint64(runtime);
|
|
94
|
+
uint64_t site_id = bigIntOrNumberToUint64(runtime, arguments[2]);
|
|
96
95
|
|
|
97
96
|
IdentityConfigResult_t config_result = ::ditto_identity_config_make_shared_key(app_id, shared_key, site_id);
|
|
98
97
|
return convertConfigResultToJSIObject(runtime, config_result);
|
|
@@ -17,7 +17,7 @@ Function ditto_live_query_signal_available_next(Runtime &runtime)
|
|
|
17
17
|
size_t count) -> Value
|
|
18
18
|
{
|
|
19
19
|
CDitto_t *ditto = jsPointerObjectToCPointer<CDitto_t>(runtime, arguments[0]);
|
|
20
|
-
int64_t liveQueryId = arguments[1]
|
|
20
|
+
int64_t liveQueryId = bigIntOrNumberToInt64(runtime, arguments[1]);
|
|
21
21
|
|
|
22
22
|
::ditto_live_query_signal_available_next(ditto, liveQueryId);
|
|
23
23
|
return Value();
|
|
@@ -36,7 +36,7 @@ Function ditto_live_query_start(Runtime &runtime)
|
|
|
36
36
|
size_t count) -> Value
|
|
37
37
|
{
|
|
38
38
|
CDitto_t *ditto = jsPointerObjectToCPointer<CDitto_t>(runtime, arguments[0]);
|
|
39
|
-
int64_t liveQueryId = arguments[1]
|
|
39
|
+
int64_t liveQueryId = bigIntOrNumberToInt64(runtime, arguments[1]);
|
|
40
40
|
int32_t res = ::ditto_live_query_start(ditto, liveQueryId);
|
|
41
41
|
return static_cast<double>(res);
|
|
42
42
|
});
|
|
@@ -54,7 +54,7 @@ Function ditto_live_query_stop(Runtime &runtime)
|
|
|
54
54
|
size_t count) -> Value
|
|
55
55
|
{
|
|
56
56
|
CDitto_t *ditto = jsPointerObjectToCPointer<CDitto_t>(runtime, arguments[0]);
|
|
57
|
-
int64_t liveQueryId = arguments[1]
|
|
57
|
+
int64_t liveQueryId = bigIntOrNumberToInt64(runtime, arguments[1]);
|
|
58
58
|
|
|
59
59
|
::ditto_live_query_stop(ditto, liveQueryId);
|
|
60
60
|
return Value();
|
|
@@ -73,13 +73,22 @@ Function dittoffi_error_code(Runtime &runtime) {
|
|
|
73
73
|
{DITTOFFI_ERROR_CODE_DQL_QUERY_COMPILATION, "DqlQueryCompilation"},
|
|
74
74
|
{DITTOFFI_ERROR_CODE_DQL_INVALID_QUERY_ARGS, "DqlInvalidQueryArgs"},
|
|
75
75
|
{DITTOFFI_ERROR_CODE_DQL_UNSUPPORTED, "DqlUnsupported"},
|
|
76
|
+
{DITTOFFI_ERROR_CODE_VALIDATION_DEPTH_LIMIT_EXCEEDED, "ValidationDepthLimitExceeded"},
|
|
77
|
+
{DITTOFFI_ERROR_CODE_VALIDATION_NOT_A_MAP, "ValidationNotAMap"},
|
|
78
|
+
{DITTOFFI_ERROR_CODE_VALIDATION_SIZE_LIMIT_EXCEEDED, "ValidationSizeLimitExceeded"},
|
|
79
|
+
{DITTOFFI_ERROR_CODE_CBOR_INVALID, "ValidationInvalidCbor"},
|
|
80
|
+
{DITTOFFI_ERROR_CODE_VALIDATION_INVALID_JSON, "ValidationInvalidJson"},
|
|
81
|
+
{DITTOFFI_ERROR_CODE_ACTIVATION_NOT_ACTIVATED, "ActivationNotActivated"},
|
|
82
|
+
{DITTOFFI_ERROR_CODE_ACTIVATION_LICENSE_TOKEN_INVALID, "ActivationLicenseTokenInvalid"},
|
|
83
|
+
{DITTOFFI_ERROR_CODE_ACTIVATION_LICENSE_TOKEN_EXPIRED, "ActivationLicenseTokenExpired"},
|
|
84
|
+
{DITTOFFI_ERROR_CODE_ACTIVATION_LICENSE_UNSUPPORTED_FUTURE_VERSION, "ActivationLicenseUnsupportedFutureVersion"},
|
|
76
85
|
};
|
|
77
86
|
|
|
78
87
|
auto it = lookup.find(error_code);
|
|
79
88
|
if (it != lookup.end()) {
|
|
80
89
|
return String::createFromUtf8(runtime, it->second);
|
|
81
90
|
} else {
|
|
82
|
-
throw std::invalid_argument("
|
|
91
|
+
throw std::invalid_argument("Unknown error code.");
|
|
83
92
|
}
|
|
84
93
|
});
|
|
85
94
|
}
|
|
@@ -159,7 +168,7 @@ Function dittoffi_get_sdk_semver(Runtime &runtime) {
|
|
|
159
168
|
});
|
|
160
169
|
}
|
|
161
170
|
|
|
162
|
-
Function
|
|
171
|
+
Function dittoffi_try_verify_license(Runtime &runtime) {
|
|
163
172
|
return Function::createFromHostFunction(runtime,
|
|
164
173
|
PropNameID::forAscii(runtime,
|
|
165
174
|
STRINGIFIED_FUNC_NAME()),
|
|
@@ -169,29 +178,11 @@ Function ditto_verify_license(Runtime &runtime) {
|
|
|
169
178
|
const Value *arguments,
|
|
170
179
|
size_t count) -> Value
|
|
171
180
|
{
|
|
172
|
-
std::string license = arguments[0]
|
|
173
|
-
|
|
174
|
-
LicenseVerificationResult_t res = ::ditto_verify_license(license.c_str(), out_err_msg);
|
|
175
|
-
|
|
176
|
-
std::string result;
|
|
177
|
-
switch (res) {
|
|
178
|
-
case LICENSE_VERIFICATION_RESULT_LICENSE_OK:
|
|
179
|
-
result = "LicenseOk";
|
|
180
|
-
break;
|
|
181
|
-
case LICENSE_VERIFICATION_RESULT_VERIFICATION_FAILED:
|
|
182
|
-
result = "VerificationFailed";
|
|
183
|
-
break;
|
|
184
|
-
case LICENSE_VERIFICATION_RESULT_LICENSE_EXPIRED:
|
|
185
|
-
result = "LicenseExpired";
|
|
186
|
-
break;
|
|
187
|
-
case LICENSE_VERIFICATION_RESULT_UNSUPPORTED_FUTURE_VERSION:
|
|
188
|
-
result = "UnsupportedFutureVersion";
|
|
189
|
-
break;
|
|
190
|
-
}
|
|
181
|
+
std::string license = jsTypedArrayToCString(runtime, arguments[0]);
|
|
182
|
+
dittoffi_result_void_t res = ::dittoffi_try_verify_license(license.c_str());
|
|
191
183
|
|
|
192
184
|
Object obj(runtime);
|
|
193
|
-
obj.setProperty(runtime, "
|
|
194
|
-
obj.setProperty(runtime, "errorMessage", String::createFromUtf8(runtime, *out_err_msg));
|
|
185
|
+
obj.setProperty(runtime, "error", cPointerToJSPointerObject(runtime, res.error));
|
|
195
186
|
return obj;
|
|
196
187
|
});
|
|
197
188
|
}
|
|
@@ -7,6 +7,8 @@ namespace sharedjsi
|
|
|
7
7
|
{
|
|
8
8
|
|
|
9
9
|
DEFINE_RETAIN_RELEASE_FOR(Function, v_retain, v_release);
|
|
10
|
+
DEFINE_RETAIN_RELEASE_ERASED_T_FOR(Function, retain_vptr, release_vptr);
|
|
11
|
+
|
|
10
12
|
extern "C"
|
|
11
13
|
{
|
|
12
14
|
void v_presence_callback(void *ctx, char const *str)
|
|
@@ -18,6 +20,20 @@ void v_presence_callback(void *ctx, char const *str)
|
|
|
18
20
|
jsCallback->call(runtime, cPointerToJSPointerObject<char>(runtime, cpp_string.c_str()));
|
|
19
21
|
});
|
|
20
22
|
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
void v_connection_handler(Erased_t const* ctx, dittoffi_connection_request *ffi_request)
|
|
26
|
+
{
|
|
27
|
+
auto ptr = (void *)(ctx);
|
|
28
|
+
Arc<Function>& borrowedJsCallback = Arc<Function>::borrow_from_raw(ptr);
|
|
29
|
+
// copy ctor / retain so as to keep the ArcPointee<Function> alive until the enqueued_call completes.
|
|
30
|
+
Arc<Function> jsCallback /* = */ (borrowedJsCallback);
|
|
31
|
+
ditto_enqueue_call([=](Runtime *jsi) {
|
|
32
|
+
Runtime &runtime = *jsi;
|
|
33
|
+
auto obj = cPointerToJSPointerObject<dittoffi_connection_request_t>(runtime, ffi_request);
|
|
34
|
+
jsCallback->call(runtime, obj);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
21
37
|
}
|
|
22
38
|
|
|
23
39
|
Function ditto_presence_v3(Runtime &runtime)
|
|
@@ -76,4 +92,75 @@ Function ditto_clear_presence_v3_callback(Runtime &runtime)
|
|
|
76
92
|
});
|
|
77
93
|
}
|
|
78
94
|
|
|
95
|
+
Function dittoffi_presence_peer_metadata_json(Runtime &runtime)
|
|
96
|
+
{
|
|
97
|
+
return Function::createFromHostFunction(runtime,
|
|
98
|
+
PropNameID::forAscii(runtime,
|
|
99
|
+
STRINGIFIED_FUNC_NAME()),
|
|
100
|
+
0,
|
|
101
|
+
[](Runtime &runtime,
|
|
102
|
+
const Value &thisValue,
|
|
103
|
+
const Value *arguments,
|
|
104
|
+
size_t count) -> Value
|
|
105
|
+
{
|
|
106
|
+
slice_boxed_uint8_t res = ::dittoffi_presence_peer_metadata_json(jsPointerObjectToCPointer<CDitto_t>(runtime, arguments[0]));
|
|
107
|
+
return cSlicedBoxToJSSlicedBox(runtime, res);
|
|
108
|
+
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
Function dittoffi_presence_try_set_peer_metadata_json(Runtime &runtime)
|
|
113
|
+
{
|
|
114
|
+
return Function::createFromHostFunction(runtime,
|
|
115
|
+
PropNameID::forAscii(runtime,
|
|
116
|
+
STRINGIFIED_FUNC_NAME()),
|
|
117
|
+
0,
|
|
118
|
+
[](Runtime &runtime,
|
|
119
|
+
const Value &thisValue,
|
|
120
|
+
const Value *arguments,
|
|
121
|
+
size_t count) -> Value
|
|
122
|
+
{
|
|
123
|
+
CDitto_t *ditto = jsPointerObjectToCPointer<CDitto_t>(runtime, arguments[0]);
|
|
124
|
+
|
|
125
|
+
TypedArrayBase typedArrayBase(runtime, arguments[1].asObject(runtime));
|
|
126
|
+
std::vector<uint8_t> peer_info_vec = typedArrayBase.toVector(runtime);
|
|
127
|
+
slice_ref_uint8_t peer_info = { .ptr = peer_info_vec.data(), .len = peer_info_vec.size() };
|
|
128
|
+
|
|
129
|
+
dittoffi_result_void_t res = ::dittoffi_presence_try_set_peer_metadata_json(ditto, peer_info);
|
|
130
|
+
|
|
131
|
+
Object obj(runtime);
|
|
132
|
+
obj.setProperty(runtime, "error", cPointerToJSPointerObject(runtime, res.error));
|
|
133
|
+
return obj;
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
Function dittoffi_presence_set_connection_request_handler(Runtime &runtime)
|
|
139
|
+
{
|
|
140
|
+
return Function::createFromHostFunction(runtime,
|
|
141
|
+
PropNameID::forAscii(runtime,
|
|
142
|
+
STRINGIFIED_FUNC_NAME()),
|
|
143
|
+
0,
|
|
144
|
+
[](Runtime &runtime,
|
|
145
|
+
const Value &thisValue,
|
|
146
|
+
const Value *arguments,
|
|
147
|
+
size_t count) -> Value
|
|
148
|
+
{
|
|
149
|
+
CDitto_t *ditto = jsPointerObjectToCPointer<CDitto_t>(runtime, arguments[0]);
|
|
150
|
+
|
|
151
|
+
Function jsCallback = arguments[1].getObject(runtime).getFunction(runtime);
|
|
152
|
+
Arc<Function> wrappedStateFfiWrapper(std::move(jsCallback));
|
|
153
|
+
|
|
154
|
+
::dittoffi_presence_set_connection_request_handler(ditto, {
|
|
155
|
+
.ptr = (Erased_t *)Arc<Function>::into_raw(std::move(wrappedStateFfiWrapper)),
|
|
156
|
+
.vtable = {
|
|
157
|
+
.retain_vptr = retain_vptr,
|
|
158
|
+
.release_vptr = release_vptr,
|
|
159
|
+
.on_connecting = v_connection_handler,
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
return Value();
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
79
166
|
}
|
|
@@ -8,127 +8,132 @@
|
|
|
8
8
|
namespace sharedjsi
|
|
9
9
|
{
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
std::string pointerToHexString(void const *ptr)
|
|
12
|
+
{
|
|
13
|
+
char buffer[20]; // Assuming a 64-bit pointer, 16 characters for address + 2 for "0x" + 1 for null-terminator.
|
|
14
|
+
snprintf(buffer, sizeof(buffer), "%p", ptr);
|
|
15
|
+
return std::string(buffer);
|
|
16
|
+
}
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
// To be used with `Option<slice_ref_uint8_t> (check Rust Core API)
|
|
19
|
+
slice_ref_uint8_t borrowVecAsOptRefSlice(std::vector<uint8_t> const &v)
|
|
20
|
+
{
|
|
21
|
+
slice_ref_uint8_t it{};
|
|
22
|
+
it.ptr = v.empty() ? nullptr : v.data();
|
|
23
|
+
it.len = v.size();
|
|
24
|
+
return it;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// To be used with non-optional `slice_ref_uint8_t` (check Rust Core API)
|
|
28
|
+
slice_ref_uint8_t borrowVecAsRefSlice(std::vector<uint8_t> const &v)
|
|
29
|
+
{
|
|
30
|
+
slice_ref_uint8_t it{};
|
|
31
|
+
it.ptr = v.empty() ? (uint8_t *)0xbad000 : v.data();
|
|
32
|
+
it.len = v.size();
|
|
33
|
+
return it;
|
|
34
|
+
}
|
|
26
35
|
|
|
27
|
-
|
|
28
|
-
|
|
36
|
+
std::vector<uint8_t> jsTypedArrayToCVector(Runtime &runtime, const Value &arg)
|
|
37
|
+
{
|
|
38
|
+
if (arg.isUndefined() || arg.isNull())
|
|
29
39
|
{
|
|
30
|
-
|
|
31
|
-
it.ptr = v.empty() ? (uint8_t *)0xbad000 : v.data();
|
|
32
|
-
it.len = v.size();
|
|
33
|
-
return it;
|
|
40
|
+
return {};
|
|
34
41
|
}
|
|
42
|
+
TypedArrayBase typedArrayBase(runtime, arg.asObject(runtime));
|
|
43
|
+
return typedArrayBase.toVector(runtime);
|
|
44
|
+
}
|
|
35
45
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
{
|
|
53
|
-
return Value::null();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
auto typedArray = TypedArray<TypedArrayKind::Uint8Array>(runtime, slice.len);
|
|
57
|
-
auto arrayBuffer = typedArray.getBuffer(runtime);
|
|
58
|
-
std::memcpy(arrayBuffer.data(runtime), slice.ptr, slice.len);
|
|
59
|
-
|
|
60
|
-
::ditto_c_bytes_free(slice);
|
|
61
|
-
|
|
62
|
-
return typedArray;
|
|
63
|
-
});
|
|
46
|
+
std::string jsTypedArrayToCString(Runtime &runtime, const Value &arg)
|
|
47
|
+
{
|
|
48
|
+
std::vector<uint8_t> vec = jsTypedArrayToCVector(runtime, arg);
|
|
49
|
+
return std::string(vec.begin(), vec.end());
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
Value int64ToBigIntOrNumber(Runtime &runtime, int64_t value) {
|
|
55
|
+
constexpr int64_t jsMaxSafeInteger = (1LL << 53) - 1;
|
|
56
|
+
constexpr int64_t jsMinSafeInteger = -(1LL << 53) + 1;
|
|
57
|
+
|
|
58
|
+
if (jsMinSafeInteger <= value && value <= jsMaxSafeInteger) {
|
|
59
|
+
return static_cast<double>(value);
|
|
60
|
+
} else {
|
|
61
|
+
return BigInt::fromInt64(runtime, value);
|
|
64
62
|
}
|
|
63
|
+
}
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return typedArrayBase.toVector(runtime);
|
|
65
|
+
Value uint64ToBigIntOrNumber(Runtime &runtime, uint64_t value) {
|
|
66
|
+
constexpr uint64_t jsMaxSafeInteger = 1ULL << (53 - 1);
|
|
67
|
+
|
|
68
|
+
if (value <= jsMaxSafeInteger) {
|
|
69
|
+
return static_cast<double>(value);
|
|
70
|
+
} else {
|
|
71
|
+
return BigInt::fromUint64(runtime, value);
|
|
74
72
|
}
|
|
73
|
+
}
|
|
75
74
|
|
|
76
|
-
|
|
77
|
-
{
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
int64_t bigIntOrNumberToInt64(Runtime &runtime, Value const& value) {
|
|
76
|
+
if (value.isNumber()) {
|
|
77
|
+
return static_cast<int64_t>(value.asNumber());
|
|
78
|
+
} else if (value.isBigInt()) {
|
|
79
|
+
return value.asBigInt(runtime).asInt64(runtime);
|
|
80
|
+
} else {
|
|
81
|
+
throw jsi::JSError(runtime, "Expected a number or BigInt");
|
|
80
82
|
}
|
|
83
|
+
}
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
{
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
uint64_t bigIntOrNumberToUint64(Runtime &runtime, Value const& value) {
|
|
86
|
+
if (value.isNumber()) {
|
|
87
|
+
return static_cast<uint64_t>(value.asNumber());
|
|
88
|
+
} else if (value.isBigInt()) {
|
|
89
|
+
return value.asBigInt(runtime).asUint64(runtime);
|
|
90
|
+
} else {
|
|
91
|
+
throw jsi::JSError(runtime, "Expected a number or BigInt");
|
|
88
92
|
}
|
|
93
|
+
}
|
|
89
94
|
|
|
90
|
-
|
|
95
|
+
using Task = std::function<void(Runtime *)>;
|
|
91
96
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
struct
|
|
98
|
+
{
|
|
99
|
+
std::mutex mutex;
|
|
100
|
+
std::vector<Task> tasks;
|
|
101
|
+
// std::condition_variable condition;
|
|
102
|
+
} TASKS;
|
|
98
103
|
|
|
99
|
-
|
|
104
|
+
void ditto_enqueue_call(Task &&task)
|
|
105
|
+
{
|
|
106
|
+
std::unique_lock<std::mutex> lock{TASKS.mutex};
|
|
107
|
+
TASKS.tasks.emplace_back(task);
|
|
108
|
+
// TASKS.condition.notify_one();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
Task try_recv_task()
|
|
112
|
+
{
|
|
113
|
+
std::unique_lock<std::mutex> lock(TASKS.mutex);
|
|
114
|
+
// TASKS.condition.wait(lock, [] { return !TASKS.tasks.empty(); });
|
|
115
|
+
if (TASKS.tasks.empty())
|
|
100
116
|
{
|
|
101
|
-
|
|
102
|
-
TASKS.tasks.emplace_back(task);
|
|
103
|
-
// TASKS.condition.notify_one();
|
|
117
|
+
return nullptr;
|
|
104
118
|
}
|
|
119
|
+
Task task{std::move(TASKS.tasks.back())};
|
|
120
|
+
TASKS.tasks.pop_back();
|
|
121
|
+
return task;
|
|
122
|
+
}
|
|
105
123
|
|
|
106
|
-
|
|
124
|
+
void ditto_tick(Runtime *jsi)
|
|
125
|
+
{
|
|
126
|
+
while (1)
|
|
107
127
|
{
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (TASKS.tasks.empty())
|
|
128
|
+
Task task = try_recv_task();
|
|
129
|
+
if (task == nullptr)
|
|
111
130
|
{
|
|
112
|
-
return
|
|
131
|
+
return;
|
|
113
132
|
}
|
|
114
|
-
|
|
115
|
-
TASKS.tasks.pop_back();
|
|
116
|
-
return task;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
void ditto_tick(Runtime *jsi)
|
|
120
|
-
{
|
|
121
|
-
while (1)
|
|
133
|
+
else
|
|
122
134
|
{
|
|
123
|
-
|
|
124
|
-
if (task == nullptr)
|
|
125
|
-
{
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
else
|
|
129
|
-
{
|
|
130
|
-
task(jsi);
|
|
131
|
-
}
|
|
135
|
+
task(jsi);
|
|
132
136
|
}
|
|
133
137
|
}
|
|
134
138
|
}
|
|
139
|
+
}
|