dominus-sdk-nodejs 1.2.18 → 1.2.19

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.
Files changed (29) hide show
  1. package/dist/index.d.ts +10 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +10 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/namespaces/oracle/OracleSession.d.ts +91 -0
  6. package/dist/namespaces/oracle/OracleSession.d.ts.map +1 -0
  7. package/dist/namespaces/oracle/OracleSession.js +187 -0
  8. package/dist/namespaces/oracle/OracleSession.js.map +1 -0
  9. package/dist/namespaces/oracle/index.d.ts +78 -0
  10. package/dist/namespaces/oracle/index.d.ts.map +1 -0
  11. package/dist/namespaces/oracle/index.js +87 -0
  12. package/dist/namespaces/oracle/index.js.map +1 -0
  13. package/dist/namespaces/oracle/internal/AudioCapture.d.ts +42 -0
  14. package/dist/namespaces/oracle/internal/AudioCapture.d.ts.map +1 -0
  15. package/dist/namespaces/oracle/internal/AudioCapture.js +316 -0
  16. package/dist/namespaces/oracle/internal/AudioCapture.js.map +1 -0
  17. package/dist/namespaces/oracle/internal/OracleWebSocket.d.ts +81 -0
  18. package/dist/namespaces/oracle/internal/OracleWebSocket.d.ts.map +1 -0
  19. package/dist/namespaces/oracle/internal/OracleWebSocket.js +204 -0
  20. package/dist/namespaces/oracle/internal/OracleWebSocket.js.map +1 -0
  21. package/dist/namespaces/oracle/internal/VADGate.d.ts +75 -0
  22. package/dist/namespaces/oracle/internal/VADGate.d.ts.map +1 -0
  23. package/dist/namespaces/oracle/internal/VADGate.js +248 -0
  24. package/dist/namespaces/oracle/internal/VADGate.js.map +1 -0
  25. package/dist/namespaces/oracle/types.d.ts +98 -0
  26. package/dist/namespaces/oracle/types.d.ts.map +1 -0
  27. package/dist/namespaces/oracle/types.js +28 -0
  28. package/dist/namespaces/oracle/types.js.map +1 -0
  29. package/package.json +2 -1
@@ -0,0 +1,316 @@
1
+ /**
2
+ * AudioCapture - Microphone capture and resampling (INTERNAL)
3
+ *
4
+ * Handles:
5
+ * - getUserMedia microphone access
6
+ * - AudioWorklet for low-latency processing
7
+ * - Resampling to 16kHz mono if needed
8
+ * - Output 20ms frames (640 bytes PCM16)
9
+ *
10
+ * This module is INTERNAL and should NOT be exported publicly.
11
+ */
12
+ import { AUDIO_CONFIG } from '../types.js';
13
+ /**
14
+ * AudioWorklet processor code as a string.
15
+ * This gets converted to a Blob URL for the AudioWorklet.
16
+ */
17
+ const AUDIO_PROCESSOR_CODE = `
18
+ class OracleAudioProcessor extends AudioWorkletProcessor {
19
+ constructor() {
20
+ super();
21
+ this.buffer = new Float32Array(0);
22
+ this.targetSampleRate = 16000;
23
+ this.frameSamples = 320; // 20ms at 16kHz
24
+ }
25
+
26
+ process(inputs, outputs, parameters) {
27
+ const input = inputs[0];
28
+ if (!input || !input[0]) return true;
29
+
30
+ const inputData = input[0];
31
+
32
+ // Resample if needed (AudioContext sample rate may differ from 16kHz)
33
+ const resampledData = this.resample(inputData, sampleRate, this.targetSampleRate);
34
+
35
+ // Append to buffer
36
+ const newBuffer = new Float32Array(this.buffer.length + resampledData.length);
37
+ newBuffer.set(this.buffer);
38
+ newBuffer.set(resampledData, this.buffer.length);
39
+ this.buffer = newBuffer;
40
+
41
+ // Extract complete frames and send to main thread
42
+ while (this.buffer.length >= this.frameSamples) {
43
+ const frame = this.buffer.slice(0, this.frameSamples);
44
+ this.buffer = this.buffer.slice(this.frameSamples);
45
+
46
+ // Convert Float32 [-1, 1] to Int16 PCM
47
+ const pcm16 = new Int16Array(this.frameSamples);
48
+ for (let i = 0; i < this.frameSamples; i++) {
49
+ const s = Math.max(-1, Math.min(1, frame[i]));
50
+ pcm16[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
51
+ }
52
+
53
+ this.port.postMessage(pcm16.buffer, [pcm16.buffer]);
54
+ }
55
+
56
+ return true;
57
+ }
58
+
59
+ resample(inputData, fromRate, toRate) {
60
+ if (fromRate === toRate) {
61
+ return inputData;
62
+ }
63
+
64
+ const ratio = fromRate / toRate;
65
+ const outputLength = Math.ceil(inputData.length / ratio);
66
+ const output = new Float32Array(outputLength);
67
+
68
+ for (let i = 0; i < outputLength; i++) {
69
+ const srcIndex = i * ratio;
70
+ const srcIndexFloor = Math.floor(srcIndex);
71
+ const srcIndexCeil = Math.min(srcIndexFloor + 1, inputData.length - 1);
72
+ const t = srcIndex - srcIndexFloor;
73
+
74
+ // Linear interpolation
75
+ output[i] = inputData[srcIndexFloor] * (1 - t) + inputData[srcIndexCeil] * t;
76
+ }
77
+
78
+ return output;
79
+ }
80
+ }
81
+
82
+ registerProcessor('oracle-audio-processor', OracleAudioProcessor);
83
+ `;
84
+ /**
85
+ * ScriptProcessor fallback for browsers without AudioWorklet support.
86
+ * Less efficient but provides compatibility.
87
+ */
88
+ class ScriptProcessorCapture {
89
+ audioContext = null;
90
+ mediaStream = null;
91
+ scriptProcessor = null;
92
+ sourceNode = null;
93
+ buffer = new Float32Array(0);
94
+ onFrame = null;
95
+ async start() {
96
+ // Request microphone access with 16kHz preference
97
+ this.mediaStream = await navigator.mediaDevices.getUserMedia({
98
+ audio: {
99
+ channelCount: AUDIO_CONFIG.CHANNELS,
100
+ sampleRate: AUDIO_CONFIG.SAMPLE_RATE,
101
+ echoCancellation: true,
102
+ noiseSuppression: true,
103
+ autoGainControl: true,
104
+ },
105
+ });
106
+ // Create audio context (may not be exactly 16kHz)
107
+ this.audioContext = new AudioContext({
108
+ sampleRate: AUDIO_CONFIG.SAMPLE_RATE,
109
+ });
110
+ // Create nodes
111
+ this.sourceNode = this.audioContext.createMediaStreamSource(this.mediaStream);
112
+ // ScriptProcessor with 4096 buffer (good balance of latency vs efficiency)
113
+ this.scriptProcessor = this.audioContext.createScriptProcessor(4096, 1, 1);
114
+ this.scriptProcessor.onaudioprocess = (event) => {
115
+ this.processAudio(event.inputBuffer.getChannelData(0));
116
+ };
117
+ // Connect: mic -> scriptProcessor -> destination (required for processing)
118
+ this.sourceNode.connect(this.scriptProcessor);
119
+ this.scriptProcessor.connect(this.audioContext.destination);
120
+ }
121
+ async stop() {
122
+ if (this.scriptProcessor) {
123
+ this.scriptProcessor.disconnect();
124
+ this.scriptProcessor = null;
125
+ }
126
+ if (this.sourceNode) {
127
+ this.sourceNode.disconnect();
128
+ this.sourceNode = null;
129
+ }
130
+ if (this.mediaStream) {
131
+ this.mediaStream.getTracks().forEach((track) => track.stop());
132
+ this.mediaStream = null;
133
+ }
134
+ if (this.audioContext) {
135
+ await this.audioContext.close();
136
+ this.audioContext = null;
137
+ }
138
+ this.buffer = new Float32Array(0);
139
+ }
140
+ processAudio(inputData) {
141
+ // Resample if audio context sample rate differs from target
142
+ const resampledData = this.resample(inputData, this.audioContext.sampleRate, AUDIO_CONFIG.SAMPLE_RATE);
143
+ // Append to buffer
144
+ const newBuffer = new Float32Array(this.buffer.length + resampledData.length);
145
+ newBuffer.set(this.buffer);
146
+ newBuffer.set(resampledData, this.buffer.length);
147
+ this.buffer = newBuffer;
148
+ // Extract complete frames
149
+ while (this.buffer.length >= AUDIO_CONFIG.SAMPLES_PER_FRAME) {
150
+ const frame = this.buffer.slice(0, AUDIO_CONFIG.SAMPLES_PER_FRAME);
151
+ this.buffer = this.buffer.slice(AUDIO_CONFIG.SAMPLES_PER_FRAME);
152
+ // Convert Float32 to Int16 PCM
153
+ const pcm16 = new Int16Array(AUDIO_CONFIG.SAMPLES_PER_FRAME);
154
+ for (let i = 0; i < AUDIO_CONFIG.SAMPLES_PER_FRAME; i++) {
155
+ const s = Math.max(-1, Math.min(1, frame[i]));
156
+ pcm16[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
157
+ }
158
+ this.onFrame?.(pcm16.buffer);
159
+ }
160
+ }
161
+ resample(inputData, fromRate, toRate) {
162
+ if (fromRate === toRate) {
163
+ return inputData;
164
+ }
165
+ const ratio = fromRate / toRate;
166
+ const outputLength = Math.ceil(inputData.length / ratio);
167
+ const output = new Float32Array(outputLength);
168
+ for (let i = 0; i < outputLength; i++) {
169
+ const srcIndex = i * ratio;
170
+ const srcIndexFloor = Math.floor(srcIndex);
171
+ const srcIndexCeil = Math.min(srcIndexFloor + 1, inputData.length - 1);
172
+ const t = srcIndex - srcIndexFloor;
173
+ // Linear interpolation
174
+ output[i] = inputData[srcIndexFloor] * (1 - t) + inputData[srcIndexCeil] * t;
175
+ }
176
+ return output;
177
+ }
178
+ }
179
+ /**
180
+ * AudioWorklet-based capture (preferred for low latency).
181
+ */
182
+ class WorkletCapture {
183
+ audioContext = null;
184
+ mediaStream = null;
185
+ sourceNode = null;
186
+ workletNode = null;
187
+ onFrame = null;
188
+ async start() {
189
+ // Request microphone access
190
+ this.mediaStream = await navigator.mediaDevices.getUserMedia({
191
+ audio: {
192
+ channelCount: AUDIO_CONFIG.CHANNELS,
193
+ sampleRate: AUDIO_CONFIG.SAMPLE_RATE,
194
+ echoCancellation: true,
195
+ noiseSuppression: true,
196
+ autoGainControl: true,
197
+ },
198
+ });
199
+ // Create audio context
200
+ this.audioContext = new AudioContext({
201
+ sampleRate: AUDIO_CONFIG.SAMPLE_RATE,
202
+ });
203
+ // Create worklet from inline code
204
+ const blob = new Blob([AUDIO_PROCESSOR_CODE], { type: 'application/javascript' });
205
+ const workletUrl = URL.createObjectURL(blob);
206
+ try {
207
+ await this.audioContext.audioWorklet.addModule(workletUrl);
208
+ }
209
+ finally {
210
+ URL.revokeObjectURL(workletUrl);
211
+ }
212
+ // Create nodes
213
+ this.sourceNode = this.audioContext.createMediaStreamSource(this.mediaStream);
214
+ this.workletNode = new AudioWorkletNode(this.audioContext, 'oracle-audio-processor');
215
+ // Handle messages from worklet
216
+ this.workletNode.port.onmessage = (event) => {
217
+ this.onFrame?.(event.data);
218
+ };
219
+ // Connect: mic -> worklet
220
+ this.sourceNode.connect(this.workletNode);
221
+ // Note: worklet doesn't need to connect to destination
222
+ }
223
+ async stop() {
224
+ if (this.workletNode) {
225
+ this.workletNode.disconnect();
226
+ this.workletNode = null;
227
+ }
228
+ if (this.sourceNode) {
229
+ this.sourceNode.disconnect();
230
+ this.sourceNode = null;
231
+ }
232
+ if (this.mediaStream) {
233
+ this.mediaStream.getTracks().forEach((track) => track.stop());
234
+ this.mediaStream = null;
235
+ }
236
+ if (this.audioContext) {
237
+ await this.audioContext.close();
238
+ this.audioContext = null;
239
+ }
240
+ }
241
+ }
242
+ /**
243
+ * AudioCapture - Main class for microphone capture.
244
+ *
245
+ * Automatically uses AudioWorklet if available, falls back to ScriptProcessor.
246
+ * Outputs 20ms frames (640 bytes PCM16) at 16kHz mono.
247
+ */
248
+ export class AudioCapture {
249
+ capture = null;
250
+ _isCapturing = false;
251
+ /** Callback for each audio frame */
252
+ onFrame = null;
253
+ /**
254
+ * Check if currently capturing audio.
255
+ */
256
+ get isCapturing() {
257
+ return this._isCapturing;
258
+ }
259
+ /**
260
+ * Start audio capture from microphone.
261
+ *
262
+ * @throws Error if microphone permission denied or capture fails
263
+ */
264
+ async start() {
265
+ if (this._isCapturing) {
266
+ return;
267
+ }
268
+ // Check for browser environment
269
+ if (typeof navigator === 'undefined' || !navigator.mediaDevices?.getUserMedia) {
270
+ throw new Error('Audio capture requires a browser environment with getUserMedia support');
271
+ }
272
+ // Choose capture method based on AudioWorklet support
273
+ const hasWorklet = typeof AudioWorkletNode !== 'undefined' &&
274
+ typeof AudioContext !== 'undefined' &&
275
+ 'audioWorklet' in AudioContext.prototype;
276
+ if (hasWorklet) {
277
+ try {
278
+ this.capture = new WorkletCapture();
279
+ await this.capture.start();
280
+ }
281
+ catch (error) {
282
+ console.warn('[OracleSDK] AudioWorklet failed, falling back to ScriptProcessor:', error);
283
+ this.capture = new ScriptProcessorCapture();
284
+ await this.capture.start();
285
+ }
286
+ }
287
+ else {
288
+ this.capture = new ScriptProcessorCapture();
289
+ await this.capture.start();
290
+ }
291
+ // Wire up frame callback
292
+ this.capture.onFrame = (pcmFrame) => {
293
+ this.onFrame?.(pcmFrame);
294
+ };
295
+ this._isCapturing = true;
296
+ }
297
+ /**
298
+ * Stop audio capture.
299
+ */
300
+ async stop() {
301
+ if (!this._isCapturing || !this.capture) {
302
+ return;
303
+ }
304
+ await this.capture.stop();
305
+ this.capture = null;
306
+ this._isCapturing = false;
307
+ }
308
+ /**
309
+ * Clean up resources.
310
+ */
311
+ dispose() {
312
+ this.stop().catch(() => { });
313
+ this.onFrame = null;
314
+ }
315
+ }
316
+ //# sourceMappingURL=AudioCapture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AudioCapture.js","sourceRoot":"","sources":["../../../../src/namespaces/oracle/internal/AudioCapture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * OracleWebSocket - WebSocket wrapper for Oracle streaming (INTERNAL)
3
+ *
4
+ * Handles:
5
+ * - First-message authentication (browser WS doesn't support headers)
6
+ * - Binary frames for audio (NOT base64)
7
+ * - JSON frames for control messages
8
+ * - Ping/pong keepalive during IDLE
9
+ * - Transcript parsing and callback firing
10
+ *
11
+ * This module is INTERNAL and should NOT be exported publicly.
12
+ */
13
+ /**
14
+ * Configuration for OracleWebSocket.
15
+ */
16
+ interface OracleWebSocketConfig {
17
+ /** Ping interval in ms (default: 10000) */
18
+ pingIntervalMs: number;
19
+ }
20
+ /**
21
+ * OracleWebSocket - Manages WebSocket connection to Oracle service.
22
+ */
23
+ export declare class OracleWebSocket {
24
+ private baseUrl;
25
+ private ws;
26
+ private authenticated;
27
+ private pingInterval;
28
+ private config;
29
+ /** Callback for transcript events */
30
+ onTranscript: ((text: string, isFinal: boolean, speechFinal: boolean) => void) | null;
31
+ /** Callback for errors */
32
+ onError: ((error: Error) => void) | null;
33
+ /** Callback for connection close */
34
+ onClose: (() => void) | null;
35
+ constructor(baseUrl: string, config?: Partial<OracleWebSocketConfig>);
36
+ /**
37
+ * Check if WebSocket is connected and authenticated.
38
+ */
39
+ get isConnected(): boolean;
40
+ /**
41
+ * Connect to Oracle WebSocket endpoint with first-message auth.
42
+ *
43
+ * @param userToken - User JWT for authentication
44
+ * @returns Promise that resolves when authenticated, rejects on error
45
+ */
46
+ connect(userToken: string): Promise<void>;
47
+ /**
48
+ * Send binary PCM audio frame.
49
+ * Only called by VADGate - NOT exposed publicly.
50
+ *
51
+ * @param pcmFrame - Raw PCM audio data
52
+ */
53
+ sendBinary(pcmFrame: ArrayBuffer): void;
54
+ /**
55
+ * Send a ping message for keepalive.
56
+ */
57
+ sendPing(): void;
58
+ /**
59
+ * Close the WebSocket connection gracefully.
60
+ */
61
+ close(): Promise<void>;
62
+ /**
63
+ * Build WebSocket URL from base URL.
64
+ */
65
+ private buildWebSocketUrl;
66
+ /**
67
+ * Handle incoming WebSocket message.
68
+ */
69
+ private handleMessage;
70
+ /**
71
+ * Start ping interval for keepalive.
72
+ * Sends ping every pingIntervalMs during IDLE state.
73
+ */
74
+ private startPingInterval;
75
+ /**
76
+ * Stop ping interval.
77
+ */
78
+ private stopPingInterval;
79
+ }
80
+ export {};
81
+ //# sourceMappingURL=OracleWebSocket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OracleWebSocket.d.ts","sourceRoot":"","sources":["../../../../src/namespaces/oracle/internal/OracleWebSocket.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAcH;;GAEG;AACH,UAAU,qBAAqB;IAC7B,2CAA2C;IAC3C,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,qBAAa,eAAe;IAgBxB,OAAO,CAAC,OAAO;IAfjB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,YAAY,CAA+C;IACnE,OAAO,CAAC,MAAM,CAAwB;IAEtC,qCAAqC;IAC9B,YAAY,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAEpG,0BAA0B;IACnB,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAEvD,oCAAoC;IAC7B,OAAO,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAQ;gBAGjC,OAAO,EAAE,MAAM,EACvB,MAAM,GAAE,OAAO,CAAC,qBAAqB,CAAM;IAO7C;;OAEG;IACH,IAAI,WAAW,IAAI,OAAO,CAIzB;IAED;;;;;OAKG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA+C/C;;;;;OAKG;IACH,UAAU,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI;IAMvC;;OAEG;IACH,QAAQ,IAAI,IAAI;IAMhB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB5B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;OAEG;IACH,OAAO,CAAC,aAAa;IA+CrB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAMzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAMzB"}
@@ -0,0 +1,204 @@
1
+ /**
2
+ * OracleWebSocket - WebSocket wrapper for Oracle streaming (INTERNAL)
3
+ *
4
+ * Handles:
5
+ * - First-message authentication (browser WS doesn't support headers)
6
+ * - Binary frames for audio (NOT base64)
7
+ * - JSON frames for control messages
8
+ * - Ping/pong keepalive during IDLE
9
+ * - Transcript parsing and callback firing
10
+ *
11
+ * This module is INTERNAL and should NOT be exported publicly.
12
+ */
13
+ /**
14
+ * WebSocket ready states (matches browser WebSocket API).
15
+ */
16
+ const WS_READY_STATE = {
17
+ CONNECTING: 0,
18
+ OPEN: 1,
19
+ CLOSING: 2,
20
+ CLOSED: 3,
21
+ };
22
+ /**
23
+ * OracleWebSocket - Manages WebSocket connection to Oracle service.
24
+ */
25
+ export class OracleWebSocket {
26
+ baseUrl;
27
+ ws = null;
28
+ authenticated = false;
29
+ pingInterval = null;
30
+ config;
31
+ /** Callback for transcript events */
32
+ onTranscript = null;
33
+ /** Callback for errors */
34
+ onError = null;
35
+ /** Callback for connection close */
36
+ onClose = null;
37
+ constructor(baseUrl, config = {}) {
38
+ this.baseUrl = baseUrl;
39
+ this.config = {
40
+ pingIntervalMs: config.pingIntervalMs ?? 10000,
41
+ };
42
+ }
43
+ /**
44
+ * Check if WebSocket is connected and authenticated.
45
+ */
46
+ get isConnected() {
47
+ return this.ws !== null &&
48
+ this.ws.readyState === WS_READY_STATE.OPEN &&
49
+ this.authenticated;
50
+ }
51
+ /**
52
+ * Connect to Oracle WebSocket endpoint with first-message auth.
53
+ *
54
+ * @param userToken - User JWT for authentication
55
+ * @returns Promise that resolves when authenticated, rejects on error
56
+ */
57
+ async connect(userToken) {
58
+ return new Promise((resolve, reject) => {
59
+ // Convert HTTP URL to WebSocket URL
60
+ const wsUrl = this.buildWebSocketUrl();
61
+ try {
62
+ this.ws = new WebSocket(wsUrl);
63
+ this.ws.binaryType = 'arraybuffer';
64
+ }
65
+ catch (error) {
66
+ reject(new Error(`Failed to create WebSocket: ${error}`));
67
+ return;
68
+ }
69
+ // Connection opened - send auth message
70
+ this.ws.onopen = () => {
71
+ // First-message auth (browser WS doesn't support custom headers)
72
+ this.ws.send(JSON.stringify({
73
+ type: 'auth',
74
+ token: userToken,
75
+ }));
76
+ };
77
+ // Handle incoming messages
78
+ this.ws.onmessage = (event) => {
79
+ this.handleMessage(event, resolve, reject);
80
+ };
81
+ // Handle connection close
82
+ this.ws.onclose = (event) => {
83
+ this.stopPingInterval();
84
+ this.authenticated = false;
85
+ // If we never authenticated, reject the connection promise
86
+ if (!this.authenticated && event.code !== 1000) {
87
+ reject(new Error(`WebSocket closed: ${event.reason || `code ${event.code}`}`));
88
+ }
89
+ this.onClose?.();
90
+ };
91
+ // Handle connection errors
92
+ this.ws.onerror = () => {
93
+ reject(new Error('WebSocket connection failed'));
94
+ };
95
+ });
96
+ }
97
+ /**
98
+ * Send binary PCM audio frame.
99
+ * Only called by VADGate - NOT exposed publicly.
100
+ *
101
+ * @param pcmFrame - Raw PCM audio data
102
+ */
103
+ sendBinary(pcmFrame) {
104
+ if (this.ws?.readyState === WS_READY_STATE.OPEN && this.authenticated) {
105
+ this.ws.send(pcmFrame);
106
+ }
107
+ }
108
+ /**
109
+ * Send a ping message for keepalive.
110
+ */
111
+ sendPing() {
112
+ if (this.ws?.readyState === WS_READY_STATE.OPEN && this.authenticated) {
113
+ this.ws.send(JSON.stringify({ type: 'ping' }));
114
+ }
115
+ }
116
+ /**
117
+ * Close the WebSocket connection gracefully.
118
+ */
119
+ async close() {
120
+ this.stopPingInterval();
121
+ if (this.ws) {
122
+ // Send close message before closing
123
+ if (this.ws.readyState === WS_READY_STATE.OPEN) {
124
+ try {
125
+ this.ws.send(JSON.stringify({ type: 'close' }));
126
+ }
127
+ catch {
128
+ // Ignore send errors during close
129
+ }
130
+ }
131
+ this.ws.close(1000, 'Session ended');
132
+ this.ws = null;
133
+ }
134
+ this.authenticated = false;
135
+ }
136
+ /**
137
+ * Build WebSocket URL from base URL.
138
+ */
139
+ buildWebSocketUrl() {
140
+ // Replace http(s) with ws(s)
141
+ const wsProtocol = this.baseUrl.startsWith('https') ? 'wss' : 'ws';
142
+ const httpProtocol = this.baseUrl.startsWith('https') ? 'https' : 'http';
143
+ return this.baseUrl.replace(httpProtocol, wsProtocol) + '/api/oracle/stream';
144
+ }
145
+ /**
146
+ * Handle incoming WebSocket message.
147
+ */
148
+ handleMessage(event, resolveConnect, rejectConnect) {
149
+ // Binary messages are not expected from server (audio is one-way)
150
+ if (event.data instanceof ArrayBuffer) {
151
+ return;
152
+ }
153
+ // Parse JSON message
154
+ let data;
155
+ try {
156
+ data = JSON.parse(event.data);
157
+ }
158
+ catch {
159
+ console.warn('[OracleSDK] Received invalid JSON from server');
160
+ return;
161
+ }
162
+ switch (data.type) {
163
+ case 'ready':
164
+ this.authenticated = true;
165
+ this.startPingInterval();
166
+ resolveConnect();
167
+ break;
168
+ case 'transcript':
169
+ this.onTranscript?.(data.text, data.is_final, data.speech_final);
170
+ break;
171
+ case 'pong':
172
+ // Keepalive response - no action needed
173
+ break;
174
+ case 'error':
175
+ const error = new Error(data.message);
176
+ this.onError?.(error);
177
+ if (!this.authenticated) {
178
+ rejectConnect(error);
179
+ }
180
+ break;
181
+ default:
182
+ console.warn('[OracleSDK] Unknown message type:', data.type);
183
+ }
184
+ }
185
+ /**
186
+ * Start ping interval for keepalive.
187
+ * Sends ping every pingIntervalMs during IDLE state.
188
+ */
189
+ startPingInterval() {
190
+ this.pingInterval = setInterval(() => {
191
+ this.sendPing();
192
+ }, this.config.pingIntervalMs);
193
+ }
194
+ /**
195
+ * Stop ping interval.
196
+ */
197
+ stopPingInterval() {
198
+ if (this.pingInterval !== null) {
199
+ clearInterval(this.pingInterval);
200
+ this.pingInterval = null;
201
+ }
202
+ }
203
+ }
204
+ //# sourceMappingURL=OracleWebSocket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OracleWebSocket.js","sourceRoot":"","sources":["../../../../src/namespaces/oracle/internal/OracleWebSocket.ts"],"names":[],"mappings":"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"}