whio-api-sdk 1.0.202-beta-staging → 1.0.204-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.
@@ -26,6 +26,7 @@ export declare class TemplateModule extends BaseClient {
26
26
  getTranscriptionSummary(id: string): Promise<TranscriptionSummary>;
27
27
  getTranscriptionSummariesByUser(userId: string): Promise<TranscriptionSummary[]>;
28
28
  getByOrganizationTranscriptionSummaries(organizationId: string): Promise<TranscriptionSummary[]>;
29
+ cloneTranscriptionSummary(id: string, content: string): Promise<TranscriptionSummary>;
29
30
  deleteTranscriptionSummary(id: string): Promise<void>;
30
31
  uploadLargeAudioFile(formData: FormData): Promise<string>;
31
32
  uploadAudioFile(formData: FormData): Promise<TranscriptionAudioUploadResponse | null>;
@@ -208,6 +208,14 @@ export class TemplateModule extends BaseClient {
208
208
  return this.request(`${urls.transcriptionSummaries}/organization/${organizationId}`, 'GET');
209
209
  });
210
210
  }
211
+ cloneTranscriptionSummary(id, content) {
212
+ return __awaiter(this, void 0, void 0, function* () {
213
+ const cloneDto = {
214
+ content,
215
+ };
216
+ return this.request(`${urls.transcriptionSummaries}/${id}/clone`, 'POST', cloneDto);
217
+ });
218
+ }
211
219
  deleteTranscriptionSummary(id) {
212
220
  return __awaiter(this, void 0, void 0, function* () {
213
221
  yield this.request(`${urls.transcriptionSummaries}/${id}`, 'DELETE');
@@ -30,10 +30,15 @@ export declare class WebSocketModule extends BaseClient {
30
30
  * Get connection statistics
31
31
  */
32
32
  getConnectionStats(): WebSocketConnectionStats;
33
+ /**
34
+ * Ensure WebSocket connection has a valid token
35
+ * Reconnects with fresh token if current token is expired
36
+ */
37
+ private ensureValidConnection;
33
38
  /**
34
39
  * Stream audio chunk to server
35
40
  */
36
- streamAudioChunk(sessionId: string, audioChunk: string): void;
41
+ streamAudioChunk(sessionId: string, audioChunk: string): Promise<void>;
37
42
  /**
38
43
  * Stream multiple audio chunks
39
44
  */
@@ -94,19 +94,48 @@ export class WebSocketModule extends BaseClient {
94
94
  getConnectionStats() {
95
95
  return Object.assign({}, this.connectionStats);
96
96
  }
97
+ /**
98
+ * Ensure WebSocket connection has a valid token
99
+ * Reconnects with fresh token if current token is expired
100
+ */
101
+ ensureValidConnection() {
102
+ return __awaiter(this, void 0, void 0, function* () {
103
+ const currentToken = this.getAccessToken();
104
+ // Check if we have a token and if it's expired
105
+ if (!currentToken || this.isTokenExpired(currentToken)) {
106
+ console.log('[WebSocket] Token expired or missing, refreshing and reconnecting...');
107
+ try {
108
+ // Refresh token
109
+ yield this.getToken();
110
+ // Disconnect current connection and reconnect with fresh token
111
+ this.disconnect();
112
+ yield this.connect();
113
+ console.log('[WebSocket] Successfully reconnected with fresh token');
114
+ }
115
+ catch (error) {
116
+ console.error('[WebSocket] Failed to refresh token and reconnect:', error);
117
+ throw new Error('Authentication failed: Unable to refresh token for WebSocket streaming');
118
+ }
119
+ }
120
+ });
121
+ }
97
122
  /**
98
123
  * Stream audio chunk to server
99
124
  */
100
125
  streamAudioChunk(sessionId, audioChunk) {
101
126
  var _a;
102
- if (!((_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected)) {
103
- throw new Error('WebSocket not connected. Cannot stream audio chunk.');
104
- }
105
- const payload = {
106
- sessionId,
107
- audioChunk
108
- };
109
- this.socket.emit('audio-chunk', payload);
127
+ return __awaiter(this, void 0, void 0, function* () {
128
+ // CRITICAL: Validate token and reconnect if needed BEFORE sending
129
+ yield this.ensureValidConnection();
130
+ if (!((_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected)) {
131
+ throw new Error('WebSocket not connected after token validation');
132
+ }
133
+ const payload = {
134
+ sessionId,
135
+ audioChunk
136
+ };
137
+ this.socket.emit('audio-chunk', payload);
138
+ });
110
139
  }
111
140
  /**
112
141
  * Stream multiple audio chunks
@@ -114,12 +143,15 @@ export class WebSocketModule extends BaseClient {
114
143
  streamAudioChunks(sessionId, audioChunks, options = {}) {
115
144
  var _a;
116
145
  return __awaiter(this, void 0, void 0, function* () {
146
+ // Validate token once before streaming multiple chunks
147
+ yield this.ensureValidConnection();
117
148
  if (!((_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected)) {
118
- throw new Error('WebSocket not connected. Cannot stream audio chunks.');
149
+ throw new Error('WebSocket not connected after token validation.');
119
150
  }
120
151
  const delay = options.delayBetweenChunks || 100; // ms between chunks
121
152
  for (let i = 0; i < audioChunks.length; i++) {
122
- this.streamAudioChunk(sessionId, audioChunks[i]);
153
+ // Note: streamAudioChunk will also validate token, but we've already done it once
154
+ yield this.streamAudioChunk(sessionId, audioChunks[i]);
123
155
  // Small delay between chunks to prevent overwhelming the server
124
156
  if (i < audioChunks.length - 1) {
125
157
  yield new Promise(resolve => setTimeout(resolve, delay));
@@ -197,29 +229,41 @@ export class WebSocketModule extends BaseClient {
197
229
  });
198
230
  // Application-specific events
199
231
  this.socket.on('connected', (data) => {
232
+ console.log('[WebSocket] Connected event received:', JSON.stringify(data, null, 2));
200
233
  this.emit('connected', data);
201
234
  });
202
235
  this.socket.on('audio-chunk-received', (data) => {
236
+ console.log('[WebSocket] Audio chunk received event:', JSON.stringify(data, null, 2));
203
237
  this.emit('audio-chunk-received', data);
204
238
  });
205
239
  this.socket.on('transcription-complete', (data) => {
240
+ console.log('[WebSocket] Transcription complete event received:', JSON.stringify(data, null, 2));
206
241
  this.emit('transcription-complete', data);
207
242
  });
208
243
  this.socket.on('transcription-queued', (data) => {
244
+ console.log('[WebSocket] Transcription queued event received:', JSON.stringify(data, null, 2));
209
245
  this.emit('transcription-queued', data);
210
246
  });
211
247
  this.socket.on('summary-complete', (data) => {
248
+ console.log('[WebSocket] Summary complete event received:', JSON.stringify(data, null, 2));
212
249
  this.emit('summary-complete', data);
213
250
  });
214
251
  this.socket.on('summary-queued', (data) => {
252
+ console.log('[WebSocket] Summary queued event received:', JSON.stringify(data, null, 2));
215
253
  this.emit('summary-queued', data);
216
254
  });
217
255
  this.socket.on('audio-error', (error) => {
256
+ console.log('[WebSocket] Audio error event received:', JSON.stringify(error, null, 2));
218
257
  this.emit('audio-error', error);
219
258
  });
220
259
  this.socket.on('transcription-error', (error) => {
260
+ console.log('[WebSocket] Transcription error event received:', JSON.stringify(error, null, 2));
221
261
  this.emit('transcription-error', error);
222
262
  });
263
+ // Catch-all event listener for debugging
264
+ this.socket.onAny((eventName, ...args) => {
265
+ console.log(`[WebSocket] Raw event received: "${eventName}"`, JSON.stringify(args, null, 2));
266
+ });
223
267
  }
224
268
  /**
225
269
  * Determine if should attempt reconnection
@@ -186,7 +186,7 @@ export declare class ApiSDK extends BaseClient {
186
186
  connectWebSocket(): Promise<void>;
187
187
  disconnectWebSocket(): void;
188
188
  isWebSocketConnected(): boolean;
189
- streamAudioChunk(...args: Parameters<WebSocketModule['streamAudioChunk']>): void;
189
+ streamAudioChunk(...args: Parameters<WebSocketModule['streamAudioChunk']>): Promise<void>;
190
190
  streamAudioChunks(...args: Parameters<WebSocketModule['streamAudioChunks']>): Promise<void>;
191
191
  onWebSocketEvent(...args: Parameters<WebSocketModule['on']>): void;
192
192
  offWebSocketEvent(...args: Parameters<WebSocketModule['off']>): void;
@@ -116,3 +116,6 @@ export interface UpdateTranscriptionSummaryDto {
116
116
  metadata?: Record<string, any>;
117
117
  templateId?: string;
118
118
  }
119
+ export interface CloneTranscriptionSummaryDto {
120
+ content: string;
121
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whio-api-sdk",
3
- "version": "1.0.202-beta-staging",
3
+ "version": "1.0.204-beta-staging",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -13,6 +13,7 @@ import {
13
13
  AssignTeamTemplateDto,
14
14
  GenerateTranscriptionSummaryDto,
15
15
  UpdateTranscriptionSummaryDto,
16
+ CloneTranscriptionSummaryDto,
16
17
  TranscriptionAudioUploadResponse,
17
18
  } from '../types';
18
19
  import urls from '../urls';
@@ -207,6 +208,13 @@ export class TemplateModule extends BaseClient {
207
208
  return this.request<TranscriptionSummary[]>(`${urls.transcriptionSummaries}/organization/${organizationId}`, 'GET');
208
209
  }
209
210
 
211
+ public async cloneTranscriptionSummary(id: string, content: string): Promise<TranscriptionSummary> {
212
+ const cloneDto: CloneTranscriptionSummaryDto = {
213
+ content,
214
+ };
215
+ return this.request<TranscriptionSummary>(`${urls.transcriptionSummaries}/${id}/clone`, 'POST', cloneDto);
216
+ }
217
+
210
218
  public async deleteTranscriptionSummary(id: string): Promise<void> {
211
219
  await this.request(`${urls.transcriptionSummaries}/${id}`, 'DELETE');
212
220
  }
@@ -117,15 +117,45 @@ export class WebSocketModule extends BaseClient {
117
117
  return { ...this.connectionStats };
118
118
  }
119
119
 
120
+ /**
121
+ * Ensure WebSocket connection has a valid token
122
+ * Reconnects with fresh token if current token is expired
123
+ */
124
+ private async ensureValidConnection(): Promise<void> {
125
+ const currentToken = this.getAccessToken();
126
+
127
+ // Check if we have a token and if it's expired
128
+ if (!currentToken || this.isTokenExpired(currentToken)) {
129
+ console.log('[WebSocket] Token expired or missing, refreshing and reconnecting...');
130
+
131
+ try {
132
+ // Refresh token
133
+ await this.getToken();
134
+
135
+ // Disconnect current connection and reconnect with fresh token
136
+ this.disconnect();
137
+ await this.connect();
138
+
139
+ console.log('[WebSocket] Successfully reconnected with fresh token');
140
+ } catch (error) {
141
+ console.error('[WebSocket] Failed to refresh token and reconnect:', error);
142
+ throw new Error('Authentication failed: Unable to refresh token for WebSocket streaming');
143
+ }
144
+ }
145
+ }
146
+
120
147
  /**
121
148
  * Stream audio chunk to server
122
149
  */
123
- public streamAudioChunk(
150
+ public async streamAudioChunk(
124
151
  sessionId: string,
125
152
  audioChunk: string
126
- ): void {
153
+ ): Promise<void> {
154
+ // CRITICAL: Validate token and reconnect if needed BEFORE sending
155
+ await this.ensureValidConnection();
156
+
127
157
  if (!this.socket?.connected) {
128
- throw new Error('WebSocket not connected. Cannot stream audio chunk.');
158
+ throw new Error('WebSocket not connected after token validation');
129
159
  }
130
160
 
131
161
  const payload: AudioChunkPayload = {
@@ -144,14 +174,18 @@ export class WebSocketModule extends BaseClient {
144
174
  audioChunks: string[],
145
175
  options: AudioStreamingOptions = {}
146
176
  ): Promise<void> {
177
+ // Validate token once before streaming multiple chunks
178
+ await this.ensureValidConnection();
179
+
147
180
  if (!this.socket?.connected) {
148
- throw new Error('WebSocket not connected. Cannot stream audio chunks.');
181
+ throw new Error('WebSocket not connected after token validation.');
149
182
  }
150
183
 
151
184
  const delay = options.delayBetweenChunks || 100; // ms between chunks
152
185
 
153
186
  for (let i = 0; i < audioChunks.length; i++) {
154
- this.streamAudioChunk(sessionId, audioChunks[i]);
187
+ // Note: streamAudioChunk will also validate token, but we've already done it once
188
+ await this.streamAudioChunk(sessionId, audioChunks[i]);
155
189
 
156
190
  // Small delay between chunks to prevent overwhelming the server
157
191
  if (i < audioChunks.length - 1) {
@@ -248,36 +282,49 @@ export class WebSocketModule extends BaseClient {
248
282
 
249
283
  // Application-specific events
250
284
  this.socket.on('connected', (data: any) => {
285
+ console.log('[WebSocket] Connected event received:', JSON.stringify(data, null, 2));
251
286
  this.emit('connected', data);
252
287
  });
253
288
 
254
289
  this.socket.on('audio-chunk-received', (data: any) => {
290
+ console.log('[WebSocket] Audio chunk received event:', JSON.stringify(data, null, 2));
255
291
  this.emit('audio-chunk-received', data);
256
292
  });
257
293
 
258
294
  this.socket.on('transcription-complete', (data: any) => {
295
+ console.log('[WebSocket] Transcription complete event received:', JSON.stringify(data, null, 2));
259
296
  this.emit('transcription-complete', data);
260
297
  });
261
298
 
262
299
  this.socket.on('transcription-queued', (data: any) => {
300
+ console.log('[WebSocket] Transcription queued event received:', JSON.stringify(data, null, 2));
263
301
  this.emit('transcription-queued', data);
264
302
  });
265
303
 
266
304
  this.socket.on('summary-complete', (data: any) => {
305
+ console.log('[WebSocket] Summary complete event received:', JSON.stringify(data, null, 2));
267
306
  this.emit('summary-complete', data);
268
307
  });
269
308
 
270
309
  this.socket.on('summary-queued', (data: any) => {
310
+ console.log('[WebSocket] Summary queued event received:', JSON.stringify(data, null, 2));
271
311
  this.emit('summary-queued', data);
272
312
  });
273
313
 
274
314
  this.socket.on('audio-error', (error: any) => {
315
+ console.log('[WebSocket] Audio error event received:', JSON.stringify(error, null, 2));
275
316
  this.emit('audio-error', error);
276
317
  });
277
318
 
278
319
  this.socket.on('transcription-error', (error: any) => {
320
+ console.log('[WebSocket] Transcription error event received:', JSON.stringify(error, null, 2));
279
321
  this.emit('transcription-error', error);
280
322
  });
323
+
324
+ // Catch-all event listener for debugging
325
+ this.socket.onAny((eventName: string, ...args: any[]) => {
326
+ console.log(`[WebSocket] Raw event received: "${eventName}"`, JSON.stringify(args, null, 2));
327
+ });
281
328
  }
282
329
 
283
330
  /**
@@ -140,3 +140,7 @@ export interface UpdateTranscriptionSummaryDto {
140
140
  metadata?: Record<string, any>;
141
141
  templateId?: string;
142
142
  }
143
+
144
+ export interface CloneTranscriptionSummaryDto {
145
+ content: string;
146
+ }