@sentdm/voice-client 0.1.1 → 0.2.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
@@ -1,5 +1,37 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.0](https://github.com/sentdm/sent-dm-voice-typescript/compare/voice-client-v0.1.1...voice-client-v0.2.0) (2026-10-23)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * tokenProvider must return the token from POST /v3/voice/tokens, and telemetry.baseURL is replaced by the top-level baseURL option, which the token exchange also uses.
9
+ * import the React bindings from @sentdm/voice-client-react instead of @sentdm/voice-client/react.
10
+ * install @sentdm/voice-client instead of @sentdm/voice.
11
+
12
+ ### Features
13
+
14
+ * add the Voice Client contract and its conformance test ([fdd7995](https://github.com/sentdm/sent-dm-voice-typescript/commit/fdd7995eb44c7a5ea93f834d24fe34d5f7a31c29))
15
+ * exchange the opaque voice token for the provider credential ([e0ec6d7](https://github.com/sentdm/sent-dm-voice-typescript/commit/e0ec6d7248b0d9f8861401752a08433967badf4d))
16
+ * extract @sentdm/voice-client-core ([a8cbf69](https://github.com/sentdm/sent-dm-voice-typescript/commit/a8cbf692a9fad8fedb4337df143e5b77f8eba88e))
17
+ * move the React bindings to @sentdm/voice-client-react ([3853f65](https://github.com/sentdm/sent-dm-voice-typescript/commit/3853f6522d31ce9a4c865749d8d39c2b6485adf7))
18
+ * publish as @sentdm/voice-client from a pnpm workspace ([cdd8b0c](https://github.com/sentdm/sent-dm-voice-typescript/commit/cdd8b0cf0bb57549816f9acf99fe4725e10ecf70))
19
+
20
+
21
+ ### Bug Fixes
22
+
23
+ * ignore call updates once the call has ended ([e33c825](https://github.com/sentdm/sent-dm-voice-typescript/commit/e33c8258a7ab282292fefafa1954353d175c67ef))
24
+
25
+
26
+ ### Documentation
27
+
28
+ * keep the units on CallStats after its move to core ([590df75](https://github.com/sentdm/sent-dm-voice-typescript/commit/590df759d0aa377d84ec875b00fdb768615f536b))
29
+
30
+
31
+ ### Build System
32
+
33
+ * bundle sinch-rtc into the voice client ([9db8bbb](https://github.com/sentdm/sent-dm-voice-typescript/commit/9db8bbbc56c307cb08def1c3973fbbfeab68fa47))
34
+
3
35
  ## [0.1.1](https://github.com/sentdm/sent-dm-voice-sdk/compare/v0.1.0...v0.1.1) (2026-09-29)
4
36
 
5
37
 
package/README.md CHANGED
@@ -18,7 +18,7 @@ Mint tokens on your server with your Sent API key, never in the browser, for the
18
18
 
19
19
  ```ts
20
20
  export async function createVoiceToken(identity: string): Promise<string> {
21
- const response = await fetch('https://api.sent.dm/v3/channels/voice/tokens', {
21
+ const response = await fetch('https://api.sent.dm/v3/voice/tokens', {
22
22
  method: 'POST',
23
23
  headers: { 'x-api-key': process.env['SENT_DM_API_KEY'] ?? '', 'Content-Type': 'application/json' },
24
24
  body: JSON.stringify({ identity }),
@@ -71,10 +71,10 @@ The first `register()` asks the user to allow notifications, which the browser n
71
71
 
72
72
  ## Token lifecycle
73
73
 
74
- `tokenProvider` is how the SDK gets every token. It must return the `token` that `POST /v3/channels/voice/tokens` responded with, fetched fresh each time, because the SDK calls it again before each token expires.
74
+ `tokenProvider` is how the SDK gets every token. It must return the `token` that `POST /v3/voice/tokens` responded with, unchanged and fetched fresh each time, because the SDK calls it again before each token expires. The token is opaque: read the identity, number and expiry from the minting response, not from the token. The SDK exchanges it with Sent for what it registers with, so nothing your backend or app handles belongs to the calling provider.
75
75
 
76
76
  - `register()` calls it and resolves once the client is `registered`. The client moves from `unregistered` to `registering` to `registered`, emitting each state as an event.
77
- - A token provider that throws or rejects is retried after a short backoff, 2 more times by default (`registerRetries`); `register()` then rejects with a `NetworkError`. A value that is not a voice token rejects with a `TokenInvalidError` at once.
77
+ - A token provider that throws or rejects, or a token exchange that cannot reach Sent or is rate limited, is retried after a short backoff, 2 more times by default (`registerRetries`); `register()` then rejects with a `NetworkError`. A value that is not a voice token, or a token Sent refuses, rejects with a `TokenInvalidError` at once.
78
78
  - The token is refreshed at 80% of its lifetime, or 30 seconds before it expires if that is earlier, but never before half of its lifetime has passed. `tokenWillExpire` fires first, then `tokenProvider` is called with the same retries. Nothing else changes for your app.
79
79
  - If the retries run out, the client emits `error` with the cause and `offline` with a `TokenExpiredError`, then tries again about every 30 seconds until it is `registered` again; calling `register()` tries at once. Calls in progress go on, but `connect()` and `joinConference()` throw a `NotRegisteredError` while the client is offline.
80
80
  - `unregister()` stops receiving calls and leaves calls in progress alone. `destroy()` ends every call and tears the client down for good.
@@ -191,13 +191,13 @@ export async function answer(invite: SentVoice.CallInvite) {
191
191
 
192
192
  | Error | `code` | `category` | When |
193
193
  | ---------------------------- | ------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
194
- | `TokenInvalidError` | `TOKEN_INVALID` | `auth` | `register()`: the token provider returned something that is not a voice token |
194
+ | `TokenInvalidError` | `TOKEN_INVALID` | `auth` | `register()`: the token provider returned something that is not a voice token, or a token Sent refuses |
195
195
  | `TokenExpiredError` | `TOKEN_EXPIRED` | `auth` | the `offline` event: the token could not be refreshed |
196
196
  | `NotRegisteredError` | `NOT_REGISTERED` | `validation` | `connect()` or `joinConference()` while not registered; registering, calling or choosing a device after `destroy()` |
197
197
  | `MediaPermissionError` | `MEDIA_PERMISSION_DENIED` | `media` | `connect()`, `joinConference()` or `accept()`: the microphone could not be opened |
198
198
  | `CallFailedError` | `CALL_FAILED` | `signaling` | `accept()` on a call that ended before it was answered; a call the provider could not set up, such as to an identity that is not registered, ends as `failed` with it |
199
199
  | `CallRejectedError` | `CALL_REJECTED` | `signaling` | not raised yet: a call the other side declines ends as `busy` |
200
- | `NetworkError` | `NETWORK` | `network` | `register()`, when the token provider keeps failing or the calling provider cannot be loaded; a call whose connection failed or was lost |
200
+ | `NetworkError` | `NETWORK` | `network` | `register()`, when the token provider or the token exchange keeps failing or the calling provider cannot be loaded; a call whose connection failed or was lost |
201
201
  | `CapabilityUnsupportedError` | `CAPABILITY_UNSUPPORTED` | `capability` | `setOutputDevice()` where the browser cannot choose the speaker; listing devices over plain HTTP |
202
202
  | `SentVoiceError` | `INVALID_ADDRESS` | `validation` | `connect()` or `joinConference()` with a `to` or `name` that does not fit |
203
203
  | `SentVoiceError` | `CALL_IN_PROGRESS` | `validation` | `connect()` or `joinConference()` while a call is in progress or an incoming call is waiting for an answer |
@@ -273,7 +273,7 @@ The SDK reports usage and call quality data to Sent, authenticated with the voic
273
273
  - for each call: its id, direction and outcome, how long it took to connect and how long it lasted, and at its end the average round-trip time, jitter and packet loss of samples taken every 10 seconds
274
274
  - the errors the client and its calls report: code, category, whether retriable, the message, and the underlying provider error with its name, message, stack and properties
275
275
 
276
- No audio, phone numbers or identities are added by the SDK; the underlying provider error travels as the provider produced it. Batches go to `https://api.sent.dm/v3/voice/telemetry` 3 seconds after the first event queued, so events that happen together share one request, and at once when a call ends, when the page is hidden and when the client is destroyed. A batch that fails, or that Sent refuses (for example with a 429 or a 5xx), is retried once, with the next batch or within 30 seconds, then dropped; telemetry never throws to your app and never delays a call. Turn it off with `telemetry: { disabled: true }`.
276
+ No audio, phone numbers or identities are added by the SDK; the underlying provider error travels as the provider produced it. Batches go to `/v3/voice/telemetry` under `baseURL` (`https://api.sent.dm` by default) 3 seconds after the first event queued, so events that happen together share one request, and at once when a call ends, when the page is hidden and when the client is destroyed. A batch that fails, or that Sent refuses (for example with a 429 or a 5xx), is retried once, with the next batch or within 30 seconds, then dropped; telemetry never throws to your app and never delays a call. Turn it off with `telemetry: { disabled: true }`.
277
277
 
278
278
  ## Browser realities
279
279
 
@@ -0,0 +1,153 @@
1
+ # Third-party notices
2
+
3
+ This package bundles the following packages into `adapter/sinch-rtc.js` and `adapter/sinch-rtc.mjs`, each under its own licence. `pubnub`, which they use, is not bundled: it is a dependency of this package.
4
+
5
+ ## crypto-js 4.2.0
6
+
7
+ Licence: MIT
8
+
9
+ ```
10
+ # License
11
+
12
+ [The MIT License (MIT)](http://opensource.org/licenses/MIT)
13
+
14
+ Copyright (c) 2009-2013 Jeff Mott
15
+ Copyright (c) 2013-2016 Evan Vosberg
16
+
17
+ Permission is hereby granted, free of charge, to any person obtaining a copy
18
+ of this software and associated documentation files (the "Software"), to deal
19
+ in the Software without restriction, including without limitation the rights
20
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21
+ copies of the Software, and to permit persons to whom the Software is
22
+ furnished to do so, subject to the following conditions:
23
+
24
+ The above copyright notice and this permission notice shall be included in
25
+ all copies or substantial portions of the Software.
26
+
27
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33
+ THE SOFTWARE.
34
+ ```
35
+
36
+ ## fp-ts 2.16.11
37
+
38
+ Licence: MIT
39
+
40
+ ```
41
+ MIT License
42
+
43
+ Copyright (c) 2017-present Giulio Canti
44
+
45
+ Permission is hereby granted, free of charge, to any person obtaining a copy
46
+ of this software and associated documentation files (the "Software"), to deal
47
+ in the Software without restriction, including without limitation the rights
48
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
49
+ copies of the Software, and to permit persons to whom the Software is
50
+ furnished to do so, subject to the following conditions:
51
+
52
+ The above copyright notice and this permission notice shall be included in all
53
+ copies or substantial portions of the Software.
54
+
55
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
56
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
58
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
59
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
60
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
61
+ SOFTWARE.
62
+ ```
63
+
64
+ ## pako 2.2.0
65
+
66
+ Licence: (MIT AND Zlib)
67
+
68
+ ```
69
+ (The MIT License)
70
+
71
+ Copyright (C) 2014-2017 by Vitaly Puzrin and Andrei Tuputcyn
72
+
73
+ Permission is hereby granted, free of charge, to any person obtaining a copy
74
+ of this software and associated documentation files (the "Software"), to deal
75
+ in the Software without restriction, including without limitation the rights
76
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
77
+ copies of the Software, and to permit persons to whom the Software is
78
+ furnished to do so, subject to the following conditions:
79
+
80
+ The above copyright notice and this permission notice shall be included in
81
+ all copies or substantial portions of the Software.
82
+
83
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
84
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
85
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
86
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
87
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
88
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
89
+ THE SOFTWARE.
90
+ ```
91
+
92
+ ## sdp-transform 2.15.0
93
+
94
+ Licence: MIT
95
+
96
+ ```
97
+ (The MIT License)
98
+
99
+ Copyright (c) 2013 Eirik Albrigtsen
100
+
101
+ Permission is hereby granted, free of charge, to any person obtaining
102
+ a copy of this software and associated documentation files (the
103
+ 'Software'), to deal in the Software without restriction, including
104
+ without limitation the rights to use, copy, modify, merge, publish,
105
+ distribute, sublicense, and/or sell copies of the Software, and to
106
+ permit persons to whom the Software is furnished to do so, subject to
107
+ the following conditions:
108
+
109
+ The above copyright notice and this permission notice shall be
110
+ included in all copies or substantial portions of the Software.
111
+
112
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
113
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
114
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
115
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
116
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
117
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
118
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
119
+ ```
120
+
121
+ ## sinch-rtc 2.49.11
122
+
123
+ Licence: ISC
124
+
125
+ The package ships no licence file.
126
+
127
+ ## ulid 2.4.0
128
+
129
+ Licence: MIT
130
+
131
+ ```
132
+ The MIT License (MIT)
133
+
134
+ Copyright (c) 2017 Alizain Feerasta
135
+
136
+ Permission is hereby granted, free of charge, to any person obtaining a copy
137
+ of this software and associated documentation files (the "Software"), to deal
138
+ in the Software without restriction, including without limitation the rights
139
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
140
+ copies of the Software, and to permit persons to whom the Software is
141
+ furnished to do so, subject to the following conditions:
142
+
143
+ The above copyright notice and this permission notice shall be included in all
144
+ copies or substantial portions of the Software.
145
+
146
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
147
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
148
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
149
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
150
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
151
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
152
+ SOFTWARE.
153
+ ```