@volley/recognition-client-sdk 0.1.254 → 0.1.287

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 (38) hide show
  1. package/dist/browser.d.ts +10 -0
  2. package/dist/browser.d.ts.map +1 -0
  3. package/dist/config-builder.d.ts +129 -0
  4. package/dist/config-builder.d.ts.map +1 -0
  5. package/dist/errors.d.ts +41 -0
  6. package/dist/errors.d.ts.map +1 -0
  7. package/dist/factory.d.ts +36 -0
  8. package/dist/factory.d.ts.map +1 -0
  9. package/dist/index.d.ts +15 -1079
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +9764 -2105
  12. package/dist/index.js.map +7 -1
  13. package/dist/recog-client-sdk.browser.d.ts +10 -2
  14. package/dist/recog-client-sdk.browser.d.ts.map +1 -0
  15. package/dist/recog-client-sdk.browser.js +4608 -704
  16. package/dist/recog-client-sdk.browser.js.map +7 -1
  17. package/dist/recognition-client.d.ts +119 -0
  18. package/dist/recognition-client.d.ts.map +1 -0
  19. package/dist/recognition-client.types.d.ts +247 -0
  20. package/dist/recognition-client.types.d.ts.map +1 -0
  21. package/dist/simplified-vgf-recognition-client.d.ts +155 -0
  22. package/dist/simplified-vgf-recognition-client.d.ts.map +1 -0
  23. package/dist/utils/audio-ring-buffer.d.ts +69 -0
  24. package/dist/utils/audio-ring-buffer.d.ts.map +1 -0
  25. package/dist/utils/message-handler.d.ts +45 -0
  26. package/dist/utils/message-handler.d.ts.map +1 -0
  27. package/dist/utils/url-builder.d.ts +26 -0
  28. package/dist/utils/url-builder.d.ts.map +1 -0
  29. package/dist/vgf-recognition-mapper.d.ts +53 -0
  30. package/dist/vgf-recognition-mapper.d.ts.map +1 -0
  31. package/dist/vgf-recognition-state.d.ts +81 -0
  32. package/dist/vgf-recognition-state.d.ts.map +1 -0
  33. package/package.json +8 -9
  34. package/src/index.ts +4 -0
  35. package/src/recognition-client.spec.ts +19 -14
  36. package/src/recognition-client.ts +13 -6
  37. package/src/utils/url-builder.spec.ts +5 -3
  38. package/dist/browser-BZs4BL_w.d.ts +0 -1118
@@ -0,0 +1,119 @@
1
+ /**
2
+ * RealTimeTwoWayWebSocketRecognitionClient - Clean, compact SDK for real-time speech recognition
3
+ *
4
+ * Features:
5
+ * - Ring buffer-based audio storage with fixed memory footprint
6
+ * - Automatic buffering when disconnected, immediate send when connected
7
+ * - Buffer persists after flush (for future retry/reconnection scenarios)
8
+ * - Built on WebSocketAudioClient for robust protocol handling
9
+ * - Simple API: connect() → sendAudio() → stopRecording()
10
+ * - Type-safe message handling with callbacks
11
+ * - Automatic backpressure management
12
+ * - Overflow detection with buffer state tracking
13
+ *
14
+ * Example:
15
+ * ```typescript
16
+ * const client = new RealTimeTwoWayWebSocketRecognitionClient({
17
+ * url: 'ws://localhost:3101/ws/v1/recognize',
18
+ * onTranscript: (result) => console.log(result.finalTranscript),
19
+ * onError: (error) => console.error(error),
20
+ * maxBufferDurationSec: 60 // Ring buffer for 60 seconds
21
+ * });
22
+ *
23
+ * await client.connect();
24
+ *
25
+ * // Send audio chunks - always stored in ring buffer, sent if connected
26
+ * micStream.on('data', (chunk) => client.sendAudio(chunk));
27
+ *
28
+ * // Signal end of audio and wait for final results
29
+ * await client.stopRecording();
30
+ *
31
+ * // Server will close connection after sending finals
32
+ * // No manual cleanup needed - browser handles it
33
+ * ```
34
+ */
35
+ import { WebSocketAudioClient } from '@recog/websocket';
36
+ import { type TranscriptionResultV1 } from '@recog/shared-types';
37
+ import { ClientState } from './recognition-client.types.js';
38
+ import type { IRecognitionClient, IRecognitionClientStats, RealTimeTwoWayWebSocketRecognitionClientConfig } from './recognition-client.types.js';
39
+ /**
40
+ * Check if a WebSocket close code indicates normal closure
41
+ * @param code - WebSocket close code
42
+ * @returns true if the disconnection was normal/expected, false if it was an error
43
+ */
44
+ export declare function isNormalDisconnection(code: number): boolean;
45
+ /**
46
+ * Re-export TranscriptionResultV1 as TranscriptionResult for backward compatibility
47
+ */
48
+ export type TranscriptionResult = TranscriptionResultV1;
49
+ export type { RealTimeTwoWayWebSocketRecognitionClientConfig } from './recognition-client.types.js';
50
+ /**
51
+ * RealTimeTwoWayWebSocketRecognitionClient - SDK-level client for real-time speech recognition
52
+ *
53
+ * Implements IRecognitionClient interface for dependency injection and testing.
54
+ * Extends WebSocketAudioClient with local audio buffering and simple callback-based API.
55
+ */
56
+ export declare class RealTimeTwoWayWebSocketRecognitionClient extends WebSocketAudioClient<number, any, any> implements IRecognitionClient {
57
+ private static readonly PROTOCOL_VERSION;
58
+ private config;
59
+ private audioBuffer;
60
+ private messageHandler;
61
+ private state;
62
+ private connectionPromise;
63
+ private isDebugLogEnabled;
64
+ private audioBytesSent;
65
+ private audioChunksSent;
66
+ private audioStatsLogInterval;
67
+ private lastAudioStatsLog;
68
+ constructor(config: RealTimeTwoWayWebSocketRecognitionClientConfig);
69
+ /**
70
+ * Internal logging helper - only logs if a logger was provided in config
71
+ * Debug logs are additionally gated by isDebugLogEnabled flag
72
+ * @param level - Log level: debug, info, warn, or error
73
+ * @param message - Message to log
74
+ * @param data - Optional additional data to log
75
+ */
76
+ private log;
77
+ /**
78
+ * Clean up internal resources to free memory
79
+ * Called when connection closes (normally or abnormally)
80
+ */
81
+ private cleanup;
82
+ connect(): Promise<void>;
83
+ /**
84
+ * Attempt to connect with retry logic
85
+ * Only retries on initial connection establishment, not mid-stream interruptions
86
+ */
87
+ private connectWithRetry;
88
+ sendAudio(audioData: ArrayBuffer | ArrayBufferView | Blob): void;
89
+ private sendAudioInternal;
90
+ stopRecording(): Promise<void>;
91
+ getAudioUtteranceId(): string;
92
+ getUrl(): string;
93
+ getState(): ClientState;
94
+ isConnected(): boolean;
95
+ isConnecting(): boolean;
96
+ isStopping(): boolean;
97
+ isTranscriptionFinished(): boolean;
98
+ isBufferOverflowing(): boolean;
99
+ getStats(): IRecognitionClientStats;
100
+ protected onConnected(): void;
101
+ protected onDisconnected(code: number, reason: string): void;
102
+ protected onError(error: Event): void;
103
+ protected onMessage(msg: {
104
+ v: number;
105
+ type: string;
106
+ data: any;
107
+ }): void;
108
+ /**
109
+ * Handle control messages from server
110
+ * @param msg - Control message containing server actions
111
+ */
112
+ private handleControlMessage;
113
+ /**
114
+ * Send audio immediately to the server (without buffering)
115
+ * @param audioData - Audio data to send
116
+ */
117
+ private sendAudioNow;
118
+ }
119
+ //# sourceMappingURL=recognition-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recognition-client.d.ts","sourceRoot":"","sources":["../src/recognition-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAML,KAAK,qBAAqB,EAS3B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,KAAK,EACV,kBAAkB,EAClB,uBAAuB,EACvB,8CAA8C,EAE/C,MAAM,+BAA+B,CAAC;AAUvC;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAgCD;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAGxD,YAAY,EAAE,8CAA8C,EAAE,MAAM,+BAA+B,CAAC;AAgCpG;;;;;GAKG;AACH,qBAAa,wCACX,SAAQ,oBAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAC7C,YAAW,kBAAkB;IAE7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAK;IAE7C,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,iBAAiB,CAA4B;IAGrD,OAAO,CAAC,iBAAiB,CAAS;IAGlC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,qBAAqB,CAAO;IACpC,OAAO,CAAC,iBAAiB,CAAK;gBAElB,MAAM,EAAE,8CAA8C;IA8ElE;;;;;;OAMG;IACH,OAAO,CAAC,GAAG;IAWX;;;OAGG;IACH,OAAO,CAAC,OAAO;IAmBA,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BvC;;;OAGG;YACW,gBAAgB;IAkIrB,SAAS,CAAC,SAAS,EAAE,WAAW,GAAG,eAAe,GAAG,IAAI,GAAG,IAAI;IAiBzE,OAAO,CAAC,iBAAiB;IAsCnB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAqCpC,mBAAmB,IAAI,MAAM;IAI7B,MAAM,IAAI,MAAM;IAIhB,QAAQ,IAAI,WAAW;IAIvB,WAAW,IAAI,OAAO;IAItB,YAAY,IAAI,OAAO;IAIvB,UAAU,IAAI,OAAO;IAIrB,uBAAuB,IAAI,OAAO;IAIlC,mBAAmB,IAAI,OAAO;IAI9B,QAAQ,IAAI,uBAAuB;IAgBnC,SAAS,CAAC,WAAW,IAAI,IAAI;IAiE7B,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAqB5D,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;cAYlB,SAAS,CAAC,GAAG,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,GAAG,CAAA;KAAE,GAAG,IAAI;IAQ/E;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAyB5B;;;OAGG;IACH,OAAO,CAAC,YAAY;CAuBrB"}
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Recognition Client Types
3
+ *
4
+ * Type definitions and interfaces for the recognition client SDK.
5
+ * These interfaces enable dependency injection, testing, and alternative implementations.
6
+ */
7
+ import { TranscriptionResultV1, FunctionCallResultV1, MetadataResultV1, ErrorResultV1, ASRRequestConfig, GameContextV1, Stage } from '@recog/shared-types';
8
+ /**
9
+ * Client connection state enum
10
+ * Represents the various states a recognition client can be in during its lifecycle
11
+ */
12
+ export declare enum ClientState {
13
+ /** Initial state, no connection established */
14
+ INITIAL = "initial",
15
+ /** Actively establishing WebSocket connection */
16
+ CONNECTING = "connecting",
17
+ /** WebSocket connected but waiting for server ready signal */
18
+ CONNECTED = "connected",
19
+ /** Server ready, can send audio */
20
+ READY = "ready",
21
+ /** Sent stop signal, waiting for final transcript */
22
+ STOPPING = "stopping",
23
+ /** Connection closed normally after stop */
24
+ STOPPED = "stopped",
25
+ /** Connection failed or lost unexpectedly */
26
+ FAILED = "failed"
27
+ }
28
+ /**
29
+ * Callback URL configuration with message type filtering
30
+ */
31
+ export interface RecognitionCallbackUrl {
32
+ /** The callback URL endpoint */
33
+ url: string;
34
+ /** Array of message types to send to this URL. If empty/undefined, all types are sent */
35
+ messageTypes?: Array<string | number>;
36
+ }
37
+ export type IRecognitionCallbackUrl = RecognitionCallbackUrl;
38
+ export interface IRecognitionClientConfig {
39
+ /**
40
+ * WebSocket endpoint URL (optional)
41
+ * Either `url` or `stage` must be provided.
42
+ * If both are provided, `url` takes precedence.
43
+ *
44
+ * Example with explicit URL:
45
+ * ```typescript
46
+ * { url: 'wss://custom-endpoint.example.com/ws/v1/recognize' }
47
+ * ```
48
+ */
49
+ url?: string;
50
+ /**
51
+ * Stage for recognition service (recommended)
52
+ * Either `url` or `stage` must be provided.
53
+ * If both are provided, `url` takes precedence.
54
+ * Defaults to production if neither is provided.
55
+ *
56
+ * Example with STAGES enum (recommended):
57
+ * ```typescript
58
+ * import { STAGES } from '@recog/shared-types';
59
+ * { stage: STAGES.STAGING }
60
+ * ```
61
+ *
62
+ * String values also accepted:
63
+ * ```typescript
64
+ * { stage: 'staging' } // STAGES.LOCAL | STAGES.DEV | STAGES.STAGING | STAGES.PRODUCTION
65
+ * ```
66
+ */
67
+ stage?: Stage | string;
68
+ /** ASR configuration (provider, model, language, etc.) - optional */
69
+ asrRequestConfig?: ASRRequestConfig;
70
+ /** Game context for improved recognition accuracy */
71
+ gameContext?: GameContextV1;
72
+ /** Audio utterance ID (optional) - if not provided, a UUID v4 will be generated */
73
+ audioUtteranceId?: string;
74
+ /** Callback URLs for server-side notifications with optional message type filtering (optional)
75
+ * Game side only need to use it if another service need to be notified about the transcription results.
76
+ */
77
+ callbackUrls?: RecognitionCallbackUrl[];
78
+ /** User identification (optional) */
79
+ userId?: string;
80
+ /** Game session identification (optional). called 'sessionId' in Platform and most games. */
81
+ gameSessionId?: string;
82
+ /** Device identification (optional) */
83
+ deviceId?: string;
84
+ /** Account identification (optional) */
85
+ accountId?: string;
86
+ /** Question answer identifier for tracking Q&A sessions (optional and tracking purpose only) */
87
+ questionAnswerId?: string;
88
+ /** Platform for audio recording device (optional, e.g., 'ios', 'android', 'web', 'unity') */
89
+ platform?: string;
90
+ /** Callback when transcript is received */
91
+ onTranscript?: (result: TranscriptionResultV1) => void;
92
+ /**
93
+ * Callback when function call is received
94
+ * Note: Not supported in 2025. P2 feature for future speech-to-function-call capability.
95
+ */
96
+ onFunctionCall?: (result: FunctionCallResultV1) => void;
97
+ /** Callback when metadata is received. Only once after transcription is complete.*/
98
+ onMetadata?: (metadata: MetadataResultV1) => void;
99
+ /** Callback when error occurs */
100
+ onError?: (error: ErrorResultV1) => void;
101
+ /** Callback when connected to WebSocket */
102
+ onConnected?: () => void;
103
+ /**
104
+ * Callback when WebSocket disconnects
105
+ * @param code - WebSocket close code (1000 = normal, 1006 = abnormal, etc.)
106
+ * @param reason - Close reason string
107
+ */
108
+ onDisconnected?: (code: number, reason: string) => void;
109
+ /** High water mark for backpressure control (bytes) */
110
+ highWaterMark?: number;
111
+ /** Low water mark for backpressure control (bytes) */
112
+ lowWaterMark?: number;
113
+ /** Maximum buffer duration in seconds (default: 60s) */
114
+ maxBufferDurationSec?: number;
115
+ /** Expected chunks per second for ring buffer sizing (default: 100) */
116
+ chunksPerSecond?: number;
117
+ /**
118
+ * Connection retry configuration (optional)
119
+ * Only applies to initial connection establishment, not mid-stream interruptions.
120
+ *
121
+ * Default: { maxAttempts: 4, delayMs: 200 } (try once, retry 3 times = 4 total attempts)
122
+ *
123
+ * Timing: Attempt 1 → FAIL → wait 200ms → Attempt 2 → FAIL → wait 200ms → Attempt 3 → FAIL → wait 200ms → Attempt 4
124
+ *
125
+ * Example:
126
+ * ```typescript
127
+ * {
128
+ * connectionRetry: {
129
+ * maxAttempts: 2, // Try connecting up to 2 times (1 retry)
130
+ * delayMs: 500 // Wait 500ms between attempts
131
+ * }
132
+ * }
133
+ * ```
134
+ */
135
+ connectionRetry?: {
136
+ /** Maximum number of connection attempts (default: 4, min: 1, max: 5) */
137
+ maxAttempts?: number;
138
+ /** Delay in milliseconds between retry attempts (default: 200ms) */
139
+ delayMs?: number;
140
+ };
141
+ /**
142
+ * Optional logger function for debugging
143
+ * If not provided, no logging will occur
144
+ * @param level - Log level: 'debug', 'info', 'warn', 'error'
145
+ * @param message - Log message
146
+ * @param data - Optional additional data
147
+ */
148
+ logger?: (level: 'debug' | 'info' | 'warn' | 'error', message: string, data?: any) => void;
149
+ }
150
+ /**
151
+ * Recognition Client Interface
152
+ *
153
+ * Main interface for real-time speech recognition clients.
154
+ * Provides methods for connection management, audio streaming, and session control.
155
+ */
156
+ export interface IRecognitionClient {
157
+ /**
158
+ * Connect to the WebSocket endpoint
159
+ * @returns Promise that resolves when connected
160
+ * @throws Error if connection fails or times out
161
+ */
162
+ connect(): Promise<void>;
163
+ /**
164
+ * Send audio data to the recognition service
165
+ * Audio is buffered locally and sent when connection is ready.
166
+ * @param audioData - PCM audio data as ArrayBuffer, typed array view, or Blob
167
+ */
168
+ sendAudio(audioData: ArrayBuffer | ArrayBufferView | Blob): void;
169
+ /**
170
+ * Stop recording and wait for final transcript
171
+ * The server will close the connection after sending the final transcript.
172
+ * @returns Promise that resolves when final transcript is received
173
+ */
174
+ stopRecording(): Promise<void>;
175
+ /**
176
+ * Get the audio utterance ID for this session
177
+ * Available immediately after client construction.
178
+ * @returns UUID v4 string identifying this recognition session
179
+ */
180
+ getAudioUtteranceId(): string;
181
+ /**
182
+ * Get the current state of the client
183
+ * @returns Current ClientState value
184
+ */
185
+ getState(): ClientState;
186
+ /**
187
+ * Check if WebSocket connection is open
188
+ * @returns true if connected and ready to communicate
189
+ */
190
+ isConnected(): boolean;
191
+ /**
192
+ * Check if client is currently connecting
193
+ * @returns true if connection is in progress
194
+ */
195
+ isConnecting(): boolean;
196
+ /**
197
+ * Check if client is currently stopping
198
+ * @returns true if stopRecording() is in progress
199
+ */
200
+ isStopping(): boolean;
201
+ /**
202
+ * Check if transcription has finished
203
+ * @returns true if the transcription is complete
204
+ */
205
+ isTranscriptionFinished(): boolean;
206
+ /**
207
+ * Check if the audio buffer has overflowed
208
+ * @returns true if the ring buffer has wrapped around
209
+ */
210
+ isBufferOverflowing(): boolean;
211
+ /**
212
+ * Get client statistics
213
+ * @returns Statistics about audio transmission and buffering
214
+ */
215
+ getStats(): IRecognitionClientStats;
216
+ /**
217
+ * Get the WebSocket URL being used by this client
218
+ * Available immediately after client construction.
219
+ * @returns WebSocket URL string
220
+ */
221
+ getUrl(): string;
222
+ }
223
+ /**
224
+ * Client statistics interface
225
+ */
226
+ export interface IRecognitionClientStats {
227
+ /** Total audio bytes sent to server */
228
+ audioBytesSent: number;
229
+ /** Total number of audio chunks sent */
230
+ audioChunksSent: number;
231
+ /** Total number of audio chunks buffered */
232
+ audioChunksBuffered: number;
233
+ /** Number of times the ring buffer overflowed */
234
+ bufferOverflowCount: number;
235
+ /** Current number of chunks in buffer */
236
+ currentBufferedChunks: number;
237
+ /** Whether the ring buffer has wrapped (overwritten old data) */
238
+ hasWrapped: boolean;
239
+ }
240
+ /**
241
+ * Configuration for RealTimeTwoWayWebSocketRecognitionClient
242
+ * This extends IRecognitionClientConfig and is the main configuration interface
243
+ * for creating a new RealTimeTwoWayWebSocketRecognitionClient instance.
244
+ */
245
+ export interface RealTimeTwoWayWebSocketRecognitionClientConfig extends IRecognitionClientConfig {
246
+ }
247
+ //# sourceMappingURL=recognition-client.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recognition-client.types.d.ts","sourceRoot":"","sources":["../src/recognition-client.types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Simplified VGF Recognition Client
3
+ *
4
+ * A thin wrapper around RealTimeTwoWayWebSocketRecognitionClient that maintains
5
+ * a VGF RecognitionState as a pure sink/output of recognition events.
6
+ *
7
+ * The VGF state is updated based on events but never influences client behavior.
8
+ * All functionality is delegated to the underlying client.
9
+ */
10
+ import { RecognitionState } from './vgf-recognition-state.js';
11
+ import { IRecognitionClientConfig, ClientState } from './recognition-client.types.js';
12
+ /**
13
+ * Configuration for SimplifiedVGFRecognitionClient
14
+ */
15
+ export interface SimplifiedVGFClientConfig extends IRecognitionClientConfig {
16
+ /**
17
+ * Callback invoked whenever the VGF state changes
18
+ * Use this to update your UI or React state
19
+ */
20
+ onStateChange?: (state: RecognitionState) => void;
21
+ /**
22
+ * Optional initial state to restore from a previous session
23
+ * If provided, audioUtteranceId will be extracted and used
24
+ */
25
+ initialState?: RecognitionState;
26
+ }
27
+ /**
28
+ * Interface for SimplifiedVGFRecognitionClient
29
+ *
30
+ * A simplified client that maintains VGF state for game developers.
31
+ * All methods from the underlying client are available, plus VGF state management.
32
+ */
33
+ export interface ISimplifiedVGFRecognitionClient {
34
+ /**
35
+ * Connect to the recognition service WebSocket
36
+ * @returns Promise that resolves when connected and ready
37
+ */
38
+ connect(): Promise<void>;
39
+ /**
40
+ * Send audio data for transcription
41
+ * @param audioData - PCM audio data as ArrayBuffer, typed array, or Blob
42
+ */
43
+ sendAudio(audioData: ArrayBuffer | ArrayBufferView | Blob): void;
44
+ /**
45
+ * Stop recording and wait for final transcription
46
+ * @returns Promise that resolves when transcription is complete
47
+ */
48
+ stopRecording(): Promise<void>;
49
+ /**
50
+ * Get the current VGF recognition state
51
+ * @returns Current RecognitionState with all transcription data
52
+ */
53
+ getVGFState(): RecognitionState;
54
+ /**
55
+ * Check if connected to the WebSocket
56
+ */
57
+ isConnected(): boolean;
58
+ /**
59
+ * Check if currently connecting
60
+ */
61
+ isConnecting(): boolean;
62
+ /**
63
+ * Check if currently stopping
64
+ */
65
+ isStopping(): boolean;
66
+ /**
67
+ * Check if transcription has finished
68
+ */
69
+ isTranscriptionFinished(): boolean;
70
+ /**
71
+ * Check if the audio buffer has overflowed
72
+ */
73
+ isBufferOverflowing(): boolean;
74
+ /**
75
+ * Get the audio utterance ID for this session
76
+ */
77
+ getAudioUtteranceId(): string;
78
+ /**
79
+ * Get the WebSocket URL being used
80
+ */
81
+ getUrl(): string;
82
+ /**
83
+ * Get the underlying client state (for advanced usage)
84
+ */
85
+ getState(): ClientState;
86
+ }
87
+ /**
88
+ * This wrapper ONLY maintains VGF state as a sink.
89
+ * All actual functionality is delegated to the underlying client.
90
+ */
91
+ export declare class SimplifiedVGFRecognitionClient implements ISimplifiedVGFRecognitionClient {
92
+ private client;
93
+ private state;
94
+ private isRecordingAudio;
95
+ private stateChangeCallback;
96
+ constructor(config: SimplifiedVGFClientConfig);
97
+ connect(): Promise<void>;
98
+ sendAudio(audioData: ArrayBuffer | ArrayBufferView | Blob): void;
99
+ stopRecording(): Promise<void>;
100
+ getAudioUtteranceId(): string;
101
+ getUrl(): string;
102
+ getState(): ClientState;
103
+ isConnected(): boolean;
104
+ isConnecting(): boolean;
105
+ isStopping(): boolean;
106
+ isTranscriptionFinished(): boolean;
107
+ isBufferOverflowing(): boolean;
108
+ getVGFState(): RecognitionState;
109
+ private notifyStateChange;
110
+ }
111
+ /**
112
+ * Factory function for creating simplified client
113
+ * Usage examples:
114
+ *
115
+ * // Basic usage
116
+ * const client = createSimplifiedVGFClient({
117
+ * asrRequestConfig: { provider: 'deepgram', language: 'en' },
118
+ * onStateChange: (state) => {
119
+ * console.log('VGF State updated:', state);
120
+ * // Update React state, game UI, etc.
121
+ * }
122
+ * });
123
+ *
124
+ * // With initial state (e.g., restoring from previous session)
125
+ * const client = createSimplifiedVGFClient({
126
+ * asrRequestConfig: { provider: 'deepgram', language: 'en' },
127
+ * initialState: previousState, // Will use audioUtteranceId from state
128
+ * onStateChange: (state) => setVGFState(state)
129
+ * });
130
+ *
131
+ * // With initial state containing promptSlotMap for enhanced recognition
132
+ * const stateWithSlots: RecognitionState = {
133
+ * audioUtteranceId: 'session-123',
134
+ * promptSlotMap: {
135
+ * 'song_title': ['one time', 'baby'],
136
+ * 'artists': ['justin bieber']
137
+ * }
138
+ * };
139
+ * const client = createSimplifiedVGFClient({
140
+ * asrRequestConfig: { provider: 'deepgram', language: 'en' },
141
+ * gameContext: {
142
+ * type: RecognitionContextTypeV1.GAME_CONTEXT,
143
+ * gameId: 'music-quiz', // Your game's ID
144
+ * gamePhase: 'song-guessing' // Current game phase
145
+ * },
146
+ * initialState: stateWithSlots, // promptSlotMap will be added to gameContext
147
+ * onStateChange: (state) => setVGFState(state)
148
+ * });
149
+ *
150
+ * await client.connect();
151
+ * client.sendAudio(audioData);
152
+ * // VGF state automatically updates based on transcription results
153
+ */
154
+ export declare function createSimplifiedVGFClient(config: SimplifiedVGFClientConfig): ISimplifiedVGFRecognitionClient;
155
+ //# sourceMappingURL=simplified-vgf-recognition-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simplified-vgf-recognition-client.d.ts","sourceRoot":"","sources":["../src/simplified-vgf-recognition-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAEH,wBAAwB,EACxB,WAAW,EACd,MAAM,+BAA+B,CAAC;AAWvC;;GAEG;AACH,MAAM,WAAW,yBAA0B,SAAQ,wBAAwB;IACvE;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAElD;;;OAGG;IACH,YAAY,CAAC,EAAE,gBAAgB,CAAC;CACnC;AAED;;;;;GAKG;AACH,MAAM,WAAW,+BAA+B;IAE5C;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzB;;;OAGG;IACH,SAAS,CAAC,SAAS,EAAE,WAAW,GAAG,eAAe,GAAG,IAAI,GAAG,IAAI,CAAC;IAEjE;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAG/B;;;OAGG;IACH,WAAW,IAAI,gBAAgB,CAAC;IAGhC;;OAEG;IACH,WAAW,IAAI,OAAO,CAAC;IAEvB;;OAEG;IACH,YAAY,IAAI,OAAO,CAAC;IAExB;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC;IAEtB;;OAEG;IACH,uBAAuB,IAAI,OAAO,CAAC;IAEnC;;OAEG;IACH,mBAAmB,IAAI,OAAO,CAAC;IAG/B;;OAEG;IACH,mBAAmB,IAAI,MAAM,CAAC;IAE9B;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,IAAI,WAAW,CAAC;CAE3B;AAED;;;GAGG;AACH,qBAAa,8BAA+B,YAAW,+BAA+B;IAClF,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,gBAAgB,CAAkB;IAC1C,OAAO,CAAC,mBAAmB,CAAkD;gBAEjE,MAAM,EAAE,yBAAyB;IAoGvC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B,SAAS,CAAC,SAAS,EAAE,WAAW,GAAG,eAAe,GAAG,IAAI,GAAG,IAAI;IAc1D,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAQpC,mBAAmB,IAAI,MAAM;IAI7B,MAAM,IAAI,MAAM;IAIhB,QAAQ,IAAI,WAAW;IAIvB,WAAW,IAAI,OAAO;IAItB,YAAY,IAAI,OAAO;IAIvB,UAAU,IAAI,OAAO;IAIrB,uBAAuB,IAAI,OAAO;IAIlC,mBAAmB,IAAI,OAAO;IAM9B,WAAW,IAAI,gBAAgB;IAI/B,OAAO,CAAC,iBAAiB;CAK5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,yBAAyB,GAAG,+BAA+B,CAE5G"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Audio Ring Buffer
3
+ * Manages circular buffer for audio data with overflow detection
4
+ */
5
+ export interface BufferedAudio {
6
+ data: ArrayBuffer | ArrayBufferView;
7
+ timestamp: number;
8
+ }
9
+ export interface AudioRingBufferConfig {
10
+ maxBufferDurationSec: number;
11
+ chunksPerSecond: number;
12
+ logger?: (level: 'debug' | 'info' | 'warn' | 'error', message: string, data?: any) => void;
13
+ }
14
+ export declare class AudioRingBuffer {
15
+ private buffer;
16
+ private bufferSize;
17
+ private writeIndex;
18
+ private readIndex;
19
+ private hasWrapped;
20
+ private totalBufferedBytes;
21
+ private overflowCount;
22
+ private chunksBuffered;
23
+ private logger?;
24
+ constructor(config: AudioRingBufferConfig);
25
+ /**
26
+ * Write audio chunk to ring buffer with overflow detection
27
+ */
28
+ write(audioData: ArrayBuffer | ArrayBufferView): void;
29
+ /**
30
+ * Read next chunk from buffer
31
+ */
32
+ read(): BufferedAudio | null;
33
+ /**
34
+ * Read all buffered chunks without removing them
35
+ */
36
+ readAll(): BufferedAudio[];
37
+ /**
38
+ * Flush all buffered data and advance read pointer
39
+ */
40
+ flush(): BufferedAudio[];
41
+ /**
42
+ * Get count of buffered chunks
43
+ */
44
+ getBufferedCount(): number;
45
+ /**
46
+ * Check if buffer is empty
47
+ */
48
+ isEmpty(): boolean;
49
+ /**
50
+ * Check if buffer has overflowed
51
+ */
52
+ isOverflowing(): boolean;
53
+ /**
54
+ * Clear the buffer and reset all counters
55
+ * Frees memory by releasing all stored audio chunks
56
+ */
57
+ clear(): void;
58
+ /**
59
+ * Get buffer statistics
60
+ */
61
+ getStats(): {
62
+ chunksBuffered: number;
63
+ currentBufferedChunks: number;
64
+ overflowCount: number;
65
+ hasWrapped: boolean;
66
+ totalBufferedBytes: number;
67
+ };
68
+ }
69
+ //# sourceMappingURL=audio-ring-buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-ring-buffer.d.ts","sourceRoot":"","sources":["../../src/utils/audio-ring-buffer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,GAAG,eAAe,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;CAC5F;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,MAAM,CAAC,CAAoF;gBAEvF,MAAM,EAAE,qBAAqB;IAQzC;;OAEG;IACH,KAAK,CAAC,SAAS,EAAE,WAAW,GAAG,eAAe,GAAG,IAAI;IAmCrD;;OAEG;IACH,IAAI,IAAI,aAAa,GAAG,IAAI;IAU5B;;OAEG;IACH,OAAO,IAAI,aAAa,EAAE;IAe1B;;OAEG;IACH,KAAK,IAAI,aAAa,EAAE;IAMxB;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAS1B;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;;OAGG;IACH,KAAK,IAAI,IAAI;IAcb;;OAEG;IACH,QAAQ;;;;;;;CAST"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Message Handler for Recognition Client
3
+ * Routes incoming WebSocket messages to appropriate callbacks
4
+ */
5
+ import { type TranscriptionResultV1, type FunctionCallResultV1, type MetadataResultV1, type ErrorResultV1, type ClientControlMessageV1 } from '@recog/shared-types';
6
+ export interface MessageHandlerCallbacks {
7
+ onTranscript: (result: TranscriptionResultV1) => void;
8
+ onFunctionCall: (result: FunctionCallResultV1) => void;
9
+ onMetadata: (metadata: MetadataResultV1) => void;
10
+ onError: (error: ErrorResultV1) => void;
11
+ onControlMessage: (msg: ClientControlMessageV1) => void;
12
+ logger?: (level: 'debug' | 'info' | 'warn' | 'error', message: string, data?: any) => void;
13
+ }
14
+ export declare class MessageHandler {
15
+ private firstTranscriptTime;
16
+ private sessionStartTime;
17
+ private callbacks;
18
+ constructor(callbacks: MessageHandlerCallbacks);
19
+ /**
20
+ * Set session start time for performance tracking
21
+ */
22
+ setSessionStartTime(time: number): void;
23
+ /**
24
+ * Handle incoming WebSocket message
25
+ */
26
+ handleMessage(msg: {
27
+ v: number;
28
+ type: string;
29
+ data: any;
30
+ }): void;
31
+ /**
32
+ * Handle transcript message and track performance metrics
33
+ * @param result - The transcription result from the server
34
+ */
35
+ private handleTranscription;
36
+ /**
37
+ * Get performance metrics
38
+ */
39
+ getMetrics(): {
40
+ sessionStartTime: number | null;
41
+ firstTranscriptTime: number | null;
42
+ timeToFirstTranscript: number | null;
43
+ };
44
+ }
45
+ //# sourceMappingURL=message-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-handler.d.ts","sourceRoot":"","sources":["../../src/utils/message-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAC5B,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACtD,cAAc,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACvD,UAAU,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACjD,OAAO,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACxC,gBAAgB,EAAE,CAAC,GAAG,EAAE,sBAAsB,KAAK,IAAI,CAAC;IACxD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;CAC5F;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,SAAS,CAA0B;gBAE/B,SAAS,EAAE,uBAAuB;IAI9C;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIvC;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,GAAG,CAAA;KAAE,GAAG,IAAI;IAsDhE;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAgB3B;;OAEG;IACH,UAAU;;;;;CAUX"}