@volley/recognition-client-sdk 0.1.200 → 0.1.210
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 +115 -15
- package/dist/{browser-CDQ_TzeH.d.ts → browser-C4ZssGoU.d.ts} +4 -3
- package/dist/index.d.ts +9 -5
- package/dist/index.js +24 -7
- package/dist/index.js.map +1 -1
- package/dist/recog-client-sdk.browser.d.ts +1 -1
- package/dist/recog-client-sdk.browser.js +24 -7
- package/dist/recog-client-sdk.browser.js.map +1 -1
- package/package.json +16 -16
- package/src/config-builder.spec.ts +265 -0
- package/src/factory.spec.ts +215 -0
- package/src/factory.ts +4 -0
- package/src/recognition-client.spec.ts +179 -0
- package/src/recognition-client.ts +44 -1
- package/src/recognition-client.types.ts +2 -2
- package/src/simplified-vgf-recognition-client.spec.ts +6 -0
- package/src/simplified-vgf-recognition-client.ts +3 -3
- package/src/utils/message-handler.spec.ts +311 -0
- package/src/utils/url-builder.spec.ts +203 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volley/recognition-client-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.210",
|
|
4
4
|
"description": "Recognition Service TypeScript/Node.js Client SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,14 +28,7 @@
|
|
|
28
28
|
"sideEffects": false,
|
|
29
29
|
"publishConfig": {
|
|
30
30
|
"access": "public",
|
|
31
|
-
"provenance":
|
|
32
|
-
},
|
|
33
|
-
"scripts": {
|
|
34
|
-
"build": "tsup",
|
|
35
|
-
"dev": "tsup --watch",
|
|
36
|
-
"test": "jest --passWithNoTests",
|
|
37
|
-
"lint": "eslint src --ext .ts",
|
|
38
|
-
"prepublishOnly": "pnpm build"
|
|
31
|
+
"provenance": true
|
|
39
32
|
},
|
|
40
33
|
"dependencies": {
|
|
41
34
|
"uuid": "^11.0.0",
|
|
@@ -43,12 +36,9 @@
|
|
|
43
36
|
"zod": "^3.22.4"
|
|
44
37
|
},
|
|
45
38
|
"devDependencies": {
|
|
46
|
-
"@recog/shared-config": "workspace:*",
|
|
47
|
-
"@recog/shared-types": "workspace:*",
|
|
48
|
-
"@recog/shared-utils": "workspace:*",
|
|
49
|
-
"@recog/websocket": "workspace:*",
|
|
50
39
|
"@semantic-release/changelog": "^6.0.3",
|
|
51
40
|
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
41
|
+
"@semantic-release/exec": "^7.1.0",
|
|
52
42
|
"@semantic-release/git": "^10.0.1",
|
|
53
43
|
"@semantic-release/github": "^12.0.0",
|
|
54
44
|
"@semantic-release/npm": "^13.1.1",
|
|
@@ -62,12 +52,22 @@
|
|
|
62
52
|
"semantic-release": "^25.0.1",
|
|
63
53
|
"ts-jest": "^29.4.5",
|
|
64
54
|
"tsup": "^8.5.0",
|
|
65
|
-
"typescript": "^5.1.6"
|
|
55
|
+
"typescript": "^5.1.6",
|
|
56
|
+
"@recog/shared-config": "1.0.0",
|
|
57
|
+
"@recog/shared-types": "1.0.0",
|
|
58
|
+
"@recog/websocket": "1.0.0",
|
|
59
|
+
"@recog/shared-utils": "1.0.0"
|
|
66
60
|
},
|
|
67
61
|
"keywords": [
|
|
68
62
|
"recognition",
|
|
69
63
|
"sdk",
|
|
70
64
|
"audio",
|
|
71
65
|
"speech"
|
|
72
|
-
]
|
|
73
|
-
|
|
66
|
+
],
|
|
67
|
+
"scripts": {
|
|
68
|
+
"build": "tsup",
|
|
69
|
+
"dev": "tsup --watch",
|
|
70
|
+
"test": "jest --passWithNoTests",
|
|
71
|
+
"lint": "eslint src --ext .ts"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for ConfigBuilder
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { ConfigBuilder } from './config-builder.js';
|
|
6
|
+
import { RecognitionProvider, RecognitionContextTypeV1 } from '@recog/shared-types';
|
|
7
|
+
|
|
8
|
+
describe('ConfigBuilder', () => {
|
|
9
|
+
it('should build empty config', () => {
|
|
10
|
+
const config = new ConfigBuilder().build();
|
|
11
|
+
expect(config).toBeDefined();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should set url', () => {
|
|
15
|
+
const config = new ConfigBuilder()
|
|
16
|
+
.url('ws://localhost:3101/ws/v1/recognize')
|
|
17
|
+
.build();
|
|
18
|
+
expect(config.url).toBe('ws://localhost:3101/ws/v1/recognize');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should set asrRequestConfig', () => {
|
|
22
|
+
const asrConfig = {
|
|
23
|
+
provider: RecognitionProvider.DEEPGRAM,
|
|
24
|
+
model: 'nova-2-general',
|
|
25
|
+
language: 'en-US',
|
|
26
|
+
sampleRate: 16000,
|
|
27
|
+
encoding: 'linear16'
|
|
28
|
+
};
|
|
29
|
+
const config = new ConfigBuilder()
|
|
30
|
+
.asrRequestConfig(asrConfig)
|
|
31
|
+
.build();
|
|
32
|
+
expect(config.asrRequestConfig).toEqual(asrConfig);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should set gameContext', () => {
|
|
36
|
+
const gameContext = {
|
|
37
|
+
type: RecognitionContextTypeV1.GAME_CONTEXT as const,
|
|
38
|
+
gameId: 'test-game',
|
|
39
|
+
gamePhase: 'test-phase'
|
|
40
|
+
};
|
|
41
|
+
const config = new ConfigBuilder()
|
|
42
|
+
.gameContext(gameContext)
|
|
43
|
+
.build();
|
|
44
|
+
expect(config.gameContext).toEqual(gameContext);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should set audioUtteranceId', () => {
|
|
48
|
+
const config = new ConfigBuilder()
|
|
49
|
+
.audioUtteranceId('test-utterance-id')
|
|
50
|
+
.build();
|
|
51
|
+
expect(config.audioUtteranceId).toBe('test-utterance-id');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should set callbackUrls', () => {
|
|
55
|
+
const callbackUrls = [
|
|
56
|
+
{ url: 'https://example.com/callback', event: 'transcript' as const }
|
|
57
|
+
];
|
|
58
|
+
const config = new ConfigBuilder()
|
|
59
|
+
.callbackUrls(callbackUrls)
|
|
60
|
+
.build();
|
|
61
|
+
expect(config.callbackUrls).toEqual(callbackUrls);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should set userId', () => {
|
|
65
|
+
const config = new ConfigBuilder()
|
|
66
|
+
.userId('user-123')
|
|
67
|
+
.build();
|
|
68
|
+
expect(config.userId).toBe('user-123');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should set gameSessionId', () => {
|
|
72
|
+
const config = new ConfigBuilder()
|
|
73
|
+
.gameSessionId('session-456')
|
|
74
|
+
.build();
|
|
75
|
+
expect(config.gameSessionId).toBe('session-456');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should set deviceId', () => {
|
|
79
|
+
const config = new ConfigBuilder()
|
|
80
|
+
.deviceId('device-789')
|
|
81
|
+
.build();
|
|
82
|
+
expect(config.deviceId).toBe('device-789');
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should set accountId', () => {
|
|
86
|
+
const config = new ConfigBuilder()
|
|
87
|
+
.accountId('account-abc')
|
|
88
|
+
.build();
|
|
89
|
+
expect(config.accountId).toBe('account-abc');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should set questionAnswerId', () => {
|
|
93
|
+
const config = new ConfigBuilder()
|
|
94
|
+
.questionAnswerId('qa-xyz')
|
|
95
|
+
.build();
|
|
96
|
+
expect(config.questionAnswerId).toBe('qa-xyz');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should set platform', () => {
|
|
100
|
+
const config = new ConfigBuilder()
|
|
101
|
+
.platform('ios')
|
|
102
|
+
.build();
|
|
103
|
+
expect(config.platform).toBe('ios');
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should set onTranscript callback', () => {
|
|
107
|
+
const callback = jest.fn();
|
|
108
|
+
const config = new ConfigBuilder()
|
|
109
|
+
.onTranscript(callback)
|
|
110
|
+
.build();
|
|
111
|
+
expect(config.onTranscript).toBe(callback);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should set onMetadata callback', () => {
|
|
115
|
+
const callback = jest.fn();
|
|
116
|
+
const config = new ConfigBuilder()
|
|
117
|
+
.onMetadata(callback)
|
|
118
|
+
.build();
|
|
119
|
+
expect(config.onMetadata).toBe(callback);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should set onError callback', () => {
|
|
123
|
+
const callback = jest.fn();
|
|
124
|
+
const config = new ConfigBuilder()
|
|
125
|
+
.onError(callback)
|
|
126
|
+
.build();
|
|
127
|
+
expect(config.onError).toBe(callback);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('should set onConnected callback', () => {
|
|
131
|
+
const callback = jest.fn();
|
|
132
|
+
const config = new ConfigBuilder()
|
|
133
|
+
.onConnected(callback)
|
|
134
|
+
.build();
|
|
135
|
+
expect(config.onConnected).toBe(callback);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('should set onDisconnected callback', () => {
|
|
139
|
+
const callback = jest.fn();
|
|
140
|
+
const config = new ConfigBuilder()
|
|
141
|
+
.onDisconnected(callback)
|
|
142
|
+
.build();
|
|
143
|
+
expect(config.onDisconnected).toBe(callback);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('should set highWaterMark', () => {
|
|
147
|
+
const config = new ConfigBuilder()
|
|
148
|
+
.highWaterMark(1000)
|
|
149
|
+
.build();
|
|
150
|
+
expect(config.highWaterMark).toBe(1000);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('should set lowWaterMark', () => {
|
|
154
|
+
const config = new ConfigBuilder()
|
|
155
|
+
.lowWaterMark(500)
|
|
156
|
+
.build();
|
|
157
|
+
expect(config.lowWaterMark).toBe(500);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('should set maxBufferDurationSec', () => {
|
|
161
|
+
const config = new ConfigBuilder()
|
|
162
|
+
.maxBufferDurationSec(10)
|
|
163
|
+
.build();
|
|
164
|
+
expect(config.maxBufferDurationSec).toBe(10);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('should set chunksPerSecond', () => {
|
|
168
|
+
const config = new ConfigBuilder()
|
|
169
|
+
.chunksPerSecond(50)
|
|
170
|
+
.build();
|
|
171
|
+
expect(config.chunksPerSecond).toBe(50);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('should set logger', () => {
|
|
175
|
+
const logger = jest.fn();
|
|
176
|
+
const config = new ConfigBuilder()
|
|
177
|
+
.logger(logger)
|
|
178
|
+
.build();
|
|
179
|
+
expect(config.logger).toBe(logger);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('should support method chaining', () => {
|
|
183
|
+
const config = new ConfigBuilder()
|
|
184
|
+
.url('ws://localhost:3101/ws/v1/recognize')
|
|
185
|
+
.audioUtteranceId('test-id')
|
|
186
|
+
.userId('user-123')
|
|
187
|
+
.gameSessionId('session-456')
|
|
188
|
+
.deviceId('device-789')
|
|
189
|
+
.platform('ios')
|
|
190
|
+
.highWaterMark(1000)
|
|
191
|
+
.lowWaterMark(500)
|
|
192
|
+
.build();
|
|
193
|
+
|
|
194
|
+
expect(config.url).toBe('ws://localhost:3101/ws/v1/recognize');
|
|
195
|
+
expect(config.audioUtteranceId).toBe('test-id');
|
|
196
|
+
expect(config.userId).toBe('user-123');
|
|
197
|
+
expect(config.gameSessionId).toBe('session-456');
|
|
198
|
+
expect(config.deviceId).toBe('device-789');
|
|
199
|
+
expect(config.platform).toBe('ios');
|
|
200
|
+
expect(config.highWaterMark).toBe(1000);
|
|
201
|
+
expect(config.lowWaterMark).toBe(500);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it('should build complete configuration', () => {
|
|
205
|
+
const onTranscript = jest.fn();
|
|
206
|
+
const onError = jest.fn();
|
|
207
|
+
const onConnected = jest.fn();
|
|
208
|
+
const onDisconnected = jest.fn();
|
|
209
|
+
const logger = jest.fn();
|
|
210
|
+
|
|
211
|
+
const config = new ConfigBuilder()
|
|
212
|
+
.url('ws://localhost:3101/ws/v1/recognize')
|
|
213
|
+
.asrRequestConfig({
|
|
214
|
+
provider: RecognitionProvider.DEEPGRAM,
|
|
215
|
+
model: 'nova-2-general',
|
|
216
|
+
language: 'en-US',
|
|
217
|
+
sampleRate: 16000,
|
|
218
|
+
encoding: 'linear16'
|
|
219
|
+
})
|
|
220
|
+
.gameContext({
|
|
221
|
+
type: RecognitionContextTypeV1.GAME_CONTEXT as const,
|
|
222
|
+
gameId: 'test-game',
|
|
223
|
+
gamePhase: 'test-phase'
|
|
224
|
+
})
|
|
225
|
+
.audioUtteranceId('test-utterance-id')
|
|
226
|
+
.userId('user-123')
|
|
227
|
+
.gameSessionId('session-456')
|
|
228
|
+
.deviceId('device-789')
|
|
229
|
+
.accountId('account-abc')
|
|
230
|
+
.questionAnswerId('qa-xyz')
|
|
231
|
+
.platform('ios')
|
|
232
|
+
.onTranscript(onTranscript)
|
|
233
|
+
.onError(onError)
|
|
234
|
+
.onConnected(onConnected)
|
|
235
|
+
.onDisconnected(onDisconnected)
|
|
236
|
+
.highWaterMark(1000)
|
|
237
|
+
.lowWaterMark(500)
|
|
238
|
+
.maxBufferDurationSec(10)
|
|
239
|
+
.chunksPerSecond(50)
|
|
240
|
+
.logger(logger)
|
|
241
|
+
.build();
|
|
242
|
+
|
|
243
|
+
expect(config).toMatchObject({
|
|
244
|
+
url: 'ws://localhost:3101/ws/v1/recognize',
|
|
245
|
+
audioUtteranceId: 'test-utterance-id',
|
|
246
|
+
userId: 'user-123',
|
|
247
|
+
gameSessionId: 'session-456',
|
|
248
|
+
deviceId: 'device-789',
|
|
249
|
+
accountId: 'account-abc',
|
|
250
|
+
questionAnswerId: 'qa-xyz',
|
|
251
|
+
platform: 'ios',
|
|
252
|
+
highWaterMark: 1000,
|
|
253
|
+
lowWaterMark: 500,
|
|
254
|
+
maxBufferDurationSec: 10,
|
|
255
|
+
chunksPerSecond: 50
|
|
256
|
+
});
|
|
257
|
+
expect(config.asrRequestConfig?.provider).toBe(RecognitionProvider.DEEPGRAM);
|
|
258
|
+
expect(config.gameContext?.gameId).toBe('test-game');
|
|
259
|
+
expect(config.onTranscript).toBe(onTranscript);
|
|
260
|
+
expect(config.onError).toBe(onError);
|
|
261
|
+
expect(config.onConnected).toBe(onConnected);
|
|
262
|
+
expect(config.onDisconnected).toBe(onDisconnected);
|
|
263
|
+
expect(config.logger).toBe(logger);
|
|
264
|
+
});
|
|
265
|
+
});
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for Factory functions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { createClient, createClientWithBuilder } from './factory.js';
|
|
6
|
+
import { ConfigBuilder } from './config-builder.js';
|
|
7
|
+
import { RecognitionProvider, RecognitionContextTypeV1 } from '@recog/shared-types';
|
|
8
|
+
|
|
9
|
+
// Mock the RealTimeTwoWayWebSocketRecognitionClient
|
|
10
|
+
jest.mock('./recognition-client.js', () => ({
|
|
11
|
+
RealTimeTwoWayWebSocketRecognitionClient: jest.fn().mockImplementation((config) => ({
|
|
12
|
+
config,
|
|
13
|
+
connect: jest.fn(),
|
|
14
|
+
disconnect: jest.fn(),
|
|
15
|
+
sendAudio: jest.fn(),
|
|
16
|
+
startRecognition: jest.fn(),
|
|
17
|
+
stopRecognition: jest.fn()
|
|
18
|
+
}))
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
describe('Factory Functions', () => {
|
|
22
|
+
describe('createClient', () => {
|
|
23
|
+
it('should create client with config object', () => {
|
|
24
|
+
const config = {
|
|
25
|
+
url: 'ws://localhost:3101/ws/v1/recognize',
|
|
26
|
+
audioUtteranceId: 'test-id',
|
|
27
|
+
asrRequestConfig: {
|
|
28
|
+
provider: RecognitionProvider.DEEPGRAM,
|
|
29
|
+
model: 'nova-2-general',
|
|
30
|
+
language: 'en-US',
|
|
31
|
+
sampleRate: 16000,
|
|
32
|
+
encoding: 'linear16'
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const client = createClient(config);
|
|
37
|
+
expect(client).toBeDefined();
|
|
38
|
+
expect(client.connect).toBeDefined();
|
|
39
|
+
expect(client.sendAudio).toBeDefined();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should create client with minimal config', () => {
|
|
43
|
+
const config = {
|
|
44
|
+
url: 'ws://localhost:3101/ws/v1/recognize',
|
|
45
|
+
audioUtteranceId: 'test-id'
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const client = createClient(config);
|
|
49
|
+
expect(client).toBeDefined();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should create client with callbacks', () => {
|
|
53
|
+
const onTranscript = jest.fn();
|
|
54
|
+
const onError = jest.fn();
|
|
55
|
+
const onConnected = jest.fn();
|
|
56
|
+
|
|
57
|
+
const config = {
|
|
58
|
+
url: 'ws://localhost:3101/ws/v1/recognize',
|
|
59
|
+
audioUtteranceId: 'test-id',
|
|
60
|
+
onTranscript,
|
|
61
|
+
onError,
|
|
62
|
+
onConnected
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const client = createClient(config);
|
|
66
|
+
expect(client).toBeDefined();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('createClientWithBuilder', () => {
|
|
71
|
+
it('should create client using builder pattern', () => {
|
|
72
|
+
const client = createClientWithBuilder((builder) =>
|
|
73
|
+
builder
|
|
74
|
+
.url('ws://localhost:3101/ws/v1/recognize')
|
|
75
|
+
.audioUtteranceId('test-id')
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
expect(client).toBeDefined();
|
|
79
|
+
expect(client.connect).toBeDefined();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should create client with multiple builder methods', () => {
|
|
83
|
+
const onTranscript = jest.fn();
|
|
84
|
+
const onError = jest.fn();
|
|
85
|
+
|
|
86
|
+
const client = createClientWithBuilder((builder) =>
|
|
87
|
+
builder
|
|
88
|
+
.url('ws://localhost:3101/ws/v1/recognize')
|
|
89
|
+
.audioUtteranceId('test-id')
|
|
90
|
+
.userId('user-123')
|
|
91
|
+
.gameSessionId('session-456')
|
|
92
|
+
.onTranscript(onTranscript)
|
|
93
|
+
.onError(onError)
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
expect(client).toBeDefined();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should create client with ASR config via builder', () => {
|
|
100
|
+
const client = createClientWithBuilder((builder) =>
|
|
101
|
+
builder
|
|
102
|
+
.url('ws://localhost:3101/ws/v1/recognize')
|
|
103
|
+
.audioUtteranceId('test-id')
|
|
104
|
+
.asrRequestConfig({
|
|
105
|
+
provider: RecognitionProvider.DEEPGRAM,
|
|
106
|
+
model: 'nova-2-general',
|
|
107
|
+
language: 'en-US',
|
|
108
|
+
sampleRate: 16000,
|
|
109
|
+
encoding: 'linear16'
|
|
110
|
+
})
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
expect(client).toBeDefined();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should create client with game context via builder', () => {
|
|
117
|
+
const client = createClientWithBuilder((builder) =>
|
|
118
|
+
builder
|
|
119
|
+
.url('ws://localhost:3101/ws/v1/recognize')
|
|
120
|
+
.audioUtteranceId('test-id')
|
|
121
|
+
.gameContext({
|
|
122
|
+
type: RecognitionContextTypeV1.GAME_CONTEXT as const,
|
|
123
|
+
gameId: 'test-game',
|
|
124
|
+
gamePhase: 'test-phase'
|
|
125
|
+
})
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
expect(client).toBeDefined();
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should create client with all optional fields via builder', () => {
|
|
132
|
+
const onTranscript = jest.fn();
|
|
133
|
+
const onMetadata = jest.fn();
|
|
134
|
+
const onError = jest.fn();
|
|
135
|
+
const onConnected = jest.fn();
|
|
136
|
+
const onDisconnected = jest.fn();
|
|
137
|
+
const logger = jest.fn();
|
|
138
|
+
|
|
139
|
+
const client = createClientWithBuilder((builder) =>
|
|
140
|
+
builder
|
|
141
|
+
.url('ws://localhost:3101/ws/v1/recognize')
|
|
142
|
+
.audioUtteranceId('test-id')
|
|
143
|
+
.userId('user-123')
|
|
144
|
+
.gameSessionId('session-456')
|
|
145
|
+
.deviceId('device-789')
|
|
146
|
+
.accountId('account-abc')
|
|
147
|
+
.questionAnswerId('qa-xyz')
|
|
148
|
+
.platform('ios')
|
|
149
|
+
.asrRequestConfig({
|
|
150
|
+
provider: RecognitionProvider.DEEPGRAM,
|
|
151
|
+
model: 'nova-2-general',
|
|
152
|
+
language: 'en-US',
|
|
153
|
+
sampleRate: 16000,
|
|
154
|
+
encoding: 'linear16'
|
|
155
|
+
})
|
|
156
|
+
.gameContext({
|
|
157
|
+
type: RecognitionContextTypeV1.GAME_CONTEXT as const,
|
|
158
|
+
gameId: 'test-game',
|
|
159
|
+
gamePhase: 'test-phase'
|
|
160
|
+
})
|
|
161
|
+
.onTranscript(onTranscript)
|
|
162
|
+
.onMetadata(onMetadata)
|
|
163
|
+
.onError(onError)
|
|
164
|
+
.onConnected(onConnected)
|
|
165
|
+
.onDisconnected(onDisconnected)
|
|
166
|
+
.highWaterMark(1000)
|
|
167
|
+
.lowWaterMark(500)
|
|
168
|
+
.maxBufferDurationSec(10)
|
|
169
|
+
.chunksPerSecond(50)
|
|
170
|
+
.logger(logger)
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
expect(client).toBeDefined();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('should accept builder as parameter', () => {
|
|
177
|
+
const builder = new ConfigBuilder();
|
|
178
|
+
const client = createClientWithBuilder((b) => b.url('ws://localhost:3101').audioUtteranceId('test-id'));
|
|
179
|
+
expect(client).toBeDefined();
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe('Factory Function Equivalence', () => {
|
|
184
|
+
it('should produce equivalent clients from config and builder', () => {
|
|
185
|
+
const config = {
|
|
186
|
+
url: 'ws://localhost:3101/ws/v1/recognize',
|
|
187
|
+
audioUtteranceId: 'test-id',
|
|
188
|
+
userId: 'user-123'
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const clientFromConfig = createClient(config);
|
|
192
|
+
const clientFromBuilder = createClientWithBuilder((builder) =>
|
|
193
|
+
builder
|
|
194
|
+
.url('ws://localhost:3101/ws/v1/recognize')
|
|
195
|
+
.audioUtteranceId('test-id')
|
|
196
|
+
.userId('user-123')
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
expect(clientFromConfig).toBeDefined();
|
|
200
|
+
expect(clientFromBuilder).toBeDefined();
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it('should handle empty config gracefully', () => {
|
|
204
|
+
const config = {
|
|
205
|
+
url: 'ws://localhost:3101/ws/v1/recognize',
|
|
206
|
+
audioUtteranceId: 'test-id'
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const client = createClient(config);
|
|
210
|
+
expect(client).toBeDefined();
|
|
211
|
+
expect(typeof client.connect).toBe('function');
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
});
|
|
215
|
+
});
|
package/src/factory.ts
CHANGED
|
@@ -13,9 +13,13 @@ import type { IRecognitionClient, RealTimeTwoWayWebSocketRecognitionClientConfig
|
|
|
13
13
|
* ```typescript
|
|
14
14
|
* const client = createClient({
|
|
15
15
|
* url: 'ws://localhost:3101/ws/v1/recognize',
|
|
16
|
+
* audioUtteranceId: 'unique-id',
|
|
16
17
|
* onTranscript: (result) => console.log(result)
|
|
17
18
|
* });
|
|
18
19
|
* ```
|
|
20
|
+
*
|
|
21
|
+
* @param config - Client configuration
|
|
22
|
+
* @returns Configured recognition client instance
|
|
19
23
|
*/
|
|
20
24
|
export function createClient(config: RealTimeTwoWayWebSocketRecognitionClientConfig): IRecognitionClient {
|
|
21
25
|
return new RealTimeTwoWayWebSocketRecognitionClient(config);
|