@minip2p/react-native 0.8.3 → 0.9.1

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/src/adapter.ts CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  DiscoverySource,
5
5
  DriverFailureKind,
6
6
  EndpointErrorKind,
7
+ MdnsFailureKind,
7
8
  Minip2pBase,
8
9
  NatErrorKind,
9
10
  Reachability,
@@ -20,6 +21,8 @@ import {
20
21
  ConnectionIdMap,
21
22
  EventDrain,
22
23
  P2pEvent_Tags,
24
+ SettleHandles,
25
+ eventStream,
23
26
  resolveEndpointConfig,
24
27
  typedFfiError,
25
28
  u64ToNumber,
@@ -29,15 +32,18 @@ import type {
29
32
  Minip2pBackend,
30
33
  Minip2pBackendFactory,
31
34
  BackendOpenStream,
35
+ NativeErrorFields,
32
36
  P2pEvent,
33
37
  PathKind,
34
38
  } from "@minip2p/core/backend";
35
39
 
36
40
  import {
41
+ ConfigCapability as NativeConfigCapability,
37
42
  ConnectTarget,
38
43
  DiscoverySource as NativeDiscoverySource,
39
44
  DriverFailureKind as NativeDriverFailureKind,
40
45
  EndpointErrorKind as NativeEndpointErrorKind,
46
+ MdnsFailureKind as NativeMdnsFailureKind,
41
47
  NatErrorKind as NativeNatErrorKind,
42
48
  P2pEndpoint,
43
49
  Reachability as NativeReachability,
@@ -58,6 +64,8 @@ class ReactNativeBackend implements Minip2pBackend {
58
64
  readonly #endpoint: P2pEndpoint;
59
65
  readonly #mdnsEnabled: boolean;
60
66
  readonly #connectionIds = new ConnectionIdMap();
67
+ /** Native stream identities while their events are in flight (ADR 0012). */
68
+ readonly #settleHandles = new SettleHandles<[bigint, bigint]>();
61
69
  #doorbell: P2pEventDoorbell | undefined;
62
70
  #events: EventDrain<NativeP2pEvent> | undefined;
63
71
 
@@ -85,7 +93,15 @@ class ReactNativeBackend implements Minip2pBackend {
85
93
  start(listener: (event: P2pEvent) => void): void {
86
94
  this.#events = new EventDrain(
87
95
  (limit) => this.#endpoint.drainEvents(limit),
88
- (event) => listener(normalizeEvent(event, this.#connectionIds))
96
+ (event) => {
97
+ const normalized = normalizeEvent(event, this.#connectionIds);
98
+ const stream = eventStream(normalized);
99
+ const native = nativeStreamOf(event);
100
+ if (stream !== undefined && native !== undefined) {
101
+ this.#settleHandles.hold(stream.connId, stream.streamId, native);
102
+ }
103
+ listener(normalized);
104
+ }
89
105
  );
90
106
  this.#doorbell = {
91
107
  onEventsReady: () => {
@@ -97,6 +113,13 @@ class ReactNativeBackend implements Minip2pBackend {
97
113
  });
98
114
  }
99
115
 
116
+ eventHandled(event: P2pEvent): void {
117
+ const stream = eventStream(event);
118
+ if (stream !== undefined) {
119
+ this.#settleHandles.release(stream.connId, stream.streamId);
120
+ }
121
+ }
122
+
100
123
  close(): void {
101
124
  try {
102
125
  this.#endpoint.stop();
@@ -259,16 +282,12 @@ class ReactNativeBackend implements Minip2pBackend {
259
282
 
260
283
  abandonStream(connId: number, streamId: number): void {
261
284
  translateErrors(() => {
262
- this.#endpoint.abandonStream(
263
- this.#connectionIds.toNative(connId),
264
- numberToU64(streamId, "streamId")
265
- );
285
+ this.#endpoint.abandonStream(...this.#settleStream(connId, streamId));
266
286
  });
267
287
  }
268
288
 
269
289
  streamConsumer(connId: number, streamId: number): (bytes: number) => void {
270
- const nativeConn = this.#connectionIds.toNative(connId);
271
- const nativeStream = numberToU64(streamId, "streamId");
290
+ const [nativeConn, nativeStream] = this.#settleStream(connId, streamId);
272
291
  return (bytes) => {
273
292
  translateErrors(() => {
274
293
  this.#endpoint.streamConsumed(
@@ -280,6 +299,25 @@ class ReactNativeBackend implements Minip2pBackend {
280
299
  };
281
300
  }
282
301
 
302
+ /**
303
+ * Native IDs for settling a stream: acknowledging or abandoning its bytes.
304
+ * Those still hold the native slot of a connection whose end this adapter
305
+ * already drained, so a stream with events in flight resolves through its
306
+ * settle handle once the live mapping is gone.
307
+ */
308
+ #settleStream(connId: number, streamId: number): [bigint, bigint] {
309
+ const nativeStream = numberToU64(streamId, "streamId");
310
+ try {
311
+ return [this.#connectionIds.toNative(connId), nativeStream];
312
+ } catch (error) {
313
+ const handle = this.#settleHandles.get(connId, streamId);
314
+ if (handle === undefined) {
315
+ throw error;
316
+ }
317
+ return handle;
318
+ }
319
+ }
320
+
283
321
  connect(target: BackendConnectTarget): number {
284
322
  const native =
285
323
  target.kind === "peer"
@@ -383,6 +421,7 @@ const ENUM_FIELDS: Readonly<
383
421
  },
384
422
  DriverFailed: { kind: [DriverFailureKind, NativeDriverFailureKind] },
385
423
  EndpointError: { kind: [EndpointErrorKind, NativeEndpointErrorKind] },
424
+ MdnsFailed: { kind: [MdnsFailureKind, NativeMdnsFailureKind] },
386
425
  PeerDiscovered: { source: [DiscoverySource, NativeDiscoverySource] },
387
426
  PeerUpdated: { source: [DiscoverySource, NativeDiscoverySource] },
388
427
  ReachabilityChanged: {
@@ -393,8 +432,9 @@ const ENUM_FIELDS: Readonly<
393
432
 
394
433
  /**
395
434
  * Converts one native event to its SDK form. Per-chunk and per-write
396
- * events, and pubsub messages, convert field by field; the rest share the
397
- * generic walk, plus their enum fields.
435
+ * events, and pubsub messages, convert field by field, and a field-less
436
+ * event passes through by tag; the rest share the generic walk, plus their
437
+ * enum fields.
398
438
  */
399
439
  function normalizeEvent(
400
440
  event: NativeP2pEvent,
@@ -418,12 +458,32 @@ function normalizeEvent(
418
458
  case P2pEvent_Tags.Message: {
419
459
  return { inner: event.inner, tag: event.tag };
420
460
  }
461
+ case P2pEvent_Tags.MdnsRecovered: {
462
+ return { tag: event.tag };
463
+ }
421
464
  default: {
422
465
  return normalizeGenericEvent(event, connectionIds);
423
466
  }
424
467
  }
425
468
  }
426
469
 
470
+ /** The native identity of the stream a native stream event names. */
471
+ function nativeStreamOf(event: NativeP2pEvent): [bigint, bigint] | undefined {
472
+ switch (event.tag) {
473
+ case P2pEvent_Tags.StreamReady:
474
+ case P2pEvent_Tags.StreamData:
475
+ case P2pEvent_Tags.StreamWriteAccepted:
476
+ case P2pEvent_Tags.StreamWriteStopped:
477
+ case P2pEvent_Tags.StreamRemoteWriteClosed:
478
+ case P2pEvent_Tags.StreamClosed: {
479
+ return [event.inner.connId, event.inner.streamId];
480
+ }
481
+ default: {
482
+ return undefined;
483
+ }
484
+ }
485
+ }
486
+
427
487
  /** The public identity of the stream a native stream event names. */
428
488
  function streamRef(
429
489
  inner: {
@@ -441,7 +501,7 @@ function streamRef(
441
501
  }
442
502
 
443
503
  function normalizeGenericEvent(
444
- event: NativeP2pEvent,
504
+ event: Extract<NativeP2pEvent, { readonly inner: unknown }>,
445
505
  connectionIds: ConnectionIdMap
446
506
  ): P2pEvent {
447
507
  const inner = normalizeBigInts(event.inner, {
@@ -568,34 +628,38 @@ function assertSafeUnsignedInteger(value: number, name: string): void {
568
628
  }
569
629
  }
570
630
 
631
+ /** Rethrows a generated `FfiError` as its typed SDK error, if it has one. */
571
632
  function translateErrors<T>(operation: () => T): T {
572
633
  try {
573
634
  return operation();
574
635
  } catch (error) {
575
- throw typedFfiError(getErrorTag(error), getErrorDetail(error)) ?? error;
636
+ throw typedFfiError(nativeErrorFields(error)) ?? error;
576
637
  }
577
638
  }
578
639
 
579
- function getErrorTag(error: unknown): string | undefined {
580
- return typeof error === "object" &&
581
- error !== null &&
582
- "tag" in error &&
583
- typeof error.tag === "string"
584
- ? error.tag
585
- : undefined;
586
- }
587
-
588
- function getErrorDetail(error: unknown): string | undefined {
589
- if (
590
- typeof error === "object" &&
591
- error !== null &&
592
- "inner" in error &&
593
- typeof error.inner === "object" &&
594
- error.inner !== null &&
595
- "detail" in error.inner &&
596
- typeof error.inner.detail === "string"
597
- ) {
598
- return error.inner.detail;
599
- }
600
- return undefined;
640
+ /**
641
+ * Reads a generated `FfiError`'s tag and inner fields. An `InvalidConfig`
642
+ * capability is a numeric UniFFI enum, so it goes through the generated
643
+ * reverse mapping to its variant name, as event enums do.
644
+ */
645
+ function nativeErrorFields(error: unknown): NativeErrorFields {
646
+ if (typeof error !== "object" || error === null) {
647
+ return {};
648
+ }
649
+ const tag: unknown = Reflect.get(error, "tag");
650
+ const inner: unknown = Reflect.get(error, "inner");
651
+ const field = (key: string): unknown =>
652
+ typeof inner === "object" && inner !== null
653
+ ? Reflect.get(inner, key)
654
+ : undefined;
655
+ const detail = field("detail");
656
+ const capability = field("capability");
657
+ return {
658
+ capability:
659
+ typeof capability === "number"
660
+ ? NativeConfigCapability[capability]
661
+ : undefined,
662
+ detail: typeof detail === "string" ? detail : undefined,
663
+ tag: typeof tag === "string" ? tag : undefined,
664
+ };
601
665
  }
@@ -410,7 +410,9 @@ export interface P2pEndpointLike {
410
410
  stop(): void;
411
411
  /**
412
412
  * Acknowledges `bytes` of a stream's received data as consumed,
413
- * letting its sender continue. Every registered protocol needs this.
413
+ * letting its sender continue. Every registered protocol needs this,
414
+ * also after the stream's connection closed: unacknowledged bytes keep
415
+ * the ended connection's slot until they are acknowledged or abandoned.
414
416
  */
415
417
  streamConsumed(connId: bigint, streamId: bigint, bytes: bigint) /*throws*/: void;
416
418
  /**
@@ -932,7 +934,9 @@ export class P2pEndpoint extends UniffiAbstractObject implements P2pEndpointLike
932
934
 
933
935
  /**
934
936
  * Acknowledges `bytes` of a stream's received data as consumed,
935
- * letting its sender continue. Every registered protocol needs this.
937
+ * letting its sender continue. Every registered protocol needs this,
938
+ * also after the stream's connection closed: unacknowledged bytes keep
939
+ * the ended connection's slot until they are acknowledged or abandoned.
936
940
  */
937
941
  streamConsumed(connId: bigint, streamId: bigint, bytes: bigint): void /*throws*/ {uniffiCaller.rustCallWithError(
938
942
  /*liftError:*/ FfiConverterTypeFfiError.lift.bind(FfiConverterTypeFfiError),
@@ -1200,7 +1204,7 @@ function uniffiEnsureInitialized() {
1200
1204
  if (nativeModule().ubrn_uniffi_minip2p_ffi_checksum_method_p2pendpoint_stop() !== 11062) {
1201
1205
  throw new UniffiInternalError.ApiChecksumMismatch("uniffi_minip2p_ffi_checksum_method_p2pendpoint_stop");
1202
1206
  }
1203
- if (nativeModule().ubrn_uniffi_minip2p_ffi_checksum_method_p2pendpoint_stream_consumed() !== 61579) {
1207
+ if (nativeModule().ubrn_uniffi_minip2p_ffi_checksum_method_p2pendpoint_stream_consumed() !== 52358) {
1204
1208
  throw new UniffiInternalError.ApiChecksumMismatch("uniffi_minip2p_ffi_checksum_method_p2pendpoint_stream_consumed");
1205
1209
  }
1206
1210
  if (nativeModule().ubrn_uniffi_minip2p_ffi_checksum_method_p2pendpoint_subscribe() !== 41051) {
@@ -662,6 +662,67 @@ const FfiConverterTypeRelayReservationInfo = (() => {
662
662
  return new FFIConverter();
663
663
  })();
664
664
 
665
+ /**
666
+ * The part of an endpoint's configuration an [`FfiError::InvalidConfig`]
667
+ * names.
668
+ *
669
+ * A configuration mistake is fixed by changing that part; an environment
670
+ * failure (a socket the platform refused) is [`FfiError::Transport`]
671
+ * instead.
672
+ */
673
+ export enum ConfigCapability {
674
+ /**
675
+ * Gossipsub settings.
676
+ */
677
+ Gossipsub,
678
+ /**
679
+ * mDNS settings.
680
+ */
681
+ Mdns,
682
+ /**
683
+ * Signed discovery or peer-book settings.
684
+ */
685
+ Discovery,
686
+ /**
687
+ * QUIC or TCP transport settings (limits, TLS, the TCP namespace).
688
+ */
689
+ Transport,
690
+ /**
691
+ * The endpoint's own options: listen addresses, protocols, NAT and
692
+ * relay policy, auto-dial.
693
+ */
694
+ Options
695
+ }
696
+
697
+ const FfiConverterTypeConfigCapability = (() => {
698
+ type TypeName = ConfigCapability;
699
+ class FFIConverter extends AbstractFfiConverterByteArray<TypeName> {
700
+ readFromCursor(c: Cursor): TypeName {
701
+ switch (c.readI32()) {
702
+ case 1: return ConfigCapability.Gossipsub;
703
+ case 2: return ConfigCapability.Mdns;
704
+ case 3: return ConfigCapability.Discovery;
705
+ case 4: return ConfigCapability.Transport;
706
+ case 5: return ConfigCapability.Options;
707
+ default: throw new UniffiInternalError.UnexpectedEnumCase();
708
+ }
709
+ }
710
+ writeIntoCursor(value: TypeName, c: Cursor): void {
711
+ switch (value) {
712
+ case ConfigCapability.Gossipsub: return c.writeI32(1);
713
+ case ConfigCapability.Mdns: return c.writeI32(2);
714
+ case ConfigCapability.Discovery: return c.writeI32(3);
715
+ case ConfigCapability.Transport: return c.writeI32(4);
716
+ case ConfigCapability.Options: return c.writeI32(5);
717
+ }
718
+ }
719
+ allocationSize(value: TypeName): number {
720
+ return 4;
721
+ }
722
+ }
723
+ return new FFIConverter();
724
+ })();
725
+
665
726
 
666
727
  // Enum: ConnectTarget
667
728
  export enum ConnectTarget_Tags {
@@ -1062,10 +1123,11 @@ export const FfiError = (() => {
1062
1123
  type InvalidConfig__interface = {
1063
1124
  tag: FfiError_Tags.InvalidConfig;
1064
1125
  inner:
1065
- Readonly<{detail: string}>
1126
+ Readonly<{capability: ConfigCapability; detail: string}>
1066
1127
  };
1067
1128
  /**
1068
- * Endpoint configuration was internally inconsistent.
1129
+ * Endpoint configuration was invalid; `capability` names the part of
1130
+ * it that was.
1069
1131
  */
1070
1132
  class InvalidConfig_ extends UniffiError implements InvalidConfig__interface {
1071
1133
  /**
@@ -1075,15 +1137,15 @@ Readonly<{detail: string}>
1075
1137
  readonly [uniffiTypeNameSymbol] = "FfiError";
1076
1138
  readonly tag = FfiError_Tags.InvalidConfig;
1077
1139
  readonly inner:
1078
- Readonly<{detail: string}>;
1140
+ Readonly<{capability: ConfigCapability; detail: string}>;
1079
1141
  constructor(
1080
- inner: {detail: string }) {
1142
+ inner: {capability: ConfigCapability; detail: string }) {
1081
1143
  super("FfiError", "InvalidConfig");
1082
1144
 
1083
1145
  this.inner = Object.freeze(inner);
1084
1146
  }
1085
1147
  static new(
1086
- inner: {detail: string }): InvalidConfig_ {
1148
+ inner: {capability: ConfigCapability; detail: string }): InvalidConfig_ {
1087
1149
  return new InvalidConfig_(inner);
1088
1150
  }
1089
1151
 
@@ -1095,7 +1157,7 @@ inner: {detail: string }): InvalidConfig_ {
1095
1157
  }
1096
1158
 
1097
1159
  static getInner(obj: InvalidConfig_):
1098
- Readonly<{detail: string}> {
1160
+ Readonly<{capability: ConfigCapability; detail: string}> {
1099
1161
  return obj.inner;
1100
1162
  }
1101
1163
 
@@ -1377,7 +1439,8 @@ Readonly<{detail: string}> {
1377
1439
  Readonly<{detail: string}>
1378
1440
  };
1379
1441
  /**
1380
- * A synchronous transport operation failed.
1442
+ * A synchronous transport operation failed, or the platform refused a
1443
+ * socket the endpoint needed (a port in use, say).
1381
1444
  */
1382
1445
  class Transport_ extends UniffiError implements Transport__interface {
1383
1446
  /**
@@ -1534,7 +1597,7 @@ const FfiConverterTypeFfiError = (() => {
1534
1597
  switch (c.readI32()) {
1535
1598
  case 1: return new FfiError.AlreadyStarted();
1536
1599
  case 2: return new FfiError.Stopped();
1537
- case 3: return new FfiError.InvalidConfig({detail: FfiConverterString.readFromCursor(c) });
1600
+ case 3: return new FfiError.InvalidConfig({capability: FfiConverterTypeConfigCapability.readFromCursor(c), detail: FfiConverterString.readFromCursor(c) });
1538
1601
  case 4: return new FfiError.InvalidKey({detail: FfiConverterString.readFromCursor(c) });
1539
1602
  case 5: return new FfiError.InvalidPeerId({detail: FfiConverterString.readFromCursor(c) });
1540
1603
  case 6: return new FfiError.InvalidAddress({detail: FfiConverterString.readFromCursor(c) });
@@ -1561,6 +1624,7 @@ const FfiConverterTypeFfiError = (() => {
1561
1624
  case FfiError_Tags.InvalidConfig: {
1562
1625
  c.writeI32(3);
1563
1626
  const inner = value.inner;
1627
+ FfiConverterTypeConfigCapability.writeIntoCursor(inner.capability, c);
1564
1628
  FfiConverterString.writeIntoCursor(inner.detail, c);
1565
1629
  return;
1566
1630
  }
@@ -1636,6 +1700,7 @@ const FfiConverterTypeFfiError = (() => {
1636
1700
  case FfiError_Tags.InvalidConfig: {
1637
1701
  const inner = value.inner;
1638
1702
  let size = 4;
1703
+ size += FfiConverterTypeConfigCapability.allocationSize(inner.capability);
1639
1704
  size += FfiConverterString.allocationSize(inner.detail);
1640
1705
  return size;
1641
1706
  }
@@ -1700,6 +1765,74 @@ const FfiConverterTypeFfiError = (() => {
1700
1765
  return new FFIConverter();
1701
1766
  })();
1702
1767
 
1768
+ /**
1769
+ * Category of an mDNS failure.
1770
+ */
1771
+ export enum MdnsFailureKind {
1772
+ /**
1773
+ * The platform cannot provide mDNS sockets.
1774
+ */
1775
+ Unsupported,
1776
+ /**
1777
+ * An interface has no usable address.
1778
+ */
1779
+ NoInterfaceAddress,
1780
+ /**
1781
+ * A send named an interface that has gone away.
1782
+ */
1783
+ UnknownInterface,
1784
+ /**
1785
+ * A goodbye could not be sent before shutdown gave up on a full send
1786
+ * buffer.
1787
+ */
1788
+ Congested,
1789
+ /**
1790
+ * A datagram is larger than the carrier can ever send.
1791
+ */
1792
+ Oversized,
1793
+ /**
1794
+ * The interface id space is exhausted.
1795
+ */
1796
+ InterfaceIdsExhausted,
1797
+ /**
1798
+ * Platform I/O failed.
1799
+ */
1800
+ Io
1801
+ }
1802
+
1803
+ const FfiConverterTypeMdnsFailureKind = (() => {
1804
+ type TypeName = MdnsFailureKind;
1805
+ class FFIConverter extends AbstractFfiConverterByteArray<TypeName> {
1806
+ readFromCursor(c: Cursor): TypeName {
1807
+ switch (c.readI32()) {
1808
+ case 1: return MdnsFailureKind.Unsupported;
1809
+ case 2: return MdnsFailureKind.NoInterfaceAddress;
1810
+ case 3: return MdnsFailureKind.UnknownInterface;
1811
+ case 4: return MdnsFailureKind.Congested;
1812
+ case 5: return MdnsFailureKind.Oversized;
1813
+ case 6: return MdnsFailureKind.InterfaceIdsExhausted;
1814
+ case 7: return MdnsFailureKind.Io;
1815
+ default: throw new UniffiInternalError.UnexpectedEnumCase();
1816
+ }
1817
+ }
1818
+ writeIntoCursor(value: TypeName, c: Cursor): void {
1819
+ switch (value) {
1820
+ case MdnsFailureKind.Unsupported: return c.writeI32(1);
1821
+ case MdnsFailureKind.NoInterfaceAddress: return c.writeI32(2);
1822
+ case MdnsFailureKind.UnknownInterface: return c.writeI32(3);
1823
+ case MdnsFailureKind.Congested: return c.writeI32(4);
1824
+ case MdnsFailureKind.Oversized: return c.writeI32(5);
1825
+ case MdnsFailureKind.InterfaceIdsExhausted: return c.writeI32(6);
1826
+ case MdnsFailureKind.Io: return c.writeI32(7);
1827
+ }
1828
+ }
1829
+ allocationSize(value: TypeName): number {
1830
+ return 4;
1831
+ }
1832
+ }
1833
+ return new FFIConverter();
1834
+ })();
1835
+
1703
1836
  /**
1704
1837
  * Category of a failed NAT connection attempt.
1705
1838
  */
@@ -2010,6 +2143,8 @@ export enum P2pEvent_Tags {
2010
2143
  PeerUpdated = "PeerUpdated",
2011
2144
  PeerExpired = "PeerExpired",
2012
2145
  DiscoveryDialFailed = "DiscoveryDialFailed",
2146
+ MdnsFailed = "MdnsFailed",
2147
+ MdnsRecovered = "MdnsRecovered",
2013
2148
  DiscoveryProtocolViolation = "DiscoveryProtocolViolation"
2014
2149
  }
2015
2150
  /**
@@ -3254,6 +3389,70 @@ inner: {peerId: string; reason: string }): DiscoveryDialFailed_ {
3254
3389
 
3255
3390
  }
3256
3391
 
3392
+ type MdnsFailed__interface = {
3393
+ tag: P2pEvent_Tags.MdnsFailed;
3394
+ inner:
3395
+ Readonly<{kind: MdnsFailureKind; detail: string}>
3396
+ };
3397
+ /**
3398
+ * mDNS hit a hard failure. mDNS keeps running and retries; reported
3399
+ * once per change in failure state, and followed by `MdnsRecovered`
3400
+ * once a retry succeeds. A goodbye that failed during shutdown is
3401
+ * final.
3402
+ */
3403
+ class MdnsFailed_ extends UniffiEnum implements MdnsFailed__interface {
3404
+ /**
3405
+ * @private
3406
+ * This field is private and should not be used, use `tag` instead.
3407
+ */
3408
+ readonly [uniffiTypeNameSymbol] = "P2pEvent";
3409
+ readonly tag = P2pEvent_Tags.MdnsFailed;
3410
+ readonly inner:
3411
+ Readonly<{kind: MdnsFailureKind; detail: string}>;
3412
+ constructor(
3413
+ inner: {kind: MdnsFailureKind; detail: string }) {
3414
+ super("P2pEvent", "MdnsFailed");
3415
+
3416
+ this.inner = Object.freeze(inner);
3417
+ }
3418
+ static new(
3419
+ inner: {kind: MdnsFailureKind; detail: string }): MdnsFailed_ {
3420
+ return new MdnsFailed_(inner);
3421
+ }
3422
+
3423
+ static instanceOf(obj: any): obj is MdnsFailed_ {
3424
+ return obj.tag === P2pEvent_Tags.MdnsFailed;
3425
+ }
3426
+
3427
+ }
3428
+
3429
+ type MdnsRecovered__interface = {
3430
+ tag: P2pEvent_Tags.MdnsRecovered
3431
+ };
3432
+ /**
3433
+ * mDNS recovered from its last `MdnsFailed`.
3434
+ */
3435
+ class MdnsRecovered_ extends UniffiEnum implements MdnsRecovered__interface {
3436
+ /**
3437
+ * @private
3438
+ * This field is private and should not be used, use `tag` instead.
3439
+ */
3440
+ readonly [uniffiTypeNameSymbol] = "P2pEvent";
3441
+ readonly tag = P2pEvent_Tags.MdnsRecovered;
3442
+ constructor() {
3443
+ super("P2pEvent", "MdnsRecovered");
3444
+ }
3445
+
3446
+ static new(): MdnsRecovered_ {
3447
+ return new MdnsRecovered_();
3448
+ }
3449
+
3450
+ static instanceOf(obj: any): obj is MdnsRecovered_ {
3451
+ return obj.tag === P2pEvent_Tags.MdnsRecovered;
3452
+ }
3453
+
3454
+ }
3455
+
3257
3456
  type DiscoveryProtocolViolation__interface = {
3258
3457
  tag: P2pEvent_Tags.DiscoveryProtocolViolation;
3259
3458
  inner:
@@ -3330,6 +3529,8 @@ inner: {peerId?: string; source: DiscoverySource; reason: string; suppressed: nu
3330
3529
  PeerUpdated: PeerUpdated_,
3331
3530
  PeerExpired: PeerExpired_,
3332
3531
  DiscoveryDialFailed: DiscoveryDialFailed_,
3532
+ MdnsFailed: MdnsFailed_,
3533
+ MdnsRecovered: MdnsRecovered_,
3333
3534
  DiscoveryProtocolViolation: DiscoveryProtocolViolation_
3334
3535
  });
3335
3536
 
@@ -3338,7 +3539,7 @@ inner: {peerId?: string; source: DiscoverySource; reason: string; suppressed: nu
3338
3539
  * Event delivered by the native endpoint driver.
3339
3540
  */
3340
3541
  export type P2pEvent = InstanceType<
3341
- typeof P2pEvent['EventsDropped' | 'DriverFailed' | 'ConnectionEstablished' | 'ConnectionClosed' | 'ConnectionReplaced' | 'PeerReady' | 'IdentifyReceived' | 'PingRttMeasured' | 'PingTimeout' | 'StreamReady' | 'StreamData' | 'StreamWriteAccepted' | 'StreamWriteStopped' | 'StreamRemoteWriteClosed' | 'StreamClosed' | 'EndpointError' | 'ReachabilityChanged' | 'PublicAddressesChanged' | 'RelayReserved' | 'RelayReservationLost' | 'PathEstablished' | 'InboundPathEstablished' | 'PathUpgraded' | 'HolePunchFailed' | 'ConnectFailed' | 'ConnectCancelled' | 'InboundDirectUpgrade' | 'Message' | 'PeerSubscribed' | 'PeerUnsubscribed' | 'GossipsubOutboundFailure' | 'GossipsubProtocolViolation' | 'PeerDiscovered' | 'PeerUpdated' | 'PeerExpired' | 'DiscoveryDialFailed' | 'DiscoveryProtocolViolation']
3542
+ typeof P2pEvent['EventsDropped' | 'DriverFailed' | 'ConnectionEstablished' | 'ConnectionClosed' | 'ConnectionReplaced' | 'PeerReady' | 'IdentifyReceived' | 'PingRttMeasured' | 'PingTimeout' | 'StreamReady' | 'StreamData' | 'StreamWriteAccepted' | 'StreamWriteStopped' | 'StreamRemoteWriteClosed' | 'StreamClosed' | 'EndpointError' | 'ReachabilityChanged' | 'PublicAddressesChanged' | 'RelayReserved' | 'RelayReservationLost' | 'PathEstablished' | 'InboundPathEstablished' | 'PathUpgraded' | 'HolePunchFailed' | 'ConnectFailed' | 'ConnectCancelled' | 'InboundDirectUpgrade' | 'Message' | 'PeerSubscribed' | 'PeerUnsubscribed' | 'GossipsubOutboundFailure' | 'GossipsubProtocolViolation' | 'PeerDiscovered' | 'PeerUpdated' | 'PeerExpired' | 'DiscoveryDialFailed' | 'MdnsFailed' | 'MdnsRecovered' | 'DiscoveryProtocolViolation']
3342
3543
  >;
3343
3544
 
3344
3545
  // FfiConverter for enum P2pEvent
@@ -3383,7 +3584,9 @@ const FfiConverterTypeP2pEvent = (() => {
3383
3584
  case 34: return new P2pEvent.PeerUpdated({peerId: FfiConverterString.readFromCursor(c), addrs: FfiConverterSequenceString.readFromCursor(c), source: FfiConverterTypeDiscoverySource.readFromCursor(c) });
3384
3585
  case 35: return new P2pEvent.PeerExpired({peerId: FfiConverterString.readFromCursor(c) });
3385
3586
  case 36: return new P2pEvent.DiscoveryDialFailed({peerId: FfiConverterString.readFromCursor(c), reason: FfiConverterString.readFromCursor(c) });
3386
- case 37: return new P2pEvent.DiscoveryProtocolViolation({peerId: FfiConverterOptionalString.readFromCursor(c), source: FfiConverterTypeDiscoverySource.readFromCursor(c), reason: FfiConverterString.readFromCursor(c), suppressed: FfiConverterUInt32.readFromCursor(c) });
3587
+ case 37: return new P2pEvent.MdnsFailed({kind: FfiConverterTypeMdnsFailureKind.readFromCursor(c), detail: FfiConverterString.readFromCursor(c) });
3588
+ case 38: return new P2pEvent.MdnsRecovered();
3589
+ case 39: return new P2pEvent.DiscoveryProtocolViolation({peerId: FfiConverterOptionalString.readFromCursor(c), source: FfiConverterTypeDiscoverySource.readFromCursor(c), reason: FfiConverterString.readFromCursor(c), suppressed: FfiConverterUInt32.readFromCursor(c) });
3387
3590
  default: throw new UniffiInternalError.UnexpectedEnumCase();
3388
3591
  }
3389
3592
  }
@@ -3673,9 +3876,20 @@ const FfiConverterTypeP2pEvent = (() => {
3673
3876
  FfiConverterString.writeIntoCursor(inner.reason, c);
3674
3877
  return;
3675
3878
  }
3676
- case P2pEvent_Tags.DiscoveryProtocolViolation: {
3879
+ case P2pEvent_Tags.MdnsFailed: {
3677
3880
  c.writeI32(37);
3678
3881
  const inner = value.inner;
3882
+ FfiConverterTypeMdnsFailureKind.writeIntoCursor(inner.kind, c);
3883
+ FfiConverterString.writeIntoCursor(inner.detail, c);
3884
+ return;
3885
+ }
3886
+ case P2pEvent_Tags.MdnsRecovered: {
3887
+ c.writeI32(38);
3888
+ return;
3889
+ }
3890
+ case P2pEvent_Tags.DiscoveryProtocolViolation: {
3891
+ c.writeI32(39);
3892
+ const inner = value.inner;
3679
3893
  FfiConverterOptionalString.writeIntoCursor(inner.peerId, c);
3680
3894
  FfiConverterTypeDiscoverySource.writeIntoCursor(inner.source, c);
3681
3895
  FfiConverterString.writeIntoCursor(inner.reason, c);
@@ -3973,6 +4187,16 @@ const FfiConverterTypeP2pEvent = (() => {
3973
4187
  size += FfiConverterString.allocationSize(inner.reason);
3974
4188
  return size;
3975
4189
  }
4190
+ case P2pEvent_Tags.MdnsFailed: {
4191
+ const inner = value.inner;
4192
+ let size = 4;
4193
+ size += FfiConverterTypeMdnsFailureKind.allocationSize(inner.kind);
4194
+ size += FfiConverterString.allocationSize(inner.detail);
4195
+ return size;
4196
+ }
4197
+ case P2pEvent_Tags.MdnsRecovered: {
4198
+ return 4;
4199
+ }
3976
4200
  case P2pEvent_Tags.DiscoveryProtocolViolation: {
3977
4201
  const inner = value.inner;
3978
4202
  let size = 4;
@@ -4038,6 +4262,7 @@ function uniffiEnsureInitialized() {
4038
4262
  export default Object.freeze({
4039
4263
  initialize: uniffiEnsureInitialized,
4040
4264
  converters: {
4265
+ FfiConverterTypeConfigCapability,
4041
4266
  FfiConverterTypeConnectTarget,
4042
4267
  FfiConverterTypeConnectionInfo,
4043
4268
  FfiConverterTypeDiscoveryOptions,
@@ -4048,6 +4273,7 @@ export default Object.freeze({
4048
4273
  FfiConverterTypeFfiError,
4049
4274
  FfiConverterTypeIdentifyInfo,
4050
4275
  FfiConverterTypeKnownPeerInfo,
4276
+ FfiConverterTypeMdnsFailureKind,
4051
4277
  FfiConverterTypeMdnsOptions,
4052
4278
  FfiConverterTypeNatErrorKind,
4053
4279
  FfiConverterTypeOpenStreamResult,