@decentnetwork/peer 0.1.87 → 0.1.89

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/dist/peer.d.ts CHANGED
@@ -131,6 +131,7 @@ export declare class Peer {
131
131
  sendInvite(pubkey: string, data: Uint8Array | string, opts?: {
132
132
  ext?: string | null;
133
133
  bundle?: string;
134
+ establishTimeoutMs?: number;
134
135
  }): Promise<bigint>;
135
136
  /**
136
137
  * Send an application-defined custom packet to a friend. `id` selects the
package/dist/peer.js CHANGED
@@ -174,7 +174,7 @@ const AGENTNET_PROTO_VERSION = 1;
174
174
  // Peer package version, advertised as the default appVersion when the embedder
175
175
  // doesn't override it. Read lazily so a bundler that inlines this file doesn't
176
176
  // need the package.json at runtime.
177
- const PEER_PKG_VERSION = "0.1.87";
177
+ const PEER_PKG_VERSION = "0.1.89";
178
178
  // Toxcore Messenger.h packet IDs (live inside encrypted 0x1b crypto data plain payload)
179
179
  const PACKET_ID_PADDING = 0;
180
180
  const PACKET_ID_REQUEST = 1; // request retransmission of unreceived packets
@@ -1217,10 +1217,14 @@ export class Peer {
1217
1217
  // extension the native WebRTC SDK registers under.
1218
1218
  const ext = opts.ext === null ? undefined : (opts.ext ?? CARRIER_EXTENSION_NAME);
1219
1219
  const bundle = opts.bundle;
1220
+ // How long to wait for a session to (re)establish before giving up. A caller
1221
+ // that wants to FAIL FAST (e.g. to fall back to an offline transport instead
1222
+ // of blocking the UI ~5s per signal) passes establishTimeoutMs: 0.
1223
+ const establishTimeoutMs = opts.establishTimeoutMs ?? 5000;
1220
1224
  let session = this.#friendSessions.get(pubkey);
1221
- if (!session?.established) {
1225
+ if (!session?.established && establishTimeoutMs > 0) {
1222
1226
  await this.#initiateSession(pubkey).catch(() => { });
1223
- const established = await this.#waitForFriendConnected(pubkey, 5000).catch(() => false);
1227
+ const established = await this.#waitForFriendConnected(pubkey, establishTimeoutMs).catch(() => false);
1224
1228
  if (established)
1225
1229
  session = this.#friendSessions.get(pubkey);
1226
1230
  }
@@ -2057,50 +2061,24 @@ export class Peer {
2057
2061
  // deliver immediately (a reorder buffer would only add latency and
2058
2062
  // would wait forever for retransmits that arrive at fresh numbers);
2059
2063
  // they still advance the ack point eagerly, exactly as before.
2060
- // - Everything else is the DUAL-SENT reliable message stream (chat 64,
2061
- // bulkmsg, invites, profile, control): delivered STRICTLY in order
2062
- // through a toxcore-style recv_array (below) so a reordered or
2063
- // retransmitted fragment is neither delivered early nor dropped as a
2064
- // duplicate. Advancing receiveBufferStart past a gap (the old bug)
2065
- // ACKed a packet we never delivered, so the sender never retransmit
2066
- // corrupting every multi-fragment message (large inline files from
2067
- // native peers surfaced as "bulkmsg totalsz 0 dropped").
2064
+ // - Everything else is a reliable message (chat 64, bulkmsg, invites,
2065
+ // profile, control): deliver immediately and advance the ack point.
2066
+ //
2067
+ // NOTE: a strict in-order recv_array (buffer-ahead + retransmit-request)
2068
+ // was tried here to fix reordered multi-fragment inline files, but it
2069
+ // STALLED the whole reliable stream against native peers whose retransmit
2070
+ // didn't recover our gaps breaking chat + files in BOTH directions
2071
+ // (the stalled ack point starved the peer's send window). Reverted to the
2072
+ // forgiving skip-the-gap behavior: a lost fragment corrupts one message
2073
+ // (rare) instead of wedging the session. Large files should use the
2074
+ // toxcore file-transfer channel (sendFile), which has its own reliability.
2068
2075
  const consumesReliableNumber = kind !== PACKET_ID_REQUEST &&
2069
2076
  kind < 192 &&
2070
2077
  kind !== this.#opts.bulkDataPacketId;
2071
- if (!consumesReliableNumber || isSingleTransportKind) {
2072
- if (consumesReliableNumber) {
2073
- state.receiveBufferStart = Math.max(state.receiveBufferStart ?? 0, (opened.packetNumber + 1) >>> 0);
2074
- }
2075
- this.#deliverLosslessPayload(friendId, state, kind, inner, remote);
2076
- return;
2077
- }
2078
- const expected = state.receiveBufferStart ?? 0;
2079
- const ahead = (opened.packetNumber - expected) >>> 0;
2080
- if (ahead >= 0x80000000) {
2081
- // Below the low-water mark — already delivered. Duplicate; drop.
2082
- return;
2083
- }
2084
- if (ahead === 0) {
2085
- // In order: deliver, advance, then drain any now-contiguous buffered.
2086
- state.receiveBufferStart = (expected + 1) >>> 0;
2087
- this.#deliverLosslessPayload(friendId, state, kind, inner, remote);
2088
- this.#drainRecvBufferContiguous(friendId, state, remote);
2089
- return;
2090
- }
2091
- // A gap sits below this packet. Hold it and drive recovery: ask the
2092
- // sender to retransmit the missing number(s). If the buffer outgrows the
2093
- // reorder window the gap is a genuine loss that won't come back — force
2094
- // the stream forward rather than wedge every later packet forever.
2095
- const buf = (state.recvBuffer ??= new Map());
2096
- if (!buf.has(opened.packetNumber))
2097
- buf.set(opened.packetNumber, { kind, inner });
2098
- if (buf.size > RECV_REORDER_WINDOW) {
2099
- this.#forceAdvanceRecvBuffer(friendId, state, remote);
2100
- }
2101
- else {
2102
- this.#requestMissingReliablePackets(friendId, state);
2078
+ if (consumesReliableNumber) {
2079
+ state.receiveBufferStart = Math.max(state.receiveBufferStart ?? 0, (opened.packetNumber + 1) >>> 0);
2103
2080
  }
2081
+ this.#deliverLosslessPayload(friendId, state, kind, inner, remote);
2104
2082
  return;
2105
2083
  }
2106
2084
  // Reverted: we used to DELETE a "desynced" session here to force a clean
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decentnetwork/peer",
3
- "version": "0.1.87",
3
+ "version": "0.1.89",
4
4
  "description": "Pure TypeScript port of Elastos Carrier (toxcore-derived) P2P messaging. DHT, onion routing, TCP relay, FlatBuffers app payloads, Express offline relay. Wire-compatible with iOS Beagle and the Carrier C SDK.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",