@vex-chat/libvex 4.0.0 → 5.1.0

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/README.md CHANGED
@@ -7,13 +7,12 @@
7
7
  [![Types](https://img.shields.io/npm/types/@vex-chat/libvex?style=flat-square&logo=typescript&color=3178c6)](./dist/index.d.ts)
8
8
  [![Type Coverage](https://img.shields.io/badge/dynamic/json?style=flat-square&label=type-coverage&prefix=%E2%89%A5&suffix=%25&query=$.typeCoverage.atLeast&url=https://raw.githubusercontent.com/vex-protocol/libvex-js/master/package.json&color=3178c6&logo=typescript)](https://github.com/plantain-00/type-coverage)
9
9
  [![Node](https://img.shields.io/node/v/@vex-chat/libvex?style=flat-square&color=339933&logo=nodedotjs)](./package.json)
10
- [![Bundle](https://deno.bundlejs.com/badge?q=@vex-chat/libvex&treeshake=[*])](https://bundlejs.com/?q=@vex-chat/libvex&treeshake=[*])
11
10
  [![OpenSSF Scorecard](https://img.shields.io/ossf-scorecard/github.com/vex-protocol/libvex-js?style=flat-square&label=Scorecard)](https://securityscorecards.dev/viewer/?uri=github.com/vex-protocol/libvex-js)
12
11
  [![Socket](https://socket.dev/api/badge/npm/package/@vex-chat/libvex)](https://socket.dev/npm/package/@vex-chat/libvex)
13
12
 
14
- Reference TypeScript client for the [Vex](https://vex.wtf) encrypted chat platform. Builds against the wire protocol defined in [@vex-chat/types](https://github.com/vex-protocol/types-js) and the cryptographic primitives in [@vex-chat/crypto](https://github.com/vex-protocol/crypto-js). Use it to build a chat client, a bot, or any application that needs to talk to a [spire](https://github.com/vex-protocol/spire) server.
13
+ Reference TypeScript client for the [Vex](https://vex.wtf) protocol. Use it to build a chat client, a bot, or between two clients that need encrypted comms via [spire](https://github.com/vex-protocol/spire) server.
15
14
 
16
- [Documentation](https://vex-chat.github.io/libvex-js/)
15
+ [Documentation](https://lib.vex.wtf/)
17
16
 
18
17
  ## What's in the box
19
18
 
@@ -22,8 +21,7 @@ The client implements an X3DH-style handshake (X25519 DH + KDF), XSalsa20-Poly13
22
21
  - **End-to-end encrypted messaging** with X3DH key agreement — sessions, prekeys, and one-time keys handled internally.
23
22
  - **Tree-shakable subpath exports** for platform-specific code: `./preset/node`, `./preset/test`, `./storage/node`, `./storage/sqlite`, `./storage/schema`, `./keystore/node`, `./keystore/memory`. Browser bundles never pull in `better-sqlite3` or other native modules.
24
23
  - **Pluggable storage backend** via Kysely so node consumers can use SQLite and browser/tauri/expo consumers can wire their own.
25
- - **Pluggable key store** so secrets can live in memory (tests), the OS keychain (`./keystore/node`), or wherever the embedding app keeps them.
26
- - **WebSocket transport** for live message delivery with automatic reconnection and HTTP fallback for the REST API.
24
+ - **Pluggable key store** so secrets can live in memory (tests), passphrase-encrypted files on disk (`./keystore/node`), or wherever the embedding app keeps them.
27
25
 
28
26
  ## Install
29
27
 
@@ -31,7 +29,7 @@ The client implements an X3DH-style handshake (X25519 DH + KDF), XSalsa20-Poly13
31
29
  npm install @vex-chat/libvex
32
30
  ```
33
31
 
34
- `@vex-chat/types`, `@vex-chat/crypto`, `axios`, `kysely`, `winston`, and `zod` are required runtime dependencies and install automatically.
32
+ `@vex-chat/types`, `@vex-chat/crypto`, `axios`, `eventemitter3`, `kysely`, `msgpackr`, `uuid`, and `zod` are required runtime dependencies and install automatically.
35
33
 
36
34
  `better-sqlite3` is an **optional peer dependency** — install it explicitly only if you plan to use the SQLite storage backend on Node:
37
35
 
@@ -46,17 +44,20 @@ Browser, Tauri, and Expo consumers should leave `better-sqlite3` out and supply
46
44
  ```ts
47
45
  import { Client } from "@vex-chat/libvex";
48
46
 
49
- // Generate or load a long-lived secret key — store it in the OS keychain.
47
+ // Generate or load a long-lived secret key.
50
48
  const secretKey = Client.generateSecretKey();
51
49
 
52
50
  const client = await Client.create(secretKey);
53
51
 
54
52
  // First-time devices must register before logging in.
55
- await client.register(Client.randomUsername());
56
- await client.login();
53
+ await client.register("myUsername", "myPassword");
54
+ await client.login("myUsername", "myPassword");
57
55
 
58
- client.on("authed", async () => {
59
- const me = await client.users.me();
56
+ // connect() authenticates the WebSocket and fires "ready" when done.
57
+ await client.connect();
58
+
59
+ client.on("ready", async () => {
60
+ const me = client.me.user();
60
61
  await client.messages.send(me.userID, "Hello world!");
61
62
  });
62
63
 
@@ -70,27 +71,19 @@ client.on("message", (message) => {
70
71
  libvex ships per-platform "presets" that wire together the appropriate storage and keystore:
71
72
 
72
73
  ```ts
73
- // Node — sqlite storage + OS keychain
74
- import {
75
- Client,
76
- makeStorage,
77
- BootstrapConfig,
78
- } from "@vex-chat/libvex/preset/node";
79
-
80
- // Tests / ephemeral — in-memory storage + memory keystore
81
- import {
82
- Client,
83
- makeStorage,
84
- BootstrapConfig,
85
- } from "@vex-chat/libvex/preset/test";
74
+ // Node — sqlite storage + encrypted file keystore
75
+ import { nodePreset } from "@vex-chat/libvex/preset/node";
76
+
77
+ // Tests / ephemeral — in-memory storage, no persistence
78
+ import { testPreset } from "@vex-chat/libvex/preset/test";
86
79
  ```
87
80
 
88
- For a custom platform (browser, tauri, expo), import `Client` from `@vex-chat/libvex` directly and supply your own `Storage` (implementing the schema in `@vex-chat/libvex/storage/schema`) and `KeyStore` to `Client.create`.
81
+ Presets return a `PlatformPreset` with a `createStorage()` factory and a `deviceName`. For a custom platform (browser, tauri, expo), import `Client` from `@vex-chat/libvex` directly and supply your own `Storage` (implementing the schema in `@vex-chat/libvex/storage/schema`) and `KeyStore` to `Client.create`.
89
82
 
90
83
  ## Development
91
84
 
92
85
  ```sh
93
- npm run build # tsc -p tsconfig.build.json
86
+ npm run build # rimraf dist && tsc -p tsconfig.build.json
94
87
  npm run lint # eslint
95
88
  npm run lint:fix # eslint --fix
96
89
  npm run format # prettier --write
@@ -105,7 +98,7 @@ npm run license:check # license allowlist gate
105
98
  npm run docs # typedoc — writes ./docs
106
99
  ```
107
100
 
108
- The unit suite (`npm test`) runs browser-safe and offline. The e2e suite (`npm run test:e2e`) spins up a real spire server in a separate process point `VEX_API_URL` at a running spire if you want to test against a different host.
101
+ The unit suite (`npm test`) runs browser-safe and offline. The e2e suite (`npm run test:e2e`) requires a running spire server — set `VEX_API_URL` to point at it (defaults to `localhost`).
109
102
 
110
103
  See [AGENTS.md](./AGENTS.md) for the release flow (changesets → publish) and the rules for writing changesets.
111
104
 
package/dist/Client.d.ts CHANGED
@@ -55,6 +55,12 @@ export interface ClientOptions {
55
55
  saveHistory?: boolean;
56
56
  /** Use `http/ws` instead of `https/wss`. Intended for local/dev environments. */
57
57
  unsafeHttp?: boolean;
58
+ /**
59
+ * When set (non-empty), sent as `x-dev-api-key` on every HTTP request.
60
+ * Spire omits in-process rate limits when this matches the server's `DEV_API_KEY`
61
+ * (local / load-testing only — never use in production).
62
+ */
63
+ devApiKey?: string;
58
64
  }
59
65
  /**
60
66
  * @ignore
@@ -506,6 +512,11 @@ export declare class Client {
506
512
  private firstMailFetch;
507
513
  private readonly forwarded;
508
514
  private readonly host;
515
+ /**
516
+ * Node-only: per-client HTTP(S) agents (see `init()` + `storage/node/http-agents`).
517
+ * Dropped on `close()` so idle keep-alive sockets do not keep the process alive.
518
+ */
519
+ private nodeHttpAgents?;
509
520
  private readonly http;
510
521
  private readonly idKeys;
511
522
  private isAlive;
@@ -553,12 +564,24 @@ export declare class Client {
553
564
  static randomUsername(): string;
554
565
  private static deserializeExtra;
555
566
  private static getMnemonic;
567
+ /**
568
+ * True when running under Node (has `process.versions`).
569
+ * Uses indirect lookup so the bare `process` global never appears in
570
+ * source that the platform-guard plugin scans.
571
+ */
572
+ private static isNodeRuntime;
556
573
  /**
557
574
  * Browser-safe NODE_ENV accessor.
558
575
  * Uses indirect lookup so the bare `process` global never appears in
559
576
  * source that the platform-guard plugin scans.
560
577
  */
561
578
  private static getNodeEnv;
579
+ /**
580
+ * Fresh read of the `manuallyClosing` flag for async loops — direct property checks
581
+ * after `await` are flagged as always-false by control-flow analysis even though
582
+ * `close()` can run concurrently.
583
+ */
584
+ private isManualCloseInFlight;
562
585
  /**
563
586
  * Closes the client — disconnects the WebSocket, shuts down storage,
564
587
  * and emits `closed` unless `muteEvent` is `true`.
@@ -656,7 +679,6 @@ export declare class Client {
656
679
  */
657
680
  whoami(): Promise<{
658
681
  exp: number;
659
- token: string;
660
682
  user: User;
661
683
  }>;
662
684
  private censorPreKey;
@@ -701,7 +723,20 @@ export declare class Client {
701
723
  private getSessionList;
702
724
  private getToken;
703
725
  private getUser;
726
+ private deviceListFailureDetail;
727
+ /**
728
+ * Single GET for `/user/:id/devices`. On failure returns `null` (swallows errors)
729
+ * — callers that need reliability should use `fetchUserDeviceListWithBackoff`.
730
+ * Similar “best effort null” patterns elsewhere: `getChannelByID`,
731
+ * `getDeviceByID` (HTTP leg), `getToken`, emoji upload fallbacks.
732
+ */
704
733
  private getUserDeviceList;
734
+ private fetchUserDeviceListOnce;
735
+ /**
736
+ * DM / forward paths need the peer’s (or self) device rows under load: bounded
737
+ * retries with exponential backoff (same shape as session pubkey hydration).
738
+ */
739
+ private fetchUserDeviceListWithBackoff;
705
740
  private getUserList;
706
741
  private handleNotify;
707
742
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Client.d.ts","sourceRoot":"","sources":["../src/Client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Client.d.ts","sourceRoot":"","sources":["../src/Client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAS5C,OAAO,KAAK,EAGR,OAAO,EACP,MAAM,EAEN,KAAK,EACL,YAAY,EACZ,OAAO,EACP,MAAM,EAIN,UAAU,EAOV,MAAM,EACN,UAAU,EACb,MAAM,iBAAiB,CAAC;AA+BzB,OAAc,EAAE,KAAK,UAAU,EAAgB,MAAM,OAAO,CAAC;AA2C7D;;;;;;;;;GASG;AACH,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,QAAQ;IACrB,qCAAqC;IACrC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7D,yBAAyB;IACzB,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,kCAAkC;IAClC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACnD,8BAA8B;IAC9B,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAC7D,kDAAkD;IAClD,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;CACpD;AAED;;;;;;;;;;GAUG;AACH,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iFAAiF;IACjF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACpB,8EAA8E;IAC9E,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACvC,gCAAgC;IAChC,QAAQ,EAAE,CAAC,gBAAgB,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAClE;AAED;;;;;;;GAOG;AACH,YAAY,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;;;;;;GAOG;AACH,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,MAAM;IACnB,0CAA0C;IAC1C,MAAM,EAAE,CACJ,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,KACf,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC3B,0CAA0C;IAC1C,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACrD,0CAA0C;IAC1C,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;CACxD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,6DAA6D;IAC7D,SAAS,EAAE,UAAU,GAAG,QAAQ,CAAC;IACjC,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,OAAO,GAAG,YAAY,CAAC;AAEnC;;GAEG;AACH,MAAM,WAAW,KAAK;IAClB,mCAAmC;IACnC,MAAM,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IACzD,6DAA6D;IAC7D,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;CAC3E;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACpB,mDAAmD;IACnD,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChE,kEAAkE;IAClE,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAClD,yCAAyC;IACzC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACrD;AAED;;;GAGG;AACH,MAAM,WAAW,IAAI;IACjB,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,EAAE;IACf,+DAA+D;IAC/D,MAAM,EAAE,MAAM,MAAM,CAAC;IACrB,gEAAgE;IAChE,SAAS,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,wDAAwD;IACxD,IAAI,EAAE,MAAM,IAAI,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACpB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,SAAS,EAAE,OAAO,CAAC;IACnB,uEAAuE;IACvE,SAAS,EAAE,UAAU,GAAG,UAAU,CAAC;IACnC,sEAAsE;IACtE,OAAO,EAAE,OAAO,CAAC;IACjB,iEAAiE;IACjE,KAAK,EAAE,IAAI,GAAG,MAAM,CAAC;IACrB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;CACrB;AAyBD;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IACzB,gEAAgE;IAChE,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,iEAAiE;IACjE,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,2CAA2C;IAC3C,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,iCAAiC;IACjC,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,qDAAqD;IACrD,YAAY,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;IAC/C,sDAAsD;IACtD,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,kDAAkD;IAClD,UAAU,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,mEAAmE;IACnE,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,mEAAmE;IACnE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CACnD;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACrB,gDAAgD;IAChD,MAAM,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,8DAA8D;IAC9D,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,kDAAkD;IAClD,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,0DAA0D;IAC1D,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACjD,2DAA2D;IAC3D,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACzD,qDAAqD;IACrD,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB,mDAAmD;IACnD,mBAAmB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACjE,2EAA2E;IAC3E,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,oCAAoC;IACpC,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACpB,wBAAwB;IACxB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,wBAAwB;IACxB,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,+DAA+D;IAC/D,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,yDAAyD;IACzD,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAClC,6BAA6B;IAC7B,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;CAC9D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,MAAM,OAAO,GAAG,UAAU,CAAC;AAEjC;;GAEG;AACH,MAAM,WAAW,QAAQ;IACrB,mDAAmD;IACnD,YAAY,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACtC,8EAA8E;IAC9E,MAAM,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,MAAM,CAAC;CAC3C;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,IAAI;IACjB,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,KAAK;IAClB,sEAAsE;IACtE,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACjC;;OAEG;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,IAAI,GAAG,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC;CAC3E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,CAAC;AAE9B,qBAAa,MAAM;IACf;;;;OAIG;IACH,OAAc,cAAc,oDAAyB;IAErD;;;;OAIG;IACH,OAAc,cAAc,kFAAyB;IAErD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAkB;IAEvD;;;;OAIG;IACH;;OAEG;IACI,QAAQ,EAAE,QAAQ,CA+BvB;IAEF;;OAEG;IACI,OAAO,EAAE,OAAO,CAIrB;IAEF;;;;;;;;OAQG;IACI,KAAK,EAAE,MAAM,CAIlB;IAEF,oCAAoC;IAC7B,KAAK,EAAE,KAAK,CASjB;IAEF;;;OAGG;IACI,OAAO,EAAE,OAAO,CAAS;IAEhC;;OAEG;IACI,WAAW,EAAE,OAAO,CAAS;IAEpC;;OAEG;IACI,OAAO,EAAE,OAAO,CAIrB;IAEF;;OAEG;IACI,EAAE,EAAE,EAAE,CAeX;IACF;;;;;;;;;OASG;IACI,QAAQ,EAAE,QAAQ,CA6BvB;IAEF;;OAEG;IACI,UAAU,EAAE,UAAU,CAG3B;IAEF;;OAEG;IACI,WAAW,EAAE,WAAW,CAG7B;IAEK,OAAO,sBAA6B;IAE3C;;;;;;;;OAQG;IACI,OAAO,EAAE,OAAO,CA0BrB;IAEF;;OAEG;IACI,QAAQ,EAAE,QAAQ,CAsBvB;IAEF;;;;;;;;OAQG;IACI,KAAK,EAAE,KAAK,CAcjB;IAEF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IAEnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,OAAO,CAAC,MAAM,CAAC,CAAS;IAExB,OAAO,CAAC,aAAa,CAA8B;IAGnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAE5D,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,cAAc,CAAQ;IAE9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAE/C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B;;;OAGG;IACH,OAAO,CAAC,cAAc,CAAC,CAGrB;IACF,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAiB;IAE/C,OAAO,CAAC,eAAe,CAAkB;IAIzC,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA6B;IAE3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA4B;IAErD,OAAO,CAAC,YAAY,CAA8C;IAClE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAEgB;IAEzC,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA0B;IACtD,OAAO,CAAC,cAAc,CAAqC;IAE3D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IAEnC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,IAAI,CAAC,CAAO;IAEpB,OAAO,CAAC,WAAW,CAA4B;IAE/C,OAAO,CAAC,QAAQ,CAAC,CAAW;IAE5B,OAAO;IA0DP;;;;;;;;;;;OAWG;IACH,OAAc,MAAM,GAChB,aAAa,MAAM,EACnB,UAAU,aAAa,EACvB,UAAU,OAAO,KAClB,OAAO,CAAC,MAAM,CAAC,CAmBhB;IAEF;;;;OAIG;WACW,iBAAiB,IAAI,MAAM;IAIzC;;;;OAIG;WACW,cAAc;IAU5B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAqB/B,OAAO,CAAC,MAAM,CAAC,WAAW;IAI1B;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAqB5B;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,UAAU;IAkCzB;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAI7B;;;;;OAKG;IACU,KAAK,CAAC,SAAS,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BpD;;;OAGG;IACU,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAmCrC;;;OAGG;IACU,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3C;;;;;;;OAOG;IACI,OAAO;IAId;;OAEG;IACI,OAAO,IAAI,IAAI;IAOtB;;;;;;;;;;;;OAYG;IACU,KAAK,CACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACjB,OAAO,CAAC;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAA;KAAE,CAAC;IAwB3C;;;;;;;OAOG;IACU,kBAAkB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IA6CzE;;OAEG;IACU,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC,gFAAgF;IAChF,GAAG,CAAC,CAAC,SAAS,MAAM,YAAY,EAC5B,KAAK,EAAE,CAAC,EACR,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,EACpB,OAAO,CAAC,EAAE,OAAO,GAClB,IAAI;IAUP,6EAA6E;IAC7E,EAAE,CAAC,CAAC,SAAS,MAAM,YAAY,EAC3B,KAAK,EAAE,CAAC,EACR,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC,EACnB,OAAO,CAAC,EAAE,OAAO,GAClB,IAAI;IAMP,qEAAqE;IACrE,IAAI,CAAC,CAAC,SAAS,MAAM,YAAY,EAC7B,KAAK,EAAE,CAAC,EACR,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC,EACnB,OAAO,CAAC,EAAE,OAAO,GAClB,IAAI;IAMP;;;;;;;;;;;OAWG;IACU,QAAQ,CACjB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACjB,OAAO,CAAC,CAAC,IAAI,GAAG,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC;IAuDvC,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,YAAY,GAAG,IAAI;IAKpD;;OAEG;IACI,QAAQ,IAAI,MAAM;IASzB;;;;;;;;;;OAUG;IACU,MAAM,IAAI,OAAO,CAAC;QAC3B,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,IAAI,CAAC;KACd,CAAC;IAOF,OAAO,CAAC,YAAY;YAYN,aAAa;YAcb,UAAU;YAyDV,YAAY;IAe1B,OAAO,CAAC,YAAY;YAWN,YAAY;YAOZ,aAAa;YAyKb,aAAa;YAIb,YAAY;YAcZ,aAAa;YAIb,gBAAgB;YAIhB,YAAY;IAG1B;;;;OAIG;YACW,mBAAmB;YAWnB,SAAS;YAiCT,OAAO;YA2CP,cAAc;YAWd,cAAc;IAO5B,OAAO,CAAC,SAAS;YASH,aAAa;YAwBb,YAAY;YAcZ,eAAe;YAOf,OAAO;YA6CP,iBAAiB;YAOjB,sBAAsB;YAkBtB,WAAW;IAUzB;;;;OAIG;YACW,cAAc;YAOd,aAAa;YAWb,aAAa;YAOb,kBAAkB;YAYlB,cAAc;YAId,QAAQ;IAsBtB,OAAO,CAAC,OAAO;IASf,OAAO,CAAC,uBAAuB;IAc/B;;;;;OAKG;YACW,iBAAiB;YAQjB,uBAAuB;IAWrC;;;OAGG;YACW,8BAA8B;YAqC9B,WAAW;YAOX,YAAY;IAoB1B;;OAEG;YACW,IAAI;IA+BlB,OAAO,CAAC,UAAU;YA+EJ,QAAQ;YAWR,WAAW;YASX,mBAAmB;YAInB,YAAY;IAU1B,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,IAAI;IAOZ,OAAO,CAAC,IAAI;YAIE,eAAe;YAsCf,QAAQ;YA8BR,YAAY;YAIZ,QAAQ;YAiSR,YAAY;YAOZ,cAAc;IAqD5B,OAAO,CAAC,OAAO;YAYD,iBAAiB;YAUjB,iBAAiB;YAOjB,YAAY;YA8CZ,eAAe;YAOf,iBAAiB;YAOjB,sBAAsB;YA+BtB,IAAI;YAkBJ,gBAAgB;YAyChB,QAAQ;YAgGR,WAAW;IAwCzB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,OAAO;YAID,SAAS;YAkBT,YAAY;YA+CZ,WAAW;CAsD5B"}
package/dist/Client.js CHANGED
@@ -307,6 +307,11 @@ export class Client {
307
307
  firstMailFetch = true;
308
308
  forwarded = new Set();
309
309
  host;
310
+ /**
311
+ * Node-only: per-client HTTP(S) agents (see `init()` + `storage/node/http-agents`).
312
+ * Dropped on `close()` so idle keep-alive sockets do not keep the process alive.
313
+ */
314
+ nodeHttpAgents;
310
315
  http;
311
316
  idKeys;
312
317
  isAlive = true;
@@ -366,6 +371,10 @@ export class Client {
366
371
  void this.close(true);
367
372
  });
368
373
  this.http = axios.create({ responseType: "arraybuffer" });
374
+ const devKey = options?.devApiKey?.trim();
375
+ if (devKey !== undefined && devKey.length > 0) {
376
+ this.http.defaults.headers.common["x-dev-api-key"] = devKey;
377
+ }
369
378
  this.socket = new WebSocketAdapter(this.prefixes.WS + this.host);
370
379
  this.socket.onerror = () => { };
371
380
  }
@@ -440,6 +449,27 @@ export class Client {
440
449
  static getMnemonic(session) {
441
450
  return xMnemonic(xKDF(XUtils.decodeHex(session.fingerprint)));
442
451
  }
452
+ /**
453
+ * True when running under Node (has `process.versions`).
454
+ * Uses indirect lookup so the bare `process` global never appears in
455
+ * source that the platform-guard plugin scans.
456
+ */
457
+ static isNodeRuntime() {
458
+ try {
459
+ const g = Object.getOwnPropertyDescriptor(globalThis, "\u0070rocess");
460
+ if (!g)
461
+ return false;
462
+ const proc = typeof g.get === "function" ? g.get() : g.value;
463
+ if (typeof proc !== "object" || proc === null) {
464
+ return false;
465
+ }
466
+ return ("versions" in proc &&
467
+ typeof proc.versions === "object");
468
+ }
469
+ catch {
470
+ return false;
471
+ }
472
+ }
443
473
  /**
444
474
  * Browser-safe NODE_ENV accessor.
445
475
  * Uses indirect lookup so the bare `process` global never appears in
@@ -448,20 +478,42 @@ export class Client {
448
478
  static getNodeEnv() {
449
479
  try {
450
480
  const g = Object.getOwnPropertyDescriptor(globalThis, "\u0070rocess");
451
- if (!g || typeof g.value !== "object" || g.value === null) {
481
+ if (!g)
482
+ return undefined;
483
+ // Node 24+ exposes `process` as an accessor (get/set), not a value.
484
+ const proc = typeof g.get === "function" ? g.get() : g.value;
485
+ if (typeof proc !== "object" || proc === null) {
452
486
  return undefined;
453
487
  }
454
- const env = Object.getOwnPropertyDescriptor(g.value, "env")?.value;
488
+ const envDesc = Object.getOwnPropertyDescriptor(proc, "env");
489
+ if (!envDesc)
490
+ return undefined;
491
+ const env = typeof envDesc.get === "function"
492
+ ? envDesc.get()
493
+ : envDesc.value;
455
494
  if (typeof env !== "object" || env === null) {
456
495
  return undefined;
457
496
  }
458
- const val = Object.getOwnPropertyDescriptor(env, "NODE_ENV")?.value;
497
+ const valDesc = Object.getOwnPropertyDescriptor(env, "NODE_ENV");
498
+ if (!valDesc)
499
+ return undefined;
500
+ const val = typeof valDesc.get === "function"
501
+ ? valDesc.get()
502
+ : valDesc.value;
459
503
  return typeof val === "string" ? val : undefined;
460
504
  }
461
505
  catch {
462
506
  return undefined;
463
507
  }
464
508
  }
509
+ /**
510
+ * Fresh read of the `manuallyClosing` flag for async loops — direct property checks
511
+ * after `await` are flagged as always-false by control-flow analysis even though
512
+ * `close()` can run concurrently.
513
+ */
514
+ isManualCloseInFlight() {
515
+ return this.manuallyClosing;
516
+ }
465
517
  /**
466
518
  * Closes the client — disconnects the WebSocket, shuts down storage,
467
519
  * and emits `closed` unless `muteEvent` is `true`.
@@ -472,6 +524,11 @@ export class Client {
472
524
  this.manuallyClosing = true;
473
525
  this.socket.close();
474
526
  await this.database.close();
527
+ if (this.nodeHttpAgents) {
528
+ this.nodeHttpAgents.http.destroy();
529
+ this.nodeHttpAgents.https.destroy();
530
+ delete this.nodeHttpAgents;
531
+ }
475
532
  if (this.pingInterval) {
476
533
  clearInterval(this.pingInterval);
477
534
  }
@@ -489,9 +546,10 @@ export class Client {
489
546
  * You can check whoami() to see before calling connect().
490
547
  */
491
548
  async connect() {
492
- const { token, user } = await this.whoami();
493
- this.token = token;
494
- this.http.defaults.headers.common.Authorization = `Bearer ${token}`;
549
+ if (!this.token) {
550
+ throw new Error("No token call login() or loginWithDeviceKey() first.");
551
+ }
552
+ const { user } = await this.whoami();
495
553
  this.setUser(user);
496
554
  this.device = await this.retrieveOrCreateDevice();
497
555
  const connectToken = await this.getToken("connect");
@@ -795,6 +853,9 @@ export class Client {
795
853
  return;
796
854
  }
797
855
  if (!this.xKeyRing) {
856
+ if (this.manuallyClosing) {
857
+ return;
858
+ }
798
859
  throw new Error("Key ring not initialized.");
799
860
  }
800
861
  // my keys
@@ -985,10 +1046,7 @@ export class Client {
985
1046
  this.forwarded.delete(first);
986
1047
  }
987
1048
  const msgBytes = Uint8Array.from(msgpack.encode(copy));
988
- const devices = await this.getUserDeviceList(this.getUser().userID);
989
- if (!devices) {
990
- throw new Error("Couldn't get own devices.");
991
- }
1049
+ const devices = await this.fetchUserDeviceListWithBackoff(this.getUser().userID, "own");
992
1050
  const promises = [];
993
1051
  for (const device of devices) {
994
1052
  if (device.deviceID !== this.getDevice().deviceID) {
@@ -1059,6 +1117,9 @@ export class Client {
1059
1117
  return messages;
1060
1118
  }
1061
1119
  async getMail() {
1120
+ if (this.manuallyClosing) {
1121
+ return;
1122
+ }
1062
1123
  while (this.fetchingMail) {
1063
1124
  await sleep(500);
1064
1125
  }
@@ -1175,19 +1236,74 @@ export class Client {
1175
1236
  }
1176
1237
  return this.user;
1177
1238
  }
1239
+ deviceListFailureDetail(err) {
1240
+ if (!isAxiosError(err)) {
1241
+ return "";
1242
+ }
1243
+ const st = err.response?.status;
1244
+ if (typeof st === "number") {
1245
+ return ` (HTTP ${String(st)})`;
1246
+ }
1247
+ if (err.code !== undefined) {
1248
+ return ` (${err.code})`;
1249
+ }
1250
+ return "";
1251
+ }
1252
+ /**
1253
+ * Single GET for `/user/:id/devices`. On failure returns `null` (swallows errors)
1254
+ * — callers that need reliability should use `fetchUserDeviceListWithBackoff`.
1255
+ * Similar “best effort null” patterns elsewhere: `getChannelByID`,
1256
+ * `getDeviceByID` (HTTP leg), `getToken`, emoji upload fallbacks.
1257
+ */
1178
1258
  async getUserDeviceList(userID) {
1179
1259
  try {
1180
- const res = await this.http.get(this.getHost() + "/user/" + userID + "/devices");
1181
- const devices = decodeAxios(DeviceArrayCodec, res.data);
1182
- for (const device of devices) {
1183
- this.deviceRecords[device.deviceID] = device;
1184
- }
1185
- return devices;
1260
+ return await this.fetchUserDeviceListOnce(userID);
1186
1261
  }
1187
1262
  catch (_err) {
1188
1263
  return null;
1189
1264
  }
1190
1265
  }
1266
+ async fetchUserDeviceListOnce(userID) {
1267
+ const res = await this.http.get(this.getHost() + "/user/" + userID + "/devices");
1268
+ const devices = decodeAxios(DeviceArrayCodec, res.data);
1269
+ for (const device of devices) {
1270
+ this.deviceRecords[device.deviceID] = device;
1271
+ }
1272
+ return devices;
1273
+ }
1274
+ /**
1275
+ * DM / forward paths need the peer’s (or self) device rows under load: bounded
1276
+ * retries with exponential backoff (same shape as session pubkey hydration).
1277
+ */
1278
+ async fetchUserDeviceListWithBackoff(userID, label) {
1279
+ const base = label === "own"
1280
+ ? "Couldn't get own devices"
1281
+ : "Couldn't get device list";
1282
+ let lastErr;
1283
+ for (let attempt = 0; attempt < 5; attempt++) {
1284
+ if (attempt > 0) {
1285
+ if (this.isManualCloseInFlight()) {
1286
+ throw new Error(`${base}${this.deviceListFailureDetail(lastErr)}`);
1287
+ }
1288
+ const delayMs = 100 * 2 ** (attempt - 1);
1289
+ // Chunk the delay to allow close() to interrupt
1290
+ const chunkMs = 10;
1291
+ for (let elapsed = 0; elapsed < delayMs; elapsed += chunkMs) {
1292
+ if (this.isManualCloseInFlight()) {
1293
+ throw new Error(`${base}${this.deviceListFailureDetail(lastErr)}`);
1294
+ }
1295
+ await sleep(Math.min(chunkMs, delayMs - elapsed));
1296
+ }
1297
+ }
1298
+ try {
1299
+ return await this.fetchUserDeviceListOnce(userID);
1300
+ }
1301
+ catch (err) {
1302
+ lastErr = err;
1303
+ }
1304
+ }
1305
+ throw new Error(`${base}${this.deviceListFailureDetail(lastErr)}`);
1306
+ }
1191
1307
  async getUserList(channelID) {
1192
1308
  const res = await this.http.post(this.getHost() + "/userList/" + channelID);
1193
1309
  return decodeAxios(UserArrayCodec, res.data);
@@ -1216,6 +1332,12 @@ export class Client {
1216
1332
  throw new Error("You should only call init() once.");
1217
1333
  }
1218
1334
  this.hasInit = true;
1335
+ if (Client.isNodeRuntime()) {
1336
+ const { attachNodeAgentsToAxios, createNodeHttpAgents } = await import("./storage/node/http-agents.js");
1337
+ const agents = createNodeHttpAgents();
1338
+ this.nodeHttpAgents = agents;
1339
+ attachNodeAgentsToAxios(this.http, agents);
1340
+ }
1219
1341
  await this.populateKeyRing();
1220
1342
  this.emitter.on("message", (message) => {
1221
1343
  if (message.direction === "outgoing" && !message.forward) {
@@ -1329,6 +1451,9 @@ export class Client {
1329
1451
  }
1330
1452
  newEphemeralKeys() {
1331
1453
  if (!this.xKeyRing) {
1454
+ if (this.manuallyClosing) {
1455
+ return;
1456
+ }
1332
1457
  throw new Error("Key ring not initialized.");
1333
1458
  }
1334
1459
  this.xKeyRing.ephemeralKeys = xBoxKeyPair();
@@ -1372,6 +1497,9 @@ export class Client {
1372
1497
  async postAuth() {
1373
1498
  let count = 0;
1374
1499
  for (;;) {
1500
+ if (this.isManualCloseInFlight()) {
1501
+ return;
1502
+ }
1375
1503
  try {
1376
1504
  await this.getMail();
1377
1505
  count++;
@@ -1382,7 +1510,17 @@ export class Client {
1382
1510
  }
1383
1511
  }
1384
1512
  catch { }
1385
- await sleep(1000 * 60);
1513
+ if (this.isManualCloseInFlight()) {
1514
+ return;
1515
+ }
1516
+ // Chunk the idle delay so `close()` can unwind instead of waiting
1517
+ // out one full 60s timer (which would keep the process alive).
1518
+ for (let i = 0; i < 60; i++) {
1519
+ if (this.isManualCloseInFlight()) {
1520
+ return;
1521
+ }
1522
+ await sleep(1000);
1523
+ }
1386
1524
  }
1387
1525
  }
1388
1526
  async purgeHistory() {
@@ -1393,6 +1531,9 @@ export class Client {
1393
1531
  return;
1394
1532
  }
1395
1533
  this.seenMailIDs.add(mail.mailID);
1534
+ if (this.manuallyClosing) {
1535
+ return;
1536
+ }
1396
1537
  this.sendReceipt(new Uint8Array(mail.nonce));
1397
1538
  let timeout = 1;
1398
1539
  while (this.reading) {
@@ -1402,6 +1543,9 @@ export class Client {
1402
1543
  this.reading = true;
1403
1544
  try {
1404
1545
  const healSession = async () => {
1546
+ if (this.manuallyClosing || !this.xKeyRing) {
1547
+ return;
1548
+ }
1405
1549
  const deviceEntry = await this.getDeviceByID(mail.sender);
1406
1550
  const [user, _err] = await this.fetchUser(mail.authorID);
1407
1551
  if (deviceEntry && user) {
@@ -1432,7 +1576,7 @@ export class Client {
1432
1576
  const IK_A = IK_A_raw;
1433
1577
  const EK_A = ephKey;
1434
1578
  if (!this.xKeyRing) {
1435
- throw new Error("Key ring not initialized.");
1579
+ return;
1436
1580
  }
1437
1581
  // my private keys
1438
1582
  const IK_B = this.xKeyRing.identityKeys.secretKey;
@@ -1853,17 +1997,7 @@ export class Client {
1853
1997
  if (!userEntry) {
1854
1998
  throw new Error("Couldn't get user entry.");
1855
1999
  }
1856
- let deviceList = await this.getUserDeviceList(userID);
1857
- if (!deviceList) {
1858
- let retries = 0;
1859
- while (!deviceList) {
1860
- deviceList = await this.getUserDeviceList(userID);
1861
- retries++;
1862
- if (retries > 3) {
1863
- throw new Error("Couldn't get device list.");
1864
- }
1865
- }
1866
- }
2000
+ const deviceList = await this.fetchUserDeviceListWithBackoff(userID, "peer");
1867
2001
  const mailID = uuid.v4();
1868
2002
  const promises = [];
1869
2003
  for (const device of deviceList) {