@tbisoftware/phone 1.0.13 → 2.0.4

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @tbisoftware/phone
2
2
 
3
- A reusable SIP phone component for React applications built with Tailwind CSS and JsSIP.
3
+ A reusable SIP phone component for **React** and **Vue** applications built with Tailwind CSS and JsSIP.
4
4
 
5
5
  ## Installation
6
6
 
@@ -10,21 +10,35 @@ npm install @tbisoftware/phone
10
10
 
11
11
  ## Features
12
12
 
13
- - 📞 Full SIP/WebRTC phone functionality
14
- - 🎨 Beautiful UI built with Tailwind CSS
15
- - 🪝 Headless mode with `usePhoneManager` hook for custom UIs
16
- - 📱 Call history with localStorage persistence
17
- - 🌐 Internationalization support with custom labels
18
- - Singleton pattern for reliable WebSocket connections
13
+ - Multi-framework support: **React** and **Vue 3**
14
+ - Full SIP/WebRTC phone functionality
15
+ - Beautiful UI built with Tailwind CSS
16
+ - Headless mode with `usePhoneManager` hook/composable for custom UIs
17
+ - Call history with localStorage persistence
18
+ - Internationalization support with custom labels
19
+ - Singleton pattern for reliable WebSocket connections
20
+ - Framework-agnostic core for custom integrations
19
21
 
20
- ## Usage
22
+ ## Entry Points
21
23
 
22
- ### Option 1: Ready-to-use Component
24
+ | Import Path | Description |
25
+ |-------------|-------------|
26
+ | `@tbisoftware/phone` | Default React exports (backward compatible) |
27
+ | `@tbisoftware/phone/react` | Explicit React exports |
28
+ | `@tbisoftware/phone/vue` | Vue 3 exports |
29
+ | `@tbisoftware/phone/core` | Framework-agnostic core (PhoneManager class) |
23
30
 
24
- The simplest way to add a phone to your app:
31
+ ---
32
+
33
+ # React Usage
34
+
35
+ ## Option 1: Ready-to-use Component
36
+
37
+ The simplest way to add a phone to your React app:
25
38
 
26
39
  ```tsx
27
40
  import { Phone } from "@tbisoftware/phone";
41
+ // or explicitly: import { Phone } from "@tbisoftware/phone/react";
28
42
 
29
43
  const config = {
30
44
  websocketUrl: "wss://your-sip-server.com:8989",
@@ -37,7 +51,7 @@ const config = {
37
51
 
38
52
  function App() {
39
53
  return (
40
- <Phone
54
+ <Phone
41
55
  config={config}
42
56
  onCallStart={(number) => console.log('Calling:', number)}
43
57
  onCallEnd={(number, duration, status) => {
@@ -48,7 +62,7 @@ function App() {
48
62
  }
49
63
  ```
50
64
 
51
- ### Option 2: Headless Hook for Custom UI
65
+ ## Option 2: Headless Hook for Custom UI
52
66
 
53
67
  Use `usePhoneManager` to build your own phone interface:
54
68
 
@@ -80,101 +94,32 @@ function CustomPhone() {
80
94
  onCallEnd: (number, duration, status) => {
81
95
  console.log(`Call ended: ${number}, ${duration}s, ${status}`);
82
96
  },
83
- onStatusChange: (status) => console.log('Status:', status),
84
- onConnectionChange: (status) => console.log('Connection:', status),
85
97
  });
86
98
 
87
99
  return (
88
100
  <div className="p-4 border rounded-lg">
89
- {/* Connection indicator */}
90
- <div className="flex items-center gap-2 mb-4">
91
- <div className={`w-2 h-2 rounded-full ${
92
- connectionStatus === 'connected' ? 'bg-green-500' :
93
- connectionStatus === 'connecting' ? 'bg-yellow-500' :
94
- 'bg-red-500'
95
- }`} />
96
- <span className="text-sm text-gray-500">
97
- {connectionStatus === 'connected' ? 'Ready' :
98
- connectionStatus === 'connecting' ? 'Connecting...' :
99
- 'Disconnected'}
100
- </span>
101
- </div>
102
-
103
- {/* Idle state - show input */}
104
101
  {status === 'disconnected' && (
105
102
  <div className="flex gap-2">
106
103
  <input
107
104
  type="tel"
108
105
  value={callNumber}
109
106
  onChange={(e) => setCallNumber(e.target.value)}
110
- onKeyDown={(e) => e.key === 'Enter' && startCall(callNumber)}
111
107
  placeholder="Enter phone number"
112
- className="flex-1 px-3 py-2 border rounded"
113
108
  />
114
109
  <button
115
110
  onClick={() => startCall(callNumber)}
116
111
  disabled={!isReady || callNumber.length < 9}
117
- className="px-4 py-2 bg-green-500 text-white rounded disabled:opacity-50"
118
112
  >
119
113
  Call
120
114
  </button>
121
115
  </div>
122
116
  )}
123
117
 
124
- {/* Calling state */}
125
- {status === 'progress' && (
126
- <div className="text-center">
127
- <p className="text-lg">Calling {callNumber}...</p>
128
- <button
129
- onClick={endCall}
130
- className="mt-4 px-4 py-2 bg-red-500 text-white rounded"
131
- >
132
- Cancel
133
- </button>
134
- </div>
135
- )}
136
-
137
- {/* In call */}
138
118
  {status === 'confirmed' && (
139
119
  <div className="text-center">
140
- <p className="text-lg font-bold">{callNumber}</p>
141
- <p className="text-2xl font-mono text-green-600">
142
- {formatDuration(currentCallDuration)}
143
- </p>
144
- <button
145
- onClick={endCall}
146
- className="mt-4 px-4 py-2 bg-red-500 text-white rounded"
147
- >
148
- Hang Up
149
- </button>
150
- </div>
151
- )}
152
-
153
- {/* Call history */}
154
- {status === 'disconnected' && callHistory.length > 0 && (
155
- <div className="mt-4">
156
- <h3 className="text-sm font-semibold mb-2">Recent Calls</h3>
157
- <ul className="space-y-1">
158
- {callHistory.slice(0, 5).map((entry) => (
159
- <li
160
- key={entry.id}
161
- className="flex justify-between text-sm cursor-pointer hover:bg-gray-50 p-1 rounded"
162
- onClick={() => {
163
- setCallNumber(entry.number);
164
- startCall(entry.number);
165
- }}
166
- >
167
- <span>{entry.number}</span>
168
- <span className={
169
- entry.status === 'completed' ? 'text-green-500' :
170
- entry.status === 'failed' ? 'text-red-500' :
171
- 'text-yellow-500'
172
- }>
173
- {entry.status}
174
- </span>
175
- </li>
176
- ))}
177
- </ul>
120
+ <p>{callNumber}</p>
121
+ <p>{formatDuration(currentCallDuration)}</p>
122
+ <button onClick={endCall}>Hang Up</button>
178
123
  </div>
179
124
  )}
180
125
  </div>
@@ -182,23 +127,15 @@ function CustomPhone() {
182
127
  }
183
128
  ```
184
129
 
185
- ### Option 3: Using Provider and usePhone Hook
130
+ ## Option 3: Using Provider and usePhone Hook
186
131
 
187
- For more complex scenarios where you need to access phone state from multiple components:
132
+ For complex scenarios where you need to access phone state from multiple components:
188
133
 
189
134
  ```tsx
190
135
  import { PhoneProvider, usePhone } from "@tbisoftware/phone";
191
136
 
192
- const config = {
193
- websocketUrl: "wss://your-sip-server.com:8989",
194
- sipUri: "sip:user@domain.com",
195
- password: "your-password",
196
- registrarServer: "sip:domain.com",
197
- displayName: "User Name",
198
- authorizationUser: "auth-user",
199
- };
137
+ const config = { /* ... */ };
200
138
 
201
- // Wrap your app with the provider
202
139
  function App() {
203
140
  return (
204
141
  <PhoneProvider config={config}>
@@ -208,10 +145,9 @@ function App() {
208
145
  );
209
146
  }
210
147
 
211
- // Access phone state from any child component
212
148
  function PhoneDialer() {
213
149
  const { callNumber, setCallNumber, startCall, isReady } = usePhone();
214
-
150
+
215
151
  return (
216
152
  <div>
217
153
  <input
@@ -227,9 +163,9 @@ function PhoneDialer() {
227
163
 
228
164
  function CallStatus() {
229
165
  const { status, currentCallDuration, endCall } = usePhone();
230
-
166
+
231
167
  if (status === 'disconnected') return null;
232
-
168
+
233
169
  return (
234
170
  <div>
235
171
  <p>Status: {status}</p>
@@ -240,9 +176,222 @@ function CallStatus() {
240
176
  }
241
177
  ```
242
178
 
243
- ## API Reference
179
+ ---
180
+
181
+ # Vue 3 Usage
182
+
183
+ ## Option 1: Ready-to-use Component
184
+
185
+ ```vue
186
+ <script setup lang="ts">
187
+ import { Phone } from "@tbisoftware/phone/vue";
188
+
189
+ const config = {
190
+ websocketUrl: "wss://your-sip-server.com:8989",
191
+ sipUri: "sip:user@domain.com",
192
+ password: "your-password",
193
+ registrarServer: "sip:domain.com",
194
+ displayName: "User Name",
195
+ authorizationUser: "auth-user",
196
+ };
197
+
198
+ function handleCallStart(number: string) {
199
+ console.log('Calling:', number);
200
+ }
201
+
202
+ function handleCallEnd(number: string, duration: number, status: string) {
203
+ console.log(`Call to ${number} ${status}. Duration: ${duration}s`);
204
+ }
205
+ </script>
206
+
207
+ <template>
208
+ <Phone
209
+ :config="config"
210
+ @call-start="handleCallStart"
211
+ @call-end="handleCallEnd"
212
+ />
213
+ </template>
214
+ ```
215
+
216
+ ## Option 2: Headless Composable for Custom UI
217
+
218
+ Use `usePhoneManager` to build your own phone interface:
219
+
220
+ ```vue
221
+ <script setup lang="ts">
222
+ import { usePhoneManager } from "@tbisoftware/phone/vue";
223
+ import { formatDuration } from "@tbisoftware/phone/core";
224
+
225
+ const config = {
226
+ websocketUrl: "wss://your-sip-server.com:8989",
227
+ sipUri: "sip:user@domain.com",
228
+ password: "your-password",
229
+ registrarServer: "sip:domain.com",
230
+ displayName: "User Name",
231
+ authorizationUser: "auth-user",
232
+ };
233
+
234
+ const {
235
+ status,
236
+ callNumber,
237
+ setCallNumber,
238
+ callHistory,
239
+ currentCallDuration,
240
+ startCall,
241
+ endCall,
242
+ isReady,
243
+ connectionStatus,
244
+ } = usePhoneManager(config, {
245
+ onCallStart: (number) => console.log('Starting call to:', number),
246
+ onCallEnd: (number, duration, status) => {
247
+ console.log(`Call ended: ${number}, ${duration}s, ${status}`);
248
+ },
249
+ });
250
+ </script>
251
+
252
+ <template>
253
+ <div class="p-4 border rounded-lg">
254
+ <div v-if="status === 'disconnected'" class="flex gap-2">
255
+ <input
256
+ type="tel"
257
+ :value="callNumber"
258
+ @input="setCallNumber(($event.target as HTMLInputElement).value)"
259
+ placeholder="Enter phone number"
260
+ />
261
+ <button
262
+ @click="startCall(callNumber)"
263
+ :disabled="!isReady || callNumber.length < 9"
264
+ >
265
+ Call
266
+ </button>
267
+ </div>
268
+
269
+ <div v-if="status === 'confirmed'" class="text-center">
270
+ <p>{{ callNumber }}</p>
271
+ <p>{{ formatDuration(currentCallDuration) }}</p>
272
+ <button @click="endCall">Hang Up</button>
273
+ </div>
274
+ </div>
275
+ </template>
276
+ ```
277
+
278
+ ## Option 3: Using Provider and usePhone Composable
279
+
280
+ For complex scenarios where you need to access phone state from multiple components:
281
+
282
+ ```vue
283
+ <!-- App.vue -->
284
+ <script setup lang="ts">
285
+ import { usePhoneProvider } from "@tbisoftware/phone/vue";
286
+ import PhoneDialer from './PhoneDialer.vue';
287
+ import CallStatus from './CallStatus.vue';
288
+
289
+ const config = { /* ... */ };
244
290
 
245
- ### `<Phone />` Component Props
291
+ usePhoneProvider({ config });
292
+ </script>
293
+
294
+ <template>
295
+ <PhoneDialer />
296
+ <CallStatus />
297
+ </template>
298
+ ```
299
+
300
+ ```vue
301
+ <!-- PhoneDialer.vue -->
302
+ <script setup lang="ts">
303
+ import { usePhone } from "@tbisoftware/phone/vue";
304
+
305
+ const { callNumber, setCallNumber, startCall, isReady } = usePhone();
306
+ </script>
307
+
308
+ <template>
309
+ <div>
310
+ <input
311
+ :value="callNumber"
312
+ @input="setCallNumber(($event.target as HTMLInputElement).value)"
313
+ />
314
+ <button @click="startCall(callNumber)" :disabled="!isReady">
315
+ Call
316
+ </button>
317
+ </div>
318
+ </template>
319
+ ```
320
+
321
+ ```vue
322
+ <!-- CallStatus.vue -->
323
+ <script setup lang="ts">
324
+ import { usePhone } from "@tbisoftware/phone/vue";
325
+
326
+ const { status, currentCallDuration, endCall } = usePhone();
327
+ </script>
328
+
329
+ <template>
330
+ <div v-if="status !== 'disconnected'">
331
+ <p>Status: {{ status }}</p>
332
+ <p v-if="status === 'confirmed'">Duration: {{ currentCallDuration }}s</p>
333
+ <button @click="endCall">End Call</button>
334
+ </div>
335
+ </template>
336
+ ```
337
+
338
+ ---
339
+
340
+ # Core Usage (Framework-Agnostic)
341
+
342
+ For custom integrations or other frameworks, you can use the `PhoneManager` class directly:
343
+
344
+ ```typescript
345
+ import { PhoneManager } from "@tbisoftware/phone/core";
346
+
347
+ const config = {
348
+ websocketUrl: "wss://your-sip-server.com:8989",
349
+ sipUri: "sip:user@domain.com",
350
+ password: "your-password",
351
+ registrarServer: "sip:domain.com",
352
+ displayName: "User Name",
353
+ authorizationUser: "auth-user",
354
+ };
355
+
356
+ const manager = new PhoneManager(
357
+ config,
358
+ {
359
+ onStatusChange: (status) => console.log('Status:', status),
360
+ onCallStart: (number) => console.log('Calling:', number),
361
+ onCallEnd: (number, duration, status) => {
362
+ console.log(`Call ended: ${number}, ${duration}s, ${status}`);
363
+ },
364
+ onConnectionChange: (status) => console.log('Connection:', status),
365
+ },
366
+ {
367
+ persistHistory: true,
368
+ historyKey: 'my-phone-history',
369
+ }
370
+ );
371
+
372
+ // Initialize the phone
373
+ manager.initialize();
374
+
375
+ // Make a call
376
+ manager.startCall('+1234567890');
377
+
378
+ // End the call
379
+ manager.endCall();
380
+
381
+ // Access state
382
+ console.log(manager.state.status);
383
+ console.log(manager.state.isReady);
384
+ console.log(manager.state.callHistory);
385
+
386
+ // Clean up when done
387
+ manager.destroy();
388
+ ```
389
+
390
+ ---
391
+
392
+ # API Reference
393
+
394
+ ## `<Phone />` Component Props
246
395
 
247
396
  | Prop | Type | Description |
248
397
  |------|------|-------------|
@@ -253,7 +402,7 @@ function CallStatus() {
253
402
  | `onStatusChange` | `(status: PhoneStatus) => void` | Callback when status changes |
254
403
  | `labels` | `Partial<PhoneLabels>` | Custom labels for internationalization |
255
404
 
256
- ### `usePhoneManager(config, options)` Hook
405
+ ## `usePhoneManager(config, options)` Hook/Composable
257
406
 
258
407
  Returns an object with:
259
408
 
@@ -271,7 +420,7 @@ Returns an object with:
271
420
  | `connectionStatus` | `ConnectionStatus` | `'connecting' \| 'connected' \| 'disconnected' \| 'failed'` |
272
421
  | `ua` | `JsSIP.UA \| null` | Raw JsSIP User Agent for advanced usage |
273
422
 
274
- #### Options
423
+ ### Options
275
424
 
276
425
  | Option | Type | Default | Description |
277
426
  |--------|------|---------|-------------|
@@ -282,7 +431,7 @@ Returns an object with:
282
431
  | `persistHistory` | `boolean` | `true` | Save history to localStorage |
283
432
  | `historyKey` | `string` | `'tbi-phone-call-history'` | localStorage key for history |
284
433
 
285
- ### `PhoneConfig` Type
434
+ ## `PhoneConfig` Type
286
435
 
287
436
  ```typescript
288
437
  interface PhoneConfig {
@@ -295,7 +444,7 @@ interface PhoneConfig {
295
444
  }
296
445
  ```
297
446
 
298
- ### `PhoneLabels` Type
447
+ ## `PhoneLabels` Type
299
448
 
300
449
  ```typescript
301
450
  interface PhoneLabels {
@@ -319,9 +468,8 @@ interface PhoneLabels {
319
468
  You can trigger a call from anywhere in your app using a custom event:
320
469
 
321
470
  ```javascript
322
- // Dispatch this event to start a call
323
- window.dispatchEvent(new CustomEvent('StartCallEvent', {
324
- detail: { number: '+1234567890' }
471
+ window.dispatchEvent(new CustomEvent('StartCallEvent', {
472
+ detail: { number: '+1234567890' }
325
473
  }));
326
474
  ```
327
475
 
@@ -335,6 +483,16 @@ The component uses Tailwind CSS classes. Make sure you have Tailwind CSS configu
335
483
  }
336
484
  ```
337
485
 
486
+ ## Migration from v1 to v2
487
+
488
+ If you're upgrading from v1 (React-only), your code should continue to work without changes. The default export still provides React components.
489
+
490
+ For explicit React imports (recommended):
491
+ ```diff
492
+ - import { Phone } from "@tbisoftware/phone";
493
+ + import { Phone } from "@tbisoftware/phone/react";
494
+ ```
495
+
338
496
  ## License
339
497
 
340
498
  MIT
@@ -0,0 +1,94 @@
1
+ import JsSIP from 'jssip';
2
+ import type { PhoneConfig, PhoneStatus, CallHistoryEntry, ConnectionStatus } from '../types';
3
+ export interface PhoneManagerEvents {
4
+ onConnecting?: () => void;
5
+ onConnected?: () => void;
6
+ onDisconnected?: () => void;
7
+ onRegistered?: () => void;
8
+ onUnregistered?: () => void;
9
+ onRegistrationFailed?: (cause?: string) => void;
10
+ onStatusChange?: (status: PhoneStatus) => void;
11
+ onConnectionChange?: (status: ConnectionStatus) => void;
12
+ onCallStart?: (number: string) => void;
13
+ onCallEnd?: (number: string, duration: number, status: 'completed' | 'failed') => void;
14
+ onDurationUpdate?: (duration: number) => void;
15
+ onHistoryUpdate?: (history: CallHistoryEntry[]) => void;
16
+ }
17
+ export interface PhoneManagerState {
18
+ status: PhoneStatus;
19
+ callNumber: string;
20
+ callHistory: CallHistoryEntry[];
21
+ currentCallDuration: number;
22
+ isReady: boolean;
23
+ connectionStatus: ConnectionStatus;
24
+ }
25
+ export interface PhoneManagerOptions {
26
+ persistHistory?: boolean;
27
+ historyKey?: string;
28
+ maxHistoryItems?: number;
29
+ }
30
+ /**
31
+ * Framework-agnostic Phone Manager class.
32
+ * Handles all SIP communication logic and can be used with any UI framework.
33
+ */
34
+ export declare class PhoneManager {
35
+ private config;
36
+ private uaInstance;
37
+ private currentSession;
38
+ private callStartedTS;
39
+ private durationInterval;
40
+ private startCallEventListener;
41
+ private _state;
42
+ private events;
43
+ private options;
44
+ private listener;
45
+ constructor(config: PhoneConfig, events?: PhoneManagerEvents, options?: PhoneManagerOptions);
46
+ /**
47
+ * Get the current state
48
+ */
49
+ get state(): Readonly<PhoneManagerState>;
50
+ /**
51
+ * Get the raw JsSIP UA instance (for advanced usage)
52
+ */
53
+ get ua(): JsSIP.UA | null;
54
+ /**
55
+ * Initialize and start the phone manager
56
+ */
57
+ initialize(): void;
58
+ /**
59
+ * Cleanup and destroy the phone manager
60
+ */
61
+ destroy(): void;
62
+ /**
63
+ * Set the call number
64
+ */
65
+ setCallNumber(number: string): void;
66
+ /**
67
+ * Start a call to the given number
68
+ */
69
+ startCall(number: string): void;
70
+ /**
71
+ * End the current call
72
+ */
73
+ endCall(): void;
74
+ /**
75
+ * Initialize the phone and start a call once registered
76
+ */
77
+ private initializeAndCall;
78
+ /**
79
+ * Clear the call history
80
+ */
81
+ clearHistory(): void;
82
+ /**
83
+ * Update events handlers
84
+ */
85
+ setEvents(events: Partial<PhoneManagerEvents>): void;
86
+ private updateState;
87
+ private loadHistory;
88
+ private saveHistory;
89
+ private addToHistory;
90
+ private startDurationTimer;
91
+ private stopDurationTimer;
92
+ }
93
+ export default PhoneManager;
94
+ //# sourceMappingURL=PhoneManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PhoneManager.d.ts","sourceRoot":"","sources":["../../src/core/PhoneManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../index-Br8w8pI3.cjs");exports.PhoneManager=e.PhoneManager;exports.cn=e.cn;exports.defaultLabels=e.defaultLabels;exports.formatDuration=e.formatDuration;
@@ -0,0 +1,7 @@
1
+ export { PhoneManager } from './PhoneManager';
2
+ export type { PhoneManagerEvents, PhoneManagerState, PhoneManagerOptions, } from './PhoneManager';
3
+ export type { PhoneConfig, PhoneStatus, ConnectionStatus, CallHistoryEntry, PhoneLabels, } from '../types';
4
+ export { defaultLabels } from '../types';
5
+ export { formatDuration } from '../utils/formatDuration';
6
+ export { cn } from '../utils/cn';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EACR,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,GACtB,MAAM,gBAAgB,CAAC;AAGxB,YAAY,EACR,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,GACd,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { P as o, c as r, d as s, f } from "../index-TymkBND5.js";
2
+ export {
3
+ o as PhoneManager,
4
+ r as cn,
5
+ s as defaultLabels,
6
+ f as formatDuration
7
+ };