@derec-alliance/react-native 0.0.5 → 0.0.7

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.
@@ -26,7 +26,16 @@ namespace {
26
26
  /// failure.
27
27
  struct FfiFailure {
28
28
  explicit FfiFailure(DeRecError e) : error(e) {}
29
+ FfiFailure(DeRecError e, std::vector<uint8_t> channelIdsJson)
30
+ : error(e), conflictingChannelIdsJson(std::move(channelIdsJson)) {}
31
+ FfiFailure(DeRecError e, ProcessFailureDetails details)
32
+ : error(e), process(std::move(details)) {}
29
33
  DeRecError error;
34
+ /// `restore`'s JSON array of colliding channel ids, empty for every other
35
+ /// failure. Carried as raw bytes: parsing needs the runtime.
36
+ std::vector<uint8_t> conflictingChannelIdsJson;
37
+ /// `process`'s events and failing channel, empty for every other failure.
38
+ ProcessFailureDetails process;
30
39
  };
31
40
 
32
41
  constexpr const char* kReentrancyMessage =
@@ -170,10 +179,14 @@ jsi::Value ProtocolHost::runAsync(
170
179
  bool failed = false;
171
180
  bool unknownFailure = false;
172
181
  DeRecError capturedError{};
182
+ std::vector<uint8_t> capturedChannelIdsJson;
183
+ ProcessFailureDetails capturedProcess;
173
184
  try {
174
185
  bytes = body();
175
- } catch (const FfiFailure& failure) {
186
+ } catch (FfiFailure& failure) {
176
187
  capturedError = failure.error;
188
+ capturedChannelIdsJson = std::move(failure.conflictingChannelIdsJson);
189
+ capturedProcess = std::move(failure.process);
177
190
  failed = true;
178
191
  } catch (...) {
179
192
  // Anything other than `FfiFailure` — `std::bad_alloc` from
@@ -198,7 +211,11 @@ jsi::Value ProtocolHost::runAsync(
198
211
 
199
212
  invoker->invokeAsync([state, runtime, resolve, reject, convert,
200
213
  bytes = std::move(bytes), failed,
201
- unknownFailure, capturedError]() mutable {
214
+ unknownFailure, capturedError,
215
+ capturedChannelIdsJson =
216
+ std::move(capturedChannelIdsJson),
217
+ capturedProcess =
218
+ std::move(capturedProcess)]() mutable {
202
219
  if (state->runtimeInvalidated.load()) {
203
220
  // Queued before the runtime was torn down, reached only
204
221
  // afterwards. Every JSI call below — including the ones the
@@ -212,7 +229,8 @@ jsi::Value ProtocolHost::runAsync(
212
229
  // Reuses the exact error shape every synchronous FFI
213
230
  // wrapper throws, rather than inventing a second one for
214
231
  // the asynchronous path.
215
- throwDeRecError(jsRt, capturedError);
232
+ throwDeRecError(jsRt, capturedError, capturedChannelIdsJson,
233
+ capturedProcess);
216
234
  }
217
235
  if (unknownFailure) {
218
236
  throw jsi::JSError(jsRt, "DeRec: an unexpected native error occurred");
@@ -269,9 +287,8 @@ jsi::Value ProtocolHost::get(jsi::Runtime& rt, const jsi::PropNameID& name) {
269
287
  size_t) -> jsi::Value { return hostSecretId(rt2, secretId_); });
270
288
  }
271
289
 
272
- // `setCommunicationInfo` and `setOwnTransport` return a Promise, unlike
273
- // `@derec-alliance/nodejs` where both are synchronous. They must not run on
274
- // the JavaScript thread: `derec_protocol_set_*` takes the same handle mutex
290
+ // `setCommunicationInfo` and `setOwnTransports` return a Promise, as in
291
+ // `@derec-alliance/nodejs`. They must not run on the JavaScript thread: `derec_protocol_set_*` takes the same handle mutex
275
292
  // that `derec_protocol_process`/`start`/`restore` hold for the whole
276
293
  // duration of a flow, including across store callbacks that park the worker
277
294
  // waiting on the JavaScript thread. Calling the setter synchronously would
@@ -281,9 +298,7 @@ jsi::Value ProtocolHost::get(jsi::Runtime& rt, const jsi::PropNameID& name) {
281
298
  // callback into a backend failure. The nodejs SDK is WASM and
282
299
  // single-threaded, so the hazard cannot arise there. Queuing onto the
283
300
  // serial worker instead orders the setter behind any in-flight flow, and
284
- // returning a Promise keeps a caller that ignores the result — which is how
285
- // nodejs code calls these — source-compatible, while letting a failure
286
- // surface as a rejection rather than being swallowed.
301
+ // a failure surfaces as a rejection rather than being swallowed.
287
302
  if (prop == "setCommunicationInfo") {
288
303
  return jsi::Function::createFromHostFunction(
289
304
  rt, name, 1,
@@ -309,38 +324,6 @@ jsi::Value ProtocolHost::get(jsi::Runtime& rt, const jsi::PropNameID& name) {
309
324
  });
310
325
  }
311
326
 
312
- if (prop == "setOwnTransport") {
313
- return jsi::Function::createFromHostFunction(
314
- rt, name, 2,
315
- [this](jsi::Runtime& rt2, const jsi::Value&, const jsi::Value* args,
316
- size_t count) -> jsi::Value {
317
- requireArgs(rt2, "setOwnTransport", count, 2);
318
- std::string uri = args[0].asString(rt2).utf8(rt2);
319
- auto protocol = static_cast<int32_t>(args[1].asNumber());
320
- DeRecProtocolHandle* handle = handle_;
321
-
322
- auto body = [handle, uri, protocol]() -> std::vector<uint8_t> {
323
- // This binding *is* the deprecated single-endpoint path, so it calls the
324
- // deprecated export on purpose — the same reason the Rust side carries
325
- // `#[allow(deprecated)]` on its compatibility paths. Both go at 0.0.5.
326
- #pragma GCC diagnostic push
327
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
328
- DeRecError error = derec_protocol_set_own_transport(
329
- handle, reinterpret_cast<const uint8_t*>(uri.data()), uri.size(),
330
- protocol);
331
- #pragma GCC diagnostic pop
332
- if (error.code != DEREC_CODE_OK) {
333
- throw FfiFailure(error);
334
- }
335
- return {};
336
- };
337
- auto convert = [](jsi::Runtime&, std::vector<uint8_t>&) {
338
- return jsi::Value::undefined();
339
- };
340
- return runAsync(rt2, std::move(body), std::move(convert));
341
- });
342
- }
343
-
344
327
  // Takes the endpoint list already JSON-encoded, the same way
345
328
  // `setCommunicationInfo` takes its map: the FFI parses JSON on the other
346
329
  // side, so encoding in JavaScript keeps this bridge free of a shape it
@@ -433,12 +416,16 @@ jsi::Value ProtocolHost::get(jsi::Runtime& rt, const jsi::PropNameID& name) {
433
416
 
434
417
  auto body = [handle,
435
418
  message = std::move(message)]() -> std::vector<uint8_t> {
436
- DeRecProtocolEventsResult result =
419
+ DeRecProtocolProcessResult result =
437
420
  derec_protocol_process(handle, message.data(), message.size());
421
+ std::vector<uint8_t> events = takeBuffer(result.events_json);
438
422
  if (result.error.code != DEREC_CODE_OK) {
439
- throw FfiFailure(result.error);
423
+ throw FfiFailure(result.error,
424
+ ProcessFailureDetails{std::move(events),
425
+ result.has_channel_id,
426
+ result.channel_id});
440
427
  }
441
- return takeBuffer(result.events_json);
428
+ return events;
442
429
  };
443
430
  return runAsync(rt2, std::move(body), bytesToArrayBuffer);
444
431
  });
@@ -599,12 +586,14 @@ jsi::Value ProtocolHost::get(jsi::Runtime& rt, const jsi::PropNameID& name) {
599
586
 
600
587
  auto body = [handle,
601
588
  params = std::move(params)]() -> std::vector<uint8_t> {
602
- DeRecProtocolEventsResult result =
589
+ DeRecProtocolRestoreResult result =
603
590
  derec_protocol_restore(handle, params.data(), params.size());
604
- if (result.error.code != DEREC_CODE_OK) {
605
- throw FfiFailure(result.error);
591
+ RestoreOutcome outcome = takeRestoreResult(result);
592
+ if (outcome.error.code != DEREC_CODE_OK) {
593
+ throw FfiFailure(outcome.error,
594
+ std::move(outcome.conflictingChannelIdsJson));
606
595
  }
607
- return takeBuffer(result.events_json);
596
+ return std::move(outcome.events);
608
597
  };
609
598
  return runAsync(rt2, std::move(body), bytesToArrayBuffer);
610
599
  });
@@ -632,8 +621,7 @@ jsi::Value ProtocolHost::get(jsi::Runtime& rt, const jsi::PropNameID& name) {
632
621
 
633
622
  std::vector<jsi::PropNameID> ProtocolHost::getPropertyNames(jsi::Runtime& rt) {
634
623
  const char* names[] = {
635
- "secretId", "setCommunicationInfo", "setOwnTransport",
636
- "setOwnTransports",
624
+ "secretId", "setCommunicationInfo", "setOwnTransports",
637
625
  "createContact", "start", "process",
638
626
  "tick", "accept", "reject",
639
627
  "getFingerprint", "verifyFingerprint", "removeExpiredChannels",