@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.
Files changed (69) hide show
  1. package/README.md +2 -2
  2. package/node/ditto.cjs.js +479 -128
  3. package/node/ditto.darwin-arm64.node +0 -0
  4. package/node/ditto.darwin-x64.node +0 -0
  5. package/node/ditto.linux-arm.node +0 -0
  6. package/node/ditto.linux-arm64.node +0 -0
  7. package/node/ditto.linux-x64.node +0 -0
  8. package/node/ditto.win32-x64.node +0 -0
  9. package/node/transports.darwin-arm64.node +0 -0
  10. package/node/transports.darwin-x64.node +0 -0
  11. package/package.json +1 -1
  12. package/react-native/android/.project +34 -0
  13. package/react-native/android/bin/.project +34 -0
  14. package/react-native/android/bin/src/main/java/com/dittolive/rnsdk/DittoRNSDKModule.class +0 -0
  15. package/react-native/android/bin/src/main/java/com/dittolive/rnsdk/DittoRNSDKPackage.class +0 -0
  16. package/react-native/android/build/intermediates/cxx/abi_configuration_4i3a4k2a.json +14 -0
  17. package/react-native/android/build/intermediates/cxx/abi_configuration_4i3a4k2a.log +1 -0
  18. package/react-native/android/build/intermediates/cxx/abi_configuration_4i3a4k2a_key.json +23 -0
  19. package/react-native/android/build/intermediates/cxx/create_cxx_tasks_371_timing.txt +5 -0
  20. package/react-native/android/build/intermediates/cxx/ndk_locator_record_4q2c3f1f.json +11 -0
  21. package/react-native/android/build/intermediates/cxx/ndk_locator_record_4q2c3f1f.log +72 -0
  22. package/react-native/android/build/intermediates/cxx/ndk_locator_record_4q2c3f1f_key.json +10 -0
  23. package/react-native/android/build.gradle +1 -1
  24. package/react-native/android/cpp-adapter.cpp +39 -43
  25. package/react-native/android/src/main/java/com/dittolive/rnsdk/DittoRNSDKModule.java +1 -1
  26. package/react-native/cpp/include/Arc.hpp +18 -0
  27. package/react-native/cpp/include/ConnectionRequest.h +18 -0
  28. package/react-native/cpp/include/FFIUtils.h +2 -0
  29. package/react-native/cpp/include/Misc.h +1 -1
  30. package/react-native/cpp/include/Presence.h +4 -0
  31. package/react-native/cpp/include/Utils.h +14 -3
  32. package/react-native/cpp/src/Attachment.cpp +5 -6
  33. package/react-native/cpp/src/Authentication.cpp +1 -1
  34. package/react-native/cpp/src/Collection.cpp +2 -0
  35. package/react-native/cpp/src/ConnectionRequest.cpp +123 -0
  36. package/react-native/cpp/src/DQL.cpp +1 -1
  37. package/react-native/cpp/src/FFIUtils.cpp +58 -0
  38. package/react-native/cpp/src/Identity.cpp +2 -3
  39. package/react-native/cpp/src/LiveQuery.cpp +3 -3
  40. package/react-native/cpp/src/Misc.cpp +14 -23
  41. package/react-native/cpp/src/Presence.cpp +87 -0
  42. package/react-native/cpp/src/Utils.cpp +104 -99
  43. package/react-native/cpp/src/main.cpp +15 -2
  44. package/react-native/dittoffi/dittoffi.h +375 -252
  45. package/react-native/ios/DittoRNSDK.mm +3 -3
  46. package/react-native/src/ditto.rn.ts +12 -4
  47. package/react-native/src/index.ts +2 -2
  48. package/react-native/src/sources/bridge.ts +6 -2
  49. package/react-native/src/sources/connection-request.ts +139 -0
  50. package/react-native/src/sources/ditto.ts +31 -28
  51. package/react-native/src/sources/epilogue.ts +4 -2
  52. package/react-native/src/sources/error-codes.ts +37 -3
  53. package/react-native/src/sources/error.ts +30 -1
  54. package/react-native/src/sources/essentials.ts +6 -0
  55. package/react-native/src/sources/ffi-error.ts +20 -9
  56. package/react-native/src/sources/ffi.ts +206 -111
  57. package/react-native/src/sources/main.ts +1 -0
  58. package/react-native/src/sources/pending-collections-operation.ts +1 -1
  59. package/react-native/src/sources/presence.ts +189 -0
  60. package/react-native/src/sources/query-result-item.ts +4 -4
  61. package/react-native/src/sources/query-result.ts +6 -6
  62. package/react-native/src/sources/small-peer-info.ts +1 -12
  63. package/react-native/src/sources/store-observer.ts +6 -15
  64. package/react-native/src/sources/store.ts +5 -13
  65. package/react-native/src/sources/sync.ts +2 -3
  66. package/types/ditto.d.ts +265 -28
  67. package/web/ditto.es6.js +1 -1
  68. package/web/ditto.umd.js +1 -1
  69. 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", BigInt::fromInt64(runtime, res.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].asBigInt(runtime).asUint64(runtime);
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].asBigInt(runtime).asInt64(runtime);
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].asBigInt(runtime).asInt64(runtime);
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].asBigInt(runtime).asInt64(runtime);
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("Invalid error code");
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 ditto_verify_license(Runtime &runtime) {
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].toString(runtime).utf8(runtime);
173
- char **out_err_msg = NULL;
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, "result", String::createFromUtf8(runtime, result));
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
- 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
- }
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
- // 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
- }
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
- // 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)
36
+ std::vector<uint8_t> jsTypedArrayToCVector(Runtime &runtime, const Value &arg)
37
+ {
38
+ if (arg.isUndefined() || arg.isNull())
29
39
  {
30
- slice_ref_uint8_t it{};
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
- Function sliceBoxedToUInt8Array(Runtime &runtime)
37
- {
38
- return Function::createFromHostFunction(runtime,
39
- PropNameID::forAscii(runtime,
40
- STRINGIFIED_FUNC_NAME()),
41
- 0,
42
- [](Runtime &runtime,
43
- const Value &thisValue,
44
- const Value *arguments,
45
- size_t count) -> Value
46
- {
47
- auto fatPtrJs = arguments[0].asObject(runtime);
48
- auto ptr = jsPointerObjectToCPointer<uint8_t>(runtime, fatPtrJs.getProperty(runtime, "ptr"));
49
- auto len = static_cast<size_t>(fatPtrJs.getProperty(runtime, "len").asNumber());
50
- slice_boxed_uint8 slice = {.ptr = ptr, .len = len};
51
- if (!slice.ptr)
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
- std::vector<uint8_t> jsTypedArrayToCVector(Runtime &runtime, const Value &arg)
67
- {
68
- if (arg.isUndefined() || arg.isNull())
69
- {
70
- return {};
71
- }
72
- TypedArrayBase typedArrayBase(runtime, arg.asObject(runtime));
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
- std::string jsTypedArrayToCString(Runtime &runtime, const Value &arg)
77
- {
78
- std::vector<uint8_t> vec = jsTypedArrayToCVector(runtime, arg);
79
- return std::string(vec.begin(), vec.end());
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
- Value cSlicedBoxToJSSlicedBox(Runtime &runtime, slice_boxed_uint8 box_c_bytes)
83
- {
84
- Object obj(runtime);
85
- obj.setProperty(runtime, "ptr", cPointerToJSPointerObject<uint8_t>(runtime, box_c_bytes.ptr));
86
- obj.setProperty(runtime, "len", static_cast<double>(box_c_bytes.len));
87
- return obj;
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
- using Task = std::function<void(Runtime *)>;
95
+ using Task = std::function<void(Runtime *)>;
91
96
 
92
- struct
93
- {
94
- std::mutex mutex;
95
- std::vector<Task> tasks;
96
- // std::condition_variable condition;
97
- } TASKS;
97
+ struct
98
+ {
99
+ std::mutex mutex;
100
+ std::vector<Task> tasks;
101
+ // std::condition_variable condition;
102
+ } TASKS;
98
103
 
99
- void ditto_enqueue_call(Task &&task)
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
- std::unique_lock<std::mutex> lock{TASKS.mutex};
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
- Task try_recv_task()
124
+ void ditto_tick(Runtime *jsi)
125
+ {
126
+ while (1)
107
127
  {
108
- std::unique_lock<std::mutex> lock(TASKS.mutex);
109
- // TASKS.condition.wait(lock, [] { return !TASKS.tasks.empty(); });
110
- if (TASKS.tasks.empty())
128
+ Task task = try_recv_task();
129
+ if (task == nullptr)
111
130
  {
112
- return nullptr;
131
+ return;
113
132
  }
114
- Task task{std::move(TASKS.tasks.back())};
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
- Task task = try_recv_task();
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
+ }