voxnix 1.0.11 → 1.0.13
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 +257 -71
- package/dist/voxnix.iife.js +92 -97
- package/dist/voxnix.js +1785 -2070
- package/dist/voxnix.umd.cjs +51 -56
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
# Voxnix
|
|
2
2
|
|
|
3
|
-
Universal Voice Widget SDK. Works in React, Vue, Angular, plain HTML
|
|
3
|
+
Universal Voice Widget SDK — SIP-based floating phone widget. Works in React, Vue, Angular, plain HTML, or any stack.
|
|
4
|
+
|
|
5
|
+
**Current version: `1.0.12`**
|
|
6
|
+
|
|
7
|
+
---
|
|
4
8
|
|
|
5
9
|
## What it does
|
|
6
10
|
|
|
7
11
|
- Floating phone button (fixed position, configurable placement)
|
|
8
12
|
- Auto-connects to your SIP/PABX server on init
|
|
9
13
|
- Shows dialer numpad immediately after registration
|
|
10
|
-
- Full call UI: incoming call, outgoing dialing, in-call controls (mute, hold, DTMF)
|
|
11
|
-
-
|
|
14
|
+
- Full call UI: incoming call, outgoing dialing, in-call controls (mute, hold, DTMF keypad)
|
|
15
|
+
- **Agent status bar** — Ready / Not Ready / AUX with optional custom AUX codes
|
|
16
|
+
- Fires callbacks for all call and agent-status events so your app can react
|
|
17
|
+
- Keyboard shortcuts: digits to dial, `Enter` to call, `Backspace` to delete, `0–9`/`*`/`#` for DTMF during a call
|
|
18
|
+
|
|
19
|
+
---
|
|
12
20
|
|
|
13
21
|
## Installation
|
|
14
22
|
|
|
@@ -18,28 +26,41 @@ npm install voxnix
|
|
|
18
26
|
yarn add voxnix
|
|
19
27
|
```
|
|
20
28
|
|
|
29
|
+
---
|
|
30
|
+
|
|
21
31
|
## Quick start (any framework)
|
|
22
32
|
|
|
23
33
|
```js
|
|
24
34
|
import { OmnixWidget } from 'voxnix';
|
|
25
35
|
|
|
26
36
|
const widget = OmnixWidget.init({
|
|
27
|
-
platform: 'sipjs',
|
|
28
37
|
auth: {
|
|
29
|
-
username:
|
|
30
|
-
pwd_pbx:
|
|
38
|
+
username: '1001',
|
|
39
|
+
pwd_pbx: 'secret',
|
|
31
40
|
pabx_host: 'sip.example.com',
|
|
32
|
-
port: 8089
|
|
41
|
+
port: 8089, // optional, default 8089
|
|
33
42
|
},
|
|
34
|
-
placement: 'bottom-left', // 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'
|
|
35
43
|
|
|
44
|
+
// Required for agent status API (Ready / AUX / Not Ready)
|
|
45
|
+
'X-CPAAS-Key-Fingerprint': 'your-cpaas-key-fingerprint-here',
|
|
46
|
+
|
|
47
|
+
placement: 'bottom-left', // 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'
|
|
48
|
+
|
|
49
|
+
// Agent status options (optional)
|
|
50
|
+
autoReady: true, // auto-set agent to Ready after SIP register (default: true)
|
|
51
|
+
showAuxButton: false, // show AUX button in status bar (default: false)
|
|
52
|
+
auxOptions: [], // array of { code, label } — custom AUX codes
|
|
53
|
+
|
|
54
|
+
// Callbacks
|
|
36
55
|
onRegisterStatus: (status) => {
|
|
37
|
-
|
|
56
|
+
// status: 'REGISTERED' | { status: 'FAILED', reason: string }
|
|
57
|
+
console.log('SIP status:', status);
|
|
38
58
|
},
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
59
|
+
onAgentStatus: (status) => console.log('Agent:', status), // 'READY' | 'NOT_READY' | 'AUX'
|
|
60
|
+
onIncomingCall: (data) => console.log('Incoming:', data),
|
|
61
|
+
onCallAnswered: (data) => console.log('Answered:', data),
|
|
62
|
+
onCallEnded: (data) => console.log('Ended:', data),
|
|
63
|
+
onCallUnanswered: () => console.log('Missed call'),
|
|
43
64
|
});
|
|
44
65
|
|
|
45
66
|
// Imperative controls (optional — widget has its own UI)
|
|
@@ -54,17 +75,155 @@ widget.dial('1002'); // programmatic dial
|
|
|
54
75
|
widget.destroy(); // unmount widget
|
|
55
76
|
```
|
|
56
77
|
|
|
57
|
-
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Config reference
|
|
81
|
+
|
|
82
|
+
### Top-level options
|
|
83
|
+
|
|
84
|
+
| Option | Type | Default | Description |
|
|
85
|
+
|-----------------------------|--------------------------------------------------------------------|-----------------|-----------------------------------------------------------------|
|
|
86
|
+
| `auth` | `object` | — | SIP credentials (see [auth object](#auth-object)) |
|
|
87
|
+
| `pabxConfig` | `{ auth: object }` | — | Alternative config shape — use `pabxConfig.auth` instead of `auth` |
|
|
88
|
+
| `X-CPAAS-Key-Fingerprint` | `string` | — | **Required** for agent status API calls. See [section below](#x-cpaas-key-fingerprint) |
|
|
89
|
+
| `fingerprint` | `string` | — | Alias for `X-CPAAS-Key-Fingerprint` |
|
|
90
|
+
| `cpaasKeyFingerprint` | `string` | — | Alias for `X-CPAAS-Key-Fingerprint` |
|
|
91
|
+
| `placement` | `'bottom-left'` \| `'bottom-right'` \| `'top-left'` \| `'top-right'` | `'bottom-left'` | Fixed position of the floating widget |
|
|
92
|
+
| `offset` | `{ bottom?, top?, left?, right? }` | — | CSS pixel coords — overrides `placement` |
|
|
93
|
+
| `container` | `string` \| `HTMLElement` | — | Mount target. Auto-creates `<div id="omnix-widget-root">` if omitted |
|
|
94
|
+
| `autoReady` | `boolean` | `true` | Auto-call the Ready API right after SIP registration |
|
|
95
|
+
| `showAuxButton` | `boolean` | `false` | Show the AUX menu in the agent status bar |
|
|
96
|
+
| `auxOptions` | `Array<{ code: string, label: string }>` | `[]` | Custom AUX reason codes shown in the status dropdown |
|
|
97
|
+
| `onRegisterStatus` | `(status) => void` | — | `'REGISTERED'` or `{ status: 'FAILED', reason: string }` |
|
|
98
|
+
| `onAgentStatus` | `(status: string) => void` | — | `'READY'` \| `'NOT_READY'` \| `'AUX'` |
|
|
99
|
+
| `onIncomingCall` | `(data) => void` | — | Fired on incoming SIP INVITE |
|
|
100
|
+
| `onCallAnswered` | `(data) => void` | — | Fired when call is established |
|
|
101
|
+
| `onCallEnded` | `(data) => void` | — | Fired on BYE / hangup |
|
|
102
|
+
| `onCallUnanswered` | `() => void` | — | Fired when incoming call is not answered (missed) |
|
|
103
|
+
|
|
104
|
+
### `auth` object
|
|
105
|
+
|
|
106
|
+
| Field | Type | Description |
|
|
107
|
+
|-------------|----------|------------------------------------------|
|
|
108
|
+
| `username` | `string` | SIP username / extension number |
|
|
109
|
+
| `user_pbx` | `string` | Alias for `username` |
|
|
110
|
+
| `pwd_pbx` | `string` | SIP password |
|
|
111
|
+
| `secret` | `string` | Alias for `pwd_pbx` |
|
|
112
|
+
| `pabx_host` | `string` | SIP domain / WSS host (strips `http(s)://`) |
|
|
113
|
+
| `pbxurl` | `string` | Alias for `pabx_host` |
|
|
114
|
+
| `port` | `number` | WSS port (default `8089`) |
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## `X-CPAAS-Key-Fingerprint`
|
|
119
|
+
|
|
120
|
+
This key is the **API authentication credential** used when the widget calls the CPaaS extension status endpoint:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
POST https://api-cpaas.omnix.co.id/voice/extensions/status
|
|
124
|
+
Header: X-CPAAS-Key-Fingerprint: <your-fingerprint>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The endpoint is hit automatically whenever the agent status changes (Ready / AUX / Not Ready). Without this key, status updates will silently fail and — if `autoReady: true` (default) — the widget will report `FAILED` registration even if the SIP connection itself succeeded.
|
|
128
|
+
|
|
129
|
+
### Accepted config locations
|
|
130
|
+
|
|
131
|
+
The widget looks for the fingerprint in the following order, using the first match:
|
|
132
|
+
|
|
133
|
+
| Priority | Config key | Example |
|
|
134
|
+
|----------|------------|---------|
|
|
135
|
+
| 1 | `'X-CPAAS-Key-Fingerprint'` (top-level) | `{ 'X-CPAAS-Key-Fingerprint': 'abc123', auth: { ... } }` |
|
|
136
|
+
| 2 | `fingerprint` (top-level) | `{ fingerprint: 'abc123', auth: { ... } }` |
|
|
137
|
+
| 3 | `cpaasKeyFingerprint` (top-level) | `{ cpaasKeyFingerprint: 'abc123', auth: { ... } }` |
|
|
138
|
+
| 4 | `env.fingerprint` | `{ env: { fingerprint: 'abc123' }, auth: { ... } }` |
|
|
139
|
+
| 5 | `env.X_CPAAS_Key_Fingerprint` | `{ env: { X_CPAAS_Key_Fingerprint: 'abc123' }, auth: { ... } }` |
|
|
140
|
+
| 6 | `pabxConfig['X-CPAAS-Key-Fingerprint']` | `{ pabxConfig: { 'X-CPAAS-Key-Fingerprint': 'abc123', auth: { ... } } }` |
|
|
141
|
+
|
|
142
|
+
### Recommended usage
|
|
143
|
+
|
|
144
|
+
```js
|
|
145
|
+
// Option A — top-level key (simplest)
|
|
146
|
+
OmnixWidget.init({
|
|
147
|
+
'X-CPAAS-Key-Fingerprint': 'your-fingerprint-here',
|
|
148
|
+
auth: { username: '1001', pwd_pbx: 'secret', pabx_host: 'sip.example.com' },
|
|
149
|
+
autoReady: true,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Option B — inside pabxConfig (if your backend returns this shape)
|
|
153
|
+
OmnixWidget.init({
|
|
154
|
+
pabxConfig: {
|
|
155
|
+
'X-CPAAS-Key-Fingerprint': 'your-fingerprint-here',
|
|
156
|
+
auth: { username: '1001', pwd_pbx: 'secret', pabx_host: 'sip.example.com' },
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Option C — via env object
|
|
161
|
+
OmnixWidget.init({
|
|
162
|
+
env: { fingerprint: 'your-fingerprint-here' },
|
|
163
|
+
auth: { username: '1001', pwd_pbx: 'secret', pabx_host: 'sip.example.com' },
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
> **Important:** If the fingerprint is missing and `autoReady: true` (default), the widget will emit `{ status: 'FAILED', reason: 'Failed to hit extension ready API' }` via `onRegisterStatus` even though the SIP connection itself was successful. Set `autoReady: false` if you do not have a fingerprint yet.
|
|
168
|
+
|
|
169
|
+
### Custom container / offset
|
|
58
170
|
|
|
59
171
|
```js
|
|
60
172
|
OmnixWidget.init({
|
|
61
173
|
container: '#my-widget-slot', // CSS selector or DOM element
|
|
62
|
-
// or
|
|
63
|
-
offset: { bottom: 80, left: 10 },
|
|
174
|
+
// — or —
|
|
175
|
+
offset: { bottom: 80, left: 10 }, // exact pixel position (bypasses placement)
|
|
64
176
|
// ... rest of config
|
|
65
177
|
});
|
|
66
178
|
```
|
|
67
179
|
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Instance API
|
|
183
|
+
|
|
184
|
+
`OmnixWidget.init()` returns an instance with these methods:
|
|
185
|
+
|
|
186
|
+
| Method | Description |
|
|
187
|
+
|----------------|------------------------------------------------------------|
|
|
188
|
+
| `answer()` | Answer the current incoming call |
|
|
189
|
+
| `hangup()` | End the active / outgoing call |
|
|
190
|
+
| `reject()` | Reject the current incoming call |
|
|
191
|
+
| `mute(bool)` | `true` = mute microphone, `false` = unmute |
|
|
192
|
+
| `hold(bool)` | `true` = put call on hold, `false` = resume |
|
|
193
|
+
| `dial(number)` | Programmatically dial a number string |
|
|
194
|
+
| `destroy()` | Unmount the widget and clean up the DOM container |
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Agent status bar
|
|
199
|
+
|
|
200
|
+
When `autoReady: false` or `showAuxButton: true` a status bar appears at the bottom of the dialer.
|
|
201
|
+
|
|
202
|
+
> **Note:** The agent status bar calls the CPaaS extension status API. You **must** provide `X-CPAAS-Key-Fingerprint` (or one of its aliases) for these calls to succeed.
|
|
203
|
+
|
|
204
|
+
```js
|
|
205
|
+
OmnixWidget.init({
|
|
206
|
+
auth: { ... },
|
|
207
|
+
'X-CPAAS-Key-Fingerprint': 'your-fingerprint-here',
|
|
208
|
+
autoReady: false, // agent starts as NOT_READY; must go Ready manually
|
|
209
|
+
showAuxButton: true, // show AUX dropdown
|
|
210
|
+
auxOptions: [
|
|
211
|
+
{ code: 'BRK', label: 'Break' },
|
|
212
|
+
{ code: 'LCH', label: 'Lunch' },
|
|
213
|
+
{ code: 'TRN', label: 'Training' },
|
|
214
|
+
],
|
|
215
|
+
onAgentStatus: (status) => console.log('Agent status changed:', status),
|
|
216
|
+
});
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
| Status | Badge colour | Meaning |
|
|
220
|
+
|-------------|--------------|--------------------------------------|
|
|
221
|
+
| `READY` | 🟢 Green | Agent is available for calls |
|
|
222
|
+
| `NOT_READY` | ⚪ Gray | Agent is unavailable |
|
|
223
|
+
| `AUX` | 🟡 Amber | Agent is on a break / custom reason |
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
68
227
|
## React integration
|
|
69
228
|
|
|
70
229
|
```jsx
|
|
@@ -76,13 +235,22 @@ function App() {
|
|
|
76
235
|
|
|
77
236
|
useEffect(() => {
|
|
78
237
|
widgetRef.current = OmnixWidget.init({
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
238
|
+
auth: {
|
|
239
|
+
username: '1001',
|
|
240
|
+
pwd_pbx: 'secret',
|
|
241
|
+
pabx_host: 'sip.example.com',
|
|
242
|
+
},
|
|
243
|
+
'X-CPAAS-Key-Fingerprint': 'your-fingerprint-here',
|
|
244
|
+
placement: 'bottom-right',
|
|
245
|
+
autoReady: true,
|
|
246
|
+
showAuxButton: true,
|
|
247
|
+
auxOptions: [{ code: 'BRK', label: 'Break' }],
|
|
248
|
+
|
|
249
|
+
onIncomingCall: (data) => { /* navigate, show notification, etc. */ },
|
|
250
|
+
onCallAnswered: (data) => { /* routing logic */ },
|
|
251
|
+
onCallEnded: () => { /* cleanup */ },
|
|
252
|
+
onRegisterStatus: (s) => { /* update UI */ },
|
|
253
|
+
onAgentStatus: (s) => { /* s: 'READY' | 'NOT_READY' | 'AUX' */ },
|
|
86
254
|
});
|
|
87
255
|
|
|
88
256
|
return () => widgetRef.current?.destroy();
|
|
@@ -92,96 +260,114 @@ function App() {
|
|
|
92
260
|
}
|
|
93
261
|
```
|
|
94
262
|
|
|
263
|
+
---
|
|
264
|
+
|
|
95
265
|
## Vue integration
|
|
96
266
|
|
|
97
267
|
```js
|
|
98
|
-
// composable or mounted()
|
|
99
268
|
import { OmnixWidget } from 'voxnix';
|
|
100
269
|
|
|
270
|
+
// inside setup() or options API
|
|
101
271
|
onMounted(() => {
|
|
102
|
-
const widget = OmnixWidget.init({
|
|
272
|
+
const widget = OmnixWidget.init({
|
|
273
|
+
auth: { username: '1001', pwd_pbx: 'secret', pabx_host: 'sip.example.com' },
|
|
274
|
+
'X-CPAAS-Key-Fingerprint': 'your-fingerprint-here',
|
|
275
|
+
autoReady: false,
|
|
276
|
+
showAuxButton: true,
|
|
277
|
+
auxOptions: [{ code: 'BRK', label: 'Break' }],
|
|
278
|
+
});
|
|
103
279
|
onUnmounted(() => widget.destroy());
|
|
104
280
|
});
|
|
105
281
|
```
|
|
106
282
|
|
|
283
|
+
---
|
|
284
|
+
|
|
107
285
|
## Via CDN (plain HTML, no bundler)
|
|
108
286
|
|
|
109
287
|
```html
|
|
110
|
-
<!--
|
|
111
|
-
<script src="https://unpkg.com/
|
|
112
|
-
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
|
|
113
|
-
|
|
114
|
-
<!-- Or use the self-contained IIFE build (includes React) -->
|
|
115
|
-
<script src="./dist/voxnix.iife.js"></script>
|
|
288
|
+
<!-- Self-contained IIFE build (bundles React) -->
|
|
289
|
+
<script src="https://unpkg.com/voxnix/dist/voxnix.iife.js"></script>
|
|
116
290
|
<script>
|
|
117
291
|
OmnixWidget.init({
|
|
118
|
-
platform: 'sipjs',
|
|
119
292
|
auth: {
|
|
120
|
-
username:
|
|
121
|
-
pwd_pbx:
|
|
293
|
+
username: '1001',
|
|
294
|
+
pwd_pbx: 'secret',
|
|
122
295
|
pabx_host: 'sip.example.com',
|
|
123
296
|
},
|
|
124
|
-
|
|
297
|
+
'X-CPAAS-Key-Fingerprint': 'your-fingerprint-here',
|
|
298
|
+
placement: 'bottom-right',
|
|
299
|
+
autoReady: true,
|
|
300
|
+
showAuxButton: true,
|
|
301
|
+
auxOptions: [
|
|
302
|
+
{ code: 'BRK', label: 'Break' },
|
|
303
|
+
{ code: 'LCH', label: 'Lunch' },
|
|
304
|
+
],
|
|
125
305
|
onRegisterStatus: (s) => console.log('SIP:', s),
|
|
126
306
|
onIncomingCall: (d) => console.log('Incoming:', d),
|
|
307
|
+
onAgentStatus: (s) => console.log('Agent:', s),
|
|
127
308
|
});
|
|
128
309
|
</script>
|
|
129
310
|
```
|
|
130
311
|
|
|
131
|
-
|
|
312
|
+
> If you need to use your own React instance, include `react@18` and `react-dom@18` UMD builds **before** the script tag and use `dist/voxnix.js` (ESM) or `dist/voxnix.umd.cjs` (CJS) instead.
|
|
132
313
|
|
|
133
|
-
|
|
134
|
-
|---------------------|------------------------------------------------|-----------------|--------------------------------------------------|
|
|
135
|
-
| `platform` | `string` | `'sipjs'` | Voice platform. Currently: `'sipjs'` |
|
|
136
|
-
| `auth` | `object` | — | SIP credentials (see below) |
|
|
137
|
-
| `placement` | `'bottom-left'│'bottom-right'│'top-left'│'top-right'` | `'bottom-left'` | Fixed position of the floating widget |
|
|
138
|
-
| `offset` | `{ bottom?, top?, left?, right? }` | `undefined` | CSS pixel coords — overrides `placement` |
|
|
139
|
-
| `container` | `string │ HTMLElement` | `undefined` | Mount target. Auto-creates `div` if omitted |
|
|
140
|
-
| `onIncomingCall` | `(data) => void` | — | Fired on incoming SIP INVITE |
|
|
141
|
-
| `onCallAnswered` | `(data) => void` | — | Fired when call is established |
|
|
142
|
-
| `onCallEnded` | `(data) => void` | — | Fired on BYE / hangup |
|
|
143
|
-
| `onCallUnanswered` | `() => void` | — | Fired when incoming call is not answered |
|
|
144
|
-
| `onRegisterStatus` | `(status: string) => void` | — | `'REGISTERED'` or `'FAILED'` |
|
|
314
|
+
---
|
|
145
315
|
|
|
146
|
-
|
|
316
|
+
## Keyboard shortcuts
|
|
147
317
|
|
|
148
|
-
|
|
149
|
-
|---------------|---------------------------------|
|
|
150
|
-
| `username` | SIP username / extension |
|
|
151
|
-
| `pwd_pbx` | SIP password |
|
|
152
|
-
| `pabx_host` | SIP domain / WSS host |
|
|
153
|
-
| `port` | WSS port (default `8089`) |
|
|
318
|
+
These shortcuts are active whenever the dialer widget is open:
|
|
154
319
|
|
|
155
|
-
|
|
320
|
+
| Key | State | Action |
|
|
321
|
+
|------------------|---------|-------------------------------|
|
|
322
|
+
| `0–9`, `*`, `#` | Idle | Append digit to dial input |
|
|
323
|
+
| `Backspace` | Idle | Delete last digit |
|
|
324
|
+
| `Enter` | Idle | Dial the current number |
|
|
325
|
+
| `0–9`, `*`, `#` | In-call | Send DTMF tone |
|
|
156
326
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
| Method | Description |
|
|
160
|
-
|-----------------|------------------------------------|
|
|
161
|
-
| `answer()` | Answer incoming call |
|
|
162
|
-
| `hangup()` | End active call |
|
|
163
|
-
| `reject()` | Reject incoming call |
|
|
164
|
-
| `mute(bool)` | Mute / unmute microphone |
|
|
165
|
-
| `hold(bool)` | Hold / resume call |
|
|
166
|
-
| `dial(number)` | Programmatically dial a number |
|
|
167
|
-
| `destroy()` | Unmount widget and clean up |
|
|
327
|
+
---
|
|
168
328
|
|
|
169
329
|
## Build
|
|
170
330
|
|
|
171
331
|
```bash
|
|
172
|
-
# ESM + UMD (peer React
|
|
332
|
+
# ESM + UMD (peer React — for npm consumers)
|
|
173
333
|
yarn build:lib
|
|
174
334
|
|
|
175
|
-
# Self-contained IIFE (bundles React
|
|
335
|
+
# Self-contained IIFE (bundles React — for CDN / script tag)
|
|
176
336
|
yarn build:iife
|
|
177
337
|
|
|
178
|
-
# Both
|
|
338
|
+
# Both outputs
|
|
179
339
|
yarn build
|
|
180
340
|
```
|
|
181
341
|
|
|
342
|
+
Output files in `dist/`:
|
|
343
|
+
|
|
344
|
+
| File | Format | React | Use case |
|
|
345
|
+
|--------------------|--------|----------|-----------------------|
|
|
346
|
+
| `voxnix.js` | ESM | peer dep | `import` / bundlers |
|
|
347
|
+
| `voxnix.umd.cjs` | UMD | peer dep | CommonJS / `require` |
|
|
348
|
+
| `voxnix.iife.js` | IIFE | bundled | `<script>` / CDN |
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
182
352
|
## Development
|
|
183
353
|
|
|
184
354
|
```bash
|
|
185
355
|
yarn install
|
|
186
|
-
yarn dev
|
|
356
|
+
yarn dev # Vite dev server with hot reload
|
|
357
|
+
yarn watch # Vite library watch mode
|
|
187
358
|
```
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## Changelog
|
|
363
|
+
|
|
364
|
+
### v1.0.12
|
|
365
|
+
- Rollback DevToast / console interceptor feature
|
|
366
|
+
|
|
367
|
+
### v1.0.11 and earlier
|
|
368
|
+
- Agent status bar (Ready / Not Ready / AUX) with configurable `auxOptions`
|
|
369
|
+
- `onAgentStatus` callback
|
|
370
|
+
- `autoReady` and `showAuxButton` config options
|
|
371
|
+
- Keyboard shortcut support for dialer and DTMF
|
|
372
|
+
- React 17 / 18 compatibility layer
|
|
373
|
+
- Dual-SIP auth shape support (`auth` and `pabxConfig.auth`)
|