@sentdm/voice-client 0.0.0-stage → 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.
Files changed (103) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/LICENSE +201 -0
  3. package/README.md +283 -2
  4. package/THIRD_PARTY_NOTICES.md +153 -0
  5. package/adapter/loader.d.mts +3 -0
  6. package/adapter/loader.d.mts.map +1 -0
  7. package/adapter/loader.d.ts +3 -0
  8. package/adapter/loader.d.ts.map +1 -0
  9. package/adapter/loader.js +6 -0
  10. package/adapter/loader.js.map +1 -0
  11. package/adapter/loader.mjs +3 -0
  12. package/adapter/loader.mjs.map +1 -0
  13. package/adapter/sinch-rtc.js +30 -0
  14. package/adapter/sinch-rtc.mjs +31 -0
  15. package/adapter/sinch.d.mts +3 -0
  16. package/adapter/sinch.d.mts.map +1 -0
  17. package/adapter/sinch.d.ts +3 -0
  18. package/adapter/sinch.d.ts.map +1 -0
  19. package/adapter/sinch.js +296 -0
  20. package/adapter/sinch.js.map +1 -0
  21. package/adapter/sinch.mjs +292 -0
  22. package/adapter/sinch.mjs.map +1 -0
  23. package/adapter/types.d.mts +79 -0
  24. package/adapter/types.d.mts.map +1 -0
  25. package/adapter/types.d.ts +79 -0
  26. package/adapter/types.d.ts.map +1 -0
  27. package/adapter/types.js +3 -0
  28. package/adapter/types.js.map +1 -0
  29. package/adapter/types.mjs +2 -0
  30. package/adapter/types.mjs.map +1 -0
  31. package/audio.d.mts +42 -0
  32. package/audio.d.mts.map +1 -0
  33. package/audio.d.ts +42 -0
  34. package/audio.d.ts.map +1 -0
  35. package/audio.js +125 -0
  36. package/audio.js.map +1 -0
  37. package/audio.mjs +121 -0
  38. package/audio.mjs.map +1 -0
  39. package/call.d.mts +60 -0
  40. package/call.d.mts.map +1 -0
  41. package/call.d.ts +60 -0
  42. package/call.d.ts.map +1 -0
  43. package/call.js +84 -0
  44. package/call.js.map +1 -0
  45. package/call.mjs +80 -0
  46. package/call.mjs.map +1 -0
  47. package/client.d.mts +118 -0
  48. package/client.d.mts.map +1 -0
  49. package/client.d.ts +118 -0
  50. package/client.d.ts.map +1 -0
  51. package/client.js +371 -0
  52. package/client.js.map +1 -0
  53. package/client.mjs +367 -0
  54. package/client.mjs.map +1 -0
  55. package/errors.d.mts +2 -0
  56. package/errors.d.mts.map +1 -0
  57. package/errors.d.ts +2 -0
  58. package/errors.d.ts.map +1 -0
  59. package/errors.js +16 -0
  60. package/errors.js.map +1 -0
  61. package/errors.mjs +4 -0
  62. package/errors.mjs.map +1 -0
  63. package/index.d.mts +4 -0
  64. package/index.d.mts.map +1 -0
  65. package/index.d.ts +4 -0
  66. package/index.d.ts.map +1 -0
  67. package/index.js +18 -0
  68. package/index.js.map +1 -0
  69. package/index.mjs +4 -0
  70. package/index.mjs.map +1 -0
  71. package/internal/tslib.js +75 -0
  72. package/internal/tslib.mjs +17 -0
  73. package/invite.d.mts +28 -0
  74. package/invite.d.mts.map +1 -0
  75. package/invite.d.ts +28 -0
  76. package/invite.d.ts.map +1 -0
  77. package/invite.js +64 -0
  78. package/invite.js.map +1 -0
  79. package/invite.mjs +60 -0
  80. package/invite.mjs.map +1 -0
  81. package/package.json +41 -3
  82. package/src/adapter/loader.ts +4 -0
  83. package/src/adapter/sinch-rtc.ts +3 -0
  84. package/src/adapter/sinch.ts +348 -0
  85. package/src/adapter/types.ts +64 -0
  86. package/src/audio.ts +174 -0
  87. package/src/call.ts +145 -0
  88. package/src/client.ts +598 -0
  89. package/src/errors.ts +15 -0
  90. package/src/index.ts +14 -0
  91. package/src/invite.ts +75 -0
  92. package/src/sw.js +14 -0
  93. package/src/tsconfig.json +11 -0
  94. package/src/version.ts +1 -0
  95. package/sw.js +14 -0
  96. package/version.d.mts +2 -0
  97. package/version.d.mts.map +1 -0
  98. package/version.d.ts +2 -0
  99. package/version.d.ts.map +1 -0
  100. package/version.js +5 -0
  101. package/version.js.map +1 -0
  102. package/version.mjs +2 -0
  103. package/version.mjs.map +1 -0
package/call.d.mts ADDED
@@ -0,0 +1,60 @@
1
+ import { type CallStats, type SentVoiceError, TypedEmitter } from '@sentdm/voice-client-core';
2
+ export type { CallStats };
3
+ export type CallState = 'initiated' | 'ringing' | 'answered' | 'connected' | 'reconnecting' | 'completed' | 'failed' | 'busy' | 'noAnswer';
4
+ export type Address = {
5
+ kind: 'user';
6
+ identity: string;
7
+ } | {
8
+ kind: 'number';
9
+ number: string;
10
+ } | {
11
+ kind: 'conference';
12
+ name: string;
13
+ };
14
+ export interface DisconnectInfo {
15
+ state: 'completed' | 'failed' | 'busy' | 'noAnswer';
16
+ error?: SentVoiceError;
17
+ }
18
+ export interface QualityWarning {
19
+ metric: 'jitter' | 'packetLoss' | 'rtt';
20
+ cleared: boolean;
21
+ }
22
+ export interface CallEvents {
23
+ ringing: () => void;
24
+ answered: () => void;
25
+ connected: () => void;
26
+ reconnecting: () => void;
27
+ reconnected: () => void;
28
+ disconnected: (info: DisconnectInfo) => void;
29
+ muteChanged: (isMuted: boolean) => void;
30
+ qualityWarning: (warning: QualityWarning) => void;
31
+ error: (error: SentVoiceError) => void;
32
+ }
33
+ interface CallProvider {
34
+ hangup(): Promise<void>;
35
+ mute(muted: boolean): void;
36
+ sendDigits(digits: string): void;
37
+ getStats(): Promise<CallStats>;
38
+ onUpdate(listener: (state: Exclude<CallState, 'initiated'>, error?: SentVoiceError) => void): void;
39
+ onQualityWarning(listener: (warning: QualityWarning) => void): void;
40
+ }
41
+ export declare class Call extends TypedEmitter<CallEvents> {
42
+ #private;
43
+ readonly id: string;
44
+ readonly direction: 'inbound' | 'outbound';
45
+ readonly from: Address;
46
+ readonly to: Address;
47
+ constructor(id: string, direction: 'inbound' | 'outbound', from: Address, to: Address, provider: CallProvider);
48
+ get state(): CallState;
49
+ get isMuted(): boolean;
50
+ /** When the call connected, in epoch milliseconds. */
51
+ get startedAt(): number | undefined;
52
+ /** Hangs up; does nothing once the call has ended. */
53
+ disconnect(): Promise<void>;
54
+ hangup(): Promise<void>;
55
+ /** Mutes or unmutes the microphone, toggling when called without an argument. */
56
+ mute(muted?: boolean): void;
57
+ sendDigits(digits: string): void;
58
+ getStats(): Promise<CallStats>;
59
+ }
60
+ //# sourceMappingURL=call.d.mts.map
package/call.d.mts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call.d.mts","sourceRoot":"","sources":["src/call.ts"],"names":[],"mappings":"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"}
package/call.d.ts ADDED
@@ -0,0 +1,60 @@
1
+ import { type CallStats, type SentVoiceError, TypedEmitter } from '@sentdm/voice-client-core';
2
+ export type { CallStats };
3
+ export type CallState = 'initiated' | 'ringing' | 'answered' | 'connected' | 'reconnecting' | 'completed' | 'failed' | 'busy' | 'noAnswer';
4
+ export type Address = {
5
+ kind: 'user';
6
+ identity: string;
7
+ } | {
8
+ kind: 'number';
9
+ number: string;
10
+ } | {
11
+ kind: 'conference';
12
+ name: string;
13
+ };
14
+ export interface DisconnectInfo {
15
+ state: 'completed' | 'failed' | 'busy' | 'noAnswer';
16
+ error?: SentVoiceError;
17
+ }
18
+ export interface QualityWarning {
19
+ metric: 'jitter' | 'packetLoss' | 'rtt';
20
+ cleared: boolean;
21
+ }
22
+ export interface CallEvents {
23
+ ringing: () => void;
24
+ answered: () => void;
25
+ connected: () => void;
26
+ reconnecting: () => void;
27
+ reconnected: () => void;
28
+ disconnected: (info: DisconnectInfo) => void;
29
+ muteChanged: (isMuted: boolean) => void;
30
+ qualityWarning: (warning: QualityWarning) => void;
31
+ error: (error: SentVoiceError) => void;
32
+ }
33
+ interface CallProvider {
34
+ hangup(): Promise<void>;
35
+ mute(muted: boolean): void;
36
+ sendDigits(digits: string): void;
37
+ getStats(): Promise<CallStats>;
38
+ onUpdate(listener: (state: Exclude<CallState, 'initiated'>, error?: SentVoiceError) => void): void;
39
+ onQualityWarning(listener: (warning: QualityWarning) => void): void;
40
+ }
41
+ export declare class Call extends TypedEmitter<CallEvents> {
42
+ #private;
43
+ readonly id: string;
44
+ readonly direction: 'inbound' | 'outbound';
45
+ readonly from: Address;
46
+ readonly to: Address;
47
+ constructor(id: string, direction: 'inbound' | 'outbound', from: Address, to: Address, provider: CallProvider);
48
+ get state(): CallState;
49
+ get isMuted(): boolean;
50
+ /** When the call connected, in epoch milliseconds. */
51
+ get startedAt(): number | undefined;
52
+ /** Hangs up; does nothing once the call has ended. */
53
+ disconnect(): Promise<void>;
54
+ hangup(): Promise<void>;
55
+ /** Mutes or unmutes the microphone, toggling when called without an argument. */
56
+ mute(muted?: boolean): void;
57
+ sendDigits(digits: string): void;
58
+ getStats(): Promise<CallStats>;
59
+ }
60
+ //# sourceMappingURL=call.d.ts.map
package/call.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call.d.ts","sourceRoot":"","sources":["src/call.ts"],"names":[],"mappings":"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"}
package/call.js ADDED
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var _Call_instances, _Call_provider, _Call_state, _Call_isMuted, _Call_startedAt, _Call_update;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.Call = void 0;
5
+ const tslib_1 = require("./internal/tslib.js");
6
+ const voice_client_core_1 = require("@sentdm/voice-client-core");
7
+ const isEnded = (state) => state === 'completed' || state === 'failed' || state === 'busy' || state === 'noAnswer';
8
+ class Call extends voice_client_core_1.TypedEmitter {
9
+ constructor(id, direction, from, to, provider) {
10
+ super();
11
+ _Call_instances.add(this);
12
+ _Call_provider.set(this, void 0);
13
+ _Call_state.set(this, void 0);
14
+ _Call_isMuted.set(this, false);
15
+ _Call_startedAt.set(this, void 0);
16
+ this.id = id;
17
+ this.direction = direction;
18
+ this.from = from;
19
+ this.to = to;
20
+ tslib_1.__classPrivateFieldSet(this, _Call_provider, provider, "f");
21
+ tslib_1.__classPrivateFieldSet(this, _Call_state, direction === 'inbound' ? 'ringing' : 'initiated', "f");
22
+ provider.onUpdate((state, error) => tslib_1.__classPrivateFieldGet(this, _Call_instances, "m", _Call_update).call(this, state, error));
23
+ provider.onQualityWarning((warning) => this.emit('qualityWarning', warning));
24
+ }
25
+ get state() {
26
+ return tslib_1.__classPrivateFieldGet(this, _Call_state, "f");
27
+ }
28
+ get isMuted() {
29
+ return tslib_1.__classPrivateFieldGet(this, _Call_isMuted, "f");
30
+ }
31
+ /** When the call connected, in epoch milliseconds. */
32
+ get startedAt() {
33
+ return tslib_1.__classPrivateFieldGet(this, _Call_startedAt, "f");
34
+ }
35
+ /** Hangs up; does nothing once the call has ended. */
36
+ async disconnect() {
37
+ if (isEnded(tslib_1.__classPrivateFieldGet(this, _Call_state, "f")))
38
+ return;
39
+ await tslib_1.__classPrivateFieldGet(this, _Call_provider, "f").hangup();
40
+ }
41
+ hangup() {
42
+ return this.disconnect();
43
+ }
44
+ /** Mutes or unmutes the microphone, toggling when called without an argument. */
45
+ mute(muted = !tslib_1.__classPrivateFieldGet(this, _Call_isMuted, "f")) {
46
+ if (muted === tslib_1.__classPrivateFieldGet(this, _Call_isMuted, "f"))
47
+ return;
48
+ tslib_1.__classPrivateFieldGet(this, _Call_provider, "f").mute(muted);
49
+ tslib_1.__classPrivateFieldSet(this, _Call_isMuted, muted, "f");
50
+ this.emit('muteChanged', muted);
51
+ }
52
+ sendDigits(digits) {
53
+ tslib_1.__classPrivateFieldGet(this, _Call_provider, "f").sendDigits(digits);
54
+ }
55
+ getStats() {
56
+ return tslib_1.__classPrivateFieldGet(this, _Call_provider, "f").getStats();
57
+ }
58
+ }
59
+ exports.Call = Call;
60
+ _Call_provider = new WeakMap(), _Call_state = new WeakMap(), _Call_isMuted = new WeakMap(), _Call_startedAt = new WeakMap(), _Call_instances = new WeakSet(), _Call_update = function _Call_update(state, error) {
61
+ const previous = tslib_1.__classPrivateFieldGet(this, _Call_state, "f");
62
+ if (isEnded(previous) ||
63
+ (state === 'ringing' && previous !== 'initiated') ||
64
+ (state === 'answered' && previous !== 'initiated' && previous !== 'ringing') ||
65
+ (state === 'connected' && previous === 'connected') ||
66
+ (state === 'reconnecting' && previous !== 'connected')) {
67
+ return;
68
+ }
69
+ tslib_1.__classPrivateFieldSet(this, _Call_state, state, "f");
70
+ if (isEnded(state)) {
71
+ if (error)
72
+ this.emit('error', error);
73
+ this.emit('disconnected', error ? { state, error } : { state });
74
+ }
75
+ else if (state === 'connected' && previous === 'reconnecting') {
76
+ this.emit('reconnected');
77
+ }
78
+ else {
79
+ if (state === 'connected')
80
+ tslib_1.__classPrivateFieldSet(this, _Call_startedAt, Date.now(), "f");
81
+ this.emit(state);
82
+ }
83
+ };
84
+ //# sourceMappingURL=call.js.map
package/call.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call.js","sourceRoot":"","sources":["src/call.ts"],"names":[],"mappings":"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"}
package/call.mjs ADDED
@@ -0,0 +1,80 @@
1
+ var _Call_instances, _Call_provider, _Call_state, _Call_isMuted, _Call_startedAt, _Call_update;
2
+ import { __classPrivateFieldGet, __classPrivateFieldSet } from "./internal/tslib.mjs";
3
+ import { TypedEmitter } from '@sentdm/voice-client-core';
4
+ const isEnded = (state) => state === 'completed' || state === 'failed' || state === 'busy' || state === 'noAnswer';
5
+ export class Call extends TypedEmitter {
6
+ constructor(id, direction, from, to, provider) {
7
+ super();
8
+ _Call_instances.add(this);
9
+ _Call_provider.set(this, void 0);
10
+ _Call_state.set(this, void 0);
11
+ _Call_isMuted.set(this, false);
12
+ _Call_startedAt.set(this, void 0);
13
+ this.id = id;
14
+ this.direction = direction;
15
+ this.from = from;
16
+ this.to = to;
17
+ __classPrivateFieldSet(this, _Call_provider, provider, "f");
18
+ __classPrivateFieldSet(this, _Call_state, direction === 'inbound' ? 'ringing' : 'initiated', "f");
19
+ provider.onUpdate((state, error) => __classPrivateFieldGet(this, _Call_instances, "m", _Call_update).call(this, state, error));
20
+ provider.onQualityWarning((warning) => this.emit('qualityWarning', warning));
21
+ }
22
+ get state() {
23
+ return __classPrivateFieldGet(this, _Call_state, "f");
24
+ }
25
+ get isMuted() {
26
+ return __classPrivateFieldGet(this, _Call_isMuted, "f");
27
+ }
28
+ /** When the call connected, in epoch milliseconds. */
29
+ get startedAt() {
30
+ return __classPrivateFieldGet(this, _Call_startedAt, "f");
31
+ }
32
+ /** Hangs up; does nothing once the call has ended. */
33
+ async disconnect() {
34
+ if (isEnded(__classPrivateFieldGet(this, _Call_state, "f")))
35
+ return;
36
+ await __classPrivateFieldGet(this, _Call_provider, "f").hangup();
37
+ }
38
+ hangup() {
39
+ return this.disconnect();
40
+ }
41
+ /** Mutes or unmutes the microphone, toggling when called without an argument. */
42
+ mute(muted = !__classPrivateFieldGet(this, _Call_isMuted, "f")) {
43
+ if (muted === __classPrivateFieldGet(this, _Call_isMuted, "f"))
44
+ return;
45
+ __classPrivateFieldGet(this, _Call_provider, "f").mute(muted);
46
+ __classPrivateFieldSet(this, _Call_isMuted, muted, "f");
47
+ this.emit('muteChanged', muted);
48
+ }
49
+ sendDigits(digits) {
50
+ __classPrivateFieldGet(this, _Call_provider, "f").sendDigits(digits);
51
+ }
52
+ getStats() {
53
+ return __classPrivateFieldGet(this, _Call_provider, "f").getStats();
54
+ }
55
+ }
56
+ _Call_provider = new WeakMap(), _Call_state = new WeakMap(), _Call_isMuted = new WeakMap(), _Call_startedAt = new WeakMap(), _Call_instances = new WeakSet(), _Call_update = function _Call_update(state, error) {
57
+ const previous = __classPrivateFieldGet(this, _Call_state, "f");
58
+ if (isEnded(previous) ||
59
+ (state === 'ringing' && previous !== 'initiated') ||
60
+ (state === 'answered' && previous !== 'initiated' && previous !== 'ringing') ||
61
+ (state === 'connected' && previous === 'connected') ||
62
+ (state === 'reconnecting' && previous !== 'connected')) {
63
+ return;
64
+ }
65
+ __classPrivateFieldSet(this, _Call_state, state, "f");
66
+ if (isEnded(state)) {
67
+ if (error)
68
+ this.emit('error', error);
69
+ this.emit('disconnected', error ? { state, error } : { state });
70
+ }
71
+ else if (state === 'connected' && previous === 'reconnecting') {
72
+ this.emit('reconnected');
73
+ }
74
+ else {
75
+ if (state === 'connected')
76
+ __classPrivateFieldSet(this, _Call_startedAt, Date.now(), "f");
77
+ this.emit(state);
78
+ }
79
+ };
80
+ //# sourceMappingURL=call.mjs.map
package/call.mjs.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call.mjs","sourceRoot":"","sources":["src/call.ts"],"names":[],"mappings":"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"}
package/client.d.mts ADDED
@@ -0,0 +1,118 @@
1
+ import { AudioController } from "./audio.mjs";
2
+ import { Call, type Address, type CallState, type CallStats, type DisconnectInfo, type QualityWarning } from "./call.mjs";
3
+ import { SentVoiceError, TypedEmitter, type Logger, type LogLevel } from '@sentdm/voice-client-core';
4
+ import { CallInvite, type CancelInfo } from "./invite.mjs";
5
+ export interface SentVoiceOptions {
6
+ /**
7
+ * Returns a voice token from your backend, which mints it with `POST /v3/voice/tokens`.
8
+ * Called by `register()` and again before each token expires. The token is opaque: pass it on
9
+ * unchanged.
10
+ */
11
+ tokenProvider: () => Promise<string>;
12
+ /**
13
+ * The Sent API the SDK calls with the voice token, to exchange it when registering and to report
14
+ * telemetry.
15
+ *
16
+ * @default 'https://api.sent.dm'
17
+ */
18
+ baseURL?: string | undefined;
19
+ /**
20
+ * The maximum number of times that registering or refreshing the voice token is retried
21
+ * in case of a temporary failure, like a network error.
22
+ *
23
+ * @default 2
24
+ */
25
+ registerRetries?: number | undefined;
26
+ /**
27
+ * Set the log level.
28
+ *
29
+ * Defaults to 'warn'.
30
+ */
31
+ logLevel?: LogLevel | undefined;
32
+ /**
33
+ * Set the logger. Voice tokens are redacted from every message.
34
+ *
35
+ * Defaults to globalThis.console.
36
+ */
37
+ logger?: Logger | undefined;
38
+ /**
39
+ * Where your app serves the service worker that delivers incoming calls, a copy of
40
+ * `@sentdm/voice-client/sw.js`. `url` is resolved against the page and defaults to `sw.js`;
41
+ * `scope` defaults to the worker's folder.
42
+ */
43
+ serviceWorker?: {
44
+ url?: string | undefined;
45
+ scope?: string | undefined;
46
+ } | undefined;
47
+ audio?: {
48
+ /**
49
+ * The microphone to start with, a `deviceId` from `client.audio.inputDevices()`. The default
50
+ * one is used while the device is missing.
51
+ */
52
+ inputDeviceId?: string | undefined;
53
+ /**
54
+ * The speaker to start with, a `deviceId` from `client.audio.outputDevices()`. The default
55
+ * one is used when the device cannot be chosen.
56
+ */
57
+ outputDeviceId?: string | undefined;
58
+ /** Plays the other party's audio through this element instead of one the SDK creates. */
59
+ element?: HTMLAudioElement | undefined;
60
+ } | undefined;
61
+ /**
62
+ * Usage and call quality data the SDK reports to Sent, authenticated with the voice token: the
63
+ * browser and device, registration and call timings, call quality and error codes. Set `disabled`
64
+ * to report nothing.
65
+ */
66
+ telemetry?: {
67
+ disabled?: boolean | undefined;
68
+ } | undefined;
69
+ }
70
+ export interface SentVoiceEvents {
71
+ registering: () => void;
72
+ registered: () => void;
73
+ unregistered: () => void;
74
+ incomingCall: (invite: CallInvite) => void;
75
+ activeCallChanged: (call: Call | null) => void;
76
+ offline: (reason: SentVoiceError) => void;
77
+ tokenWillExpire: (info: {
78
+ expiresAt: number;
79
+ }) => void;
80
+ error: (error: SentVoiceError) => void;
81
+ }
82
+ export declare class SentVoice extends TypedEmitter<SentVoiceEvents> {
83
+ #private;
84
+ static readonly version: string;
85
+ readonly audio: AudioController;
86
+ constructor({ tokenProvider, baseURL, registerRetries, logLevel, logger, serviceWorker, audio, telemetry, }: SentVoiceOptions);
87
+ get state(): SentVoice.ClientState;
88
+ get identity(): string | undefined;
89
+ get number(): string | undefined;
90
+ get calls(): Call[];
91
+ get activeCall(): Call | null;
92
+ get isBusy(): boolean;
93
+ /** Fetches a token from `tokenProvider`, registers with it and keeps it refreshed. */
94
+ register(): Promise<void>;
95
+ /** Goes offline and stops receiving calls. */
96
+ unregister(): Promise<void>;
97
+ /** Calls a phone number in E.164 format or another user of your app. */
98
+ connect({ to }: SentVoice.ConnectParams): Promise<Call>;
99
+ /** Joins one of your account's conference rooms. */
100
+ joinConference({ name }: SentVoice.JoinConferenceParams): Promise<Call>;
101
+ /** Ends every call and tears the client down for good; later calls throw `NotRegisteredError`. */
102
+ destroy(): Promise<void>;
103
+ }
104
+ export declare namespace SentVoice {
105
+ export type ClientState = 'unregistered' | 'registering' | 'registered' | 'offline' | 'destroyed';
106
+ export interface ConnectParams {
107
+ /** A phone number in E.164 format like `+14155551234`, or the identity of another user of your app. */
108
+ to: string;
109
+ }
110
+ export interface JoinConferenceParams {
111
+ /** The room name, private to your account: letters, digits, `-` and `_`, up to 27 characters. */
112
+ name: string;
113
+ }
114
+ export { type Call as Call, type CallState as CallState, type Address as Address, type CallStats as CallStats, type DisconnectInfo as DisconnectInfo, type QualityWarning as QualityWarning, };
115
+ export { type CallInvite as CallInvite, type CancelInfo as CancelInfo };
116
+ export { type AudioController as AudioController };
117
+ }
118
+ //# sourceMappingURL=client.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.mts","sourceRoot":"","sources":["src/client.ts"],"names":[],"mappings":"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"}
package/client.d.ts ADDED
@@ -0,0 +1,118 @@
1
+ import { AudioController } from "./audio.js";
2
+ import { Call, type Address, type CallState, type CallStats, type DisconnectInfo, type QualityWarning } from "./call.js";
3
+ import { SentVoiceError, TypedEmitter, type Logger, type LogLevel } from '@sentdm/voice-client-core';
4
+ import { CallInvite, type CancelInfo } from "./invite.js";
5
+ export interface SentVoiceOptions {
6
+ /**
7
+ * Returns a voice token from your backend, which mints it with `POST /v3/voice/tokens`.
8
+ * Called by `register()` and again before each token expires. The token is opaque: pass it on
9
+ * unchanged.
10
+ */
11
+ tokenProvider: () => Promise<string>;
12
+ /**
13
+ * The Sent API the SDK calls with the voice token, to exchange it when registering and to report
14
+ * telemetry.
15
+ *
16
+ * @default 'https://api.sent.dm'
17
+ */
18
+ baseURL?: string | undefined;
19
+ /**
20
+ * The maximum number of times that registering or refreshing the voice token is retried
21
+ * in case of a temporary failure, like a network error.
22
+ *
23
+ * @default 2
24
+ */
25
+ registerRetries?: number | undefined;
26
+ /**
27
+ * Set the log level.
28
+ *
29
+ * Defaults to 'warn'.
30
+ */
31
+ logLevel?: LogLevel | undefined;
32
+ /**
33
+ * Set the logger. Voice tokens are redacted from every message.
34
+ *
35
+ * Defaults to globalThis.console.
36
+ */
37
+ logger?: Logger | undefined;
38
+ /**
39
+ * Where your app serves the service worker that delivers incoming calls, a copy of
40
+ * `@sentdm/voice-client/sw.js`. `url` is resolved against the page and defaults to `sw.js`;
41
+ * `scope` defaults to the worker's folder.
42
+ */
43
+ serviceWorker?: {
44
+ url?: string | undefined;
45
+ scope?: string | undefined;
46
+ } | undefined;
47
+ audio?: {
48
+ /**
49
+ * The microphone to start with, a `deviceId` from `client.audio.inputDevices()`. The default
50
+ * one is used while the device is missing.
51
+ */
52
+ inputDeviceId?: string | undefined;
53
+ /**
54
+ * The speaker to start with, a `deviceId` from `client.audio.outputDevices()`. The default
55
+ * one is used when the device cannot be chosen.
56
+ */
57
+ outputDeviceId?: string | undefined;
58
+ /** Plays the other party's audio through this element instead of one the SDK creates. */
59
+ element?: HTMLAudioElement | undefined;
60
+ } | undefined;
61
+ /**
62
+ * Usage and call quality data the SDK reports to Sent, authenticated with the voice token: the
63
+ * browser and device, registration and call timings, call quality and error codes. Set `disabled`
64
+ * to report nothing.
65
+ */
66
+ telemetry?: {
67
+ disabled?: boolean | undefined;
68
+ } | undefined;
69
+ }
70
+ export interface SentVoiceEvents {
71
+ registering: () => void;
72
+ registered: () => void;
73
+ unregistered: () => void;
74
+ incomingCall: (invite: CallInvite) => void;
75
+ activeCallChanged: (call: Call | null) => void;
76
+ offline: (reason: SentVoiceError) => void;
77
+ tokenWillExpire: (info: {
78
+ expiresAt: number;
79
+ }) => void;
80
+ error: (error: SentVoiceError) => void;
81
+ }
82
+ export declare class SentVoice extends TypedEmitter<SentVoiceEvents> {
83
+ #private;
84
+ static readonly version: string;
85
+ readonly audio: AudioController;
86
+ constructor({ tokenProvider, baseURL, registerRetries, logLevel, logger, serviceWorker, audio, telemetry, }: SentVoiceOptions);
87
+ get state(): SentVoice.ClientState;
88
+ get identity(): string | undefined;
89
+ get number(): string | undefined;
90
+ get calls(): Call[];
91
+ get activeCall(): Call | null;
92
+ get isBusy(): boolean;
93
+ /** Fetches a token from `tokenProvider`, registers with it and keeps it refreshed. */
94
+ register(): Promise<void>;
95
+ /** Goes offline and stops receiving calls. */
96
+ unregister(): Promise<void>;
97
+ /** Calls a phone number in E.164 format or another user of your app. */
98
+ connect({ to }: SentVoice.ConnectParams): Promise<Call>;
99
+ /** Joins one of your account's conference rooms. */
100
+ joinConference({ name }: SentVoice.JoinConferenceParams): Promise<Call>;
101
+ /** Ends every call and tears the client down for good; later calls throw `NotRegisteredError`. */
102
+ destroy(): Promise<void>;
103
+ }
104
+ export declare namespace SentVoice {
105
+ export type ClientState = 'unregistered' | 'registering' | 'registered' | 'offline' | 'destroyed';
106
+ export interface ConnectParams {
107
+ /** A phone number in E.164 format like `+14155551234`, or the identity of another user of your app. */
108
+ to: string;
109
+ }
110
+ export interface JoinConferenceParams {
111
+ /** The room name, private to your account: letters, digits, `-` and `_`, up to 27 characters. */
112
+ name: string;
113
+ }
114
+ export { type Call as Call, type CallState as CallState, type Address as Address, type CallStats as CallStats, type DisconnectInfo as DisconnectInfo, type QualityWarning as QualityWarning, };
115
+ export { type CallInvite as CallInvite, type CancelInfo as CancelInfo };
116
+ export { type AudioController as AudioController };
117
+ }
118
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["src/client.ts"],"names":[],"mappings":"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"}