@glassly/cloud-client 0.1.0-dev.90 → 0.1.0-dev.96
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glassly/cloud-client",
|
|
3
|
-
"version": "0.1.0-dev.
|
|
3
|
+
"version": "0.1.0-dev.96",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"exports": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"test": "bun test"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@glassly/cloud-protocol": "0.1.0-dev.
|
|
15
|
+
"@glassly/cloud-protocol": "0.1.0-dev.96",
|
|
16
16
|
"tweetnacl": "^1.0.3"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
package/src/client.ts
CHANGED
|
@@ -22,9 +22,8 @@ import { CloudClientError } from "./errors";
|
|
|
22
22
|
import type { ConnectionInit } from "@glassly/cloud-protocol";
|
|
23
23
|
import { systemTimers } from "./timers";
|
|
24
24
|
|
|
25
|
-
// The module implementations
|
|
26
|
-
//
|
|
27
|
-
// design.md exactly.
|
|
25
|
+
// The module implementations, under ./modules/**. This file only constructs
|
|
26
|
+
// them, matching the constructor signatures fixed in design.md exactly.
|
|
28
27
|
import { Auth } from "./modules/auth/auth";
|
|
29
28
|
import { TokenStore } from "./modules/auth/token-store";
|
|
30
29
|
import { Runtime } from "./modules/runtime/runtime";
|
|
@@ -51,12 +50,12 @@ import { Core } from "./modules/core/core";
|
|
|
51
50
|
const DEFAULT_RECONNECT = { baseMs: 500, maxMs: 5_000, jitter: true };
|
|
52
51
|
|
|
53
52
|
/**
|
|
54
|
-
* The default audio codec the client announces in the handshake
|
|
53
|
+
* The default audio codec the client announces in the handshake when a host
|
|
54
|
+
* does not set `config.audio.codec`.
|
|
55
55
|
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* after connect is decoded correctly.
|
|
56
|
+
* PCM at 16 kHz needs no frame-size negotiation, so it is the safe default; a
|
|
57
|
+
* host whose device captures LC3 sets `config.audio.codec = "lc3"` (and the
|
|
58
|
+
* required `frameSizeBytes`) explicitly.
|
|
60
59
|
*/
|
|
61
60
|
const DEFAULT_AUDIO_CODEC = "pcm" as const;
|
|
62
61
|
const DEFAULT_AUDIO_SAMPLE_RATE = 16_000;
|
package/src/modules/auth/auth.ts
CHANGED
|
@@ -411,9 +411,9 @@ export class Auth implements AuthModule {
|
|
|
411
411
|
* dead refresh token will not heal on its own, and retrying would loop.
|
|
412
412
|
*
|
|
413
413
|
* A transient failure — network error, 5xx during a deploy, 429 — keeps
|
|
414
|
-
* the stored token and propagates as-is
|
|
415
|
-
*
|
|
416
|
-
*
|
|
414
|
+
* the stored token and propagates as-is: clearing on a transient failure
|
|
415
|
+
* would log out a perfectly healthy session on a flaky cold start (e.g.
|
|
416
|
+
* first launch after an app update).
|
|
417
417
|
*/
|
|
418
418
|
private async refresh(refreshToken: string, opts?: { deferExpired?: boolean }): Promise<string> {
|
|
419
419
|
const body = new URLSearchParams({
|
|
@@ -12,30 +12,14 @@
|
|
|
12
12
|
* It never imports a real socket: the platform supplies a `WebSocketLike`
|
|
13
13
|
* factory, so the same code runs on the phone and in a Node/Bun test harness.
|
|
14
14
|
*
|
|
15
|
-
* Reconnect
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* nothing schedules the next retry, so the client sits SILENTLY disconnected
|
|
24
|
-
* forever until a full app relaunch. We hit this in dev (ADB/Metro flapping
|
|
25
|
-
* wedged the v2 socket; only a cold relaunch recovered it).
|
|
26
|
-
*
|
|
27
|
-
* Three changes close that gap, belt-and-suspenders:
|
|
28
|
-
* 0. A failed initial `open()` now also enters the reconnect loop. Before
|
|
29
|
-
* this, reconnect was robust only AFTER the first successful session had
|
|
30
|
-
* dropped; if the app booted while cloud was down, `open()` rejected and no
|
|
31
|
-
* retry was queued.
|
|
32
|
-
* 1. The scheduled attempt's `.catch()` now reschedules itself, so a failure
|
|
33
|
-
* that did NOT fire `onClose` still queues the next try. `scheduleReconnect`
|
|
34
|
-
* is idempotent (guarded by `reconnectTimer`), so the double call from
|
|
35
|
-
* `onClose` + this catch never stacks two timers.
|
|
36
|
-
* 2. A lightweight watchdog interval revives the loop if some unforeseen path
|
|
37
|
-
* ever leaves us `closed`, not host-closed, with no reconnect pending. Even
|
|
38
|
-
* if reasoning (1) misses a case, the watchdog guarantees we never sit dead.
|
|
15
|
+
* Reconnect must not depend on `onClose`: a connect attempt can fail without
|
|
16
|
+
* ever firing a clean close (network/DNS blip mid-handshake, or a
|
|
17
|
+
* `WebSocketLike` transport that emits only `onError`), which would otherwise
|
|
18
|
+
* leave the client silently disconnected until relaunch. So the loop is driven
|
|
19
|
+
* from three places: a failed initial `open()`, the scheduled attempt's own
|
|
20
|
+
* `.catch()`, and a watchdog interval that revives it if we are ever `closed`,
|
|
21
|
+
* not host-closed, with no reconnect pending. `scheduleReconnect` is idempotent
|
|
22
|
+
* (guarded by `reconnectTimer`) so the overlapping callers never stack timers.
|
|
39
23
|
*
|
|
40
24
|
* See docs/issues/004-cloud-client/design.md ("src/modules/runtime/connection.ts")
|
|
41
25
|
* and docs/issues/002-cloud-runtime/protocol.md (envelope, handshake, control).
|