react-sip-kit 0.5.21 → 0.6.2
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/LICENSE +21 -21
- package/README.md +254 -211
- package/dist/components/audio/index.d.ts +2 -2
- package/dist/components/video/index.d.ts +2 -2
- package/dist/constructors/line.d.ts +5 -3
- package/dist/hooks/useWatchSessionData/index.d.ts +65 -5
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/manager.d.ts +67 -53
- package/dist/methods/session/index.d.ts +12 -14
- package/dist/store/types.d.ts +17 -13
- package/dist/types.d.ts +39 -1
- package/package.json +99 -99
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Shervin Ghajar
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Shervin Ghajar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,212 +1,255 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
import
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
```tsx
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
{
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
1
|
+
|
|
2
|
+
# react-sip-kit
|
|
3
|
+
|
|
4
|
+
A modern **React SIP.js toolkit** for building web softphones and SIP clients.
|
|
5
|
+
Supports **audio/video calls**, **call recording**, **screen sharing**, and **device management**, all with a clean, extensible, TypeScript-first architecture.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## ✨ Features
|
|
10
|
+
|
|
11
|
+
- 📞 **Audio & Video Calls** — automatic device detection
|
|
12
|
+
- 🎥 **Video Support** — manage local & remote streams seamlessly
|
|
13
|
+
- 🔴 **Call Recording** — audio/video recording built-in
|
|
14
|
+
- 🖥️ **Screen Sharing** — during video calls
|
|
15
|
+
- 🎧 **Device Management** — select audio/video input & output devices
|
|
16
|
+
- 🔄 **Multi-account & Multi-line Support** — handle multiple SIP accounts and concurrent calls
|
|
17
|
+
- ⚡ **TypeScript-first** — type-safe, modular APIs
|
|
18
|
+
- 🛠️ **Configurable & Extensible** — tailored to your SIP setup
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 📦 Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install react-sip-kit
|
|
26
|
+
# or
|
|
27
|
+
yarn add react-sip-kit
|
|
28
|
+
````
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 🚀 Getting Started
|
|
33
|
+
|
|
34
|
+
### 1️⃣ Initialize a `SipManager`
|
|
35
|
+
|
|
36
|
+
Create a single `SipManager` instance. Add accounts dynamically as needed.
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
// main.tsx
|
|
40
|
+
import App from './App';
|
|
41
|
+
import { SipManager } from 'react-sip-kit';
|
|
42
|
+
import { StrictMode, useEffect } from 'react';
|
|
43
|
+
import { createRoot } from 'react-dom/client';
|
|
44
|
+
|
|
45
|
+
export const SipConnection = new SipManager();
|
|
46
|
+
|
|
47
|
+
const Providers = () => {
|
|
48
|
+
const configs = [
|
|
49
|
+
{
|
|
50
|
+
account: {
|
|
51
|
+
domain: 'sip.example.com',
|
|
52
|
+
username: '1010',
|
|
53
|
+
password: 'password',
|
|
54
|
+
wssServer: 'sip.example.com',
|
|
55
|
+
webSocketPort: '8089',
|
|
56
|
+
serverPath: '/ws',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
configs.forEach((config) => SipConnection.add(config));
|
|
63
|
+
}, [configs]);
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<StrictMode>
|
|
67
|
+
{configs.map((config) => (
|
|
68
|
+
<App key={config.account.username} username={config.account.username} />
|
|
69
|
+
))}
|
|
70
|
+
</StrictMode>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
createRoot(document.getElementById('root')!).render(<Providers />);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### 2️⃣ Access SIP state & methods
|
|
80
|
+
|
|
81
|
+
Fetch **methods** and **account state** via username, lineKey, or remoteNumber:
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
// App.tsx
|
|
85
|
+
import { SipConnection } from './main';
|
|
86
|
+
|
|
87
|
+
function App({ username }: { username: string }) {
|
|
88
|
+
const { dialByNumber } = SipConnection.getSessionMethodsBy({ username });
|
|
89
|
+
const { watch, status, lines } = SipConnection.getAccountBy({ username });
|
|
90
|
+
|
|
91
|
+
const account = watch();
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<>
|
|
95
|
+
<h2>Web Phone {username} — {status}</h2>
|
|
96
|
+
<button onClick={() => dialByNumber('audio', '1012')}>Call 1012</button>
|
|
97
|
+
<button onClick={() => dialByNumber('video', '1012')}>Video Call 1012</button>
|
|
98
|
+
</>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
You can also use **lineKey** or **remoteNumber** instead of username:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
SipConnection.getSessionMethodsBy({ lineKey: 1 });
|
|
107
|
+
SipConnection.getAccountBy({ remoteNumber: '1001' });
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
### 3️⃣ Watch session data (`useWatchSessionData`)
|
|
113
|
+
|
|
114
|
+
Fine-grained updates for a line/session:
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
import { useWatchSessionData } from 'react-sip-kit';
|
|
118
|
+
|
|
119
|
+
function RecordingStatus({ lineKey }: { lineKey: number }) {
|
|
120
|
+
const isRecording = useWatchSessionData({
|
|
121
|
+
key: { lineKey },
|
|
122
|
+
name: 'recordMedia.recording',
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
return <p>Recording: {isRecording ? 'Yes' : 'No'}</p>;
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Watch multiple fields:
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
const [localMediaStatus, isRecording] = useWatchSessionData({
|
|
133
|
+
key: { lineKey: 1 },
|
|
134
|
+
name: ['localMediaStreamStatus', 'recordMedia.recording'],
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Works with `remoteNumber` as well:
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
const isMuted = useWatchSessionData({
|
|
142
|
+
key: { remoteNumber: '1001' },
|
|
143
|
+
name: 'localMediaStreamStatus.muted',
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
### 4️⃣ Helper Resolver Methods
|
|
149
|
+
|
|
150
|
+
`SipManager` provides convenient **resolver methods** for quickly looking up lines, sessions, or usernames by `lineKey` or `remoteNumber`. These help avoid manually mapping usernames or tracking lines.
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
import { SipConnection } from './main';
|
|
154
|
+
|
|
155
|
+
// Get a specific line
|
|
156
|
+
const line = SipConnection.getLineBy({ lineKey: 1 });
|
|
157
|
+
// or by remote number
|
|
158
|
+
const remoteLine = SipConnection.getLineBy({ remoteNumber: '1001' });
|
|
159
|
+
|
|
160
|
+
// Get an active SIP session
|
|
161
|
+
const session = SipConnection.getSessionBy({ lineKey: 1 });
|
|
162
|
+
// or by remote number
|
|
163
|
+
const remoteSession = SipConnection.getSessionBy({ remoteNumber: '1001' });
|
|
164
|
+
|
|
165
|
+
// Get the username for a line
|
|
166
|
+
const username = SipConnection.getUsernameBy({ lineKey: 1 });
|
|
167
|
+
// or by remote number
|
|
168
|
+
const remoteUsername = SipConnection.getUsernameBy({ remoteNumber: '1001' });
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Notes:**
|
|
172
|
+
|
|
173
|
+
* These methods are **lookup helpers only** — they do not return reactive data.
|
|
174
|
+
* Combine with `getAccountBy()` or `useWatchSessionData()` for reactive state.
|
|
175
|
+
* Useful when you have only a `lineKey` or `remoteNumber` but need the username or session quickly.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
### 5️⃣ Render media streams
|
|
180
|
+
|
|
181
|
+
Media components are line-bound:
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
import { VideoStream, AudioStream } from 'react-sip-kit';
|
|
185
|
+
|
|
186
|
+
<VideoStream type="local" lineKey={1} />
|
|
187
|
+
<VideoStream type="remote" lineKey={1} />
|
|
188
|
+
<AudioStream type="local" lineKey={1} />
|
|
189
|
+
<AudioStream type="remote" lineKey={1} />
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## ⚙️ Configuration
|
|
195
|
+
|
|
196
|
+
Each SIP account supports account, media, and feature settings:
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
{
|
|
200
|
+
account: {
|
|
201
|
+
domain: 'your.sip.domain',
|
|
202
|
+
username: 'user',
|
|
203
|
+
password: 'secret',
|
|
204
|
+
wssServer: 'your.sip.domain',
|
|
205
|
+
webSocketPort: '8089',
|
|
206
|
+
serverPath: '/ws',
|
|
207
|
+
},
|
|
208
|
+
features: { enableVideo: true },
|
|
209
|
+
media: {
|
|
210
|
+
audioInputDeviceId: 'default',
|
|
211
|
+
audioOutputDeviceId: 'default',
|
|
212
|
+
videoInputDeviceId: 'default',
|
|
213
|
+
},
|
|
214
|
+
registration: { registerExpires: 3600 },
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## 💡 Best Practices
|
|
221
|
+
|
|
222
|
+
* Use `username`, `lineKey`, or `remoteNumber` to fetch methods/state.
|
|
223
|
+
* `.watch()` provides reactive account data (`lines`, `status`).
|
|
224
|
+
* `useWatchSessionData` tracks **line-specific updates** (mute, hold, video, recording, etc.).
|
|
225
|
+
* Render `<VideoStream>` & `<AudioStream>` only for active calls.
|
|
226
|
+
* Manage mic/camera permissions upfront.
|
|
227
|
+
* Add accounts dynamically with `SipConnection.add(config)`.
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## 🧑💻 Examples
|
|
232
|
+
|
|
233
|
+
Check [`/example`](https://github.com/shervin-ghajar/react-sip-kit/tree/main/example) for:
|
|
234
|
+
|
|
235
|
+
* Multi-account setups
|
|
236
|
+
* Audio & video calls
|
|
237
|
+
* Hold, mute, attended transfer
|
|
238
|
+
* Call recording & screen sharing
|
|
239
|
+
* Local & remote media rendering
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## 📄 License
|
|
244
|
+
|
|
245
|
+
MIT
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## 👤 Author
|
|
250
|
+
|
|
251
|
+
**Shervin Ghajar**
|
|
252
|
+
|
|
253
|
+
* GitHub: [@shervin-ghajar](https://github.com/shervin-ghajar)
|
|
254
|
+
* NPM: [react-sip-kit](https://www.npmjs.com/package/react-sip-kit)
|
|
212
255
|
* Repository: [react-sip-kit](https://github.com/shervin-ghajar/react-sip-kit)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AudioHTMLAttributes, HTMLAttributes } from 'react';
|
|
2
2
|
interface DefaultAudioProps {
|
|
3
|
-
|
|
3
|
+
lineKey: string | number;
|
|
4
4
|
}
|
|
5
5
|
interface LocalAudioProps extends AudioHTMLAttributes<HTMLAudioElement>, DefaultAudioProps {
|
|
6
6
|
type: 'local';
|
|
@@ -11,5 +11,5 @@ interface RemoteAudioProps extends HTMLAttributes<HTMLDivElement>, DefaultAudioP
|
|
|
11
11
|
id?: `line-${number}-remoteAudios`;
|
|
12
12
|
}
|
|
13
13
|
type AudioProps = LocalAudioProps | RemoteAudioProps;
|
|
14
|
-
export declare const Audio: ({
|
|
14
|
+
export declare const Audio: ({ lineKey, ...rest }: AudioProps) => import("react/jsx-runtime").JSX.Element;
|
|
15
15
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HTMLAttributes, VideoHTMLAttributes } from 'react';
|
|
2
2
|
interface DefaultVideoProps {
|
|
3
|
-
|
|
3
|
+
lineKey: string | number;
|
|
4
4
|
}
|
|
5
5
|
interface LocalVideoProps extends VideoHTMLAttributes<HTMLVideoElement>, DefaultVideoProps {
|
|
6
6
|
type: 'local';
|
|
@@ -11,5 +11,5 @@ interface RemoteVidepProps extends HTMLAttributes<HTMLDivElement>, DefaultVideoP
|
|
|
11
11
|
id?: `line-${number}-${RemoteVidepProps['type']}Video` | `line-${number}-remoteVideos`;
|
|
12
12
|
}
|
|
13
13
|
type VideoProps = LocalVideoProps | RemoteVidepProps;
|
|
14
|
-
export declare const Video: ({
|
|
14
|
+
export declare const Video: ({ lineKey, ...rest }: VideoProps) => import("react/jsx-runtime").JSX.Element;
|
|
15
15
|
export {};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { SipAccountConfig } from '../configs/types';
|
|
1
2
|
import { LineType, SipInvitationType } from '../store/types';
|
|
2
3
|
export declare class Line implements LineType {
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
lineKey: number;
|
|
5
|
+
remoteNumber: string;
|
|
6
|
+
username: string;
|
|
5
7
|
sipSession: SipInvitationType | null;
|
|
6
8
|
localSoundMeter: any;
|
|
7
9
|
remoteSoundMeter: any;
|
|
8
|
-
constructor(
|
|
10
|
+
constructor(username: SipAccountConfig['username'], lineKey: number, remoteNumber: string);
|
|
9
11
|
}
|
|
@@ -1,21 +1,81 @@
|
|
|
1
|
-
import { SipSessionDataType } from '../../store/types';
|
|
1
|
+
import { LineType, SipSessionDataType } from '../../store/types';
|
|
2
2
|
type Primitive = string | number | boolean | symbol | null | undefined;
|
|
3
3
|
type Path<T> = {
|
|
4
4
|
[K in keyof T & string]: T[K] extends Primitive | Array<any> ? K : K | `${K}.${Path<T[K]>}`;
|
|
5
5
|
}[keyof T & string];
|
|
6
6
|
/** Resolve the value type of a dot-path string. */
|
|
7
7
|
type PathValue<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? Rest extends string ? PathValue<T[K], Rest> : never : never : P extends keyof T ? T[P] : never;
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* React hook to watch SIP session data for a specific line.
|
|
10
|
+
*
|
|
11
|
+
* Provide a single `key` object containing **either** `lineKey` or `remoteNumber`.
|
|
12
|
+
* You can also optionally specify `name` to access a specific property (supports dot-paths),
|
|
13
|
+
* or an array of names to get multiple properties at once.
|
|
14
|
+
*
|
|
15
|
+
* @param {Object} params
|
|
16
|
+
* @param {Object} params.key - Lookup key for the line/session.
|
|
17
|
+
* @param {number} [params.key.lineKey] - Numeric line identifier. Takes priority if both keys are somehow provided.
|
|
18
|
+
* @param {string} [params.key.remoteNumber] - Remote number of the SIP session. Used if `lineKey` is not provided.
|
|
19
|
+
* @param {string | string[]} [params.name] - Optional dot-path string (e.g., 'localMediaStreamStatus.videoEnabled')
|
|
20
|
+
* or array of dot-paths to select specific data from the session.
|
|
21
|
+
*
|
|
22
|
+
* @returns {SipSessionDataType | any | any[]}
|
|
23
|
+
* Returns the full session data if `name` is undefined,
|
|
24
|
+
* a single property if `name` is a string,
|
|
25
|
+
* or an array of properties if `name` is an array.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* // Watch full session data by lineKey
|
|
29
|
+
* const sessionData = useWatchSessionData({ key: { lineKey: 1 } });
|
|
30
|
+
*
|
|
31
|
+
* // Watch a specific property by lineKey
|
|
32
|
+
* const videoEnabled = useWatchSessionData({ key: { lineKey: 1 }, name: 'localMediaStreamStatus.videoEnabled' });
|
|
33
|
+
*
|
|
34
|
+
* // Watch full session data by remoteNumber
|
|
35
|
+
* const sessionData = useWatchSessionData({ key: { remoteNumber: '1001' } });
|
|
36
|
+
*
|
|
37
|
+
* // Watch multiple properties by remoteNumber
|
|
38
|
+
* const [videoEnabled, audioEnabled] = useWatchSessionData({
|
|
39
|
+
* key: { remoteNumber: '1001' },
|
|
40
|
+
* name: ['localMediaStreamStatus.videoEnabled', 'localMediaStreamStatus.audioEnabled']
|
|
41
|
+
* });
|
|
42
|
+
*/
|
|
9
43
|
export declare function useWatchSessionData(props: {
|
|
10
|
-
|
|
44
|
+
key: {
|
|
45
|
+
lineKey: LineType['lineKey'];
|
|
46
|
+
};
|
|
11
47
|
name?: undefined;
|
|
12
48
|
}): SipSessionDataType;
|
|
49
|
+
export declare function useWatchSessionData(props: {
|
|
50
|
+
key: {
|
|
51
|
+
remoteNumber: SipSessionDataType['remoteNumber'];
|
|
52
|
+
};
|
|
53
|
+
name?: undefined;
|
|
54
|
+
}): SipSessionDataType;
|
|
55
|
+
export declare function useWatchSessionData<P extends Path<SipSessionDataType>>(props: {
|
|
56
|
+
key: {
|
|
57
|
+
lineKey: LineType['lineKey'];
|
|
58
|
+
};
|
|
59
|
+
name: P;
|
|
60
|
+
}): PathValue<SipSessionDataType, P>;
|
|
13
61
|
export declare function useWatchSessionData<P extends Path<SipSessionDataType>>(props: {
|
|
14
|
-
|
|
62
|
+
key: {
|
|
63
|
+
remoteNumber: SipSessionDataType['remoteNumber'];
|
|
64
|
+
};
|
|
15
65
|
name: P;
|
|
16
66
|
}): PathValue<SipSessionDataType, P>;
|
|
17
67
|
export declare function useWatchSessionData<const P extends readonly Path<SipSessionDataType>[]>(props: {
|
|
18
|
-
|
|
68
|
+
key: {
|
|
69
|
+
lineKey: LineType['lineKey'];
|
|
70
|
+
};
|
|
71
|
+
name: P;
|
|
72
|
+
}): {
|
|
73
|
+
[K in keyof P]: PathValue<SipSessionDataType, P[K] & string>;
|
|
74
|
+
};
|
|
75
|
+
export declare function useWatchSessionData<const P extends readonly Path<SipSessionDataType>[]>(props: {
|
|
76
|
+
key: {
|
|
77
|
+
remoteNumber: SipSessionDataType['remoteNumber'];
|
|
78
|
+
};
|
|
19
79
|
name: P;
|
|
20
80
|
}): {
|
|
21
81
|
[K in keyof P]: PathValue<SipSessionDataType, P[K] & string>;
|