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 CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 agions
3
+ Copyright (c) 2025-2026 agions
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -259,13 +259,17 @@ class ConfigManager {
259
259
  /**
260
260
  * 日志级别枚举
261
261
  */
262
- var LogLevel;
263
- (function (LogLevel) {
264
- LogLevel["DEBUG"] = "debug";
265
- LogLevel["INFO"] = "info";
266
- LogLevel["WARN"] = "warn";
267
- LogLevel["ERROR"] = "error";
268
- })(LogLevel || (LogLevel = {}));
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 LogLevel.DEBUG:
286
+ case LoggerLevel.DEBUG:
283
287
  console.debug(prefix, entry.message, entry.error || '');
284
288
  break;
285
- case LogLevel.INFO:
289
+ case LoggerLevel.INFO:
286
290
  console.info(prefix, entry.message, entry.error || '');
287
291
  break;
288
- case LogLevel.WARN:
292
+ case LoggerLevel.WARN:
289
293
  console.warn(prefix, entry.message, entry.error || '');
290
294
  break;
291
- case LogLevel.ERROR:
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
- window.addEventListener('beforeunload', () => {
373
- this.flush();
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 >= LogLevel.INFO) {
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 = LogLevel.INFO;
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(LogLevel.DEBUG, tag, message, error);
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(LogLevel.INFO, tag, message, error);
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(LogLevel.WARN, tag, message, error);
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(LogLevel.ERROR, tag, message, error);
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 LogLevel.DEBUG:
622
+ case LoggerLevel.DEBUG:
604
623
  console.debug(`${prefix} ${entry.message}`, entry.error || '');
605
624
  break;
606
- case LogLevel.INFO:
625
+ case LoggerLevel.INFO:
607
626
  console.info(`${prefix} ${entry.message}`, entry.error || '');
608
627
  break;
609
- case LogLevel.WARN:
628
+ case LoggerLevel.WARN:
610
629
  console.warn(`${prefix} ${entry.message}`, entry.error || '');
611
630
  break;
612
- case LogLevel.ERROR:
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 LogLevel.DEBUG:
642
+ case LoggerLevel.DEBUG:
624
643
  return 0;
625
- case LogLevel.INFO:
644
+ case LoggerLevel.INFO:
626
645
  return 1;
627
- case LogLevel.WARN:
646
+ case LoggerLevel.WARN:
628
647
  return 2;
629
- case LogLevel.ERROR:
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 = LogLevel.DEBUG;
662
+ this.logLevel = LoggerLevel.DEBUG;
644
663
  break;
645
664
  case 'info':
646
- this.logLevel = LogLevel.INFO;
665
+ this.logLevel = LoggerLevel.INFO;
647
666
  break;
648
667
  case 'warn':
649
- this.logLevel = LogLevel.WARN;
668
+ this.logLevel = LoggerLevel.WARN;
650
669
  break;
651
670
  case 'error':
652
- this.logLevel = LogLevel.ERROR;
671
+ this.logLevel = LoggerLevel.ERROR;
653
672
  break;
654
673
  default:
655
- this.logLevel = LogLevel.INFO;
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
- get data() {
1082
+ getData() {
1056
1083
  return this._data;
1057
1084
  }
1058
1085
  /**
1059
1086
  * 获取错误对象
1060
1087
  */
1061
- get error() {
1088
+ getError() {
1062
1089
  return this._error;
1063
1090
  }
1064
1091
  /**
1065
1092
  * 获取元数据
1066
1093
  */
1067
- get meta() {
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
- if (!detectionResult.isSuccess() || !detectionResult.data) {
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: detectionResult.data.type || IDCardType.FRONT,
3779
- confidence: detectionResult.data.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 = detectionResult.data.image || this.convertToImageData(image);
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.data) {
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: result.data.type,
3972
- confidence: result.data.confidence || 0,
3973
- croppedImage: result.data.image
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 !== false) {
4877
+ if (options.enableIDCard === true) {
4849
4878
  this.moduleManager.register(new IDCardModule(options.idCard));
4850
4879
  }
4851
- if (options.enableQRCode !== false) {
4880
+ if (options.enableQRCode === true) {
4852
4881
  this.moduleManager.register(new QRCodeModule(options.qrCode));
4853
4882
  }
4854
- if (options.enableFace !== false) {
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