whio-api-sdk 1.0.199-beta-staging → 1.0.201-beta-staging
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/dist/src/sdk/modules/websocket.module.d.ts +3 -3
- package/dist/src/sdk/modules/websocket.module.js +37 -28
- package/dist/src/sdk/sdk.d.ts +1 -1
- package/dist/src/sdk/types/websocket.types.d.ts +2 -4
- package/package.json +1 -1
- package/src/sdk/modules/websocket.module.ts +33 -28
- package/src/sdk/types/websocket.types.ts +2 -4
- package/test-websocket.mjs +2 -2
|
@@ -17,7 +17,7 @@ export declare class WebSocketModule extends BaseClient {
|
|
|
17
17
|
/**
|
|
18
18
|
* Connect to WebSocket server
|
|
19
19
|
*/
|
|
20
|
-
connect(): void
|
|
20
|
+
connect(): Promise<void>;
|
|
21
21
|
/**
|
|
22
22
|
* Disconnect from WebSocket server
|
|
23
23
|
*/
|
|
@@ -33,9 +33,9 @@ export declare class WebSocketModule extends BaseClient {
|
|
|
33
33
|
/**
|
|
34
34
|
* Stream audio chunk to server
|
|
35
35
|
*/
|
|
36
|
-
streamAudioChunk(sessionId: string, audioChunk: string
|
|
36
|
+
streamAudioChunk(sessionId: string, audioChunk: string): void;
|
|
37
37
|
/**
|
|
38
|
-
* Stream multiple audio chunks
|
|
38
|
+
* Stream multiple audio chunks
|
|
39
39
|
*/
|
|
40
40
|
streamAudioChunks(sessionId: string, audioChunks: string[], options?: AudioStreamingOptions): Promise<void>;
|
|
41
41
|
/**
|
|
@@ -29,7 +29,9 @@ export class WebSocketModule extends BaseClient {
|
|
|
29
29
|
reconnectAttempts: 0
|
|
30
30
|
};
|
|
31
31
|
if (this.config.autoConnect) {
|
|
32
|
-
this.connect()
|
|
32
|
+
this.connect().catch(error => {
|
|
33
|
+
console.error('Failed to auto-connect WebSocket:', error);
|
|
34
|
+
});
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
/**
|
|
@@ -37,23 +39,32 @@ export class WebSocketModule extends BaseClient {
|
|
|
37
39
|
*/
|
|
38
40
|
connect() {
|
|
39
41
|
var _a;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
42
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
if ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const wsUrl = this.getWebSocketUrl();
|
|
47
|
+
try {
|
|
48
|
+
// Ensure we have a fresh token before connecting
|
|
49
|
+
yield this.getToken();
|
|
50
|
+
const token = this.getAccessToken();
|
|
51
|
+
if (!token) {
|
|
52
|
+
this.emit('connection-error', new Error('No access token available for WebSocket connection'));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
this.socket = io(wsUrl, {
|
|
56
|
+
auth: {
|
|
57
|
+
token: token
|
|
58
|
+
},
|
|
59
|
+
forceNew: true,
|
|
60
|
+
timeout: 10000
|
|
61
|
+
});
|
|
62
|
+
this.setupEventHandlers();
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
this.emit('connection-error', error);
|
|
66
|
+
}
|
|
55
67
|
});
|
|
56
|
-
this.setupEventHandlers();
|
|
57
68
|
}
|
|
58
69
|
/**
|
|
59
70
|
* Disconnect from WebSocket server
|
|
@@ -86,20 +97,19 @@ export class WebSocketModule extends BaseClient {
|
|
|
86
97
|
/**
|
|
87
98
|
* Stream audio chunk to server
|
|
88
99
|
*/
|
|
89
|
-
streamAudioChunk(sessionId, audioChunk
|
|
100
|
+
streamAudioChunk(sessionId, audioChunk) {
|
|
90
101
|
var _a;
|
|
91
102
|
if (!((_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected)) {
|
|
92
103
|
throw new Error('WebSocket not connected. Cannot stream audio chunk.');
|
|
93
104
|
}
|
|
94
105
|
const payload = {
|
|
95
106
|
sessionId,
|
|
96
|
-
audioChunk
|
|
97
|
-
flag: isEnd ? 'end' : null
|
|
107
|
+
audioChunk
|
|
98
108
|
};
|
|
99
109
|
this.socket.emit('audio-chunk', payload);
|
|
100
110
|
}
|
|
101
111
|
/**
|
|
102
|
-
* Stream multiple audio chunks
|
|
112
|
+
* Stream multiple audio chunks
|
|
103
113
|
*/
|
|
104
114
|
streamAudioChunks(sessionId, audioChunks, options = {}) {
|
|
105
115
|
var _a;
|
|
@@ -107,12 +117,11 @@ export class WebSocketModule extends BaseClient {
|
|
|
107
117
|
if (!((_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected)) {
|
|
108
118
|
throw new Error('WebSocket not connected. Cannot stream audio chunks.');
|
|
109
119
|
}
|
|
110
|
-
const delay = options.
|
|
120
|
+
const delay = options.delayBetweenChunks || 100; // ms between chunks
|
|
111
121
|
for (let i = 0; i < audioChunks.length; i++) {
|
|
112
|
-
|
|
113
|
-
this.streamAudioChunk(sessionId, audioChunks[i], isLastChunk);
|
|
122
|
+
this.streamAudioChunk(sessionId, audioChunks[i]);
|
|
114
123
|
// Small delay between chunks to prevent overwhelming the server
|
|
115
|
-
if (
|
|
124
|
+
if (i < audioChunks.length - 1) {
|
|
116
125
|
yield new Promise(resolve => setTimeout(resolve, delay));
|
|
117
126
|
}
|
|
118
127
|
}
|
|
@@ -230,9 +239,9 @@ export class WebSocketModule extends BaseClient {
|
|
|
230
239
|
// Calculate exponential backoff delay
|
|
231
240
|
const delay = Math.min(this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1), this.maxReconnectDelay);
|
|
232
241
|
this.emit('reconnecting', this.reconnectAttempts);
|
|
233
|
-
this.reconnectTimeout = setTimeout(() => {
|
|
234
|
-
this.connect();
|
|
235
|
-
}, delay);
|
|
242
|
+
this.reconnectTimeout = setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
243
|
+
yield this.connect();
|
|
244
|
+
}), delay);
|
|
236
245
|
}
|
|
237
246
|
/**
|
|
238
247
|
* Get WebSocket URL
|
package/dist/src/sdk/sdk.d.ts
CHANGED
|
@@ -183,7 +183,7 @@ export declare class ApiSDK extends BaseClient {
|
|
|
183
183
|
getExternalIntegration(...args: Parameters<ExternalIntegrationModule['getExternalIntegration']>): Promise<import("./types").ExternalIntegration>;
|
|
184
184
|
updateExternalIntegration(...args: Parameters<ExternalIntegrationModule['updateExternalIntegration']>): Promise<import("./types").ExternalIntegration>;
|
|
185
185
|
deleteExternalIntegration(...args: Parameters<ExternalIntegrationModule['deleteExternalIntegration']>): Promise<void>;
|
|
186
|
-
connectWebSocket(): void
|
|
186
|
+
connectWebSocket(): Promise<void>;
|
|
187
187
|
disconnectWebSocket(): void;
|
|
188
188
|
isWebSocketConnected(): boolean;
|
|
189
189
|
streamAudioChunk(...args: Parameters<WebSocketModule['streamAudioChunk']>): void;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export interface AudioChunkPayload {
|
|
2
2
|
sessionId: string;
|
|
3
3
|
audioChunk: string;
|
|
4
|
-
flag: 'end' | null;
|
|
5
4
|
}
|
|
6
5
|
export interface WebSocketConfig {
|
|
7
6
|
autoConnect?: boolean;
|
|
@@ -17,8 +16,7 @@ export interface WebSocketConnectionStats {
|
|
|
17
16
|
lastDisconnectedAt?: Date;
|
|
18
17
|
}
|
|
19
18
|
export interface AudioStreamingOptions {
|
|
20
|
-
|
|
21
|
-
autoTranscribe?: boolean;
|
|
19
|
+
delayBetweenChunks?: number;
|
|
22
20
|
}
|
|
23
21
|
export interface WebSocketEvents {
|
|
24
22
|
connected: (data: {
|
|
@@ -29,7 +27,7 @@ export interface WebSocketEvents {
|
|
|
29
27
|
disconnected: (reason: string) => void;
|
|
30
28
|
'audio-chunk-received': (data: {
|
|
31
29
|
sessionId: string;
|
|
32
|
-
chunkCount
|
|
30
|
+
chunkCount?: number;
|
|
33
31
|
timestamp: string;
|
|
34
32
|
}) => void;
|
|
35
33
|
'transcription-queued': (data: {
|
package/package.json
CHANGED
|
@@ -45,35 +45,44 @@ export class WebSocketModule extends BaseClient {
|
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
if (this.config.autoConnect) {
|
|
48
|
-
this.connect()
|
|
48
|
+
this.connect().catch(error => {
|
|
49
|
+
console.error('Failed to auto-connect WebSocket:', error);
|
|
50
|
+
});
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
/**
|
|
53
55
|
* Connect to WebSocket server
|
|
54
56
|
*/
|
|
55
|
-
public connect(): void {
|
|
57
|
+
public async connect(): Promise<void> {
|
|
56
58
|
if (this.socket?.connected) {
|
|
57
59
|
return;
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
const wsUrl = this.getWebSocketUrl();
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
this.
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
// Ensure we have a fresh token before connecting
|
|
66
|
+
await this.getToken();
|
|
67
|
+
const token = this.getAccessToken();
|
|
68
|
+
|
|
69
|
+
if (!token) {
|
|
70
|
+
this.emit('connection-error', new Error('No access token available for WebSocket connection'));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
67
73
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
this.socket = io(wsUrl, {
|
|
75
|
+
auth: {
|
|
76
|
+
token: token
|
|
77
|
+
},
|
|
78
|
+
forceNew: true,
|
|
79
|
+
timeout: 10000
|
|
80
|
+
});
|
|
75
81
|
|
|
76
|
-
|
|
82
|
+
this.setupEventHandlers();
|
|
83
|
+
} catch (error) {
|
|
84
|
+
this.emit('connection-error', error as Error);
|
|
85
|
+
}
|
|
77
86
|
}
|
|
78
87
|
|
|
79
88
|
/**
|
|
@@ -113,8 +122,7 @@ export class WebSocketModule extends BaseClient {
|
|
|
113
122
|
*/
|
|
114
123
|
public streamAudioChunk(
|
|
115
124
|
sessionId: string,
|
|
116
|
-
audioChunk: string
|
|
117
|
-
isEnd: boolean = false
|
|
125
|
+
audioChunk: string
|
|
118
126
|
): void {
|
|
119
127
|
if (!this.socket?.connected) {
|
|
120
128
|
throw new Error('WebSocket not connected. Cannot stream audio chunk.');
|
|
@@ -122,15 +130,14 @@ export class WebSocketModule extends BaseClient {
|
|
|
122
130
|
|
|
123
131
|
const payload: AudioChunkPayload = {
|
|
124
132
|
sessionId,
|
|
125
|
-
audioChunk
|
|
126
|
-
flag: isEnd ? 'end' : null
|
|
133
|
+
audioChunk
|
|
127
134
|
};
|
|
128
135
|
|
|
129
136
|
this.socket.emit('audio-chunk', payload);
|
|
130
137
|
}
|
|
131
138
|
|
|
132
139
|
/**
|
|
133
|
-
* Stream multiple audio chunks
|
|
140
|
+
* Stream multiple audio chunks
|
|
134
141
|
*/
|
|
135
142
|
public async streamAudioChunks(
|
|
136
143
|
sessionId: string,
|
|
@@ -141,15 +148,13 @@ export class WebSocketModule extends BaseClient {
|
|
|
141
148
|
throw new Error('WebSocket not connected. Cannot stream audio chunks.');
|
|
142
149
|
}
|
|
143
150
|
|
|
144
|
-
const delay = options.
|
|
151
|
+
const delay = options.delayBetweenChunks || 100; // ms between chunks
|
|
145
152
|
|
|
146
153
|
for (let i = 0; i < audioChunks.length; i++) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
this.streamAudioChunk(sessionId, audioChunks[i], isLastChunk);
|
|
154
|
+
this.streamAudioChunk(sessionId, audioChunks[i]);
|
|
150
155
|
|
|
151
156
|
// Small delay between chunks to prevent overwhelming the server
|
|
152
|
-
if (
|
|
157
|
+
if (i < audioChunks.length - 1) {
|
|
153
158
|
await new Promise(resolve => setTimeout(resolve, delay));
|
|
154
159
|
}
|
|
155
160
|
}
|
|
@@ -300,8 +305,8 @@ export class WebSocketModule extends BaseClient {
|
|
|
300
305
|
|
|
301
306
|
this.emit('reconnecting', this.reconnectAttempts);
|
|
302
307
|
|
|
303
|
-
this.reconnectTimeout = setTimeout(() => {
|
|
304
|
-
this.connect();
|
|
308
|
+
this.reconnectTimeout = setTimeout(async () => {
|
|
309
|
+
await this.connect();
|
|
305
310
|
}, delay);
|
|
306
311
|
}
|
|
307
312
|
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
export interface AudioChunkPayload {
|
|
4
4
|
sessionId: string;
|
|
5
5
|
audioChunk: string; // Base64 encoded audio data
|
|
6
|
-
flag: 'end' | null;
|
|
7
6
|
}
|
|
8
7
|
|
|
9
8
|
export interface WebSocketConfig {
|
|
@@ -22,8 +21,7 @@ export interface WebSocketConnectionStats {
|
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
export interface AudioStreamingOptions {
|
|
25
|
-
|
|
26
|
-
autoTranscribe?: boolean;
|
|
24
|
+
delayBetweenChunks?: number; // Delay in ms between sending chunks
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
// WebSocket events
|
|
@@ -32,7 +30,7 @@ export interface WebSocketEvents {
|
|
|
32
30
|
disconnected: (reason: string) => void;
|
|
33
31
|
'audio-chunk-received': (data: {
|
|
34
32
|
sessionId: string;
|
|
35
|
-
chunkCount
|
|
33
|
+
chunkCount?: number;
|
|
36
34
|
timestamp: string;
|
|
37
35
|
}) => void;
|
|
38
36
|
'transcription-queued': (data: {
|
package/test-websocket.mjs
CHANGED
|
@@ -57,7 +57,7 @@ async function testWebSocketIntegration() {
|
|
|
57
57
|
|
|
58
58
|
// Test error handling for streaming without connection
|
|
59
59
|
try {
|
|
60
|
-
sdk.streamAudioChunk('test-session',
|
|
60
|
+
sdk.streamAudioChunk('test-session', 'dGVzdC1hdWRpby1kYXRh'); // base64 test data
|
|
61
61
|
console.log('✗ Should have thrown error for streaming without connection');
|
|
62
62
|
} catch (error) {
|
|
63
63
|
console.log('✓ Correctly throws error when streaming without connection:', error.message);
|
|
@@ -86,7 +86,7 @@ sdk.onWebSocketEvent('audio-chunk-received', (data) => {
|
|
|
86
86
|
});
|
|
87
87
|
|
|
88
88
|
// Stream audio data
|
|
89
|
-
sdk.streamAudioChunk('session-id',
|
|
89
|
+
sdk.streamAudioChunk('session-id', audioBase64String);
|
|
90
90
|
|
|
91
91
|
// Or stream multiple chunks
|
|
92
92
|
await sdk.streamAudioChunks('session-id', [chunk1, chunk2, chunk3]);
|