id-scanner-lib 1.7.0 → 2.0.0

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.
@@ -5,251 +5,95 @@
5
5
  })(this, (function (exports, tesseract_js, imageCompression, jsQR) { 'use strict';
6
6
 
7
7
  /**
8
- * @file 配置管理器
9
- * @description 提供全局配置管理功能
8
+ * @file 配置管理器 + Scanner 配置
9
+ * @description 提供全局配置管理功能 + Scanner v2.0 配置接口
10
10
  * @module core/config
11
11
  */
12
- /**
13
- * 配置管理器
14
- * 负责存储和管理应用程序的配置
15
- */
12
+ // ============================================================
13
+ // 原有 ConfigManager(保持向后兼容)
14
+ // ============================================================
16
15
  class ConfigManager {
17
- /**
18
- * 私有构造函数
19
- */
20
16
  constructor() {
21
- /** 配置存储 */
22
17
  this.config = {};
23
- /** 配置变更回调 */
24
18
  this.changeCallbacks = new Map();
25
- /** 初始化状态 */
26
19
  this.initialized = false;
27
- // 设置默认配置
28
20
  this._resetDefaults();
29
21
  }
30
- /**
31
- * 获取单例实例
32
- */
33
22
  static getInstance() {
34
23
  if (!ConfigManager.instance) {
35
24
  ConfigManager.instance = new ConfigManager();
36
25
  }
37
26
  return ConfigManager.instance;
38
27
  }
39
- /**
40
- * 重置单例实例(主要用于测试)
41
- */
42
28
  static resetInstance() {
43
29
  ConfigManager.instance = undefined;
44
30
  }
45
- /**
46
- * 重置为默认配置
47
- */
48
31
  _resetDefaults() {
49
32
  this.config = {
50
33
  debug: false,
51
34
  logLevel: 'info',
52
- camera: {
53
- resolution: {
54
- width: 1280,
55
- height: 720
56
- },
57
- frameRate: 30,
58
- facingMode: 'environment'
35
+ modelPath: '/models',
36
+ maxRetries: 3,
37
+ retryDelay: 1000,
38
+ detectionInterval: 100,
39
+ face: {
40
+ enabled: true,
41
+ confidenceThreshold: 0.5,
42
+ maxFaces: 10,
43
+ },
44
+ idCard: {
45
+ enabled: false,
46
+ },
47
+ qr: {
48
+ enabled: false,
59
49
  },
60
- performance: {
61
- useCache: true
62
- }
63
50
  };
64
51
  this.initialized = true;
65
52
  }
66
- /**
67
- * 获取配置值
68
- * @param key 配置键,支持点号分隔的路径
69
- * @param defaultValue 默认值
70
- */
71
53
  get(key, defaultValue) {
72
- const value = this.getNestedValue(this.config, key);
73
- return (value !== undefined) ? value : defaultValue;
54
+ const keys = key.split('.');
55
+ let value = this.config;
56
+ for (const k of keys) {
57
+ value = value?.[k];
58
+ }
59
+ return (value !== undefined ? value : defaultValue);
74
60
  }
75
- /**
76
- * 设置配置值
77
- * @param key 配置键,支持点号分隔的路径
78
- * @param value 配置值
79
- */
80
61
  set(key, value) {
81
- const oldValue = this.get(key);
82
- // 如果值相同,不做任何事
83
- if (oldValue === value) {
84
- return;
62
+ const keys = key.split('.');
63
+ let target = this.config;
64
+ for (let i = 0; i < keys.length - 1; i++) {
65
+ if (!target[keys[i]])
66
+ target[keys[i]] = {};
67
+ target = target[keys[i]];
68
+ }
69
+ const oldValue = target[keys[keys.length - 1]];
70
+ target[keys[keys.length - 1]] = value;
71
+ const callbacks = this.changeCallbacks.get(key);
72
+ if (callbacks) {
73
+ callbacks.forEach(cb => cb(value, oldValue));
85
74
  }
86
- this.setNestedValue(this.config, key, value);
87
- // 触发变更回调
88
- this.triggerChangeCallbacks(key, value, oldValue);
89
- }
90
- /**
91
- * 批量更新配置
92
- * @param config 配置对象
93
- */
94
- updateConfig(config) {
95
- Object.entries(config).forEach(([key, value]) => {
96
- this.set(key, value);
97
- });
98
- }
99
- /**
100
- * 重置为默认配置
101
- */
102
- reset() {
103
- const oldConfig = { ...this.config };
104
- // 使用私有 reset 方法重建默认配置
105
- this.config = {
106
- debug: false,
107
- logLevel: 'info',
108
- camera: {
109
- resolution: {
110
- width: 1280,
111
- height: 720
112
- },
113
- frameRate: 30,
114
- facingMode: 'environment'
115
- },
116
- performance: {
117
- useCache: true
118
- }
119
- };
120
- // 触发所有回调
121
- Object.keys(oldConfig).forEach(key => {
122
- this.triggerChangeCallbacks(key, this.get(key), oldConfig[key]);
123
- });
124
75
  }
125
- /**
126
- * 注册配置变更回调
127
- * @param key 配置键
128
- * @param callback 回调函数
129
- */
130
- onConfigChange(key, callback) {
76
+ onChange(key, callback) {
131
77
  if (!this.changeCallbacks.has(key)) {
132
78
  this.changeCallbacks.set(key, []);
133
79
  }
134
80
  this.changeCallbacks.get(key).push(callback);
135
81
  }
136
- /**
137
- * 移除配置变更回调
138
- * @param key 配置键
139
- * @param callback 特定回调函数,如不提供则移除所有
140
- */
141
- offConfigChange(key, callback) {
142
- if (!this.changeCallbacks.has(key)) {
143
- return;
144
- }
145
- if (callback) {
146
- // 移除特定回调
147
- const callbacks = this.changeCallbacks.get(key);
82
+ /** @deprecated Use onChange instead */
83
+ onConfigChange(key, callback) {
84
+ this.onChange(key, callback);
85
+ }
86
+ removeChangeCallback(key, callback) {
87
+ const callbacks = this.changeCallbacks.get(key);
88
+ if (callbacks) {
148
89
  const index = callbacks.indexOf(callback);
149
- if (index !== -1) {
90
+ if (index > -1)
150
91
  callbacks.splice(index, 1);
151
- }
152
- // 如果没有回调,删除键
153
- if (callbacks.length === 0) {
154
- this.changeCallbacks.delete(key);
155
- }
156
- }
157
- else {
158
- // 移除所有回调
159
- this.changeCallbacks.delete(key);
160
92
  }
161
93
  }
162
- /**
163
- * 获取嵌套值
164
- * @param obj 对象
165
- * @param path 路径
166
- */
167
- getNestedValue(obj, path) {
168
- // 处理根路径
169
- if (!path) {
170
- return obj;
171
- }
172
- // 处理嵌套路径
173
- const parts = path.split('.');
174
- let current = obj;
175
- for (const part of parts) {
176
- if (current === undefined || current === null) {
177
- return undefined;
178
- }
179
- current = current[part];
180
- }
181
- return current;
182
- }
183
- /**
184
- * 设置嵌套值
185
- * @param obj 对象
186
- * @param path 路径
187
- * @param value 值
188
- */
189
- setNestedValue(obj, path, value) {
190
- // 处理根路径
191
- if (!path) {
192
- return;
193
- }
194
- // 处理嵌套路径
195
- const parts = path.split('.');
196
- let current = obj;
197
- // 遍历路径,直到倒数第二部分
198
- for (let i = 0; i < parts.length - 1; i++) {
199
- const part = parts[i];
200
- // 如果不存在,创建新对象
201
- if (current[part] === undefined || current[part] === null || typeof current[part] !== 'object') {
202
- current[part] = {};
203
- }
204
- current = current[part];
205
- }
206
- // 设置最终值
207
- current[parts[parts.length - 1]] = value;
208
- }
209
- /**
210
- * 触发变更回调
211
- * @param key 配置键
212
- * @param value 新值
213
- * @param oldValue 旧值
214
- */
215
- triggerChangeCallbacks(key, value, oldValue) {
216
- // 触发特定键的回调
217
- if (this.changeCallbacks.has(key)) {
218
- const callbacks = this.changeCallbacks.get(key);
219
- callbacks.forEach(callback => {
220
- try {
221
- callback(value, oldValue);
222
- }
223
- catch (error) {
224
- console.error(`Error in config change callback for key ${key}:`, error);
225
- }
226
- });
227
- }
228
- // 触发父路径的回调
229
- const parts = key.split('.');
230
- while (parts.length > 1) {
231
- parts.pop();
232
- const parentKey = parts.join('.');
233
- if (this.changeCallbacks.has(parentKey)) {
234
- const parentValue = this.get(parentKey);
235
- this.changeCallbacks.get(parentKey).forEach(callback => {
236
- try {
237
- callback(parentValue, parentValue);
238
- }
239
- catch (error) {
240
- console.error(`Error in config change callback for parent key ${parentKey}:`, error);
241
- }
242
- });
243
- }
244
- }
245
- }
246
- /**
247
- * 检查模块是否启用
248
- * @param moduleName 模块名称
249
- */
250
- isModuleEnabled(moduleName) {
251
- const key = `modules.${moduleName}.enabled`;
252
- return this.get(key) ?? false;
94
+ reset() {
95
+ this.config = {};
96
+ this._resetDefaults();
253
97
  }
254
98
  }
255
99
 
@@ -4776,157 +4620,106 @@
4776
4620
  }
4777
4621
 
4778
4622
  /**
4779
- * @file 错误处理模块
4780
- * @description 定义ID-Scanner-Lib的错误类层次结构
4623
+ * @file Scanner Errors
4624
+ * @description Error classes for Scanner
4781
4625
  * @module core/errors
4782
4626
  */
4783
4627
  /**
4784
- * ID-Scanner-Lib 基础错误类
4785
- * 所有库特定错误的基类
4628
+ * Scanner specific error
4786
4629
  */
4787
- class IDScannerError extends Error {
4630
+ class ScannerError extends Error {
4788
4631
  /**
4789
- * 构造函数
4790
- * @param message 错误消息
4791
- * @param options 错误选项
4632
+ * Create a ScannerError
4633
+ * @param message Error message
4634
+ * @param code Error code
4635
+ * @param module Module name
4792
4636
  */
4793
- constructor(message, options) {
4637
+ constructor(message, code, module) {
4794
4638
  super(message);
4795
- // 设置错误名称
4796
- this.name = this.constructor.name;
4797
- // 设置错误代码
4798
- this.code = options?.code || 'UNKNOWN_ERROR';
4799
- // 设置错误原因
4800
- this.cause = options?.cause;
4801
- // 捕获堆栈 (Node.js专有,浏览器环境忽略)
4802
- if (typeof Error.captureStackTrace === 'function') {
4803
- Error.captureStackTrace(this, this.constructor);
4804
- }
4639
+ this.name = 'ScannerError';
4640
+ this.code = code;
4641
+ this.module = module;
4805
4642
  }
4806
4643
  }
4807
4644
  /**
4808
- * 初始化错误
4809
- * 当库初始化失败时抛出
4645
+ * Camera access error
4810
4646
  */
4811
- class InitializationError extends IDScannerError {
4812
- constructor(message, details) {
4813
- super(`初始化失败: ${message}${details ? ` (${details})` : ''}`, { code: 'INIT_FAILED' });
4814
- this.name = 'InitializationError';
4647
+ class CameraAccessError extends Error {
4648
+ constructor(message = 'Camera access denied') {
4649
+ super(message);
4650
+ this.name = 'CameraAccessError';
4815
4651
  }
4816
4652
  }
4817
4653
  /**
4818
- * 设备错误
4819
- * 当访问硬件设备(如摄像头)失败时抛出
4654
+ * Device error
4820
4655
  */
4821
- class DeviceError extends IDScannerError {
4822
- constructor(message) {
4823
- super(`设备错误: ${message}`, { code: 'DEVICE_ERROR' });
4656
+ class DeviceError extends Error {
4657
+ constructor(message = 'Device error') {
4658
+ super(message);
4824
4659
  this.name = 'DeviceError';
4825
4660
  }
4826
4661
  }
4827
4662
  /**
4828
- * 摄像头访问错误
4829
- * 当无法访问或启动摄像头时抛出
4663
+ * Resource load error
4830
4664
  */
4831
- class CameraAccessError extends IDScannerError {
4832
- constructor(message, options) {
4833
- super(`摄像头访问失败: ${message}`, {
4834
- code: options?.code || 'CAMERA_ACCESS_FAILED',
4835
- cause: options?.cause
4836
- });
4837
- this.name = 'CameraAccessError';
4665
+ class ResourceLoadError extends Error {
4666
+ constructor(message = 'Failed to load resource', id) {
4667
+ super(message);
4668
+ this.name = 'ResourceLoadError';
4669
+ this.id = id;
4838
4670
  }
4839
4671
  }
4840
4672
  /**
4841
- * 人脸检测错误
4842
- * 当人脸检测过程失败时抛出
4673
+ * Face detection error
4843
4674
  */
4844
- class FaceDetectionError extends IDScannerError {
4845
- constructor(message) {
4846
- super(`人脸检测失败: ${message}`, { code: 'FACE_DETECTION_FAILED' });
4675
+ class FaceDetectionError extends Error {
4676
+ constructor(message = 'Face detection failed') {
4677
+ super(message);
4847
4678
  this.name = 'FaceDetectionError';
4848
4679
  }
4849
4680
  }
4850
4681
  /**
4851
- * 人脸比对错误
4852
- * 当人脸比对过程失败时抛出
4682
+ * Face comparison error
4853
4683
  */
4854
- class FaceComparisonError extends IDScannerError {
4855
- constructor(message) {
4856
- super(`人脸比对失败: ${message}`, { code: 'FACE_COMPARISON_FAILED' });
4684
+ class FaceComparisonError extends Error {
4685
+ constructor(message = 'Face comparison failed') {
4686
+ super(message);
4857
4687
  this.name = 'FaceComparisonError';
4858
4688
  }
4859
4689
  }
4860
4690
  /**
4861
- * 活体检测错误
4862
- * 当活体检测过程失败时抛出
4863
- */
4864
- class LivenessDetectionError extends IDScannerError {
4865
- constructor(message) {
4866
- super(`活体检测失败: ${message}`, { code: 'LIVENESS_DETECTION_FAILED' });
4867
- this.name = 'LivenessDetectionError';
4868
- }
4869
- }
4870
- /**
4871
- * OCR识别错误
4872
- * 当OCR文字识别失败时抛出
4873
- */
4874
- class OCRProcessingError extends IDScannerError {
4875
- constructor(message) {
4876
- super(`OCR处理失败: ${message}`, { code: 'OCR_PROCESSING_FAILED' });
4877
- this.name = 'OCRProcessingError';
4878
- }
4879
- }
4880
- /**
4881
- * 二维码扫描错误
4882
- * 当二维码扫描失败时抛出
4691
+ * Initialization error
4883
4692
  */
4884
- class QRScanError extends IDScannerError {
4885
- constructor(message) {
4886
- super(`二维码扫描失败: ${message}`, { code: 'QR_SCAN_FAILED' });
4887
- this.name = 'QRScanError';
4888
- }
4889
- }
4890
- /**
4891
- * 身份证检测错误
4892
- * 当身份证检测失败时抛出
4893
- */
4894
- class IDCardDetectionError extends IDScannerError {
4895
- constructor(message) {
4896
- super(`身份证检测失败: ${message}`, { code: 'ID_CARD_DETECTION_FAILED' });
4897
- this.name = 'IDCardDetectionError';
4898
- }
4899
- }
4900
- /**
4901
- * 资源加载错误
4902
- * 当无法加载必要资源(如模型)时抛出
4903
- */
4904
- class ResourceLoadError extends IDScannerError {
4905
- constructor(resource, reason) {
4906
- super(`无法加载资源 ${resource}: ${reason}`, { code: 'RESOURCE_LOAD_FAILED' });
4907
- this.name = 'ResourceLoadError';
4693
+ class InitializationError extends Error {
4694
+ constructor(message = 'Initialization failed') {
4695
+ super(message);
4696
+ this.name = 'InitializationError';
4908
4697
  }
4909
4698
  }
4910
4699
  /**
4911
- * 参数错误
4912
- * 当提供的参数无效时抛出
4700
+ * Liveness detection error
4913
4701
  */
4914
- class InvalidArgumentError extends IDScannerError {
4915
- constructor(paramName, reason) {
4916
- super(`无效的参数 ${paramName}: ${reason}`, { code: 'INVALID_ARGUMENT' });
4917
- this.name = 'InvalidArgumentError';
4702
+ class LivenessDetectionError extends Error {
4703
+ constructor(message = 'Liveness detection failed') {
4704
+ super(message);
4705
+ this.name = 'LivenessDetectionError';
4918
4706
  }
4919
4707
  }
4920
4708
  /**
4921
- * 不支持错误
4922
- * 当尝试使用不支持的功能或当前环境无法使用的功能时抛出
4709
+ * Error codes for Scanner
4923
4710
  */
4924
- class NotSupportedError extends IDScannerError {
4925
- constructor(feature) {
4926
- super(`不支持的功能: ${feature}`, { code: 'NOT_SUPPORTED' });
4927
- this.name = 'NotSupportedError';
4928
- }
4929
- }
4711
+ const ErrorCodes = {
4712
+ /** Scanner not initialized */
4713
+ NOT_INITIALIZED: 'SCANNER_001',
4714
+ /** Module not found */
4715
+ MODULE_NOT_FOUND: 'SCANNER_002',
4716
+ /** Detection failed */
4717
+ DETECTION_FAILED: 'SCANNER_003',
4718
+ /** Camera access denied */
4719
+ CAMERA_ACCESS_DENIED: 'CAMERA_001',
4720
+ /** Camera not available */
4721
+ CAMERA_NOT_AVAILABLE: 'CAMERA_002',
4722
+ };
4930
4723
 
4931
4724
  /* eslint-disable */
4932
4725
  /**
@@ -5031,27 +4824,23 @@
5031
4824
  exports.ConsoleLogHandler = ConsoleLogHandler;
5032
4825
  exports.DEFAULT_FORMATS = DEFAULT_FORMATS;
5033
4826
  exports.DeviceError = DeviceError;
4827
+ exports.ErrorCodes = ErrorCodes;
5034
4828
  exports.FaceComparisonError = FaceComparisonError;
5035
4829
  exports.FaceDetectionError = FaceDetectionError;
5036
4830
  exports.FaceModule = FaceModule;
5037
- exports.IDCardDetectionError = IDCardDetectionError;
5038
4831
  exports.IDCardModule = IDCardModule;
5039
4832
  exports.IDScanner = IDScanner;
5040
- exports.IDScannerError = IDScannerError;
5041
4833
  exports.InitializationError = InitializationError;
5042
- exports.InvalidArgumentError = InvalidArgumentError;
5043
4834
  exports.LivenessDetectionError = LivenessDetectionError;
5044
4835
  exports.LoadingStateManager = LoadingStateManager;
5045
4836
  exports.LogLevel = LogLevel;
5046
4837
  exports.Logger = Logger;
5047
4838
  exports.MemoryLogHandler = MemoryLogHandler;
5048
4839
  exports.ModuleManager = ModuleManager;
5049
- exports.NotSupportedError = NotSupportedError;
5050
- exports.OCRProcessingError = OCRProcessingError;
5051
4840
  exports.QRCodeModule = QRCodeModule;
5052
- exports.QRScanError = QRScanError;
5053
4841
  exports.RemoteLogHandler = RemoteLogHandler;
5054
4842
  exports.ResourceLoadError = ResourceLoadError;
4843
+ exports.ScannerError = ScannerError;
5055
4844
  exports.TaggedLogger = TaggedLogger;
5056
4845
  exports.createLoadingStateManager = createLoadingStateManager;
5057
4846
  exports.default = IDScanner;