@decentnetwork/lan 0.1.228 → 0.1.229

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.
@@ -1633,8 +1633,14 @@ function Conversation({ T, peer, lang, thread: threadProp, onSend, onSendFile, o
1633
1633
  if (!files || !files.length || !sender) return;
1634
1634
  const file = files[0];
1635
1635
  followScrollRef.current = true;
1636
- setSending({ name: file.name, via: mode, pct: 0 });
1637
- const onProgress = (p) => setSending((s) => s && s.name === file.name ? { ...s, pct: p && p.pct } : s);
1636
+ setSending({ name: file.name, via: mode, pct: 0, sent: 0, size: file.size });
1637
+ const onProgress = (p) => setSending((s) => s && s.name === file.name ? {
1638
+ ...s,
1639
+ pct: p && p.pct,
1640
+ sent: p && p.sent,
1641
+ size: p && p.size || s.size,
1642
+ kbps: p && p.kbps
1643
+ } : s);
1638
1644
  Promise.resolve(sender(file, onProgress)).then((r) => {
1639
1645
  if (r && r.ok === false) window.alert((lang === "zh" ? "\u53D1\u9001\u5931\u8D25: " : "Send failed: ") + (r.error || ""));
1640
1646
  else showFlash("ok", mode === "webrtc" ? lang === "zh" ? "WebRTC \u6587\u4EF6\u53D1\u9001\u5B8C\u6210" : "WebRTC file sent" : lang === "zh" ? "\u6587\u4EF6\u5DF2\u63D0\u4EA4\u53D1\u9001" : "File send started");
@@ -1722,7 +1728,7 @@ function Conversation({ T, peer, lang, thread: threadProp, onSend, onSendFile, o
1722
1728
  stroke: 2.2,
1723
1729
  color: flash.kind === "err" ? "var(--danger)" : "var(--accent)"
1724
1730
  }
1725
- ), flash.msg), sending && /* @__PURE__ */ React.createElement("div", { style: { maxWidth: 760, margin: "0 auto 8px", display: "flex", alignItems: "center", gap: 8, fontFamily: "var(--mono)", fontSize: 11.5, color: "var(--faint)" } }, /* @__PURE__ */ React.createElement(Icon, { name: "paperclip", size: 13, stroke: 2, color: "var(--accent)" }), (lang === "zh" ? "\u53D1\u9001\u4E2D: " : "Sending: ") + (sending.via === "webrtc" ? "WebRTC \xB7 " : "") + sending.name + (sending.pct != null ? " \xB7 " + Math.min(100, Math.max(0, sending.pct)).toFixed(1) + "%" : "")), /* @__PURE__ */ React.createElement("div", { style: { maxWidth: 760, margin: "0 auto", display: "flex", alignItems: "center", gap: 10 } }, /* @__PURE__ */ React.createElement(
1731
+ ), flash.msg), sending && /* @__PURE__ */ React.createElement("div", { style: { maxWidth: 760, margin: "0 auto 8px", display: "flex", alignItems: "center", gap: 8, fontFamily: "var(--mono)", fontSize: 11.5, color: "var(--faint)" } }, /* @__PURE__ */ React.createElement(Icon, { name: "paperclip", size: 13, stroke: 2, color: "var(--accent)" }), (lang === "zh" ? "\u53D1\u9001\u4E2D: " : "Sending: ") + (sending.via === "webrtc" ? "WebRTC \xB7 " : "") + sending.name + (sending.size ? " \xB7 " + dkFileSize(sending.sent || 0) + " / " + dkFileSize(sending.size) : "") + (sending.pct != null ? " \xB7 " + Math.min(100, Math.max(0, sending.pct)).toFixed(1) + "%" : "") + (sending.kbps != null ? " \xB7 " + dkSpeed(sending.kbps) : "")), /* @__PURE__ */ React.createElement("div", { style: { maxWidth: 760, margin: "0 auto", display: "flex", alignItems: "center", gap: 10 } }, /* @__PURE__ */ React.createElement(
1726
1732
  "input",
1727
1733
  {
1728
1734
  ref: fileRef,
@@ -2207,16 +2213,36 @@ function useRtcFileController(selfId, onReceivedFile) {
2207
2213
  await dkWaitForOpen(dc, DK_FILE_RTC_OPEN_TIMEOUT_MS, () => dkRtcState(pc));
2208
2214
  dc.send(JSON.stringify({ type: "meta", name: file.name, size: file.size, mime: file.type || "application/octet-stream" }));
2209
2215
  let sent = 0;
2216
+ const startedAt = Date.now();
2217
+ let lastProgressAt = 0;
2210
2218
  const highWater = 4 * 1024 * 1024;
2219
+ const reportProgress = (force) => {
2220
+ if (!onProgress) return;
2221
+ const now = Date.now();
2222
+ if (!force && now - lastProgressAt < 250 && sent < file.size) return;
2223
+ lastProgressAt = now;
2224
+ const elapsedMs = Math.max(1, now - startedAt);
2225
+ const kbps = sent / 1024 / (elapsedMs / 1e3);
2226
+ onProgress({
2227
+ sent,
2228
+ size: file.size,
2229
+ pct: file.size ? sent / file.size * 100 : 100,
2230
+ kbps,
2231
+ elapsedMs,
2232
+ via: "webrtc"
2233
+ });
2234
+ };
2235
+ reportProgress(true);
2211
2236
  while (sent < file.size) {
2212
2237
  if (dc.readyState !== "open") throw new Error("WebRTC data channel closed");
2213
2238
  const end = Math.min(file.size, sent + DK_FILE_RTC_CHUNK);
2214
2239
  const buf = await file.slice(sent, end).arrayBuffer();
2215
2240
  dc.send(buf);
2216
2241
  sent = end;
2217
- if (onProgress) onProgress({ sent, size: file.size, pct: file.size ? sent / file.size * 100 : 100 });
2242
+ reportProgress(false);
2218
2243
  await dkWaitBufferedLow(dc, highWater);
2219
2244
  }
2245
+ reportProgress(true);
2220
2246
  dc.send(JSON.stringify({ type: "done" }));
2221
2247
  await sendSignal("bye", { reason: "done" }).catch(() => {
2222
2248
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decentnetwork/lan",
3
- "version": "0.1.228",
3
+ "version": "0.1.229",
4
4
  "description": "Private virtual LAN for self-hosted services and AI agents, built on Elastos Carrier. NAT-traversal, name service, ACL, all over a peer-to-peer mesh — no public IP required.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",