@decentnetwork/peer 0.1.142 → 0.1.144

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.js CHANGED
@@ -373,6 +373,10 @@ export class Peer {
373
373
  #knownNodes;
374
374
  #announceDataKey;
375
375
  #lastSelfAnnounceMs = 0;
376
+ // Env vars OR an explicit option. A browser has no process.env, so peer
377
+ // debugging there was simply unreachable — which is why the browser client
378
+ // has been a black box every time it misbehaved. The option is the only way
379
+ // in from a page.
376
380
  #debug = process.env.DECENT_DEBUG === "1" || process.env.DECENT_DEBUG_VERBOSE === "1";
377
381
  #debugVerbose = process.env.DECENT_DEBUG_VERBOSE === "1";
378
382
  #packetTrace = process.env.DECENT_PACKET_TRACE === "1";
@@ -538,6 +542,15 @@ export class Peer {
538
542
  ...opts,
539
543
  compatibilityMode: opts.compatibilityMode ?? "legacy"
540
544
  };
545
+ // A browser has no process.env, so the env-var switches above can never
546
+ // be set there and peer debugging was unreachable from a page. That is
547
+ // why every browser misbehaviour has had to be diagnosed by inference.
548
+ if (opts.debug)
549
+ this.#debug = true;
550
+ if (opts.debugVerbose) {
551
+ this.#debug = true;
552
+ this.#debugVerbose = true;
553
+ }
541
554
  this.#knownNodes = [...opts.bootstrapNodes];
542
555
  this.#friendStoreFile = opts.friendStoreFile ?? `${opts.keyFile}.friends.json`;
543
556
  // Enable resumable (断点续传) receives when the app gives us a directory to
@@ -898,6 +911,41 @@ export class Peer {
898
911
  if (!this.#bootstrap) {
899
912
  throw new Error("Peer is not started");
900
913
  }
914
+ // A browser has no UDP and never will. The DHT bootstrap is a getnodes
915
+ // datagram waiting for a sendnodes reply, so there it can only ever time
916
+ // out — 30 seconds, then an error that reads like a network fault.
917
+ //
918
+ // That cost far more than a slow start. Everything after the await lives
919
+ // downstream of it: the self-announce (without which nobody can FIND this
920
+ // peer), the announce loop, and the express pull loop (without which
921
+ // offline messages are never collected). start() launches only the
922
+ // friend-connection loop, so a browser could talk to a friend who was
923
+ // already online and whose endpoint it had cached — and nothing else.
924
+ // That is exactly the half-working shape this looked like from outside.
925
+ //
926
+ // With tcpOnlyBootstrap we skip the datagram round trip and seed the node
927
+ // list from the configured bootstrap nodes, which is what the TCP relay
928
+ // path uses anyway. Announce and both loops then run normally.
929
+ if (this.#opts.tcpOnlyBootstrap) {
930
+ const seed = this.#opts.bootstrapNodes ?? [];
931
+ if (seed.length === 0) {
932
+ throw new Error("tcpOnlyBootstrap needs at least one bootstrap node to seed from");
933
+ }
934
+ this.#knownNodes = dedupeNodes([...seed]);
935
+ await this.#runSelfAnnounce(false, Date.now() + JOIN_ANNOUNCE_TIMEOUT_MS);
936
+ this.#ensureSelfAnnounceLoop();
937
+ this.#ensureDhtMaintenanceLoop();
938
+ this.#ensureFriendConnectionLoop();
939
+ this.#ensureExpressPullLoop();
940
+ void this.#doFriendConnections().catch((error) => {
941
+ this.#debugLog(`initial friend connection cycle failed: ${error.message}`);
942
+ });
943
+ const first = seed[0];
944
+ return {
945
+ respondingNode: first,
946
+ discoveredNodes: []
947
+ };
948
+ }
901
949
  const result = await this.#bootstrap.join();
902
950
  this.#recordNodeSuccess(`${result.respondingNode.host}:${result.respondingNode.port}`);
903
951
  const discovered = result.discoveredNodes.map((node) => ({
@@ -93,6 +93,17 @@ export type PeerOptions = {
93
93
  * and the field is omitted entirely (never sent as ""), so a friend keeps
94
94
  * whatever picture they already have for us. */
95
95
  punkId?: number;
96
+ /** Skip the UDP DHT bootstrap and seed the node list from bootstrapNodes.
97
+ *
98
+ * For hosts with no UDP — a browser above all. Without it joinNetwork()
99
+ * waits 30s for a datagram that cannot arrive, and everything downstream
100
+ * of it never runs: self-announce (so nobody can find this peer) and the
101
+ * express pull loop (so offline messages are never collected). */
102
+ tcpOnlyBootstrap?: boolean;
103
+ /** Turn on peer debug logging without env vars — the only route in from a
104
+ * browser, where process.env does not exist. */
105
+ debug?: boolean;
106
+ debugVerbose?: boolean;
96
107
  compatibilityMode?: CompatibilityMode;
97
108
  debugLabel?: string;
98
109
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decentnetwork/peer",
3
- "version": "0.1.142",
3
+ "version": "0.1.144",
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",