@decentnetwork/lan 0.1.163 → 0.1.165

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.
Binary file
Binary file
Binary file
Binary file
@@ -466,10 +466,14 @@ export class DaemonServer {
466
466
  // receive is the inline FileModel-JSON-over-bulkmsg envelope the
467
467
  // Beagle apps themselves use. Detected via the DHT-key signature.
468
468
  if (this.peerManager?.isNativeFriend(userid)) {
469
- const INLINE_MAX = 2 * 1024 * 1024; // base64 inflates ~1.37x; protocol cap is 5MB
469
+ // The FileModel JSON envelope is base64 (inflates ~1.34x) + a little
470
+ // JSON overhead, and the whole thing must fit the 5MB bulkmsg cap
471
+ // (CARRIER_MAX_APP_BULKMSG_LEN). 3.5MB raw → ~4.7MB envelope, safely
472
+ // under 5MB. (Was a conservative 2MB.)
473
+ const INLINE_MAX = 3.5 * 1024 * 1024;
470
474
  if (data.length > INLINE_MAX) {
471
475
  throw new Error(`This friend is a native (iOS/Android) client — files are sent inline and limited to ` +
472
- `${(INLINE_MAX / 1024 / 1024) | 0} MB (this is ${(data.length / 1024 / 1024).toFixed(1)} MB).`);
476
+ `${(INLINE_MAX / 1024 / 1024).toFixed(1)} MB (this is ${(data.length / 1024 / 1024).toFixed(1)} MB).`);
473
477
  }
474
478
  await this.peerManager.sendInlineFile(userid, new Uint8Array(data), name);
475
479
  this.logger.info(`Sent inline file "${name}" (${data.length}B) to native peer ${userid.slice(0, 8)}`);
@@ -151,7 +151,7 @@ var PeerWebRTC = (() => {
151
151
  var DEFAULT_ICE_SERVERS = [
152
152
  { urls: "stun:stun.l.google.com:19302" }
153
153
  ];
154
- var _opts, _iceServers, _sessions, _CallEngine_instances, handleSignal_fn, onOffer_fn, onAnswer_fn, onCandidate_fn, onBye_fn, onAuxiliary_fn, createSession_fn, wirePeerConnection_fn, ensureRemoteStream_fn, attachLocalMedia_fn, flushLocalCandidates_fn, drainRemoteCandidates_fn, send_fn, sendByeSafe_fn, cleanup_fn, setState_fn, _toInfo, newCallId_fn, log_fn;
154
+ var _opts, _iceServers, _sessions, _CallEngine_instances, handleSignal_fn, onOffer_fn, onAnswer_fn, onCandidate_fn, onBye_fn, onAuxiliary_fn, createSession_fn, wirePeerConnection_fn, ensureRemoteStream_fn, attachLocalMedia_fn, flushLocalCandidates_fn, drainRemoteCandidates_fn, send_fn, sendByeSafe_fn, cleanup_fn, setState_fn, normId_fn, _toInfo, newCallId_fn, log_fn;
155
155
  var CallEngine = class extends Emitter {
156
156
  constructor(opts) {
157
157
  var _a;
@@ -232,7 +232,7 @@ var PeerWebRTC = (() => {
232
232
  * local media, applies the stored offer, and sends the answer.
233
233
  */
234
234
  async accept(callId) {
235
- const session = __privateGet(this, _sessions).get(callId);
235
+ const session = __privateGet(this, _sessions).get(__privateMethod(this, _CallEngine_instances, normId_fn).call(this, callId));
236
236
  if (!session || session.direction !== "incoming" || !session.pendingOffer) {
237
237
  throw new Error(`accept: no pending incoming call ${callId}`);
238
238
  }
@@ -250,7 +250,7 @@ var PeerWebRTC = (() => {
250
250
  }
251
251
  /** Reject an incoming call (sends bye/declined). */
252
252
  async reject(callId) {
253
- const session = __privateGet(this, _sessions).get(callId);
253
+ const session = __privateGet(this, _sessions).get(__privateMethod(this, _CallEngine_instances, normId_fn).call(this, callId));
254
254
  if (!session)
255
255
  return;
256
256
  await __privateMethod(this, _CallEngine_instances, sendByeSafe_fn).call(this, session, "declined");
@@ -259,7 +259,7 @@ var PeerWebRTC = (() => {
259
259
  }
260
260
  /** Hang up an active call (sends bye/normal). */
261
261
  async hangup(callId, reason = "normal") {
262
- const session = __privateGet(this, _sessions).get(callId);
262
+ const session = __privateGet(this, _sessions).get(__privateMethod(this, _CallEngine_instances, normId_fn).call(this, callId));
263
263
  if (!session)
264
264
  return;
265
265
  await __privateMethod(this, _CallEngine_instances, sendByeSafe_fn).call(this, session, reason);
@@ -267,7 +267,7 @@ var PeerWebRTC = (() => {
267
267
  }
268
268
  /** Enable/disable a local track kind on an active call (mute / camera off). */
269
269
  setLocalTrackEnabled(callId, kind, enabled) {
270
- const session = __privateGet(this, _sessions).get(callId);
270
+ const session = __privateGet(this, _sessions).get(__privateMethod(this, _CallEngine_instances, normId_fn).call(this, callId));
271
271
  if (!(session == null ? void 0 : session.localStream))
272
272
  return;
273
273
  for (const track of session.localStream.getTracks()) {
@@ -315,7 +315,7 @@ var PeerWebRTC = (() => {
315
315
  onOffer_fn = function(peerId, signal) {
316
316
  if (!signal.sdp)
317
317
  return;
318
- const existing = __privateGet(this, _sessions).get(signal.callId);
318
+ const existing = __privateGet(this, _sessions).get(__privateMethod(this, _CallEngine_instances, normId_fn).call(this, signal.callId));
319
319
  if (existing) {
320
320
  existing.pendingOffer = signal.sdp;
321
321
  return;
@@ -329,7 +329,7 @@ var PeerWebRTC = (() => {
329
329
  __privateMethod(this, _CallEngine_instances, log_fn).call(this, `incoming call from ${peerId} callId=${signal.callId} audio=${audio} video=${video}`);
330
330
  };
331
331
  onAnswer_fn = function(peerId, signal) {
332
- const session = __privateGet(this, _sessions).get(signal.callId);
332
+ const session = __privateGet(this, _sessions).get(__privateMethod(this, _CallEngine_instances, normId_fn).call(this, signal.callId));
333
333
  if (!session || session.peerId !== peerId || !signal.sdp)
334
334
  return;
335
335
  void (async () => {
@@ -346,7 +346,7 @@ var PeerWebRTC = (() => {
346
346
  };
347
347
  onCandidate_fn = function(peerId, signal) {
348
348
  var _a;
349
- const session = __privateGet(this, _sessions).get(signal.callId);
349
+ const session = __privateGet(this, _sessions).get(__privateMethod(this, _CallEngine_instances, normId_fn).call(this, signal.callId));
350
350
  if (!session || session.peerId !== peerId || !signal.candidates)
351
351
  return;
352
352
  for (const c of signal.candidates) {
@@ -364,7 +364,7 @@ var PeerWebRTC = (() => {
364
364
  };
365
365
  onBye_fn = function(peerId, signal) {
366
366
  var _a;
367
- const session = __privateGet(this, _sessions).get(signal.callId);
367
+ const session = __privateGet(this, _sessions).get(__privateMethod(this, _CallEngine_instances, normId_fn).call(this, signal.callId));
368
368
  if (!session || session.peerId !== peerId)
369
369
  return;
370
370
  const reason = (_a = signal.reason) != null ? _a : "normal";
@@ -374,7 +374,7 @@ var PeerWebRTC = (() => {
374
374
  __privateMethod(this, _CallEngine_instances, log_fn).call(this, `bye from ${peerId} callId=${signal.callId} reason=${reason}`);
375
375
  };
376
376
  onAuxiliary_fn = function(peerId, signal) {
377
- const session = __privateGet(this, _sessions).get(signal.callId);
377
+ const session = __privateGet(this, _sessions).get(__privateMethod(this, _CallEngine_instances, normId_fn).call(this, signal.callId));
378
378
  if (!session || session.peerId !== peerId)
379
379
  return;
380
380
  if (signal.type === "event") {
@@ -405,7 +405,7 @@ var PeerWebRTC = (() => {
405
405
  remoteCandidateQueue: [],
406
406
  closed: false
407
407
  };
408
- __privateGet(this, _sessions).set(callId, session);
408
+ __privateGet(this, _sessions).set(__privateMethod(this, _CallEngine_instances, normId_fn).call(this, callId), session);
409
409
  __privateMethod(this, _CallEngine_instances, wirePeerConnection_fn).call(this, session);
410
410
  return session;
411
411
  };
@@ -523,7 +523,7 @@ var PeerWebRTC = (() => {
523
523
  } catch {
524
524
  }
525
525
  }
526
- __privateGet(this, _sessions).delete(session.callId);
526
+ __privateGet(this, _sessions).delete(__privateMethod(this, _CallEngine_instances, normId_fn).call(this, session.callId));
527
527
  if (session.state !== "ended" && session.state !== "failed") {
528
528
  session.state = endedReason === "failed" ? "failed" : "ended";
529
529
  }
@@ -535,6 +535,15 @@ var PeerWebRTC = (() => {
535
535
  session.state = state;
536
536
  this.emit("stateChanged", __privateGet(this, _toInfo).call(this, session), state);
537
537
  };
538
+ /** Canonical session key. callId is a UUID; iOS re-serializes it UPPERCASE
539
+ * (it parses our lowercase UUID into a `UUID` and echoes `.uuidString`), so
540
+ * the answer/candidates come back cased differently than the offer. Key and
541
+ * look up sessions case-insensitively — exactly as the native SDK does
542
+ * (`callId.lowercased()`). Without this, outgoing calls to iOS never match
543
+ * the answer → candidates never flush → ICE stalls at "connecting". */
544
+ normId_fn = function(callId) {
545
+ return callId.toLowerCase();
546
+ };
538
547
  _toInfo = new WeakMap();
539
548
  newCallId_fn = function() {
540
549
  if (__privateGet(this, _opts).generateCallId)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decentnetwork/lan",
3
- "version": "0.1.163",
3
+ "version": "0.1.165",
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",
@@ -80,7 +80,7 @@
80
80
  "dependencies": {
81
81
  "@decentnetwork/dora": "^0.1.13",
82
82
  "@decentnetwork/peer": "^0.1.86",
83
- "@decentnetwork/peer-webrtc": "^0.1.0",
83
+ "@decentnetwork/peer-webrtc": "^0.1.1",
84
84
  "ink": "^5.2.1",
85
85
  "js-yaml": "^4.1.0",
86
86
  "node-forge": "^1.4.0",