@voxevolv/client 0.2.0 → 0.3.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/CHANGELOG.md CHANGED
@@ -2,6 +2,32 @@
2
2
 
3
3
  All notable changes to `@voxevolv/client` are recorded here.
4
4
 
5
+ ## Unreleased
6
+
7
+ ## 0.3.0 - 2026-07-24
8
+
9
+ - Add opt-in SDK-owned recovery with `autoRejoin`, bounded backoff, terminal
10
+ disconnect-reason handling, and the `resuming` connection state.
11
+ - Surface signal-only LiveKit reconnects instead of skipping directly from
12
+ `connected` to readiness restoration.
13
+ - Add `hasConnectedBefore`, `onRecovery()`, `onConnectionQuality()`, and
14
+ `waitForState()`.
15
+ - Make rejoin disconnect based on the underlying LiveKit room state so a
16
+ failed post-reconnect hello cannot leave a connected room in the way.
17
+ - Add configurable lifecycle fetch credentials with a `same-origin` default,
18
+ preserving cookie-authenticated same-origin proxies while omitting cookies
19
+ on direct cross-origin calls.
20
+ - End an in-flight recovery cleanly when the server emits `session.ended`
21
+ instead of leaving the wrapper state at `resuming`.
22
+ - Preserve the outer `rejoin` recovery when late LiveKit reconnect events
23
+ arrive during that attempt, preventing them from moving the wrapper back to
24
+ `reconnecting` and blocking the replacement connection.
25
+ - Preserve the user's microphone mute state across manual and automatic full
26
+ rejoin so recovery never returns with a previously muted microphone enabled.
27
+ - Keep commands pending when the first post-reconnect data publish is rejected,
28
+ allowing the existing retry loop to deliver them once the data channel is
29
+ writable.
30
+
5
31
  ## 0.2.0 - 2026-07-20
6
32
 
7
33
  - Add `session.outputStream`: a stable `MediaStream` that always holds the
package/README.md CHANGED
@@ -26,7 +26,7 @@ Browsers without a build step can use the versioned bundle after publication:
26
26
  ```html
27
27
  <script type="module">
28
28
  import { RealtimeSession } from
29
- "https://cdn.jsdelivr.net/npm/@voxevolv/client@0.1.0/dist/browser/index.js";
29
+ "https://cdn.jsdelivr.net/npm/@voxevolv/client@0.3.0/dist/browser/index.js";
30
30
  </script>
31
31
  ```
32
32
 
@@ -38,9 +38,10 @@ VoxEvolv session without exposing an organization API key:
38
38
  ```ts
39
39
  const session = await RealtimeSession.create({
40
40
  endpoint: "/api/voice-session",
41
- // Recommended: expose the scoped lifecycle routes through your backend.
42
- // An allowlisted absolute VoxEvolv API URL is also supported.
43
- apiBase: "/api/voxevolv/v1",
41
+ // Use the hosted API directly when its lifecycle CORS policy is public.
42
+ // A same-origin lifecycle proxy remains supported.
43
+ apiBase: "https://YOUR_VOXEVOLV_HOST/v1",
44
+ autoRejoin: true,
44
45
  tools: {
45
46
  present_attachment: (arguments_) => presentAttachment(arguments_),
46
47
  },
@@ -60,7 +61,8 @@ play remote audio:
60
61
 
61
62
  ```ts
62
63
  const session = new RealtimeSession(credentials, {
63
- connect: { apiBase: "/api/voxevolv/v1" },
64
+ connect: { apiBase: "https://YOUR_VOXEVOLV_HOST/v1" },
65
+ autoRejoin: true,
64
66
  });
65
67
  await session.connect({ microphone: true });
66
68
  ```
@@ -121,11 +123,38 @@ Applications that intentionally run without agent audio can opt out:
121
123
  await session.connect({ waitForRemoteAudio: false });
122
124
  ```
123
125
 
124
- ## Rejoin and end
126
+ ## Recovery, rejoin, and connection quality
125
127
 
126
- `rejoin()` can be called from a connected or disconnected state. It obtains a
127
- fresh room token, disconnects an existing room connection when necessary, and
128
- reconnects with the original microphone or application-owned track choice.
128
+ Set `autoRejoin: true` to let the SDK own recovery after LiveKit exhausts its
129
+ transport-level reconnect. Automatic recovery runs only after the session has
130
+ connected successfully, never after an explicit `disconnect()`, `end()`, or
131
+ terminal LiveKit removal. It waits for browser connectivity, obtains a fresh
132
+ room token, and retries with bounded backoff.
133
+
134
+ ```ts
135
+ session.onStateChange((state) => {
136
+ // reconnecting: LiveKit is restoring transport
137
+ // resuming: VoxEvolv is restoring readiness with a fresh connection
138
+ renderConnectionState(state);
139
+ });
140
+
141
+ session.onRecovery(({ status, strategy, attempt, error }) => {
142
+ recordRecovery({ status, strategy, attempt, error });
143
+ });
144
+
145
+ session.onConnectionQuality((quality) => {
146
+ renderCallQuality(quality);
147
+ });
148
+ ```
149
+
150
+ `session.hasConnectedBefore` distinguishes recovery from initial setup.
151
+ `waitForState(states, timeoutMs, { signal })` is available for advanced flows
152
+ that need to await a bounded set of lifecycle states.
153
+
154
+ Manual `rejoin()` remains available. It obtains a fresh room token, disconnects
155
+ any underlying room connection, and reconnects with the original microphone or
156
+ application-owned track choice. A managed microphone that the user muted with
157
+ `setMicrophoneEnabled(false)` remains muted after rejoin.
129
158
 
130
159
  ```ts
131
160
  await session.rejoin();
@@ -134,8 +163,8 @@ await session.end();
134
163
 
135
164
  `RealtimeSession.create()` requires `apiBase` because rejoin, durable replay,
136
165
  and scoped ending happen after the application-owned creation request. Set it
137
- to either an explicit absolute VoxEvolv `/v1` base whose deployment allowlists
138
- the application origin, or a same-origin proxy base that forwards only:
166
+ to either an explicit absolute VoxEvolv `/v1` base (browser lifecycle access is
167
+ enabled by default), or a same-origin proxy base that forwards only:
139
168
 
140
169
  - `POST /sessions/{id}/room-tokens`
141
170
  - `GET /sessions/{id}/events`
@@ -144,6 +173,12 @@ the application origin, or a same-origin proxy base that forwards only:
144
173
  The proxy must forward the browser's `Authorization: Bearer vsa_...` header. It
145
174
  must not replace that credential with an organization API key.
146
175
 
176
+ Lifecycle fetches default to `credentials: "same-origin"`. This sends cookies
177
+ to a same-origin proxy but not to an absolute cross-origin VoxEvolv API. Set
178
+ `lifecycleCredentials` only when a custom proxy has a different credential
179
+ policy; cross-origin `include` requires an exact-origin credentialed CORS
180
+ configuration and is incompatible with wildcard CORS.
181
+
147
182
  `end()` uses the browser-safe `vsa_...` credential to end only that session and
148
183
  then leaves the LiveKit room. Pass `endEndpoint` to the constructor or
149
184
  `end({ endpoint })` when application policy requires a backend completion route.