@lee-zg/melange 1.0.0 → 1.2.2

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 (40) hide show
  1. package/README.md +14 -14
  2. package/dist/chunk-3RM45M64.js +1637 -0
  3. package/dist/chunk-3RM45M64.js.map +1 -0
  4. package/dist/{chunk-Q7XG6YN6.cjs → chunk-BEY4UAYF.cjs} +3 -5
  5. package/dist/chunk-BEY4UAYF.cjs.map +1 -0
  6. package/dist/{chunk-ALBD5XC5.js → chunk-GXFWPL5M.js} +4 -8
  7. package/dist/chunk-GXFWPL5M.js.map +1 -0
  8. package/dist/{chunk-352XNR3C.js → chunk-GZBY4BUP.js} +7 -24
  9. package/dist/chunk-GZBY4BUP.js.map +1 -0
  10. package/dist/{chunk-2PXWQDZC.js → chunk-ILNGTDQ4.js} +3 -5
  11. package/dist/chunk-ILNGTDQ4.js.map +1 -0
  12. package/dist/{chunk-Q73NOVWX.cjs → chunk-JLBTZPBY.cjs} +7 -24
  13. package/dist/chunk-JLBTZPBY.cjs.map +1 -0
  14. package/dist/{chunk-ZT6HVG4G.cjs → chunk-UYJUSNDI.cjs} +4 -8
  15. package/dist/chunk-UYJUSNDI.cjs.map +1 -0
  16. package/dist/chunk-YZVCK6VZ.cjs +1646 -0
  17. package/dist/chunk-YZVCK6VZ.cjs.map +1 -0
  18. package/dist/core/index.cjs +23 -23
  19. package/dist/core/index.js +1 -1
  20. package/dist/fp/index.cjs +45 -45
  21. package/dist/fp/index.js +1 -1
  22. package/dist/index.cjs +147 -147
  23. package/dist/index.js +4 -4
  24. package/dist/plugins/index.cjs +9 -9
  25. package/dist/plugins/index.d.cts +287 -133
  26. package/dist/plugins/index.d.ts +287 -133
  27. package/dist/plugins/index.js +1 -1
  28. package/dist/utils/index.cjs +73 -73
  29. package/dist/utils/index.js +1 -1
  30. package/package.json +5 -2
  31. package/dist/chunk-2PXWQDZC.js.map +0 -1
  32. package/dist/chunk-352XNR3C.js.map +0 -1
  33. package/dist/chunk-ALBD5XC5.js.map +0 -1
  34. package/dist/chunk-O7K662J5.cjs +0 -842
  35. package/dist/chunk-O7K662J5.cjs.map +0 -1
  36. package/dist/chunk-Q73NOVWX.cjs.map +0 -1
  37. package/dist/chunk-Q7XG6YN6.cjs.map +0 -1
  38. package/dist/chunk-YGMBCZJQ.js +0 -833
  39. package/dist/chunk-YGMBCZJQ.js.map +0 -1
  40. package/dist/chunk-ZT6HVG4G.cjs.map +0 -1
@@ -1,833 +0,0 @@
1
- import { __name } from './chunk-7QVYU63E.js';
2
-
3
- // src/plugins/speech/synthesis.ts
4
- var BrowserSynthesisProvider = class {
5
- static {
6
- __name(this, "BrowserSynthesisProvider");
7
- }
8
- type = "browser";
9
- synthesis = null;
10
- eventHandlers = /* @__PURE__ */ new Map();
11
- voicesLoaded = false;
12
- voicesPromise = null;
13
- constructor() {
14
- if (this.isAvailable()) {
15
- this.synthesis = window.speechSynthesis;
16
- }
17
- }
18
- /**
19
- * 检查浏览器是否支持语音合成
20
- */
21
- isAvailable() {
22
- return typeof window !== "undefined" && "speechSynthesis" in window;
23
- }
24
- /**
25
- * 获取可用语音列表
26
- */
27
- async getVoices() {
28
- if (!this.synthesis) {
29
- return [];
30
- }
31
- if (this.voicesPromise) {
32
- return this.voicesPromise;
33
- }
34
- this.voicesPromise = new Promise((resolve) => {
35
- const loadVoices = /* @__PURE__ */ __name(() => {
36
- const voices = this.synthesis.getVoices();
37
- if (voices.length > 0) {
38
- this.voicesLoaded = true;
39
- resolve(
40
- voices.map((voice) => ({
41
- id: voice.voiceURI,
42
- name: voice.name,
43
- lang: voice.lang,
44
- localService: voice.localService,
45
- default: voice.default,
46
- provider: "browser"
47
- }))
48
- );
49
- }
50
- }, "loadVoices");
51
- loadVoices();
52
- if (!this.voicesLoaded) {
53
- this.synthesis.addEventListener("voiceschanged", loadVoices, { once: true });
54
- setTimeout(() => {
55
- if (!this.voicesLoaded) {
56
- resolve([]);
57
- }
58
- }, 3e3);
59
- }
60
- });
61
- return this.voicesPromise;
62
- }
63
- /**
64
- * 朗读文本
65
- */
66
- async speak(text, config) {
67
- if (!this.synthesis) {
68
- throw this.createError("NOT_AVAILABLE", "\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u8BED\u97F3\u5408\u6210");
69
- }
70
- this.cancel();
71
- return new Promise((resolve, reject) => {
72
- const utterance = new SpeechSynthesisUtterance(text);
73
- if (config) {
74
- if (config.lang) utterance.lang = config.lang;
75
- if (config.volume !== void 0) utterance.volume = config.volume;
76
- if (config.rate !== void 0) utterance.rate = config.rate;
77
- if (config.pitch !== void 0) utterance.pitch = config.pitch;
78
- if (config.voice) {
79
- const voices = this.synthesis.getVoices();
80
- const voiceConfig = config.voice;
81
- const targetVoice = typeof voiceConfig === "string" ? voices.find((v) => v.name === voiceConfig || v.voiceURI === voiceConfig) : voices.find((v) => v.voiceURI === voiceConfig.id);
82
- if (targetVoice) {
83
- utterance.voice = targetVoice;
84
- }
85
- }
86
- }
87
- utterance.onstart = () => {
88
- this.emit("start", { type: "start" });
89
- };
90
- utterance.onend = () => {
91
- this.emit("end", { type: "end" });
92
- resolve();
93
- };
94
- utterance.onpause = () => {
95
- this.emit("pause", { type: "pause" });
96
- };
97
- utterance.onresume = () => {
98
- this.emit("resume", { type: "resume" });
99
- };
100
- utterance.onboundary = (event) => {
101
- this.emit("boundary", {
102
- type: "boundary",
103
- charIndex: event.charIndex,
104
- charLength: event.charLength,
105
- elapsedTime: event.elapsedTime,
106
- name: event.name
107
- });
108
- };
109
- utterance.onmark = (event) => {
110
- this.emit("mark", {
111
- type: "mark",
112
- name: event.name
113
- });
114
- };
115
- utterance.onerror = (event) => {
116
- const error = this.createError(event.error, `\u8BED\u97F3\u5408\u6210\u9519\u8BEF: ${event.error}`);
117
- this.emit("error", { type: "error", error });
118
- reject(error);
119
- };
120
- this.synthesis.speak(utterance);
121
- });
122
- }
123
- /**
124
- * 暂停朗读
125
- */
126
- pause() {
127
- if (this.synthesis && this.isSpeaking()) {
128
- this.synthesis.pause();
129
- }
130
- }
131
- /**
132
- * 继续朗读
133
- */
134
- resume() {
135
- if (this.synthesis && this.isPaused()) {
136
- this.synthesis.resume();
137
- }
138
- }
139
- /**
140
- * 取消朗读
141
- */
142
- cancel() {
143
- if (this.synthesis) {
144
- this.synthesis.cancel();
145
- }
146
- }
147
- /**
148
- * 是否正在朗读
149
- */
150
- isSpeaking() {
151
- return this.synthesis?.speaking ?? false;
152
- }
153
- /**
154
- * 是否已暂停
155
- */
156
- isPaused() {
157
- return this.synthesis?.paused ?? false;
158
- }
159
- /**
160
- * 添加事件监听
161
- */
162
- on(event, handler) {
163
- if (!this.eventHandlers.has(event)) {
164
- this.eventHandlers.set(event, /* @__PURE__ */ new Set());
165
- }
166
- this.eventHandlers.get(event).add(handler);
167
- }
168
- /**
169
- * 移除事件监听
170
- */
171
- off(event, handler) {
172
- this.eventHandlers.get(event)?.delete(handler);
173
- }
174
- /**
175
- * 触发事件
176
- */
177
- emit(type, event) {
178
- this.eventHandlers.get(type)?.forEach((handler) => {
179
- try {
180
- handler(event);
181
- } catch (e) {
182
- console.error("\u8BED\u97F3\u5408\u6210\u4E8B\u4EF6\u5904\u7406\u5668\u9519\u8BEF:", e);
183
- }
184
- });
185
- }
186
- /**
187
- * 创建错误对象
188
- */
189
- createError(code, message, originalError) {
190
- const result = { code, message };
191
- if (originalError) {
192
- result.originalError = originalError;
193
- }
194
- return result;
195
- }
196
- };
197
- var SpeechSynthesizerImpl = class {
198
- static {
199
- __name(this, "SpeechSynthesizerImpl");
200
- }
201
- _currentProvider = "browser";
202
- _status = "idle";
203
- provider = null;
204
- config = {};
205
- eventHandlers = /* @__PURE__ */ new Map();
206
- providers = /* @__PURE__ */ new Map();
207
- /**
208
- * 当前使用的提供商类型
209
- */
210
- get currentProvider() {
211
- return this._currentProvider;
212
- }
213
- /**
214
- * 服务状态
215
- */
216
- get status() {
217
- return this._status;
218
- }
219
- /**
220
- * 初始化语音合成器
221
- * @param config - 合成配置
222
- */
223
- async initialize(config) {
224
- this._status = "loading";
225
- this.config = {
226
- lang: "zh-CN",
227
- preferredProvider: "browser",
228
- autoFallback: true,
229
- fallbackProviders: ["azure", "google", "aws"],
230
- ...config
231
- };
232
- try {
233
- const browserProvider = new BrowserSynthesisProvider();
234
- this.providers.set("browser", browserProvider);
235
- const preferredProvider = this.config.preferredProvider || "browser";
236
- if (await this.tryProvider(preferredProvider)) {
237
- this._status = "ready";
238
- return;
239
- }
240
- if (this.config.autoFallback && this.config.fallbackProviders) {
241
- for (const providerType of this.config.fallbackProviders) {
242
- if (await this.tryProvider(providerType)) {
243
- this._status = "ready";
244
- return;
245
- }
246
- }
247
- }
248
- this._status = "error";
249
- throw new Error("\u6CA1\u6709\u53EF\u7528\u7684\u8BED\u97F3\u5408\u6210\u63D0\u4F9B\u5546");
250
- } catch (error) {
251
- this._status = "error";
252
- throw error;
253
- }
254
- }
255
- /**
256
- * 尝试使用指定提供商
257
- */
258
- async tryProvider(type) {
259
- const provider = this.providers.get(type);
260
- if (provider && provider.isAvailable()) {
261
- this.provider = provider;
262
- this._currentProvider = type;
263
- this.forwardProviderEvents(provider);
264
- return true;
265
- }
266
- return false;
267
- }
268
- /**
269
- * 转发提供商事件到合成器
270
- */
271
- forwardProviderEvents(provider) {
272
- const events = [
273
- "start",
274
- "end",
275
- "pause",
276
- "resume",
277
- "boundary",
278
- "mark",
279
- "error"
280
- ];
281
- events.forEach((event) => {
282
- provider.on(event, (e) => this.emit(event, e));
283
- });
284
- }
285
- /**
286
- * 获取可用语音列表
287
- */
288
- async getVoices() {
289
- if (!this.provider) {
290
- throw new Error("\u8BED\u97F3\u5408\u6210\u5668\u672A\u521D\u59CB\u5316");
291
- }
292
- return this.provider.getVoices();
293
- }
294
- /**
295
- * 朗读文本
296
- * @param text - 要朗读的文本
297
- * @param config - 可选的合成配置
298
- */
299
- async speak(text, config) {
300
- if (!this.provider) {
301
- throw new Error("\u8BED\u97F3\u5408\u6210\u5668\u672A\u521D\u59CB\u5316");
302
- }
303
- const mergedConfig = { ...this.config, ...config };
304
- return this.provider.speak(text, mergedConfig);
305
- }
306
- /**
307
- * 暂停朗读
308
- */
309
- pause() {
310
- this.provider?.pause();
311
- }
312
- /**
313
- * 继续朗读
314
- */
315
- resume() {
316
- this.provider?.resume();
317
- }
318
- /**
319
- * 取消朗读
320
- */
321
- cancel() {
322
- this.provider?.cancel();
323
- }
324
- /**
325
- * 是否正在朗读
326
- */
327
- isSpeaking() {
328
- return this.provider?.isSpeaking() ?? false;
329
- }
330
- /**
331
- * 是否已暂停
332
- */
333
- isPaused() {
334
- return this.provider?.isPaused() ?? false;
335
- }
336
- /**
337
- * 添加事件监听
338
- */
339
- on(event, handler) {
340
- if (!this.eventHandlers.has(event)) {
341
- this.eventHandlers.set(event, /* @__PURE__ */ new Set());
342
- }
343
- this.eventHandlers.get(event).add(handler);
344
- }
345
- /**
346
- * 移除事件监听
347
- */
348
- off(event, handler) {
349
- this.eventHandlers.get(event)?.delete(handler);
350
- }
351
- /**
352
- * 触发事件
353
- */
354
- emit(type, event) {
355
- this.eventHandlers.get(type)?.forEach((handler) => {
356
- try {
357
- handler(event);
358
- } catch (e) {
359
- console.error("\u8BED\u97F3\u5408\u6210\u4E8B\u4EF6\u5904\u7406\u5668\u9519\u8BEF:", e);
360
- }
361
- });
362
- }
363
- /**
364
- * 销毁实例
365
- */
366
- dispose() {
367
- this.cancel();
368
- this.eventHandlers.clear();
369
- this.provider = null;
370
- this._status = "idle";
371
- }
372
- /**
373
- * 注册自定义提供商
374
- * @param type - 提供商类型
375
- * @param provider - 提供商实例
376
- */
377
- registerProvider(type, provider) {
378
- this.providers.set(type, provider);
379
- }
380
- };
381
- async function createSpeechSynthesizer(config) {
382
- const synthesizer = new SpeechSynthesizerImpl();
383
- await synthesizer.initialize(config);
384
- return synthesizer;
385
- }
386
- __name(createSpeechSynthesizer, "createSpeechSynthesizer");
387
- function isSpeechSynthesisSupported() {
388
- return typeof window !== "undefined" && "speechSynthesis" in window;
389
- }
390
- __name(isSpeechSynthesisSupported, "isSpeechSynthesisSupported");
391
- async function speak(text, config) {
392
- if (!isSpeechSynthesisSupported()) {
393
- throw new Error("\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301\u8BED\u97F3\u5408\u6210");
394
- }
395
- const synthesizer = await createSpeechSynthesizer(config);
396
- try {
397
- await synthesizer.speak(text, config);
398
- } finally {
399
- synthesizer.dispose();
400
- }
401
- }
402
- __name(speak, "speak");
403
-
404
- // src/plugins/speech/recognition.ts
405
- function getSpeechRecognitionConstructor() {
406
- if (typeof window === "undefined") {
407
- return null;
408
- }
409
- return window.SpeechRecognition || window.webkitSpeechRecognition || null;
410
- }
411
- __name(getSpeechRecognitionConstructor, "getSpeechRecognitionConstructor");
412
- var BrowserRecognitionProvider = class {
413
- static {
414
- __name(this, "BrowserRecognitionProvider");
415
- }
416
- type = "browser";
417
- recognition = null;
418
- eventHandlers = /* @__PURE__ */ new Map();
419
- _isListening = false;
420
- SpeechRecognitionClass = null;
421
- constructor() {
422
- this.SpeechRecognitionClass = getSpeechRecognitionConstructor();
423
- }
424
- /**
425
- * 检查浏览器是否支持语音识别
426
- */
427
- isAvailable() {
428
- return this.SpeechRecognitionClass !== null;
429
- }
430
- /**
431
- * 开始语音识别
432
- */
433
- async start(config) {
434
- if (!this.SpeechRecognitionClass) {
435
- throw this.createError("NOT_AVAILABLE", "\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u8BED\u97F3\u8BC6\u522B");
436
- }
437
- if (this._isListening) {
438
- this.stop();
439
- }
440
- return new Promise((resolve, reject) => {
441
- this.recognition = new this.SpeechRecognitionClass();
442
- if (config) {
443
- if (config.lang) this.recognition.lang = config.lang;
444
- if (config.continuous !== void 0) this.recognition.continuous = config.continuous;
445
- if (config.interimResults !== void 0) {
446
- this.recognition.interimResults = config.interimResults;
447
- }
448
- if (config.maxAlternatives !== void 0) {
449
- this.recognition.maxAlternatives = config.maxAlternatives;
450
- }
451
- }
452
- this.recognition.onstart = () => {
453
- this._isListening = true;
454
- this.emit("start", { type: "start" });
455
- resolve();
456
- };
457
- this.recognition.onend = () => {
458
- this._isListening = false;
459
- this.emit("end", { type: "end" });
460
- };
461
- this.recognition.onresult = (event) => {
462
- const results = this.convertResults(event.results);
463
- this.emit("result", { type: "result", result: results });
464
- };
465
- this.recognition.onerror = (event) => {
466
- const error = this.createError(event.error, this.getErrorMessage(event.error));
467
- this._isListening = false;
468
- this.emit("error", { type: "error", error });
469
- if (event.error === "not-allowed" || event.error === "no-speech") {
470
- reject(error);
471
- }
472
- };
473
- this.recognition.onsoundstart = () => {
474
- this.emit("soundstart", { type: "soundstart" });
475
- };
476
- this.recognition.onsoundend = () => {
477
- this.emit("soundend", { type: "soundend" });
478
- };
479
- this.recognition.onspeechstart = () => {
480
- this.emit("speechstart", { type: "speechstart" });
481
- };
482
- this.recognition.onspeechend = () => {
483
- this.emit("speechend", { type: "speechend" });
484
- };
485
- this.recognition.onaudiostart = () => {
486
- this.emit("audiostart", { type: "audiostart" });
487
- };
488
- this.recognition.onaudioend = () => {
489
- this.emit("audioend", { type: "audioend" });
490
- };
491
- this.recognition.onnomatch = () => {
492
- this.emit("nomatch", { type: "nomatch" });
493
- };
494
- try {
495
- this.recognition.start();
496
- } catch (e) {
497
- const error = this.createError("START_ERROR", "\u542F\u52A8\u8BED\u97F3\u8BC6\u522B\u5931\u8D25", e);
498
- reject(error);
499
- }
500
- });
501
- }
502
- /**
503
- * 转换识别结果
504
- */
505
- convertResults(results) {
506
- const items = [];
507
- let bestTranscript = "";
508
- let bestConfidence = 0;
509
- let isFinal = false;
510
- for (let i = 0; i < results.length; i++) {
511
- const result = results[i];
512
- if (!result) continue;
513
- isFinal = isFinal || result.isFinal;
514
- for (let j = 0; j < result.length; j++) {
515
- const alternative = result[j];
516
- if (!alternative) continue;
517
- items.push({
518
- transcript: alternative.transcript,
519
- confidence: alternative.confidence,
520
- isFinal: result.isFinal
521
- });
522
- if (alternative.confidence > bestConfidence) {
523
- bestConfidence = alternative.confidence;
524
- bestTranscript = alternative.transcript;
525
- }
526
- }
527
- }
528
- if (bestTranscript === "" && items.length > 0) {
529
- const firstItem = items[0];
530
- if (firstItem) {
531
- bestTranscript = firstItem.transcript;
532
- bestConfidence = firstItem.confidence || 1;
533
- }
534
- }
535
- return {
536
- results: items,
537
- bestTranscript,
538
- bestConfidence,
539
- isFinal
540
- };
541
- }
542
- /**
543
- * 获取错误消息
544
- */
545
- getErrorMessage(errorCode) {
546
- const errorMessages = {
547
- "no-speech": "\u672A\u68C0\u6D4B\u5230\u8BED\u97F3\u8F93\u5165",
548
- "audio-capture": "\u65E0\u6CD5\u8BBF\u95EE\u9EA6\u514B\u98CE",
549
- "not-allowed": "\u9EA6\u514B\u98CE\u6743\u9650\u88AB\u62D2\u7EDD",
550
- network: "\u7F51\u7EDC\u9519\u8BEF",
551
- aborted: "\u8BC6\u522B\u88AB\u4E2D\u6B62",
552
- "language-not-supported": "\u4E0D\u652F\u6301\u7684\u8BED\u8A00",
553
- "service-not-allowed": "\u8BED\u97F3\u670D\u52A1\u4E0D\u53EF\u7528",
554
- "bad-grammar": "\u8BED\u6CD5\u9519\u8BEF"
555
- };
556
- return errorMessages[errorCode] || `\u8BED\u97F3\u8BC6\u522B\u9519\u8BEF: ${errorCode}`;
557
- }
558
- /**
559
- * 停止语音识别
560
- */
561
- stop() {
562
- if (this.recognition && this._isListening) {
563
- this.recognition.stop();
564
- }
565
- }
566
- /**
567
- * 中止语音识别
568
- */
569
- abort() {
570
- if (this.recognition) {
571
- this.recognition.abort();
572
- this._isListening = false;
573
- }
574
- }
575
- /**
576
- * 是否正在监听
577
- */
578
- isListening() {
579
- return this._isListening;
580
- }
581
- /**
582
- * 添加事件监听
583
- */
584
- on(event, handler) {
585
- if (!this.eventHandlers.has(event)) {
586
- this.eventHandlers.set(event, /* @__PURE__ */ new Set());
587
- }
588
- this.eventHandlers.get(event).add(handler);
589
- }
590
- /**
591
- * 移除事件监听
592
- */
593
- off(event, handler) {
594
- this.eventHandlers.get(event)?.delete(handler);
595
- }
596
- /**
597
- * 触发事件
598
- */
599
- emit(type, event) {
600
- this.eventHandlers.get(type)?.forEach((handler) => {
601
- try {
602
- handler(event);
603
- } catch (e) {
604
- console.error("\u8BED\u97F3\u8BC6\u522B\u4E8B\u4EF6\u5904\u7406\u5668\u9519\u8BEF:", e);
605
- }
606
- });
607
- }
608
- /**
609
- * 创建错误对象
610
- */
611
- createError(code, message, originalError) {
612
- const result = { code, message };
613
- if (originalError) {
614
- result.originalError = originalError;
615
- }
616
- return result;
617
- }
618
- };
619
- var SpeechRecognizerImpl = class {
620
- static {
621
- __name(this, "SpeechRecognizerImpl");
622
- }
623
- _currentProvider = "browser";
624
- _status = "idle";
625
- provider = null;
626
- config = {};
627
- eventHandlers = /* @__PURE__ */ new Map();
628
- providers = /* @__PURE__ */ new Map();
629
- /**
630
- * 当前使用的提供商类型
631
- */
632
- get currentProvider() {
633
- return this._currentProvider;
634
- }
635
- /**
636
- * 服务状态
637
- */
638
- get status() {
639
- return this._status;
640
- }
641
- /**
642
- * 初始化语音识别器
643
- * @param config - 识别配置
644
- */
645
- async initialize(config) {
646
- this._status = "loading";
647
- this.config = {
648
- lang: "zh-CN",
649
- continuous: false,
650
- interimResults: true,
651
- maxAlternatives: 1,
652
- preferredProvider: "browser",
653
- autoFallback: true,
654
- fallbackProviders: ["azure", "google", "aws"],
655
- ...config
656
- };
657
- try {
658
- const browserProvider = new BrowserRecognitionProvider();
659
- this.providers.set("browser", browserProvider);
660
- const preferredProvider = this.config.preferredProvider || "browser";
661
- if (await this.tryProvider(preferredProvider)) {
662
- this._status = "ready";
663
- return;
664
- }
665
- if (this.config.autoFallback && this.config.fallbackProviders) {
666
- for (const providerType of this.config.fallbackProviders) {
667
- if (await this.tryProvider(providerType)) {
668
- this._status = "ready";
669
- return;
670
- }
671
- }
672
- }
673
- this._status = "error";
674
- throw new Error("\u6CA1\u6709\u53EF\u7528\u7684\u8BED\u97F3\u8BC6\u522B\u63D0\u4F9B\u5546");
675
- } catch (error) {
676
- this._status = "error";
677
- throw error;
678
- }
679
- }
680
- /**
681
- * 尝试使用指定提供商
682
- */
683
- async tryProvider(type) {
684
- const provider = this.providers.get(type);
685
- if (provider && provider.isAvailable()) {
686
- this.provider = provider;
687
- this._currentProvider = type;
688
- this.forwardProviderEvents(provider);
689
- return true;
690
- }
691
- return false;
692
- }
693
- /**
694
- * 转发提供商事件到识别器
695
- */
696
- forwardProviderEvents(provider) {
697
- const events = [
698
- "start",
699
- "end",
700
- "result",
701
- "error",
702
- "soundstart",
703
- "soundend",
704
- "speechstart",
705
- "speechend",
706
- "audiostart",
707
- "audioend",
708
- "nomatch"
709
- ];
710
- events.forEach((event) => {
711
- provider.on(event, (e) => this.emit(event, e));
712
- });
713
- }
714
- /**
715
- * 开始语音识别
716
- * @param config - 可选的识别配置
717
- */
718
- async start(config) {
719
- if (!this.provider) {
720
- throw new Error("\u8BED\u97F3\u8BC6\u522B\u5668\u672A\u521D\u59CB\u5316");
721
- }
722
- const mergedConfig = { ...this.config, ...config };
723
- return this.provider.start(mergedConfig);
724
- }
725
- /**
726
- * 停止语音识别
727
- */
728
- stop() {
729
- this.provider?.stop();
730
- }
731
- /**
732
- * 中止语音识别
733
- */
734
- abort() {
735
- this.provider?.abort();
736
- }
737
- /**
738
- * 是否正在监听
739
- */
740
- isListening() {
741
- return this.provider?.isListening() ?? false;
742
- }
743
- /**
744
- * 添加事件监听
745
- */
746
- on(event, handler) {
747
- if (!this.eventHandlers.has(event)) {
748
- this.eventHandlers.set(event, /* @__PURE__ */ new Set());
749
- }
750
- this.eventHandlers.get(event).add(handler);
751
- }
752
- /**
753
- * 移除事件监听
754
- */
755
- off(event, handler) {
756
- this.eventHandlers.get(event)?.delete(handler);
757
- }
758
- /**
759
- * 触发事件
760
- */
761
- emit(type, event) {
762
- this.eventHandlers.get(type)?.forEach((handler) => {
763
- try {
764
- handler(event);
765
- } catch (e) {
766
- console.error("\u8BED\u97F3\u8BC6\u522B\u4E8B\u4EF6\u5904\u7406\u5668\u9519\u8BEF:", e);
767
- }
768
- });
769
- }
770
- /**
771
- * 销毁实例
772
- */
773
- dispose() {
774
- this.abort();
775
- this.eventHandlers.clear();
776
- this.provider = null;
777
- this._status = "idle";
778
- }
779
- /**
780
- * 注册自定义提供商
781
- * @param type - 提供商类型
782
- * @param provider - 提供商实例
783
- */
784
- registerProvider(type, provider) {
785
- this.providers.set(type, provider);
786
- }
787
- };
788
- async function createSpeechRecognizer(config) {
789
- const recognizer = new SpeechRecognizerImpl();
790
- await recognizer.initialize(config);
791
- return recognizer;
792
- }
793
- __name(createSpeechRecognizer, "createSpeechRecognizer");
794
- function isSpeechRecognitionSupported() {
795
- return getSpeechRecognitionConstructor() !== null;
796
- }
797
- __name(isSpeechRecognitionSupported, "isSpeechRecognitionSupported");
798
- async function listen(config) {
799
- if (!isSpeechRecognitionSupported()) {
800
- throw new Error("\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301\u8BED\u97F3\u8BC6\u522B");
801
- }
802
- const recognizer = await createSpeechRecognizer({
803
- ...config,
804
- continuous: false
805
- });
806
- return new Promise((resolve, reject) => {
807
- recognizer.on("result", (event) => {
808
- if (event.result && event.result.isFinal) {
809
- recognizer.dispose();
810
- resolve(event.result);
811
- }
812
- });
813
- recognizer.on("error", (event) => {
814
- recognizer.dispose();
815
- reject(event.error);
816
- });
817
- recognizer.on("end", () => {
818
- recognizer.dispose();
819
- resolve({
820
- results: [],
821
- bestTranscript: "",
822
- bestConfidence: 0,
823
- isFinal: true
824
- });
825
- });
826
- recognizer.start().catch(reject);
827
- });
828
- }
829
- __name(listen, "listen");
830
-
831
- export { SpeechRecognizerImpl, SpeechSynthesizerImpl, createSpeechRecognizer, createSpeechSynthesizer, isSpeechRecognitionSupported, isSpeechSynthesisSupported, listen, speak };
832
- //# sourceMappingURL=chunk-YGMBCZJQ.js.map
833
- //# sourceMappingURL=chunk-YGMBCZJQ.js.map