id-scanner-lib 1.3.2 → 1.5.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.
Files changed (115) hide show
  1. package/README.md +55 -460
  2. package/dist/id-scanner-lib.esm.js +4641 -0
  3. package/dist/id-scanner-lib.esm.js.map +1 -0
  4. package/dist/id-scanner-lib.js +14755 -0
  5. package/dist/id-scanner-lib.js.map +1 -0
  6. package/dist/types/core/base-module.d.ts +44 -0
  7. package/dist/types/core/camera-manager.d.ts +258 -0
  8. package/dist/types/core/config.d.ts +88 -0
  9. package/dist/types/core/errors.d.ts +111 -0
  10. package/dist/types/core/event-emitter.d.ts +55 -0
  11. package/dist/types/core/logger.d.ts +277 -0
  12. package/dist/types/core/module-manager.d.ts +78 -0
  13. package/dist/types/core/plugin-manager.d.ts +158 -0
  14. package/dist/types/core/resource-manager.d.ts +246 -0
  15. package/dist/types/core/result.d.ts +83 -0
  16. package/dist/types/core/scanner-factory.d.ts +93 -0
  17. package/dist/types/index.bundle.d.ts +1303 -0
  18. package/dist/types/index.d.ts +86 -0
  19. package/dist/types/interfaces/external-types.d.ts +174 -0
  20. package/dist/types/interfaces/face-detection.d.ts +293 -0
  21. package/dist/types/interfaces/scanner-module.d.ts +280 -0
  22. package/dist/types/modules/face/face-detector.d.ts +170 -0
  23. package/dist/types/modules/face/index.d.ts +56 -0
  24. package/dist/types/modules/face/liveness-detector.d.ts +177 -0
  25. package/dist/types/modules/face/types.d.ts +136 -0
  26. package/dist/types/modules/id-card/anti-fake-detector.d.ts +170 -0
  27. package/dist/types/modules/id-card/id-card-detector.d.ts +131 -0
  28. package/dist/types/modules/id-card/index.d.ts +89 -0
  29. package/dist/types/modules/id-card/ocr-processor.d.ts +110 -0
  30. package/dist/types/modules/id-card/ocr-worker.d.ts +31 -0
  31. package/dist/types/modules/id-card/types.d.ts +181 -0
  32. package/dist/types/modules/qrcode/index.d.ts +51 -0
  33. package/dist/types/modules/qrcode/qr-code-scanner.d.ts +64 -0
  34. package/dist/types/modules/qrcode/types.d.ts +67 -0
  35. package/dist/types/utils/camera.d.ts +81 -0
  36. package/dist/types/utils/image-processing.d.ts +176 -0
  37. package/dist/types/utils/index.d.ts +175 -0
  38. package/dist/types/utils/performance.d.ts +81 -0
  39. package/dist/types/utils/resource-manager.d.ts +53 -0
  40. package/dist/types/utils/types.d.ts +166 -0
  41. package/dist/types/utils/worker.d.ts +52 -0
  42. package/dist/types/version.d.ts +7 -0
  43. package/package.json +76 -77
  44. package/src/core/base-module.ts +78 -0
  45. package/src/core/camera-manager.ts +798 -0
  46. package/src/core/config.ts +268 -0
  47. package/src/core/errors.ts +174 -0
  48. package/src/core/event-emitter.ts +110 -0
  49. package/src/core/logger.ts +549 -0
  50. package/src/core/module-manager.ts +165 -0
  51. package/src/core/plugin-manager.ts +429 -0
  52. package/src/core/resource-manager.ts +762 -0
  53. package/src/core/result.ts +163 -0
  54. package/src/core/scanner-factory.ts +237 -0
  55. package/src/index.ts +113 -936
  56. package/src/interfaces/external-types.ts +200 -0
  57. package/src/interfaces/face-detection.ts +309 -0
  58. package/src/interfaces/scanner-module.ts +384 -0
  59. package/src/modules/face/face-detector.ts +931 -0
  60. package/src/modules/face/index.ts +208 -0
  61. package/src/modules/face/liveness-detector.ts +908 -0
  62. package/src/modules/face/types.ts +133 -0
  63. package/src/modules/id-card/anti-fake-detector.ts +732 -0
  64. package/src/modules/id-card/id-card-detector.ts +474 -0
  65. package/src/modules/id-card/index.ts +425 -0
  66. package/src/modules/id-card/ocr-processor.ts +538 -0
  67. package/src/modules/id-card/ocr-worker.ts +259 -0
  68. package/src/modules/id-card/types.ts +178 -0
  69. package/src/modules/qrcode/index.ts +175 -0
  70. package/src/modules/qrcode/qr-code-scanner.ts +230 -0
  71. package/src/modules/qrcode/types.ts +65 -0
  72. package/src/types/browser-image-compression.d.ts +19 -0
  73. package/src/types/tesseract.d.ts +280 -0
  74. package/src/utils/image-processing.ts +432 -49
  75. package/src/utils/index.ts +426 -0
  76. package/src/utils/performance.ts +168 -131
  77. package/src/utils/resource-manager.ts +65 -146
  78. package/src/utils/types.ts +90 -2
  79. package/src/utils/worker.ts +123 -84
  80. package/src/version.ts +11 -0
  81. package/tools/scaffold.js +543 -0
  82. package/dist/id-scanner-core.esm.js +0 -11076
  83. package/dist/id-scanner-core.esm.js.map +0 -1
  84. package/dist/id-scanner-core.js +0 -11088
  85. package/dist/id-scanner-core.js.map +0 -1
  86. package/dist/id-scanner-core.min.js +0 -1
  87. package/dist/id-scanner-core.min.js.map +0 -1
  88. package/dist/id-scanner-ocr.esm.js +0 -1802
  89. package/dist/id-scanner-ocr.esm.js.map +0 -1
  90. package/dist/id-scanner-ocr.js +0 -1811
  91. package/dist/id-scanner-ocr.js.map +0 -1
  92. package/dist/id-scanner-ocr.min.js +0 -1
  93. package/dist/id-scanner-ocr.min.js.map +0 -1
  94. package/dist/id-scanner-qr.esm.js +0 -1023
  95. package/dist/id-scanner-qr.esm.js.map +0 -1
  96. package/dist/id-scanner-qr.js +0 -1032
  97. package/dist/id-scanner-qr.js.map +0 -1
  98. package/dist/id-scanner-qr.min.js +0 -1
  99. package/dist/id-scanner-qr.min.js.map +0 -1
  100. package/dist/id-scanner.js +0 -3740
  101. package/dist/id-scanner.js.map +0 -1
  102. package/dist/id-scanner.min.js +0 -1
  103. package/dist/id-scanner.min.js.map +0 -1
  104. package/src/core.ts +0 -138
  105. package/src/demo/demo.ts +0 -204
  106. package/src/id-recognition/anti-fake-detector.ts +0 -317
  107. package/src/id-recognition/data-extractor.ts +0 -262
  108. package/src/id-recognition/id-detector.ts +0 -363
  109. package/src/id-recognition/ocr-processor.ts +0 -334
  110. package/src/id-recognition/ocr-worker.ts +0 -156
  111. package/src/index-umd.ts +0 -477
  112. package/src/ocr-module.ts +0 -187
  113. package/src/qr-module.ts +0 -179
  114. package/src/scanner/barcode-scanner.ts +0 -251
  115. package/src/scanner/qr-scanner.ts +0 -167
@@ -0,0 +1,429 @@
1
+ /**
2
+ * @file 插件管理器
3
+ * @description 提供插件的注册、初始化和管理功能
4
+ * @module core/plugin-manager
5
+ */
6
+
7
+ import { EventEmitter } from 'events';
8
+ import { Logger } from './logger';
9
+ import { ConfigManager } from './config';
10
+ import { IDScannerError } from './errors';
11
+
12
+ /**
13
+ * 插件优先级枚举
14
+ */
15
+ export enum PluginPriority {
16
+ /** 高优先级,最先初始化和激活 */
17
+ HIGH = 'high',
18
+ /** 中等优先级 */
19
+ NORMAL = 'normal',
20
+ /** 低优先级,最后初始化和激活 */
21
+ LOW = 'low'
22
+ }
23
+
24
+ /**
25
+ * 插件状态枚举
26
+ */
27
+ export enum PluginStatus {
28
+ /** 已注册 */
29
+ REGISTERED = 'registered',
30
+ /** 初始化中 */
31
+ INITIALIZING = 'initializing',
32
+ /** 已初始化 */
33
+ INITIALIZED = 'initialized',
34
+ /** 激活中 */
35
+ ACTIVATING = 'activating',
36
+ /** 已激活 */
37
+ ACTIVE = 'active',
38
+ /** 已停用 */
39
+ INACTIVE = 'inactive',
40
+ /** 错误状态 */
41
+ ERROR = 'error'
42
+ }
43
+
44
+ /**
45
+ * 插件接口
46
+ */
47
+ export interface Plugin {
48
+ /** 插件ID */
49
+ id: string;
50
+ /** 插件名称 */
51
+ name: string;
52
+ /** 插件版本 */
53
+ version: string;
54
+ /** 插件描述 */
55
+ description?: string;
56
+ /** 插件优先级 */
57
+ priority?: PluginPriority;
58
+ /** 依赖的插件ID列表 */
59
+ dependencies?: string[];
60
+ /** 初始化方法 */
61
+ initialize?: (api: PluginAPI) => Promise<void>;
62
+ /** 激活方法 */
63
+ activate?: (api: PluginAPI) => Promise<void>;
64
+ /** 停用方法 */
65
+ deactivate?: (api: PluginAPI) => Promise<void>;
66
+ }
67
+
68
+ /**
69
+ * 插件API接口
70
+ * 提供给插件使用的API
71
+ */
72
+ export interface PluginAPI {
73
+ /** 日志记录器 */
74
+ logger: Logger;
75
+ /** 配置管理器 */
76
+ config: ConfigManager;
77
+ /** 事件发射器 */
78
+ eventBus: EventEmitter;
79
+ /** 获取插件 */
80
+ getPlugin: (id: string) => Plugin | undefined;
81
+ /** 获取所有插件 */
82
+ getAllPlugins: () => Map<string, Plugin>;
83
+ }
84
+
85
+ /**
86
+ * 插件管理器
87
+ * 提供插件的注册、初始化和管理功能
88
+ */
89
+ export class PluginManager extends EventEmitter {
90
+ /** 单例实例 */
91
+ private static instance: PluginManager;
92
+
93
+ /** 日志记录器 */
94
+ private logger: Logger;
95
+
96
+ /** 配置管理器 */
97
+ private config: ConfigManager;
98
+
99
+ /** 插件映射表 */
100
+ private plugins: Map<string, Plugin> = new Map();
101
+
102
+ /** 插件状态 */
103
+ private pluginStatus: Map<string, PluginStatus> = new Map();
104
+
105
+ /** 插件API */
106
+ private pluginAPI: PluginAPI;
107
+
108
+ /** 初始化状态 */
109
+ private initialized: boolean = false;
110
+
111
+ /**
112
+ * 私有构造函数
113
+ */
114
+ private constructor() {
115
+ super();
116
+
117
+ this.logger = Logger.getInstance();
118
+ this.config = ConfigManager.getInstance();
119
+
120
+ // 创建插件API
121
+ this.pluginAPI = {
122
+ logger: this.logger,
123
+ config: this.config,
124
+ eventBus: this,
125
+ getPlugin: this.getPlugin.bind(this),
126
+ getAllPlugins: this.getAllPlugins.bind(this)
127
+ };
128
+ }
129
+
130
+ /**
131
+ * 获取单例实例
132
+ */
133
+ public static getInstance(): PluginManager {
134
+ if (!PluginManager.instance) {
135
+ PluginManager.instance = new PluginManager();
136
+ }
137
+ return PluginManager.instance;
138
+ }
139
+
140
+ /**
141
+ * 初始化插件管理器
142
+ */
143
+ public async initialize(): Promise<void> {
144
+ if (this.initialized) {
145
+ this.logger.debug('PluginManager', '插件管理器已初始化');
146
+ return;
147
+ }
148
+
149
+ this.logger.debug('PluginManager', '初始化插件管理器');
150
+
151
+ this.initialized = true;
152
+ this.emit('manager:initialized', {});
153
+ }
154
+
155
+ /**
156
+ * 注册插件
157
+ * @param plugin 插件
158
+ */
159
+ public registerPlugin(plugin: Plugin): void {
160
+ if (!plugin.id) {
161
+ throw new Error('插件ID不能为空');
162
+ }
163
+
164
+ if (this.plugins.has(plugin.id)) {
165
+ this.logger.warn('PluginManager', `插件已注册: ${plugin.id}`);
166
+ return;
167
+ }
168
+
169
+ // 设置默认优先级
170
+ if (!plugin.priority) {
171
+ plugin.priority = PluginPriority.NORMAL;
172
+ }
173
+
174
+ this.plugins.set(plugin.id, plugin);
175
+ this.pluginStatus.set(plugin.id, PluginStatus.REGISTERED);
176
+
177
+ this.logger.info('PluginManager', `注册插件: ${plugin.name} (${plugin.id}) v${plugin.version}`);
178
+ this.emit('plugin:registered', { plugin });
179
+ }
180
+
181
+ /**
182
+ * 卸载插件
183
+ * @param id 插件ID
184
+ */
185
+ public unregisterPlugin(id: string): boolean {
186
+ if (!this.plugins.has(id)) {
187
+ return false;
188
+ }
189
+
190
+ // 如果插件处于激活状态,先停用
191
+ if (this.pluginStatus.get(id) === PluginStatus.ACTIVE) {
192
+ this.deactivatePlugin(id);
193
+ }
194
+
195
+ const plugin = this.plugins.get(id)!;
196
+ this.plugins.delete(id);
197
+ this.pluginStatus.delete(id);
198
+
199
+ this.logger.info('PluginManager', `卸载插件: ${plugin.name} (${id})`);
200
+ this.emit('plugin:unregistered', { plugin });
201
+
202
+ return true;
203
+ }
204
+
205
+ /**
206
+ * 初始化插件
207
+ * @param id 插件ID
208
+ */
209
+ public async initializePlugin(id: string): Promise<boolean> {
210
+ if (!this.plugins.has(id)) {
211
+ this.logger.warn('PluginManager', `初始化失败: 插件不存在 ${id}`);
212
+ return false;
213
+ }
214
+
215
+ const plugin = this.plugins.get(id)!;
216
+ const status = this.pluginStatus.get(id)!;
217
+
218
+ if (status === PluginStatus.INITIALIZED || status === PluginStatus.ACTIVE) {
219
+ this.logger.debug('PluginManager', `插件已初始化: ${id}`);
220
+ return true;
221
+ }
222
+
223
+ if (status === PluginStatus.INITIALIZING) {
224
+ this.logger.warn('PluginManager', `插件正在初始化中: ${id}`);
225
+ return false;
226
+ }
227
+
228
+ // 检查依赖
229
+ if (plugin.dependencies && plugin.dependencies.length > 0) {
230
+ for (const depId of plugin.dependencies) {
231
+ if (!this.plugins.has(depId)) {
232
+ this.logger.error('PluginManager', `初始化失败: 依赖的插件不存在 ${depId}`);
233
+ this.pluginStatus.set(id, PluginStatus.ERROR);
234
+ return false;
235
+ }
236
+
237
+ // 初始化依赖插件
238
+ const depStatus = this.pluginStatus.get(depId);
239
+ if (depStatus !== PluginStatus.INITIALIZED && depStatus !== PluginStatus.ACTIVE) {
240
+ const success = await this.initializePlugin(depId);
241
+ if (!success) {
242
+ this.logger.error('PluginManager', `初始化失败: 依赖的插件初始化失败 ${depId}`);
243
+ this.pluginStatus.set(id, PluginStatus.ERROR);
244
+ return false;
245
+ }
246
+ }
247
+ }
248
+ }
249
+
250
+ this.pluginStatus.set(id, PluginStatus.INITIALIZING);
251
+ this.emit('plugin:initializing', { plugin });
252
+
253
+ try {
254
+ if (plugin.initialize) {
255
+ await plugin.initialize(this.pluginAPI);
256
+ }
257
+
258
+ this.pluginStatus.set(id, PluginStatus.INITIALIZED);
259
+ this.logger.debug('PluginManager', `插件初始化成功: ${plugin.name} (${id})`);
260
+ this.emit('plugin:initialized', { plugin });
261
+
262
+ return true;
263
+ } catch (error) {
264
+ this.pluginStatus.set(id, PluginStatus.ERROR);
265
+ this.logger.error('PluginManager', `插件初始化失败: ${id}`, error as Error);
266
+ this.emit('plugin:error', { plugin, error });
267
+
268
+ return false;
269
+ }
270
+ }
271
+
272
+ /**
273
+ * 激活插件
274
+ * @param id 插件ID
275
+ */
276
+ public async activatePlugin(id: string): Promise<boolean> {
277
+ if (!this.plugins.has(id)) {
278
+ this.logger.warn('PluginManager', `激活失败: 插件不存在 ${id}`);
279
+ return false;
280
+ }
281
+
282
+ const plugin = this.plugins.get(id)!;
283
+ const status = this.pluginStatus.get(id)!;
284
+
285
+ if (status === PluginStatus.ACTIVE) {
286
+ this.logger.debug('PluginManager', `插件已激活: ${id}`);
287
+ return true;
288
+ }
289
+
290
+ if (status === PluginStatus.ACTIVATING) {
291
+ this.logger.warn('PluginManager', `插件正在激活中: ${id}`);
292
+ return false;
293
+ }
294
+
295
+ if (status !== PluginStatus.INITIALIZED) {
296
+ // 尝试初始化插件
297
+ const success = await this.initializePlugin(id);
298
+ if (!success) {
299
+ this.logger.error('PluginManager', `激活失败: 插件初始化失败 ${id}`);
300
+ return false;
301
+ }
302
+ }
303
+
304
+ // 激活依赖插件
305
+ if (plugin.dependencies && plugin.dependencies.length > 0) {
306
+ for (const depId of plugin.dependencies) {
307
+ const depStatus = this.pluginStatus.get(depId);
308
+ if (depStatus !== PluginStatus.ACTIVE) {
309
+ const success = await this.activatePlugin(depId);
310
+ if (!success) {
311
+ this.logger.error('PluginManager', `激活失败: 依赖的插件激活失败 ${depId}`);
312
+ return false;
313
+ }
314
+ }
315
+ }
316
+ }
317
+
318
+ this.pluginStatus.set(id, PluginStatus.ACTIVATING);
319
+ this.emit('plugin:activating', { plugin });
320
+
321
+ try {
322
+ if (plugin.activate) {
323
+ await plugin.activate(this.pluginAPI);
324
+ }
325
+
326
+ this.pluginStatus.set(id, PluginStatus.ACTIVE);
327
+ this.logger.info('PluginManager', `插件激活成功: ${plugin.name} (${id})`);
328
+ this.emit('plugin:activated', { plugin });
329
+
330
+ return true;
331
+ } catch (error) {
332
+ this.pluginStatus.set(id, PluginStatus.ERROR);
333
+ this.logger.error('PluginManager', `插件激活失败: ${id}`, error as Error);
334
+ this.emit('plugin:error', { plugin, error });
335
+
336
+ return false;
337
+ }
338
+ }
339
+
340
+ /**
341
+ * 停用插件
342
+ * @param id 插件ID
343
+ */
344
+ public async deactivatePlugin(id: string): Promise<boolean> {
345
+ if (!this.plugins.has(id)) {
346
+ this.logger.warn('PluginManager', `停用失败: 插件不存在 ${id}`);
347
+ return false;
348
+ }
349
+
350
+ const plugin = this.plugins.get(id)!;
351
+ const status = this.pluginStatus.get(id)!;
352
+
353
+ if (status !== PluginStatus.ACTIVE) {
354
+ this.logger.debug('PluginManager', `插件未激活: ${id}`);
355
+ return true;
356
+ }
357
+
358
+ // 检查依赖关系:如果有其他激活的插件依赖于此插件,则不能停用
359
+ for (const [pluginId, p] of this.plugins.entries()) {
360
+ if (p.dependencies && p.dependencies.includes(id) && this.pluginStatus.get(pluginId) === PluginStatus.ACTIVE) {
361
+ this.logger.warn('PluginManager', `停用失败: 插件 ${pluginId} 依赖于此插件`);
362
+ return false;
363
+ }
364
+ }
365
+
366
+ this.emit('plugin:deactivating', { plugin });
367
+
368
+ try {
369
+ if (plugin.deactivate) {
370
+ await plugin.deactivate(this.pluginAPI);
371
+ }
372
+
373
+ this.pluginStatus.set(id, PluginStatus.INACTIVE);
374
+ this.logger.info('PluginManager', `插件停用成功: ${plugin.name} (${id})`);
375
+ this.emit('plugin:deactivated', { plugin });
376
+
377
+ return true;
378
+ } catch (error) {
379
+ this.pluginStatus.set(id, PluginStatus.ERROR);
380
+ this.logger.error('PluginManager', `插件停用失败: ${id}`, error as Error);
381
+ this.emit('plugin:error', { plugin, error });
382
+
383
+ return false;
384
+ }
385
+ }
386
+
387
+ /**
388
+ * 获取插件
389
+ * @param id 插件ID
390
+ */
391
+ public getPlugin(id: string): Plugin | undefined {
392
+ return this.plugins.get(id);
393
+ }
394
+
395
+ /**
396
+ * 获取所有插件
397
+ */
398
+ public getAllPlugins(): Map<string, Plugin> {
399
+ return new Map(this.plugins);
400
+ }
401
+
402
+ /**
403
+ * 获取插件状态
404
+ * @param id 插件ID
405
+ */
406
+ public getPluginStatus(id: string): PluginStatus | undefined {
407
+ return this.pluginStatus.get(id);
408
+ }
409
+
410
+ /**
411
+ * 按优先级获取插件
412
+ * @param priority 优先级
413
+ */
414
+ public getPluginsByPriority(priority: PluginPriority): Plugin[] {
415
+ return Array.from(this.plugins.values())
416
+ .filter(plugin => plugin.priority === priority);
417
+ }
418
+
419
+ /**
420
+ * 获取按优先级排序的所有插件
421
+ */
422
+ public getSortedPlugins(): Plugin[] {
423
+ const high = this.getPluginsByPriority(PluginPriority.HIGH);
424
+ const normal = this.getPluginsByPriority(PluginPriority.NORMAL);
425
+ const low = this.getPluginsByPriority(PluginPriority.LOW);
426
+
427
+ return [...high, ...normal, ...low];
428
+ }
429
+ }