id-scanner-lib 1.3.3 → 1.6.2

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 (80) hide show
  1. package/README.md +324 -410
  2. package/dist/id-scanner-lib.esm.js +4826 -0
  3. package/dist/id-scanner-lib.esm.js.map +1 -0
  4. package/dist/id-scanner-lib.js +4858 -0
  5. package/dist/id-scanner-lib.js.map +1 -0
  6. package/dist/types/browser-image-compression.d.ts +19 -0
  7. package/dist/types/tesseract.d.ts +280 -0
  8. package/package.json +89 -78
  9. package/src/core/base-module.ts +78 -0
  10. package/src/core/camera-manager.ts +813 -0
  11. package/src/core/config.ts +305 -0
  12. package/src/core/errors.ts +174 -0
  13. package/src/core/event-emitter.test.ts +42 -0
  14. package/src/core/event-emitter.ts +110 -0
  15. package/src/core/loading-state.test.ts +67 -0
  16. package/src/core/loading-state.ts +156 -0
  17. package/src/core/logger.test.ts +49 -0
  18. package/src/core/logger.ts +549 -0
  19. package/src/core/module-manager.ts +163 -0
  20. package/src/core/plugin-manager.ts +429 -0
  21. package/src/core/resource-manager.ts +762 -0
  22. package/src/core/result.ts +163 -0
  23. package/src/core/scanner-factory.ts +236 -0
  24. package/src/index.ts +117 -939
  25. package/src/interfaces/external-types.ts +200 -0
  26. package/src/interfaces/face-detection.ts +309 -0
  27. package/src/interfaces/scanner-module.ts +384 -0
  28. package/src/modules/face/face-detector.ts +988 -0
  29. package/src/modules/face/index.ts +208 -0
  30. package/src/modules/face/liveness-detector.ts +908 -0
  31. package/src/modules/face/types.ts +133 -0
  32. package/src/{id-recognition → modules/id-card}/anti-fake-detector.ts +274 -240
  33. package/src/modules/id-card/id-card-detector.ts +474 -0
  34. package/src/modules/id-card/index.ts +425 -0
  35. package/src/{id-recognition → modules/id-card}/ocr-processor.ts +149 -92
  36. package/src/modules/id-card/ocr-worker.ts +259 -0
  37. package/src/modules/id-card/types.ts +178 -0
  38. package/src/modules/qrcode/index.ts +175 -0
  39. package/src/modules/qrcode/qr-code-scanner.ts +231 -0
  40. package/src/modules/qrcode/types.ts +169 -0
  41. package/src/types/common.test.ts +99 -0
  42. package/src/types/common.ts +166 -0
  43. package/src/types/tesseract.d.ts +265 -22
  44. package/src/utils/camera.test.ts +30 -0
  45. package/src/utils/camera.ts +4 -1
  46. package/src/utils/error-handler.test.ts +137 -0
  47. package/src/utils/error-handler.ts +110 -0
  48. package/src/utils/image-processing.ts +68 -49
  49. package/src/utils/index.test.ts +186 -0
  50. package/src/utils/index.ts +429 -0
  51. package/src/utils/performance.ts +168 -131
  52. package/src/utils/resource-manager.ts +65 -146
  53. package/src/utils/retry.test.ts +142 -0
  54. package/src/utils/retry.ts +282 -0
  55. package/src/utils/types.ts +90 -2
  56. package/src/utils/utils.test.ts +171 -0
  57. package/src/utils/worker.ts +123 -84
  58. package/src/version.ts +11 -0
  59. package/tools/scaffold.js +543 -0
  60. package/dist/id-scanner-core.esm.js +0 -11349
  61. package/dist/id-scanner-core.js +0 -11361
  62. package/dist/id-scanner-core.min.js +0 -1
  63. package/dist/id-scanner-ocr.esm.js +0 -2319
  64. package/dist/id-scanner-ocr.js +0 -2328
  65. package/dist/id-scanner-ocr.min.js +0 -1
  66. package/dist/id-scanner-qr.esm.js +0 -1296
  67. package/dist/id-scanner-qr.js +0 -1305
  68. package/dist/id-scanner-qr.min.js +0 -1
  69. package/dist/id-scanner.js +0 -4561
  70. package/dist/id-scanner.min.js +0 -1
  71. package/src/core.ts +0 -138
  72. package/src/demo/demo.ts +0 -204
  73. package/src/id-recognition/data-extractor.ts +0 -262
  74. package/src/id-recognition/id-detector.ts +0 -510
  75. package/src/id-recognition/ocr-worker.ts +0 -156
  76. package/src/index-umd.ts +0 -477
  77. package/src/ocr-module.ts +0 -187
  78. package/src/qr-module.ts +0 -179
  79. package/src/scanner/barcode-scanner.ts +0 -251
  80. package/src/scanner/qr-scanner.ts +0 -167
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Type definitions for browser-image-compression
3
+ */
4
+
5
+ declare module 'browser-image-compression' {
6
+ export interface Options {
7
+ maxSizeMB?: number;
8
+ maxWidthOrHeight?: number;
9
+ useWebWorker?: boolean;
10
+ maxIteration?: number;
11
+ quality?: number;
12
+ fileType?: string;
13
+ onProgress?: (progress: number) => void;
14
+ }
15
+
16
+ function imageCompression(file: File, options?: Options): Promise<File>;
17
+
18
+ export default imageCompression;
19
+ }
@@ -0,0 +1,280 @@
1
+ /**
2
+ * Type definitions for tesseract.js
3
+ */
4
+
5
+ declare module "tesseract.js" {
6
+ // Based on https://github.com/naptha/tesseract.js/blob/master/src/index.d.ts
7
+ // and https://github.com/naptha/tesseract.js/blob/master/docs/api.md
8
+
9
+ export interface Point {
10
+ x: number
11
+ y: number
12
+ }
13
+
14
+ export interface Bbox {
15
+ x0: number
16
+ y0: number
17
+ x1: number
18
+ y1: number
19
+ }
20
+
21
+ export interface Baseline {
22
+ x0: number
23
+ y0: number
24
+ x1: number
25
+ y1: number
26
+ has_descenders: boolean
27
+ has_ascenders: boolean
28
+ }
29
+
30
+ export interface Word {
31
+ symbols: Symbol[]
32
+ choices: Choice[]
33
+ text: string
34
+ confidence: number
35
+ baseline: Baseline
36
+ bbox: Bbox
37
+ is_numeric: boolean
38
+ in_dictionary: boolean
39
+ direction: string
40
+ language: string
41
+ is_from_dictionary: boolean
42
+ is_fuzzy: boolean
43
+ is_certain: boolean
44
+ is_bold: boolean
45
+ is_italic: boolean
46
+ is_underlined: boolean
47
+ is_monospace: boolean
48
+ is_serif: boolean
49
+ is_smallcaps: boolean
50
+ font_id: number
51
+ font_size: number
52
+ font_name: string
53
+ }
54
+
55
+ export interface Symbol {
56
+ choices: Choice[]
57
+ image: null | HTMLImageElement // Or string if it's a path/URL
58
+ text: string
59
+ confidence: number
60
+ baseline: Baseline
61
+ bbox: Bbox
62
+ is_superscript: boolean
63
+ is_subscript: boolean
64
+ is_dropcap: boolean
65
+ }
66
+
67
+ export interface Choice {
68
+ text: string
69
+ confidence: number
70
+ }
71
+
72
+ export interface Line {
73
+ words: Word[]
74
+ text: string
75
+ confidence: number
76
+ baseline: Baseline
77
+ bbox: Bbox
78
+ }
79
+
80
+ export interface Paragraph {
81
+ lines: Line[]
82
+ text: string
83
+ confidence: number
84
+ baseline: Baseline
85
+ bbox: Bbox
86
+ is_ltr: boolean
87
+ }
88
+
89
+ export interface Block {
90
+ paragraphs: Paragraph[]
91
+ lines: Line[]
92
+ words: Word[]
93
+ text: string
94
+ confidence: number
95
+ baseline: Baseline
96
+ bbox: Bbox
97
+ blocktype: string
98
+ polygon: Point[]
99
+ }
100
+
101
+ export interface Page {
102
+ blocks: Block[]
103
+ confidence: number
104
+ html: string // HTML representation of the page
105
+ jobId?: string
106
+ text: string
107
+ lines: Line[]
108
+ oem: string
109
+ operator: string
110
+ paragraphs: Paragraph[]
111
+ psm: string
112
+ symbols: Symbol[]
113
+ version: string
114
+ words: Word[]
115
+ hocr?: string // hOCR output
116
+ tsv?: string // TSV output
117
+ }
118
+
119
+ export interface LoggerMessage {
120
+ jobId?: string
121
+ workerId?: string
122
+ status: string
123
+ progress: number
124
+ userfriendlyText?: string
125
+ }
126
+
127
+ export interface WorkerOptions {
128
+ langPath?: string
129
+ corePath?: string
130
+ workerPath?: string
131
+ logger?: (message: LoggerMessage) => void // More specific type for logger message <mcreference index="1" link="https://github.com/naptha/tesseract.js/blob/master/docs/api.md"></mcreference>
132
+ errorHandler?: (error: Error) => void
133
+ // Add other options based on documentation if needed
134
+ [key: string]: any // For other less common or dynamic options
135
+ }
136
+
137
+ export interface RecognizeResult {
138
+ data: Page // Use the detailed Page interface
139
+ }
140
+
141
+ export interface DetectResult {
142
+ data: {
143
+ tesseract_script_id: number | null
144
+ script: string | null
145
+ script_confidence: number | null
146
+ orientation_degrees: number | null
147
+ orientation_confidence: number | null
148
+ }
149
+ jobId?: string
150
+ }
151
+
152
+ export interface ConfigResult {
153
+ data: null
154
+ jobId?: string
155
+ }
156
+
157
+ export type ImageLike =
158
+ | HTMLImageElement
159
+ | HTMLCanvasElement
160
+ | File
161
+ | string
162
+ | Buffer
163
+ | ImageData // Common image types
164
+
165
+ export interface Worker {
166
+ load(jobId?: string): Promise<ConfigResult> // <mcreference index="4" link="https://github.com/naptha/tesseract.js/blob/master/src/index.d.ts"></mcreference>
167
+ loadLanguage(
168
+ langs?: string | string[],
169
+ jobId?: string
170
+ ): Promise<ConfigResult> // <mcreference index="4" link="https://github.com/naptha/tesseract.js/blob/master/src/index.d.ts"></mcreference>
171
+ initialize(
172
+ langs?: string | string[],
173
+ oem?: OEM,
174
+ config?: string | Partial<InitOptions>,
175
+ jobId?: string
176
+ ): Promise<ConfigResult> // <mcreference index="4" link="https://github.com/naptha/tesseract.js/blob/master/src/index.d.ts"></mcreference>
177
+ setParameters(
178
+ params: Partial<Parameters>,
179
+ jobId?: string
180
+ ): Promise<ConfigResult> // <mcreference index="4" link="https://github.com/naptha/tesseract.js/blob/master/src/index.d.ts"></mcreference>
181
+ recognize(
182
+ image: ImageLike,
183
+ options?: Partial<RecognizeOptions>,
184
+ output?: Partial<OutputFormats>,
185
+ jobId?: string
186
+ ): Promise<RecognizeResult> // <mcreference index="4" link="https://github.com/naptha/tesseract.js/blob/master/src/index.d.ts"></mcreference>
187
+ detect(
188
+ image: ImageLike,
189
+ options?: Partial<WorkerOptions>,
190
+ jobId?: string
191
+ ): Promise<DetectResult> // <mcreference index="4" link="https://github.com/naptha/tesseract.js/blob/master/src/index.d.ts"></mcreference>
192
+ terminate(jobId?: string): Promise<ConfigResult> // <mcreference index="4" link="https://github.com/naptha/tesseract.js/blob/master/src/index.d.ts"></mcreference>
193
+ // Add other worker methods if present in the version you are targeting
194
+ // Example from docs for other methods like FS operations:
195
+ writeText?(
196
+ path: string,
197
+ text: string,
198
+ jobId?: string
199
+ ): Promise<ConfigResult>
200
+ readText?(path: string, jobId?: string): Promise<ConfigResult>
201
+ removeFile?(path: string, jobId?: string): Promise<ConfigResult> // Assuming removeFile also returns ConfigResult or similar
202
+ FS?(method: string, args: any[], jobId?: string): Promise<any> // FS is more generic
203
+ }
204
+
205
+ // Based on Tesseract's OEM and PSM enums
206
+ export enum OEM {
207
+ TESSERACT_ONLY = 0,
208
+ LSTM_ONLY = 1,
209
+ TESSERACT_LSTM_COMBINED = 2,
210
+ DEFAULT = 3,
211
+ }
212
+
213
+ export enum PSM {
214
+ OSD_ONLY = 0,
215
+ AUTO_OSD = 1,
216
+ AUTO_ONLY = 2,
217
+ AUTO = 3,
218
+ SINGLE_COLUMN = 4,
219
+ SINGLE_BLOCK_VERT_TEXT = 5,
220
+ SINGLE_BLOCK = 6,
221
+ SINGLE_LINE = 7,
222
+ SINGLE_WORD = 8,
223
+ CIRCLE_WORD = 9,
224
+ SINGLE_CHAR = 10,
225
+ SPARSE_TEXT = 11,
226
+ SPARSE_TEXT_OSD = 12,
227
+ RAW_LINE = 13,
228
+ }
229
+
230
+ export interface Parameters {
231
+ tessedit_char_whitelist?: string
232
+ tessedit_pageseg_mode?: PSM
233
+ // Add other Tesseract parameters as needed
234
+ [key: string]: any // For flexibility with other parameters
235
+ }
236
+
237
+ export interface RecognizeOptions {
238
+ rectangle?: Bbox // For recognizing a specific region
239
+ rectangles?: Bbox[] // For recognizing multiple regions
240
+ // Add other recognize specific options
241
+ [key: string]: any
242
+ }
243
+
244
+ export interface OutputFormats {
245
+ text?: boolean
246
+ blocks?: boolean
247
+ hocr?: boolean
248
+ tsv?: boolean
249
+ pdf?: boolean // If PDF output is supported
250
+ // Add other output formats
251
+ [key: string]: any
252
+ }
253
+
254
+ export interface InitOptions {
255
+ load_system_dawg?: boolean
256
+ load_freq_dawg?: boolean
257
+ load_punc_dawg?: boolean
258
+ load_number_dawg?: boolean
259
+ load_unambig_dawg?: boolean
260
+ load_bigram_dawg?: boolean
261
+ load_fixed_length_dawgs?: boolean
262
+ // Add other init-only parameters
263
+ [key: string]: any
264
+ }
265
+
266
+ export function createWorker(options?: Partial<WorkerOptions>): Worker // 修正返回类型为 Worker 而非 Promise<Worker>
267
+ export function setLogging(logging: boolean): void
268
+ export function recognize(
269
+ image: ImageLike,
270
+ langs?: string | string[],
271
+ options?: Partial<RecognizeOptions & WorkerOptions>
272
+ ): Promise<RecognizeResult>
273
+ export function detect(
274
+ image: ImageLike,
275
+ options?: Partial<WorkerOptions>
276
+ ): Promise<DetectResult>
277
+
278
+ // 正确导出 OEM 和 PSM 枚举
279
+ export { OEM, PSM }
280
+ }
package/package.json CHANGED
@@ -1,95 +1,106 @@
1
1
  {
2
2
  "name": "id-scanner-lib",
3
- "version": "1.3.3",
4
- "type": "module",
5
- "main": "dist/id-scanner.js",
6
- "module": "dist/id-scanner-core.esm.js",
7
- "exports": {
8
- ".": {
9
- "import": "./dist/id-scanner-core.esm.js",
10
- "require": "./dist/id-scanner.js"
11
- },
12
- "./core": {
13
- "import": "./dist/id-scanner-core.esm.js",
14
- "require": "./dist/id-scanner-core.js"
15
- },
16
- "./ocr": {
17
- "import": "./dist/id-scanner-ocr.esm.js",
18
- "require": "./dist/id-scanner-ocr.js"
19
- },
20
- "./qr": {
21
- "import": "./dist/id-scanner-qr.esm.js",
22
- "require": "./dist/id-scanner-qr.js"
23
- }
24
- },
3
+ "version": "1.6.2",
4
+ "description": "Browser-based ID card, QR code, and face recognition scanner with liveness detection",
5
+ "main": "dist/id-scanner-lib.js",
6
+ "module": "dist/id-scanner-lib.esm.js",
25
7
  "types": "dist/types/index.d.ts",
26
- "sideEffects": false,
8
+ "files": [
9
+ "dist",
10
+ "src",
11
+ "LICENSE",
12
+ "README.md"
13
+ ],
14
+ "bin": {
15
+ "id-scanner-scaffold": "./tools/scaffold.js"
16
+ },
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
27
20
  "scripts": {
28
- "build": "rollup -c",
29
- "dev": "rollup -c -w",
30
- "test": "echo \"Error: no test specified\" && exit 1",
31
- "prepublishOnly": "npm run build",
32
- "publish:npm": "node scripts/publish.js",
33
- "update:github": "node scripts/update-github.js",
34
- "analyze": "rollup -c --environment ANALYZE:true",
35
- "build:prod": "rollup -c --environment NODE_ENV:production",
36
- "size": "npm run build:prod && node scripts/size-report.js",
37
- "serve:demo": "npx http-server examples -o"
21
+ "build": "rimraf dist && rollup -c rollup.config.js",
22
+ "dev": "vite build --watch",
23
+ "test": "jest",
24
+ "lint": "eslint --ext .ts,.js src",
25
+ "format": "prettier --write \"src/**/*.{ts,js}\"",
26
+ "docs:dev": "vitepress dev docs",
27
+ "docs:build": "vitepress build docs",
28
+ "docs:serve": "vitepress serve docs",
29
+ "prepare": "npm run build",
30
+ "scaffold": "node ./tools/scaffold.js"
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/agions/id-scanner-lib.git"
38
35
  },
39
36
  "keywords": [
37
+ "id-scanner",
40
38
  "id-card",
41
39
  "qr-code",
42
40
  "scanner",
43
- "ocr",
44
- "barcode",
45
- "identity",
46
- "recognition",
47
- "image-processing"
41
+ "face-recognition",
42
+ "id-verification",
43
+ "face-detection",
44
+ "face-liveness",
45
+ "biometrics",
46
+ "webcam"
48
47
  ],
49
- "author": "agions",
48
+ "author": "Your Name",
50
49
  "license": "MIT",
51
- "description": "一款纯前端实现的TypeScript身份证&二维码识别库,无需后端支持,所有处理在浏览器端完成,新增图像批处理与优化",
52
- "repository": {
53
- "type": "git",
54
- "url": "git+https://github.com/agions/id-scanner-lib.git"
55
- },
56
50
  "bugs": {
57
- "url": "https://github.com/agions/id-scanner-lib/issues"
51
+ "url": "https://github.com/yourusername/id-scanner-lib/issues"
58
52
  },
59
- "homepage": "https://github.com/agions/id-scanner-lib#readme",
60
- "files": [
61
- "dist",
62
- "src",
63
- "README.md",
64
- "LICENSE"
65
- ],
66
- "publishConfig": {
67
- "access": "public"
53
+ "homepage": "https://github.com/yourusername/id-scanner-lib#readme",
54
+ "dependencies": {
55
+ "@tensorflow/tfjs": "^4.16.0",
56
+ "@vladmandic/face-api": "^1.7.13",
57
+ "jsqr": "^1.4.0"
68
58
  },
69
59
  "devDependencies": {
70
- "@rollup/plugin-commonjs": "^28.0.3",
71
- "@rollup/plugin-json": "^6.1.0",
72
- "@rollup/plugin-node-resolve": "^16.0.1",
73
- "@rollup/plugin-terser": "^0.4.4",
74
- "@rollup/plugin-typescript": "^12.1.2",
75
- "@types/node": "^22.13.10",
76
- "picocolors": "^1.1.1",
77
- "rollup": "^4.35.0",
78
- "rollup-plugin-bundle-analyzer": "^1.6.6",
79
- "rollup-plugin-visualizer": "^5.9.2",
80
- "tslib": "^2.8.1",
81
- "typescript": "^5.8.2"
60
+ "@babel/core": "^7.23.7",
61
+ "@babel/preset-env": "^7.23.7",
62
+ "@babel/preset-typescript": "^7.23.7",
63
+ "@eslint/js": "^10.0.1",
64
+ "@rollup/plugin-babel": "^6.0.4",
65
+ "@rollup/plugin-commonjs": "^25.0.7",
66
+ "@rollup/plugin-json": "^6.0.1",
67
+ "@rollup/plugin-node-resolve": "^15.2.3",
68
+ "@rollup/plugin-terser": "^1.0.0",
69
+ "@rollup/plugin-typescript": "^11.1.5",
70
+ "@testing-library/jest-dom": "^6.9.1",
71
+ "@types/jest": "^29.5.11",
72
+ "@types/node": "^20.0.0",
73
+ "@typescript-eslint/eslint-plugin": "^8.56.1",
74
+ "@typescript-eslint/parser": "^8.56.1",
75
+ "dts-bundle-generator": "^9.2.4",
76
+ "eslint": "^9.39.4",
77
+ "eslint-config-prettier": "^9.1.0",
78
+ "eslint-plugin-prettier": "^5.1.3",
79
+ "globals": "^17.4.0",
80
+ "jest": "^29.7.0",
81
+ "jest-environment-jsdom": "^30.2.0",
82
+ "prettier": "^3.2.4",
83
+ "rimraf": "^5.0.5",
84
+ "rollup": "^4.9.6",
85
+ "rollup-plugin-copy": "^3.5.0",
86
+ "rollup-plugin-dts": "^6.1.0",
87
+ "rollup-plugin-livereload": "^2.0.5",
88
+ "rollup-plugin-polyfill-node": "^0.13.0",
89
+ "rollup-plugin-serve": "^1.1.1",
90
+ "rollup-plugin-typescript2": "^0.36.0",
91
+ "ts-jest": "^29.1.1",
92
+ "tslib": "^2.6.2",
93
+ "typedoc": "^0.25.7",
94
+ "typescript": "^5.9.3",
95
+ "typescript-eslint": "^8.57.1",
96
+ "vite-plugin-dts": "^4.5.4",
97
+ "vitepress": "^1.6.4"
82
98
  },
83
- "dependencies": {
84
- "browser-image-compression": "^2.0.2",
85
- "jsqr": "^1.4.0",
86
- "lodash-es": "^4.17.21",
87
- "tesseract.js": "^6.0.0"
99
+ "engines": {
100
+ "node": ">=14.0.0"
88
101
  },
89
- "browserslist": [
90
- ">0.2%",
91
- "not dead",
92
- "not op_mini all",
93
- "last 2 versions"
94
- ]
95
- }
102
+ "overrides": {
103
+ "esbuild": "^0.27.0",
104
+ "vite": "^6.0.0"
105
+ }
106
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * @file 基础模块
3
+ * @description 提供基础模块实现,作为所有功能模块的基类
4
+ * @module core/base-module
5
+ */
6
+
7
+ import { EventEmitter } from './event-emitter';
8
+ import { Logger } from './logger';
9
+ import { Module } from './module-manager';
10
+ import { VERSION } from '../version';
11
+
12
+ /**
13
+ * 基础模块类
14
+ * 提供模块的基本功能和生命周期管理
15
+ */
16
+ export abstract class BaseModule extends EventEmitter implements Module {
17
+ /** 模块名称 */
18
+ public abstract readonly name: string;
19
+
20
+ /** 模块版本 */
21
+ public readonly version: string = VERSION;
22
+
23
+ /** 模块是否已初始化 */
24
+ protected _isInitialized: boolean = false;
25
+
26
+ /** 日志工具 */
27
+ protected logger: Logger;
28
+
29
+ /**
30
+ * 构造函数
31
+ */
32
+ constructor() {
33
+ super();
34
+ this.logger = Logger.getInstance();
35
+ }
36
+
37
+ /**
38
+ * 获取模块是否已初始化
39
+ */
40
+ public get isInitialized(): boolean {
41
+ return this._isInitialized;
42
+ }
43
+
44
+ /**
45
+ * 初始化模块
46
+ * 子类必须实现此方法
47
+ */
48
+ public abstract initialize(): Promise<void>;
49
+
50
+ /**
51
+ * 释放模块资源
52
+ * 子类可以覆盖此方法以添加额外的资源释放逻辑
53
+ */
54
+ public async dispose(): Promise<void> {
55
+ if (!this._isInitialized) {
56
+ return;
57
+ }
58
+
59
+ this.logger.debug(this.name, '释放模块资源');
60
+
61
+ // 重置初始化状态
62
+ this._isInitialized = false;
63
+
64
+ // 删除所有事件监听器
65
+ this.removeAllListeners();
66
+
67
+ this.logger.debug(this.name, '模块资源已释放');
68
+ }
69
+
70
+ /**
71
+ * 检查模块是否已初始化,如果未初始化则抛出错误
72
+ */
73
+ protected ensureInitialized(): void {
74
+ if (!this._isInitialized) {
75
+ throw new Error(`模块 ${this.name} 尚未初始化`);
76
+ }
77
+ }
78
+ }