@lee-zg/melange 1.2.2 → 1.2.5

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/README.md +257 -256
  2. package/dist/{chunk-YZVCK6VZ.cjs → chunk-AAWWAPSG.cjs} +1425 -2
  3. package/dist/{chunk-3RM45M64.js → chunk-R3BPDZ3R.js} +1388 -3
  4. package/dist/container-B8n-ok8M.d.cts +201 -0
  5. package/dist/container-n8Q2Xa_y.d.ts +201 -0
  6. package/dist/core/index.d.cts +3 -200
  7. package/dist/core/index.d.ts +3 -200
  8. package/dist/generator-CEj5qxFh.d.cts +1752 -0
  9. package/dist/generator-D7ofMxfc.d.ts +1752 -0
  10. package/dist/index.cjs +138 -34
  11. package/dist/index.d.cts +4 -3
  12. package/dist/index.d.ts +4 -3
  13. package/dist/index.js +2 -2
  14. package/dist/plugins/index.cjs +162 -9
  15. package/dist/plugins/index.d.cts +108 -755
  16. package/dist/plugins/index.d.ts +108 -755
  17. package/dist/plugins/index.js +2 -1
  18. package/package.json +143 -135
  19. package/dist/chunk-3RM45M64.js.map +0 -1
  20. package/dist/chunk-7QVYU63E.js.map +0 -1
  21. package/dist/chunk-BEY4UAYF.cjs.map +0 -1
  22. package/dist/chunk-GXFWPL5M.js.map +0 -1
  23. package/dist/chunk-GZBY4BUP.js.map +0 -1
  24. package/dist/chunk-ILNGTDQ4.js.map +0 -1
  25. package/dist/chunk-JLBTZPBY.cjs.map +0 -1
  26. package/dist/chunk-PK6SKIKE.cjs.map +0 -1
  27. package/dist/chunk-UYJUSNDI.cjs.map +0 -1
  28. package/dist/chunk-YZVCK6VZ.cjs.map +0 -1
  29. package/dist/core/index.cjs.map +0 -1
  30. package/dist/core/index.js.map +0 -1
  31. package/dist/fp/index.cjs.map +0 -1
  32. package/dist/fp/index.js.map +0 -1
  33. package/dist/index.cjs.map +0 -1
  34. package/dist/index.js.map +0 -1
  35. package/dist/plugins/index.cjs.map +0 -1
  36. package/dist/plugins/index.js.map +0 -1
  37. package/dist/utils/index.cjs.map +0 -1
  38. package/dist/utils/index.js.map +0 -1
@@ -1,797 +1,150 @@
1
+ import { as as FingerprintCollector, am as FingerprintValue, ao as FingerprintComponentMap, al as FingerprintHashAlgorithm } from '../generator-D7ofMxfc.js';
2
+ export { a1 as AWSSpeechConfig, c as AWSSynthesisAdapter, t as AlibabaAdapter, d as AlibabaSynthesisAdapter, n as AudioUtils, v as AzureAdapter, $ as AzureSpeechConfig, A as AzureSynthesisAdapter, r as BaiduAdapter, B as BaiduSynthesisAdapter, H as BaseSpeechConfig, a5 as CloudAudioFormat, ac as CloudTransportType, a2 as CustomProviderConfig, aw as FINGERPRINT_GENERATOR, av as FINGERPRINT_VERSION, ar as FingerprintCollectorContext, an as FingerprintComponent, ai as FingerprintComponentKey, aj as FingerprintComponentSource, ap as FingerprintConfidence, au as FingerprintGenerator, F as FingerprintGeneratorImpl, at as FingerprintOptions, ak as FingerprintPrivacyMode, aq as FingerprintResult, o as GenericAdapter, G as GenericSynthesisAdapter, u as GoogleAdapter, a0 as GoogleSpeechConfig, b as GoogleSynthesisAdapter, ag as IAdvancedRecognitionConfig, a9 as IAdvancedSynthesisConfig, af as IAudioConfig, ah as ICloudRecognitionAdapter, aa as ICloudSynthesisAdapter, a8 as ICloudVoice, ae as IRecognitionError, ad as IRecognitionResult, a7 as ISynthesisError, a6 as ISynthesisResult, a3 as ProviderConfig, Q as RecognitionConfig, ab as RecognitionEngineMode, W as RecognitionEvent, Y as RecognitionEventHandler, U as RecognitionEventType, Z as RecognitionProvider, P as RecognitionResult, O as RecognitionResultItem, R as RecognitionStatus, E as SpeechError, C as SpeechProviderType, _ as SpeechRecognizer, h as SpeechRecognizerImpl, D as SpeechServiceStatus, N as SpeechSynthesizer, e as SpeechSynthesizerImpl, a as SynthesisAudioUtils, I as SynthesisConfig, a4 as SynthesisEngineMode, K as SynthesisEvent, L as SynthesisEventHandler, J as SynthesisEventType, M as SynthesisProvider, S as SynthesisStatus, q as TencentAdapter, T as TencentSynthesisAdapter, V as VoiceInfo, p as XunfeiAdapter, X as XunfeiSynthesisAdapter, w as createFingerprintGenerator, j as createSpeechRecognizer, f as createSpeechSynthesizer, x as getFingerprint, z as isFingerprintSupported, k as isSpeechRecognitionSupported, i as isSpeechSynthesisSupported, l as listen, m as listenWithTimeout, y as registerFingerprintPlugin, s as speak, g as speakWithCloud } from '../generator-D7ofMxfc.js';
3
+ import '../container-n8Q2Xa_y.js';
4
+ import '../types-BtOUCLB-.js';
5
+
1
6
  /**
2
- * @fileoverview 语音模块类型定义
3
- * @module melange/plugins/speech/types
4
- * @description 语音合成和语音识别的类型定义
5
- */
6
- /**
7
- * 语音服务提供商类型
8
- */
9
- type SpeechProviderType = 'browser' | 'azure' | 'google' | 'aws' | 'custom';
10
- /**
11
- * 语音服务状态
12
- */
13
- type SpeechServiceStatus = 'idle' | 'loading' | 'ready' | 'error';
14
- /**
15
- * 语音服务错误
16
- */
17
- interface SpeechError {
18
- /** 错误代码 */
19
- code: string;
20
- /** 错误信息 */
21
- message: string;
22
- /** 原始错误对象 */
23
- originalError?: Error;
24
- }
25
- /**
26
- * 语音服务基础配置
27
- */
28
- interface BaseSpeechConfig {
29
- /** 语言代码 (如 'zh-CN', 'en-US') */
30
- lang?: string;
31
- /** 首选提供商 */
32
- preferredProvider?: SpeechProviderType;
33
- /** 是否自动降级 */
34
- autoFallback?: boolean;
35
- /** 降级提供商列表 */
36
- fallbackProviders?: SpeechProviderType[];
37
- }
38
- /**
39
- * 语音信息
40
- */
41
- interface VoiceInfo {
42
- /** 语音唯一标识 */
43
- id: string;
44
- /** 语音名称 */
45
- name: string;
46
- /** 语言代码 */
47
- lang: string;
48
- /** 是否为本地语音 */
49
- localService: boolean;
50
- /** 是否为默认语音 */
51
- default: boolean;
52
- /** 提供商类型 */
53
- provider: SpeechProviderType;
54
- }
55
- /**
56
- * 语音合成配置
57
- */
58
- interface SynthesisConfig extends BaseSpeechConfig {
59
- /** 语音对象或语音名称 */
60
- voice?: VoiceInfo | string;
61
- /** 音量 (0-1) */
62
- volume?: number;
63
- /** 语速 (0.1-10) */
64
- rate?: number;
65
- /** 音调 (0-2) */
66
- pitch?: number;
67
- }
68
- /**
69
- * 语音合成事件类型
70
- */
71
- type SynthesisEventType = 'start' | 'end' | 'pause' | 'resume' | 'boundary' | 'mark' | 'error';
72
- /**
73
- * 语音合成事件数据
74
- */
75
- interface SynthesisEvent {
76
- /** 事件类型 */
77
- type: SynthesisEventType;
78
- /** 当前字符索引 */
79
- charIndex?: number;
80
- /** 当前字符长度 */
81
- charLength?: number;
82
- /** 经过的时间(毫秒) */
83
- elapsedTime?: number;
84
- /** 边界名称 */
85
- name?: string;
86
- /** 错误信息 */
87
- error?: SpeechError;
88
- }
89
- /**
90
- * 语音合成事件处理器
91
- */
92
- type SynthesisEventHandler = (event: SynthesisEvent) => void;
93
- /**
94
- * 语音合成提供商接口
95
- */
96
- interface SynthesisProvider {
97
- /** 提供商类型 */
98
- readonly type: SpeechProviderType;
99
- /** 检查是否可用 */
100
- isAvailable(): boolean;
101
- /** 获取可用语音列表 */
102
- getVoices(): Promise<VoiceInfo[]>;
103
- /** 朗读文本 */
104
- speak(text: string, config?: SynthesisConfig): Promise<void>;
105
- /** 暂停 */
106
- pause(): void;
107
- /** 继续 */
108
- resume(): void;
109
- /** 取消 */
110
- cancel(): void;
111
- /** 是否正在朗读 */
112
- isSpeaking(): boolean;
113
- /** 是否已暂停 */
114
- isPaused(): boolean;
115
- /** 添加事件监听 */
116
- on(event: SynthesisEventType, handler: SynthesisEventHandler): void;
117
- /** 移除事件监听 */
118
- off(event: SynthesisEventType, handler: SynthesisEventHandler): void;
119
- }
120
- /**
121
- * 语音合成器接口
122
- */
123
- interface SpeechSynthesizer {
124
- /** 当前使用的提供商 */
125
- readonly currentProvider: SpeechProviderType;
126
- /** 服务状态 */
127
- readonly status: SpeechServiceStatus;
128
- /** 初始化 */
129
- initialize(config?: SynthesisConfig): Promise<void>;
130
- /** 获取可用语音列表 */
131
- getVoices(): Promise<VoiceInfo[]>;
132
- /** 朗读文本 */
133
- speak(text: string, config?: SynthesisConfig): Promise<void>;
134
- /** 暂停 */
135
- pause(): void;
136
- /** 继续 */
137
- resume(): void;
138
- /** 取消 */
139
- cancel(): void;
140
- /** 是否正在朗读 */
141
- isSpeaking(): boolean;
142
- /** 是否已暂停 */
143
- isPaused(): boolean;
144
- /** 添加事件监听 */
145
- on(event: SynthesisEventType, handler: SynthesisEventHandler): void;
146
- /** 移除事件监听 */
147
- off(event: SynthesisEventType, handler: SynthesisEventHandler): void;
148
- /** 销毁实例 */
149
- dispose(): void;
150
- }
151
- /**
152
- * 识别结果项
153
- */
154
- interface RecognitionResultItem {
155
- /** 识别的文本 */
156
- transcript: string;
157
- /** 置信度 (0-1) */
158
- confidence: number;
159
- /** 是否为最终结果 */
160
- isFinal: boolean;
161
- }
162
- /**
163
- * 识别结果
164
- */
165
- interface RecognitionResult {
166
- /** 结果列表 */
167
- results: RecognitionResultItem[];
168
- /** 最佳结果 */
169
- bestTranscript: string;
170
- /** 最佳置信度 */
171
- bestConfidence: number;
172
- /** 是否为最终结果 */
173
- isFinal: boolean;
174
- }
175
- /**
176
- * 语音识别配置
177
- */
178
- interface RecognitionConfig extends BaseSpeechConfig {
179
- /** 是否连续识别 */
180
- continuous?: boolean;
181
- /** 是否返回中间结果 */
182
- interimResults?: boolean;
183
- /** 最大备选结果数 */
184
- maxAlternatives?: number;
185
- /** 语法列表 (仅部分浏览器支持) */
186
- grammars?: string[];
187
- }
188
- /**
189
- * 语音识别事件类型
190
- */
191
- type RecognitionEventType = 'start' | 'end' | 'result' | 'error' | 'soundstart' | 'soundend' | 'speechstart' | 'speechend' | 'audiostart' | 'audioend' | 'nomatch';
192
- /**
193
- * 语音识别事件数据
194
- */
195
- interface RecognitionEvent {
196
- /** 事件类型 */
197
- type: RecognitionEventType;
198
- /** 识别结果 (仅 result 事件) */
199
- result?: RecognitionResult;
200
- /** 错误信息 (仅 error 事件) */
201
- error?: SpeechError;
202
- }
203
- /**
204
- * 语音识别事件处理器
205
- */
206
- type RecognitionEventHandler = (event: RecognitionEvent) => void;
207
- /**
208
- * 语音识别提供商接口
209
- */
210
- interface RecognitionProvider {
211
- /** 提供商类型 */
212
- readonly type: SpeechProviderType;
213
- /** 检查是否可用 */
214
- isAvailable(): boolean;
215
- /** 开始识别 */
216
- start(config?: RecognitionConfig): Promise<void>;
217
- /** 停止识别 */
218
- stop(): void;
219
- /** 中止识别 */
220
- abort(): void;
221
- /** 是否正在识别 */
222
- isListening(): boolean;
223
- /** 添加事件监听 */
224
- on(event: RecognitionEventType, handler: RecognitionEventHandler): void;
225
- /** 移除事件监听 */
226
- off(event: RecognitionEventType, handler: RecognitionEventHandler): void;
227
- }
228
- /**
229
- * 语音识别器接口
230
- */
231
- interface SpeechRecognizer {
232
- /** 当前使用的提供商 */
233
- readonly currentProvider: SpeechProviderType;
234
- /** 服务状态 */
235
- readonly status: SpeechServiceStatus;
236
- /** 初始化 */
237
- initialize(config?: RecognitionConfig): Promise<void>;
238
- /** 开始识别 */
239
- start(config?: RecognitionConfig): Promise<void>;
240
- /** 停止识别 */
241
- stop(): void;
242
- /** 中止识别 */
243
- abort(): void;
244
- /** 是否正在识别 */
245
- isListening(): boolean;
246
- /** 添加事件监听 */
247
- on(event: RecognitionEventType, handler: RecognitionEventHandler): void;
248
- /** 移除事件监听 */
249
- off(event: RecognitionEventType, handler: RecognitionEventHandler): void;
250
- /** 销毁实例 */
251
- dispose(): void;
252
- }
253
- /**
254
- * Azure 语音服务配置
255
- */
256
- interface AzureSpeechConfig {
257
- /** 订阅密钥 */
258
- subscriptionKey: string;
259
- /** 服务区域 */
260
- region: string;
261
- /** 自定义端点 */
262
- endpoint?: string;
263
- }
264
- /**
265
- * Google Cloud Speech 配置
266
- */
267
- interface GoogleSpeechConfig {
268
- /** API 密钥 */
269
- apiKey: string;
270
- /** 项目 ID */
271
- projectId?: string;
272
- }
273
- /**
274
- * AWS Polly/Transcribe 配置
275
- */
276
- interface AWSSpeechConfig {
277
- /** 访问密钥 ID */
278
- accessKeyId: string;
279
- /** 秘密访问密钥 */
280
- secretAccessKey: string;
281
- /** 区域 */
282
- region: string;
283
- }
284
- /**
285
- * 自定义提供商配置
286
- */
287
- interface CustomProviderConfig {
288
- /** 合成 API 端点 */
289
- synthesisEndpoint?: string;
290
- /** 识别 API 端点 */
291
- recognitionEndpoint?: string;
292
- /** 自定义请求头 */
293
- headers?: Record<string, string>;
294
- /** 认证令牌 */
295
- authToken?: string;
296
- }
297
- /**
298
- * 提供商配置联合类型
7
+ * @fileoverview 指纹识别模块内置采集器
8
+ * @module melange/plugins/fingerprint/collectors
9
+ * @description
10
+ * 提供默认的低敏浏览器/设备环境采集器。采集器只读取同步可得的环境信息,
11
+ * 不触发权限弹窗,不渲染 Canvas/WebGL,不枚举字体或插件,也不写入持久化存储。
299
12
  */
300
- type ProviderConfig = AzureSpeechConfig | GoogleSpeechConfig | AWSSpeechConfig | CustomProviderConfig;
301
13
 
302
14
  /**
303
- * @fileoverview 语音合成 (TTS) 实现 - 商业级版本 v2.0
304
- * @module melange/plugins/speech/synthesis
305
- * @description 生产级 Web 语音合成插件
15
+ * 内置低敏指纹组件采集器。
306
16
  *
307
- * 架构:
308
- * [UI层] -> [SpeechSynthesizerImpl] -> [NativeStrategy / CloudStrategy]
309
- * |
310
- * +-> [音频核心]: AudioContext, 流式播放
311
- * +-> [适配器]: AzureAdapter, GoogleAdapter, TencentAdapter...
17
+ * @description
18
+ * 采集器按数组顺序注册,但最终哈希输入会按组件键排序,因此顺序不会影响
19
+ * `visitorId`。每个采集器都提供 `confidence`,用于最终置信度估算。
312
20
  *
313
- * 功能特性:
314
- * 1. 多模式: 支持原生 Web Speech API & 云端 TTS 服务
315
- * 2. 状态机: IDLE -> LOADING -> SPEAKING -> PAUSED
316
- * 3. 插件化: 内置 Azure/Google/AWS/讯飞/腾讯/百度/阿里 适配器
317
- * 4. 核心: AudioContext 流式播放 + 音频队列管理
318
- * 5. 兼容性: 多浏览器支持 + 自动降级处理
21
+ * @remarks
22
+ * 这里刻意不包含 Canvas、音频、WebGL 渲染、字体探测、浏览器插件枚举等
23
+ * 高熵或更易引发隐私争议的采集方式。
319
24
  */
25
+ declare const defaultFingerprintCollectors: readonly FingerprintCollector[];
320
26
 
321
27
  /**
322
- * 合成器状态枚举
323
- */
324
- declare enum SynthesisStatus {
325
- /** 空闲状态 */
326
- IDLE = "IDLE",
327
- /** 加载中(获取语音/准备中) */
328
- LOADING = "LOADING",
329
- /** 正在播放 */
330
- SPEAKING = "SPEAKING",
331
- /** 已暂停 */
332
- PAUSED = "PAUSED"
333
- }
334
- /**
335
- * 合成引擎模式
28
+ * @fileoverview 指纹识别模块工具函数
29
+ * @module melange/plugins/fingerprint/utils
30
+ * @description
31
+ * 提供稳定序列化、哈希计算和隐私友好的归一化工具。
32
+ * 这些工具是生成 `visitorId` 的底层能力,也可以被业务侧复用来测试
33
+ * 自定义组件的稳定性。
336
34
  */
337
- type SynthesisEngineMode = 'native' | 'cloud' | 'auto';
338
- /**
339
- * 云端 TTS 音频格式
340
- */
341
- type CloudAudioFormat = 'mp3' | 'wav' | 'ogg' | 'pcm';
342
- /**
343
- * 云端合成结果接口
344
- */
345
- interface ISynthesisResult {
346
- /** 音频数据 */
347
- audioData: ArrayBuffer;
348
- /** 音频格式 */
349
- format: CloudAudioFormat;
350
- /** 音频时长 (ms) */
351
- duration?: number;
352
- /** 原始响应数据 */
353
- original?: unknown;
354
- }
355
- /**
356
- * 云端语音信息
357
- */
358
- interface ICloudVoice {
359
- /** 语音 ID */
360
- id: string;
361
- /** 语音名称 */
362
- name: string;
363
- /** 语言代码 */
364
- lang: string;
365
- /** 性别 */
366
- gender?: 'male' | 'female' | 'neutral';
367
- /** 提供商名称 */
368
- provider: string;
369
- }
370
- /**
371
- * 高级合成配置
372
- */
373
- interface IAdvancedSynthesisConfig extends SynthesisConfig {
374
- /** 合成引擎模式 */
375
- mode?: SynthesisEngineMode;
376
- /** 云端适配器 */
377
- cloudAdapter?: ICloudSynthesisAdapter;
378
- /** 音频格式偏好 */
379
- audioFormat?: CloudAudioFormat;
380
- /** 是否启用 SSML */
381
- enableSSML?: boolean;
382
- /** 是否预加载音频 */
383
- preload?: boolean;
384
- /** 音频缓存大小 */
385
- cacheSize?: number;
386
- }
387
- /**
388
- * 云端合成适配器接口
389
- * 提供统一的第三方语音合成服务集成接口
390
- */
391
- interface ICloudSynthesisAdapter {
392
- /** 适配器名称 */
393
- readonly name: string;
394
- /**
395
- * 合成语音
396
- * @param text 要合成的文本
397
- * @param config 合成配置
398
- * @returns 合成结果(音频数据)
399
- */
400
- synthesize(text: string, config?: IAdvancedSynthesisConfig): Promise<ISynthesisResult>;
401
- /**
402
- * 获取可用语音列表
403
- * @returns 语音列表
404
- */
405
- getVoices?(): Promise<ICloudVoice[]>;
406
- /**
407
- * 检查适配器是否可用
408
- * @returns 是否可用
409
- */
410
- isAvailable?(): boolean;
411
- }
412
- /**
413
- * 语音合成器实现
414
- * 统一封装原生合成和云端合成
415
- */
416
- declare class SpeechSynthesizerImpl implements SpeechSynthesizer {
417
- private strategy;
418
- private config;
419
- private _currentProvider;
420
- private _status;
421
- private eventHandlers;
422
- private customProviders;
423
- get currentProvider(): SpeechProviderType;
424
- get status(): SpeechServiceStatus;
425
- /**
426
- * 获取当前合成状态
427
- */
428
- get synthesisStatus(): SynthesisStatus;
429
- /**
430
- * 初始化语音合成器
431
- */
432
- initialize(config?: SynthesisConfig): Promise<void>;
433
- /**
434
- * 初始化合成策略
435
- */
436
- private initializeStrategy;
437
- /**
438
- * 转发策略事件
439
- */
440
- private forwardStrategyEvents;
441
- /**
442
- * 获取可用语音列表
443
- */
444
- getVoices(): Promise<VoiceInfo[]>;
445
- /**
446
- * 朗读文本
447
- */
448
- speak(text: string, config?: SynthesisConfig): Promise<void>;
449
- /**
450
- * 暂停朗读
451
- */
452
- pause(): void;
453
- /**
454
- * 继续朗读
455
- */
456
- resume(): void;
457
- /**
458
- * 取消朗读
459
- */
460
- cancel(): void;
461
- /**
462
- * 是否正在朗读
463
- */
464
- isSpeaking(): boolean;
465
- /**
466
- * 是否已暂停
467
- */
468
- isPaused(): boolean;
469
- /**
470
- * 添加事件监听
471
- */
472
- on(event: SynthesisEventType, handler: SynthesisEventHandler): void;
473
- /**
474
- * 移除事件监听
475
- */
476
- off(event: SynthesisEventType, handler: SynthesisEventHandler): void;
477
- /**
478
- * 触发事件
479
- */
480
- private emit;
481
- /**
482
- * 销毁实例
483
- */
484
- dispose(): void;
485
- /**
486
- * 注册自定义提供商
487
- */
488
- registerProvider(type: SpeechProviderType, provider: SynthesisProvider): void;
489
- /**
490
- * 使用云端适配器
491
- */
492
- useCloudAdapter(adapter: ICloudSynthesisAdapter): void;
493
- }
35
+
494
36
  /**
495
- * 创建语音合成器实例
496
- * @param config - 可选的合成配置
497
- * @returns 语音合成器实例
37
+ * 稳定序列化指纹值,保证对象键顺序不影响哈希。
38
+ *
39
+ * @description
40
+ * JavaScript 对象的键顺序可能受构造顺序影响。为了让相同组件值在不同
41
+ * 采集顺序下得到相同哈希,本函数会递归排序对象键,再生成 JSON 兼容字符串。
498
42
  *
499
43
  * @example
500
44
  * ```typescript
501
- * // 使用原生合成
502
- * const synthesizer = await createSpeechSynthesizer({
503
- * lang: 'zh-CN',
504
- * rate: 1.0,
505
- * });
506
- *
507
- * // 使用云端合成 (Azure)
508
- * const azureAdapter = new AzureSynthesisAdapter('key', 'eastasia');
509
- * const cloudSynthesizer = await createSpeechSynthesizer({
510
- * mode: 'cloud',
511
- * cloudAdapter: azureAdapter,
512
- * });
513
- *
514
- * await synthesizer.speak('你好,世界!');
45
+ * stableStringify({ b: 2, a: 1 }) === stableStringify({ a: 1, b: 2 });
515
46
  * ```
47
+ *
48
+ * @param value - 要序列化的值
49
+ * @returns 稳定 JSON 字符串
516
50
  */
517
- declare function createSpeechSynthesizer(config?: SynthesisConfig | IAdvancedSynthesisConfig): Promise<SpeechSynthesizer>;
518
- /**
519
- * 检查当前环境是否支持语音合成
520
- * @returns 是否支持语音合成
521
- */
522
- declare function isSpeechSynthesisSupported(): boolean;
51
+ declare function stableStringify(value: FingerprintValue): string;
523
52
  /**
524
- * 快速朗读文本(一次性使用)
525
- * @param text - 要朗读的文本
526
- * @param config - 可选的合成配置
53
+ * 将组件集合转换为稳定的哈希输入。
527
54
  *
528
- * @example
529
- * ```typescript
530
- * // 快速朗读
531
- * await speak('你好,世界!');
55
+ * @description
56
+ * 仅组件的 `value` 会参与哈希计算,`duration`、`source` 和 `confidence`
57
+ * 只用于调试和置信度说明。组件键会先排序,避免对象插入顺序影响输出。
532
58
  *
533
- * // 带配置的朗读
534
- * await speak('Hello World', { lang: 'en-US', rate: 0.8 });
535
- * ```
59
+ * @param components - 指纹组件集合
60
+ * @param salt - 命名空间盐值,用于隔离不同业务域或用途
61
+ * @returns 稳定的哈希输入字符串
536
62
  */
537
- declare function speak(text: string, config?: SynthesisConfig | IAdvancedSynthesisConfig): Promise<void>;
538
-
63
+ declare function serializeComponents(components: FingerprintComponentMap, salt: string): string;
539
64
  /**
540
- * @fileoverview 语音识别 (STT) 实现 - 商业级版本 v2.0
541
- * @module melange/plugins/speech/recognition
542
- * @description 生产级 Web 语音识别插件
65
+ * 计算 FNV-1a 64 位哈希。
543
66
  *
544
- * 架构:
545
- * [UI层] -> [SpeechRecognizerImpl] -> [NativeStrategy / CloudStrategy]
546
- * |
547
- * +-> [音频核心]: Worklet, VAD, Resample
548
- * +-> [适配器]: BaiduAdapter, XunfeiAdapter, TencentAdapter...
67
+ * @description
68
+ * FNV-1a 是非加密哈希,速度快、实现小,适合生成本地稳定标识。
69
+ * 它不具备抗碰撞或安全签名能力,不应作为密码学用途。
549
70
  *
550
- * 功能特性:
551
- * 1. 多模式: 支持 WebSocket 流式识别 & HTTP 短语音识别
552
- * 2. 状态机: IDLE -> CONNECTING -> RECORDING -> PROCESSING
553
- * 3. 插件化: 内置 讯飞/腾讯/百度/阿里/Google/Azure 适配器
554
- * 4. 核心: AudioWorklet + VAD + 自动重采样 + WAV编码
555
- * 5. 兼容性: 自动降级处理 (ScriptProcessor) + 断网缓冲队列
556
- */
557
-
558
- declare global {
559
- interface Window {
560
- SpeechRecognition?: unknown;
561
- webkitSpeechRecognition?: unknown;
562
- webkitAudioContext?: typeof AudioContext;
563
- }
564
- }
565
- /**
566
- * 识别器状态枚举
71
+ * @param input - 输入字符串
72
+ * @returns 16 位十六进制哈希
567
73
  */
568
- declare enum RecognitionStatus {
569
- /** 空闲状态 */
570
- IDLE = "IDLE",
571
- /** 连接中 */
572
- CONNECTING = "CONNECTING",
573
- /** 录音中 */
574
- RECORDING = "RECORDING",
575
- /** 处理中/上传中 */
576
- PROCESSING = "PROCESSING"
577
- }
74
+ declare function fnv1a64(input: string): string;
578
75
  /**
579
- * 识别引擎模式
580
- */
581
- type RecognitionEngineMode = 'native' | 'cloud' | 'auto';
582
- /**
583
- * 云端传输协议类型
584
- */
585
- type CloudTransportType = 'websocket' | 'http';
586
- /**
587
- * 识别结果接口
588
- */
589
- interface IRecognitionResult {
590
- /** 识别文本 */
591
- transcript: string;
592
- /** 是否为最终结果 */
593
- isFinal: boolean;
594
- /** 置信度 (0-1) */
595
- confidence: number;
596
- /** 原始响应数据 */
597
- original?: unknown;
598
- }
599
- /**
600
- * 音频配置接口
601
- */
602
- interface IAudioConfig {
603
- /** 目标采样率 (默认 16000) */
604
- sampleRate?: number;
605
- /** VAD 阈值 (0.01 ~ 0.5) */
606
- vadThreshold?: number;
607
- /** VAD 静音超时 (ms) */
608
- vadDuration?: number;
609
- /** 是否启用回声消除 */
610
- echoCancellation?: boolean;
611
- /** 是否启用噪声抑制 */
612
- noiseSuppression?: boolean;
613
- /** 是否启用自动增益控制 */
614
- autoGainControl?: boolean;
615
- }
616
- /**
617
- * 高级识别配置
76
+ * 计算 SHA-256 哈希。
77
+ *
78
+ * @description
79
+ * 优先使用标准 Web Crypto API。部分非浏览器或旧浏览器环境可能没有
80
+ * `crypto.subtle`,此时返回 `null`,由上层决定是否降级。
81
+ *
82
+ * @param input - 要计算哈希的输入字符串
83
+ * @returns 十六进制哈希;不可用时返回 null
618
84
  */
619
- interface IAdvancedRecognitionConfig extends RecognitionConfig {
620
- /** 识别引擎模式 */
621
- mode?: RecognitionEngineMode;
622
- /** 云端适配器 */
623
- cloudAdapter?: ICloudRecognitionAdapter;
624
- /** 传输协议 */
625
- transport?: CloudTransportType;
626
- /** 音频配置 */
627
- audioConfig?: IAudioConfig;
628
- /** 是否启用自动重连 */
629
- autoReconnect?: boolean;
630
- /** 最大重连次数 */
631
- maxReconnectAttempts?: number;
632
- /** 重连间隔 (ms) */
633
- reconnectInterval?: number;
634
- }
85
+ declare function sha256(input: string): Promise<string | null>;
635
86
  /**
636
- * 云端识别适配器接口
637
- * 提供统一的第三方语音识别服务集成接口
87
+ * 计算指纹哈希。
88
+ *
89
+ * @description
90
+ * 统一封装哈希策略。选择 `sha256` 时,如果当前环境缺少 Web Crypto API,
91
+ * 会自动降级到 `fnv1a64`,保证指纹生成不会因为环境能力不足而失败。
92
+ *
93
+ * @param input - 已稳定序列化的哈希输入
94
+ * @param algorithm - 哈希算法,默认为 `fnv1a64`
95
+ * @returns 指纹哈希
638
96
  */
639
- interface ICloudRecognitionAdapter {
640
- /** 适配器名称 */
641
- readonly name: string;
642
- /**
643
- * 获取 WebSocket 连接地址
644
- * @returns WebSocket URL
645
- */
646
- getConnectUrl?(): Promise<string> | string;
647
- /**
648
- * 获取握手参数
649
- * @returns 握手消息
650
- */
651
- getHandshakeParams?(): unknown;
652
- /**
653
- * HTTP 短语音识别
654
- * @param audioData WAV/PCM 二进制数据
655
- * @returns 识别结果
656
- */
657
- recognizeShortAudio?(audioData: ArrayBuffer): Promise<IRecognitionResult>;
658
- /**
659
- * 转换音频数据格式
660
- * @param pcmData PCM 原始数据
661
- * @returns 转换后的数据
662
- */
663
- transformAudioData?(pcmData: ArrayBuffer): ArrayBuffer | string;
664
- /**
665
- * 解析识别结果
666
- * @param data 原始响应数据
667
- * @returns 识别结果
668
- */
669
- parseResult(data: unknown): IRecognitionResult | null;
670
- /**
671
- * 检查适配器是否可用
672
- * @returns 是否可用
673
- */
674
- isAvailable?(): boolean;
675
- }
97
+ declare function hashString(input: string, algorithm?: FingerprintHashAlgorithm): Promise<string>;
676
98
  /**
677
- * 语音识别器实现
678
- * 统一封装原生识别和云端识别
99
+ * 将数值按指定大小分桶。
100
+ *
101
+ * @description
102
+ * 分桶可以降低精确数值带来的唯一性。例如屏幕高度 1080 在 bucketSize=100
103
+ * 时会归入 1100 桶,从而避免把过细的设备差异直接写入指纹。
104
+ *
105
+ * @param value - 原始数值
106
+ * @param bucketSize - 分桶大小;小于等于 0 时返回原值
107
+ * @returns 分桶后的数值
679
108
  */
680
- declare class SpeechRecognizerImpl implements SpeechRecognizer {
681
- private strategy;
682
- private config;
683
- private _currentProvider;
684
- private _status;
685
- private eventHandlers;
686
- private customProviders;
687
- get currentProvider(): SpeechProviderType;
688
- get status(): SpeechServiceStatus;
689
- /**
690
- * 获取当前识别状态
691
- */
692
- get recognitionStatus(): RecognitionStatus;
693
- /**
694
- * 初始化语音识别器
695
- */
696
- initialize(config?: RecognitionConfig): Promise<void>;
697
- /**
698
- * 初始化识别策略
699
- */
700
- private initializeStrategy;
701
- /**
702
- * 转发策略事件
703
- */
704
- private forwardStrategyEvents;
705
- /**
706
- * 转换识别结果格式
707
- */
708
- private convertResult;
709
- /**
710
- * 开始识别
711
- */
712
- start(config?: RecognitionConfig): Promise<void>;
713
- /**
714
- * 停止识别
715
- */
716
- stop(): void;
717
- /**
718
- * 中止识别
719
- */
720
- abort(): void;
721
- /**
722
- * 是否正在识别
723
- */
724
- isListening(): boolean;
725
- /**
726
- * 添加事件监听
727
- */
728
- on(event: RecognitionEventType, handler: RecognitionEventHandler): void;
729
- /**
730
- * 移除事件监听
731
- */
732
- off(event: RecognitionEventType, handler: RecognitionEventHandler): void;
733
- /**
734
- * 触发事件
735
- */
736
- private emit;
737
- /**
738
- * 销毁实例
739
- */
740
- dispose(): void;
741
- /**
742
- * 注册自定义提供商
743
- */
744
- registerProvider(type: SpeechProviderType, provider: RecognitionProvider): void;
745
- /**
746
- * 使用云端适配器
747
- */
748
- useCloudAdapter(adapter: ICloudRecognitionAdapter): void;
749
- }
109
+ declare function bucketNumber(value: number, bucketSize: number): number;
750
110
  /**
751
- * 创建语音识别器实例
752
- * @param config 识别配置
753
- * @returns 语音识别器实例
111
+ * 归一化 User-Agent,降低补丁版本和构建号带来的高熵差异。
112
+ *
113
+ * @description
114
+ * User-Agent 中的补丁版本和构建号会频繁变化,也可能提升唯一性。
115
+ * 本函数保留主版本/次版本等粗粒度信息,同时去除常见构建号细节。
754
116
  *
755
117
  * @example
756
118
  * ```typescript
757
- * // 使用原生识别
758
- * const recognizer = await createSpeechRecognizer({
759
- * lang: 'zh-CN',
760
- * continuous: true,
761
- * });
762
- *
763
- * // 使用云端识别 (百度)
764
- * const baiduAdapter = new BaiduAdapter('your-access-token');
765
- * const cloudRecognizer = await createSpeechRecognizer({
766
- * mode: 'cloud',
767
- * cloudAdapter: baiduAdapter,
768
- * transport: 'http',
769
- * });
770
- *
771
- * recognizer.on('result', (event) => {
772
- * console.log('识别结果:', event.result?.bestTranscript);
773
- * });
774
- *
775
- * await recognizer.start();
119
+ * normalizeUserAgent('Chrome/120.0.6099.130');
120
+ * // 'Chrome/120.0'
776
121
  * ```
122
+ *
123
+ * @param userAgent - 原始 User-Agent
124
+ * @returns 归一化后的 User-Agent
777
125
  */
778
- declare function createSpeechRecognizer(config?: RecognitionConfig | IAdvancedRecognitionConfig): Promise<SpeechRecognizer>;
126
+ declare function normalizeUserAgent(userAgent: string): string;
779
127
  /**
780
- * 检查当前环境是否支持语音识别
781
- * @returns 是否支持
128
+ * 将硬件线程数分桶,降低唯一性。
129
+ *
130
+ * @description
131
+ * 浏览器暴露的硬件线程数可能比较稳定,但精确值会增加区分度。
132
+ * balanced 模式下会将常见高线程设备归入 4/8/16 等粗粒度区间。
133
+ *
134
+ * @param value - 原始硬件线程数
135
+ * @returns 分桶后的线程数
782
136
  */
783
- declare function isSpeechRecognitionSupported(): boolean;
137
+ declare function bucketHardwareConcurrency(value: number): number;
784
138
  /**
785
- * 快速进行一次语音识别
786
- * @param config 识别配置
787
- * @returns 识别结果
139
+ * 将设备内存分桶,降低唯一性。
788
140
  *
789
- * @example
790
- * ```typescript
791
- * const result = await listen({ lang: 'zh-CN' });
792
- * console.log('识别结果:', result.bestTranscript);
793
- * ```
141
+ * @description
142
+ * `navigator.deviceMemory` 本身通常已经是粗粒度值,但仍统一归入
143
+ * 1/2/4/8/16 桶,便于跨浏览器表现一致。
144
+ *
145
+ * @param value - 原始设备内存,单位通常为 GB
146
+ * @returns 分桶后的设备内存
794
147
  */
795
- declare function listen(config?: RecognitionConfig | IAdvancedRecognitionConfig): Promise<RecognitionResult>;
148
+ declare function bucketDeviceMemory(value: number): number;
796
149
 
797
- export { type AWSSpeechConfig, type AzureSpeechConfig, type BaseSpeechConfig, type CustomProviderConfig, type GoogleSpeechConfig, type ProviderConfig, type RecognitionConfig, type RecognitionEvent, type RecognitionEventHandler, type RecognitionEventType, type RecognitionProvider, type RecognitionResult, type RecognitionResultItem, type SpeechError, type SpeechProviderType, type SpeechRecognizer, SpeechRecognizerImpl, type SpeechServiceStatus, type SpeechSynthesizer, SpeechSynthesizerImpl, type SynthesisConfig, type SynthesisEvent, type SynthesisEventHandler, type SynthesisEventType, type SynthesisProvider, type VoiceInfo, createSpeechRecognizer, createSpeechSynthesizer, isSpeechRecognitionSupported, isSpeechSynthesisSupported, listen, speak };
150
+ export { FingerprintCollector, FingerprintComponentMap, FingerprintHashAlgorithm, FingerprintValue, bucketDeviceMemory, bucketHardwareConcurrency, bucketNumber, defaultFingerprintCollectors, fnv1a64, hashString, normalizeUserAgent, serializeComponents, sha256, stableStringify };