id-scanner-lib 1.6.4 → 1.6.6
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/LICENSE +1 -1
- package/dist/id-scanner-lib.esm.js +82 -53
- package/dist/id-scanner-lib.esm.js.map +1 -1
- package/dist/id-scanner-lib.js +82 -52
- package/dist/id-scanner-lib.js.map +1 -1
- package/package.json +1 -1
- package/src/core/event-emitter.ts +9 -0
- package/src/core/logger.ts +62 -37
- package/src/core/resource-manager.ts +23 -9
- package/src/core/result.ts +3 -3
- package/src/index.ts +5 -5
- package/src/modules/face/face-detector.ts +8 -6
- package/src/modules/face/liveness-detector.ts +3 -2
- package/src/modules/id-card/index.ts +10 -8
- package/src/modules/id-card/ocr-processor.ts +3 -3
- package/src/utils/camera.ts +15 -2
- package/src/core/scanner-factory.ts +0 -236
package/LICENSE
CHANGED
|
@@ -259,13 +259,17 @@ class ConfigManager {
|
|
|
259
259
|
/**
|
|
260
260
|
* 日志级别枚举
|
|
261
261
|
*/
|
|
262
|
-
var
|
|
263
|
-
(function (
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
})(
|
|
262
|
+
var LoggerLevel;
|
|
263
|
+
(function (LoggerLevel) {
|
|
264
|
+
LoggerLevel["DEBUG"] = "debug";
|
|
265
|
+
LoggerLevel["INFO"] = "info";
|
|
266
|
+
LoggerLevel["WARN"] = "warn";
|
|
267
|
+
LoggerLevel["ERROR"] = "error";
|
|
268
|
+
})(LoggerLevel || (LoggerLevel = {}));
|
|
269
|
+
/**
|
|
270
|
+
* @deprecated 使用 LoggerLevel 代替
|
|
271
|
+
*/
|
|
272
|
+
const LogLevel = LoggerLevel;
|
|
269
273
|
/**
|
|
270
274
|
* 控制台日志处理器
|
|
271
275
|
* 将日志输出到浏览器控制台
|
|
@@ -279,16 +283,16 @@ class ConsoleLogHandler {
|
|
|
279
283
|
const timestamp = new Date(entry.timestamp).toISOString();
|
|
280
284
|
const prefix = `[${timestamp}] [${entry.level.toUpperCase()}] [${entry.tag}]`;
|
|
281
285
|
switch (entry.level) {
|
|
282
|
-
case
|
|
286
|
+
case LoggerLevel.DEBUG:
|
|
283
287
|
console.debug(prefix, entry.message, entry.error || '');
|
|
284
288
|
break;
|
|
285
|
-
case
|
|
289
|
+
case LoggerLevel.INFO:
|
|
286
290
|
console.info(prefix, entry.message, entry.error || '');
|
|
287
291
|
break;
|
|
288
|
-
case
|
|
292
|
+
case LoggerLevel.WARN:
|
|
289
293
|
console.warn(prefix, entry.message, entry.error || '');
|
|
290
294
|
break;
|
|
291
|
-
case
|
|
295
|
+
case LoggerLevel.ERROR:
|
|
292
296
|
console.error(prefix, entry.message, entry.error || '');
|
|
293
297
|
break;
|
|
294
298
|
// 输出什么也不做
|
|
@@ -366,12 +370,15 @@ class RemoteLogHandler {
|
|
|
366
370
|
this.endpoint = endpoint;
|
|
367
371
|
this.maxQueueSize = maxQueueSize;
|
|
368
372
|
this.flushInterval = flushInterval;
|
|
373
|
+
this.isBrowser = typeof window !== 'undefined' && typeof window.addEventListener === 'function';
|
|
369
374
|
// 设置定时发送
|
|
370
375
|
this.startTimer();
|
|
371
376
|
// 页面卸载前尝试发送剩余日志
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
377
|
+
if (this.isBrowser) {
|
|
378
|
+
window.addEventListener('beforeunload', () => {
|
|
379
|
+
this.flush();
|
|
380
|
+
});
|
|
381
|
+
}
|
|
375
382
|
}
|
|
376
383
|
/**
|
|
377
384
|
* 处理日志条目
|
|
@@ -379,7 +386,7 @@ class RemoteLogHandler {
|
|
|
379
386
|
*/
|
|
380
387
|
handle(entry) {
|
|
381
388
|
// 只处理INFO以上级别的日志
|
|
382
|
-
if (entry.level >=
|
|
389
|
+
if (entry.level >= LoggerLevel.INFO) {
|
|
383
390
|
this.queue.push(entry);
|
|
384
391
|
// 如果队列满了,立即发送
|
|
385
392
|
if (this.queue.length >= this.maxQueueSize) {
|
|
@@ -412,18 +419,22 @@ class RemoteLogHandler {
|
|
|
412
419
|
'Content-Type': 'application/json'
|
|
413
420
|
},
|
|
414
421
|
body: JSON.stringify(entriesToSend),
|
|
415
|
-
// 不等待响应,避免阻塞
|
|
416
422
|
keepalive: true
|
|
417
423
|
}).catch((err) => {
|
|
418
424
|
console.error('Failed to send logs to remote server:', err);
|
|
425
|
+
// 防止无限重试 - 如果失败次数过多,丢弃日志
|
|
426
|
+
if (this._sendCount > 10) {
|
|
427
|
+
console.warn('RemoteLogHandler: Max retry exceeded, discarding logs');
|
|
428
|
+
this.queue = []; // 清空队列,避免内存泄漏
|
|
429
|
+
this._sendCount = 0;
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
419
432
|
// 失败时把日志放回队列,但防止无限增长
|
|
420
433
|
if (this.queue.length < this.maxQueueSize) {
|
|
421
|
-
// 限制放回的数量,防止内存溢出
|
|
422
434
|
const maxReturn = Math.min(entriesToSend.length, this.maxQueueSize - this.queue.length);
|
|
423
435
|
const returnedEntries = entriesToSend.slice(0, maxReturn);
|
|
424
436
|
this.queue = [...returnedEntries, ...this.queue];
|
|
425
437
|
}
|
|
426
|
-
// 重置发送计数,允许后续重试
|
|
427
438
|
this._sendCount = 0;
|
|
428
439
|
});
|
|
429
440
|
}
|
|
@@ -435,6 +446,8 @@ class RemoteLogHandler {
|
|
|
435
446
|
* 开始定时发送
|
|
436
447
|
*/
|
|
437
448
|
startTimer() {
|
|
449
|
+
if (!this.isBrowser)
|
|
450
|
+
return;
|
|
438
451
|
if (this.timerId !== null)
|
|
439
452
|
return;
|
|
440
453
|
this.timerId = window.setInterval(() => {
|
|
@@ -465,7 +478,7 @@ class Logger {
|
|
|
465
478
|
/** 默认标签 */
|
|
466
479
|
this.defaultTag = 'IDScanner';
|
|
467
480
|
/** 日志级别 */
|
|
468
|
-
this.logLevel =
|
|
481
|
+
this.logLevel = LoggerLevel.INFO;
|
|
469
482
|
this.config = ConfigManager.getInstance();
|
|
470
483
|
// 默认添加控制台处理器
|
|
471
484
|
this.addHandler(new ConsoleLogHandler());
|
|
@@ -483,6 +496,12 @@ class Logger {
|
|
|
483
496
|
}
|
|
484
497
|
return Logger.instance;
|
|
485
498
|
}
|
|
499
|
+
/**
|
|
500
|
+
* 重置单例实例(主要用于测试)
|
|
501
|
+
*/
|
|
502
|
+
static resetInstance() {
|
|
503
|
+
Logger.instance = undefined;
|
|
504
|
+
}
|
|
486
505
|
/**
|
|
487
506
|
* 添加日志处理器
|
|
488
507
|
* @param handler 日志处理器
|
|
@@ -520,7 +539,7 @@ class Logger {
|
|
|
520
539
|
* @param error 错误
|
|
521
540
|
*/
|
|
522
541
|
debug(tag, message, error) {
|
|
523
|
-
this.log(
|
|
542
|
+
this.log(LoggerLevel.DEBUG, tag, message, error);
|
|
524
543
|
}
|
|
525
544
|
/**
|
|
526
545
|
* 记录信息级别日志
|
|
@@ -529,7 +548,7 @@ class Logger {
|
|
|
529
548
|
* @param error 错误
|
|
530
549
|
*/
|
|
531
550
|
info(tag, message, error) {
|
|
532
|
-
this.log(
|
|
551
|
+
this.log(LoggerLevel.INFO, tag, message, error);
|
|
533
552
|
}
|
|
534
553
|
/**
|
|
535
554
|
* 记录警告级别日志
|
|
@@ -538,7 +557,7 @@ class Logger {
|
|
|
538
557
|
* @param error 错误
|
|
539
558
|
*/
|
|
540
559
|
warn(tag, message, error) {
|
|
541
|
-
this.log(
|
|
560
|
+
this.log(LoggerLevel.WARN, tag, message, error);
|
|
542
561
|
}
|
|
543
562
|
/**
|
|
544
563
|
* 记录错误级别日志
|
|
@@ -547,7 +566,7 @@ class Logger {
|
|
|
547
566
|
* @param error 错误
|
|
548
567
|
*/
|
|
549
568
|
error(tag, message, error) {
|
|
550
|
-
this.log(
|
|
569
|
+
this.log(LoggerLevel.ERROR, tag, message, error);
|
|
551
570
|
}
|
|
552
571
|
/**
|
|
553
572
|
* 创建标记了特定标签的日志记录器
|
|
@@ -600,16 +619,16 @@ class Logger {
|
|
|
600
619
|
const timestamp = new Date(entry.timestamp).toISOString();
|
|
601
620
|
const prefix = `[${timestamp}] [${entry.level.toUpperCase()}] [${entry.tag}]`;
|
|
602
621
|
switch (entry.level) {
|
|
603
|
-
case
|
|
622
|
+
case LoggerLevel.DEBUG:
|
|
604
623
|
console.debug(`${prefix} ${entry.message}`, entry.error || '');
|
|
605
624
|
break;
|
|
606
|
-
case
|
|
625
|
+
case LoggerLevel.INFO:
|
|
607
626
|
console.info(`${prefix} ${entry.message}`, entry.error || '');
|
|
608
627
|
break;
|
|
609
|
-
case
|
|
628
|
+
case LoggerLevel.WARN:
|
|
610
629
|
console.warn(`${prefix} ${entry.message}`, entry.error || '');
|
|
611
630
|
break;
|
|
612
|
-
case
|
|
631
|
+
case LoggerLevel.ERROR:
|
|
613
632
|
console.error(`${prefix} ${entry.message}`, entry.error || '');
|
|
614
633
|
break;
|
|
615
634
|
}
|
|
@@ -620,13 +639,13 @@ class Logger {
|
|
|
620
639
|
*/
|
|
621
640
|
getLevelValue(level) {
|
|
622
641
|
switch (level) {
|
|
623
|
-
case
|
|
642
|
+
case LoggerLevel.DEBUG:
|
|
624
643
|
return 0;
|
|
625
|
-
case
|
|
644
|
+
case LoggerLevel.INFO:
|
|
626
645
|
return 1;
|
|
627
|
-
case
|
|
646
|
+
case LoggerLevel.WARN:
|
|
628
647
|
return 2;
|
|
629
|
-
case
|
|
648
|
+
case LoggerLevel.ERROR:
|
|
630
649
|
return 3;
|
|
631
650
|
default:
|
|
632
651
|
return 1; // 默认INFO级别
|
|
@@ -640,19 +659,19 @@ class Logger {
|
|
|
640
659
|
if (typeof level === 'string') {
|
|
641
660
|
switch (level) {
|
|
642
661
|
case 'debug':
|
|
643
|
-
this.logLevel =
|
|
662
|
+
this.logLevel = LoggerLevel.DEBUG;
|
|
644
663
|
break;
|
|
645
664
|
case 'info':
|
|
646
|
-
this.logLevel =
|
|
665
|
+
this.logLevel = LoggerLevel.INFO;
|
|
647
666
|
break;
|
|
648
667
|
case 'warn':
|
|
649
|
-
this.logLevel =
|
|
668
|
+
this.logLevel = LoggerLevel.WARN;
|
|
650
669
|
break;
|
|
651
670
|
case 'error':
|
|
652
|
-
this.logLevel =
|
|
671
|
+
this.logLevel = LoggerLevel.ERROR;
|
|
653
672
|
break;
|
|
654
673
|
default:
|
|
655
|
-
this.logLevel =
|
|
674
|
+
this.logLevel = LoggerLevel.INFO;
|
|
656
675
|
}
|
|
657
676
|
}
|
|
658
677
|
else {
|
|
@@ -765,6 +784,14 @@ class EventEmitter {
|
|
|
765
784
|
this.eventHandlers.delete(eventName);
|
|
766
785
|
}
|
|
767
786
|
}
|
|
787
|
+
/**
|
|
788
|
+
* 取消订阅事件 (off的别名)
|
|
789
|
+
* @param eventName 事件名称
|
|
790
|
+
* @param handler 事件处理器
|
|
791
|
+
*/
|
|
792
|
+
removeListener(eventName, handler) {
|
|
793
|
+
this.off(eventName, handler);
|
|
794
|
+
}
|
|
768
795
|
/**
|
|
769
796
|
* 订阅事件,但只触发一次
|
|
770
797
|
* @param eventName 事件名称
|
|
@@ -1052,19 +1079,19 @@ class Result {
|
|
|
1052
1079
|
/**
|
|
1053
1080
|
* 获取结果数据
|
|
1054
1081
|
*/
|
|
1055
|
-
|
|
1082
|
+
getData() {
|
|
1056
1083
|
return this._data;
|
|
1057
1084
|
}
|
|
1058
1085
|
/**
|
|
1059
1086
|
* 获取错误对象
|
|
1060
1087
|
*/
|
|
1061
|
-
|
|
1088
|
+
getError() {
|
|
1062
1089
|
return this._error;
|
|
1063
1090
|
}
|
|
1064
1091
|
/**
|
|
1065
1092
|
* 获取元数据
|
|
1066
1093
|
*/
|
|
1067
|
-
|
|
1094
|
+
getMeta() {
|
|
1068
1095
|
return this._meta;
|
|
1069
1096
|
}
|
|
1070
1097
|
/**
|
|
@@ -2890,8 +2917,8 @@ class OCRProcessor {
|
|
|
2890
2917
|
? JSON.stringify(error)
|
|
2891
2918
|
: String(error);
|
|
2892
2919
|
this.options.logger?.(`OCR识别错误: ${errorMessage}`);
|
|
2893
|
-
//
|
|
2894
|
-
return
|
|
2920
|
+
// 返回 null,让调用方知道识别失败
|
|
2921
|
+
return null;
|
|
2895
2922
|
}
|
|
2896
2923
|
}
|
|
2897
2924
|
/**
|
|
@@ -3770,18 +3797,19 @@ class IDCardModule extends BaseModule {
|
|
|
3770
3797
|
try {
|
|
3771
3798
|
// 检测身份证
|
|
3772
3799
|
const detectionResult = await this.detector.processImage(image);
|
|
3773
|
-
|
|
3800
|
+
const detectionData = detectionResult.getData();
|
|
3801
|
+
if (!detectionResult.isSuccess() || !detectionData) {
|
|
3774
3802
|
throw new Error('未检测到身份证');
|
|
3775
3803
|
}
|
|
3776
3804
|
// 创建结果对象
|
|
3777
3805
|
const idCardInfo = {
|
|
3778
|
-
type:
|
|
3779
|
-
confidence:
|
|
3806
|
+
type: detectionData.type || IDCardType.FRONT,
|
|
3807
|
+
confidence: detectionData.confidence
|
|
3780
3808
|
};
|
|
3781
3809
|
// 如果启用OCR且OCR处理器已初始化
|
|
3782
3810
|
if (this.options.detector?.enableOCR && this.ocrProcessor) {
|
|
3783
3811
|
// 裁剪并处理图像
|
|
3784
|
-
const processedImage =
|
|
3812
|
+
const processedImage = detectionData.image || this.convertToImageData(image);
|
|
3785
3813
|
// 识别文本信息
|
|
3786
3814
|
const ocrResult = await this.ocrProcessor.processIDCard(processedImage);
|
|
3787
3815
|
// 合并OCR结果
|
|
@@ -3963,14 +3991,15 @@ class IDCardModule extends BaseModule {
|
|
|
3963
3991
|
try {
|
|
3964
3992
|
// 调用检测器处理图像
|
|
3965
3993
|
const result = await this.detector.processImage(image);
|
|
3966
|
-
if (!result.isSuccess() || !result.
|
|
3994
|
+
if (!result.isSuccess() || !result.getData()) {
|
|
3967
3995
|
return { success: false, confidence: 0 };
|
|
3968
3996
|
}
|
|
3997
|
+
const data = result.getData();
|
|
3969
3998
|
return {
|
|
3970
3999
|
success: true,
|
|
3971
|
-
type:
|
|
3972
|
-
confidence:
|
|
3973
|
-
croppedImage:
|
|
4000
|
+
type: data.type,
|
|
4001
|
+
confidence: data.confidence || 0,
|
|
4002
|
+
croppedImage: data.image
|
|
3974
4003
|
};
|
|
3975
4004
|
}
|
|
3976
4005
|
catch (error) {
|
|
@@ -4845,13 +4874,13 @@ class IDScanner {
|
|
|
4845
4874
|
}
|
|
4846
4875
|
this.moduleManager = ModuleManager.getInstance();
|
|
4847
4876
|
// 注册模块
|
|
4848
|
-
if (options.enableIDCard
|
|
4877
|
+
if (options.enableIDCard === true) {
|
|
4849
4878
|
this.moduleManager.register(new IDCardModule(options.idCard));
|
|
4850
4879
|
}
|
|
4851
|
-
if (options.enableQRCode
|
|
4880
|
+
if (options.enableQRCode === true) {
|
|
4852
4881
|
this.moduleManager.register(new QRCodeModule(options.qrCode));
|
|
4853
4882
|
}
|
|
4854
|
-
if (options.enableFace
|
|
4883
|
+
if (options.enableFace === true) {
|
|
4855
4884
|
this.moduleManager.register(new FaceModule(options.face));
|
|
4856
4885
|
}
|
|
4857
4886
|
}
|
|
@@ -4919,5 +4948,5 @@ IDScanner.VERSION = VERSION;
|
|
|
4919
4948
|
/** 构建日期 */
|
|
4920
4949
|
IDScanner.BUILD_DATE = BUILD_DATE;
|
|
4921
4950
|
|
|
4922
|
-
export { BarcodeFormat, CameraAccessError, ConsoleLogHandler, DEFAULT_FORMATS, DeviceError, FaceComparisonError, FaceDetectionError, FaceModule, IDCardDetectionError, IDCardModule, IDCardType, IDScanner, IDScannerError, InitializationError, InvalidArgumentError, LivenessDetectionError, LoadingState, LoadingStateManager, LogLevel, Logger, MemoryLogHandler, ModuleManager, NotSupportedError, OCRProcessingError, QRCodeModule, QRScanError, RemoteLogHandler, ResourceLoadError, TaggedLogger, createLoadingStateManager, IDScanner as default };
|
|
4951
|
+
export { BarcodeFormat, CameraAccessError, ConsoleLogHandler, DEFAULT_FORMATS, DeviceError, FaceComparisonError, FaceDetectionError, FaceModule, IDCardDetectionError, IDCardModule, IDCardType, IDScanner, IDScannerError, InitializationError, InvalidArgumentError, LivenessDetectionError, LoadingState, LoadingStateManager, LogLevel, Logger, LoggerLevel, MemoryLogHandler, ModuleManager, NotSupportedError, OCRProcessingError, QRCodeModule, QRScanError, RemoteLogHandler, ResourceLoadError, TaggedLogger, createLoadingStateManager, IDScanner as default };
|
|
4923
4952
|
//# sourceMappingURL=id-scanner-lib.esm.js.map
|