@decentnetwork/beagle 0.1.52 → 0.1.54

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.
@@ -1,4 +1,4 @@
1
- window.__DK_UI_VERSION="0.1.52";
1
+ window.__DK_UI_VERSION="0.1.54";
2
2
  const ICON_PATHS = {
3
3
  // ---- tab bar (the four must feel like one set) ----
4
4
  users: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
@@ -592,21 +592,19 @@ export class EmbeddedHost {
592
592
  this.#events.emit("event", { type: "chat", userid, dir: "out" });
593
593
  return { queued: true, name: safe, size: data.length };
594
594
  }
595
- // A NATIVE friend (iOS/Android/C Carrier) cannot see the toxcore transfer
596
- // protocol AT ALL offering it one just hangs the chip at "sending" until
597
- // the 60s give-up. Its only file path is the inline envelope, so reject an
598
- // oversized file BEFORE any bytes move, with the reason (ticket req. 2).
595
+ // A NATIVE friend (iOS/Android/C Carrier) takes the inline envelope for
596
+ // small files (single blob, the Beagle apps' own fast path). Larger files
597
+ // go through the normal sendFile below peer >= 0.1.141 carries those to
598
+ // natives as DNFT1 frames inside friend messages (offset acks, FEC,
599
+ // resume; verified 100MB JS→iPad). Only route to inline what fits it.
599
600
  const native = this.#node.isNativeFriend(userid);
600
- if (native && data.length > INLINE_MAX_BYTES) {
601
- throw new Error(`This friend is a native (iOS/Android) client — files are sent inline and limited to ` +
602
- `${(INLINE_MAX_BYTES / 1024 / 1024).toFixed(1)} MB (this is ${(data.length / 1024 / 1024).toFixed(1)} MB).`);
603
- }
601
+ const inlineNative = native && data.length <= INLINE_MAX_BYTES;
604
602
  const msg = this.#messages.appendFile(userid, "out", { name: safe, size: data.length, status: "sending", sent: 0 });
605
603
  if (!msg)
606
604
  throw new Error("Could not create file message");
607
605
  await mkdir(this.outboxDir, { recursive: true });
608
606
  await writeFile(resolve(this.outboxDir, msg.id), data);
609
- const fileId = native ? null : this.#node.sendFile(userid, new Uint8Array(data), safe);
607
+ const fileId = inlineNative ? null : this.#node.sendFile(userid, new Uint8Array(data), safe);
610
608
  if (!fileId) {
611
609
  // Native friend, or no transfer slot — the inline envelope path.
612
610
  if (data.length > INLINE_MAX_BYTES) {
@@ -614,27 +612,29 @@ export class EmbeddedHost {
614
612
  throw new Error(`Could not start the transfer, and the file is too large (${(data.length / 1024 / 1024).toFixed(1)} MB) ` +
615
613
  `for the inline fallback (limit ${(INLINE_MAX_BYTES / 1024 / 1024).toFixed(1)} MB).`);
616
614
  }
617
- // "sent" means the PEER CONFIRMED receipt — nothing less. Stamping it
618
- // when sendInlineFile resolved was the fake-sent of INBOX 2026-08-21:
619
- // bytes left the machine, the phone had nothing, the UI showed a
620
- // checkmark. The SDK's verdict now decides the chip.
621
- let delivery;
622
- try {
623
- delivery = await this.#node.sendInlineFile(userid, new Uint8Array(data), safe);
624
- }
625
- catch (e) {
626
- this.#messages.patchFile(userid, msg.id, { status: "failed" });
615
+ // "sent" means the PEER CONFIRMED receipt — nothing less (the fake-sent
616
+ // of INBOX 2026-08-21). And sends are NON-BLOCKING (the 2026-08-05
617
+ // rule): the delivery wait scales to 180s, and holding the request open
618
+ // that long froze the UI on an 8MB inline send. Return now; the SDK's
619
+ // verdict patches the chip through the event stream.
620
+ const bytes = new Uint8Array(data);
621
+ void (async () => {
622
+ let delivery;
623
+ try {
624
+ delivery = await this.#node.sendInlineFile(userid, bytes, safe);
625
+ }
626
+ catch (e) {
627
+ this.#messages.patchFile(userid, msg.id, { status: "failed" });
628
+ this.#events.emit("event", { type: "chat", userid, dir: "out" });
629
+ this.#logger.warn(`inline file "${safe}" to ${userid.slice(0, 8)} failed: ${e.message}`);
630
+ return;
631
+ }
632
+ const status = delivery === "acked" ? "sent" : delivery === "offline" ? "queued" : "failed";
633
+ this.#messages.patchFile(userid, msg.id, { status, sent: delivery === "acked" ? data.length : 0 });
627
634
  this.#events.emit("event", { type: "chat", userid, dir: "out" });
628
- throw e;
629
- }
630
- const status = delivery === "acked" ? "sent" : delivery === "offline" ? "queued" : "failed";
631
- this.#messages.patchFile(userid, msg.id, { status, sent: delivery === "acked" ? data.length : 0 });
632
- this.#events.emit("event", { type: "chat", userid, dir: "out" });
633
- if (delivery === "accepted") {
634
- throw new Error(`The peer never confirmed receiving "${safe}" — it likely did not arrive. ` +
635
- `Check that their app is open and try again.`);
636
- }
637
- return { inline: true, name: safe, size: data.length, delivery };
635
+ this.#logger.info(`inline file "${safe}" (${data.length}B) to ${userid.slice(0, 8)}: delivery=${delivery} → ${status}`);
636
+ })();
637
+ return { inline: true, name: safe, size: data.length, pending: true };
638
638
  }
639
639
  this.#activeSends.set(fileId, { peer: userid, msgId: msg.id });
640
640
  this.#meta.ensure(userid);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decentnetwork/beagle",
3
- "version": "0.1.52",
3
+ "version": "0.1.54",
4
4
  "description": "Beagle — P2P chat, file transfer and calls for regular users, on the Decent Network. No admin privilege required.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -26,8 +26,8 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@decentnetwork/chat-components": "^0.1.3",
29
- "@decentnetwork/lan": "^0.1.279",
30
- "@decentnetwork/peer": "^0.1.140",
29
+ "@decentnetwork/lan": "^0.1.281",
30
+ "@decentnetwork/peer": "^0.1.141",
31
31
  "@decentnetwork/peer-webrtc": "^0.2.16",
32
32
  "js-yaml": "^4.1.0",
33
33
  "yargs": "^17.7.2"