pure-md5 0.2.0 → 0.2.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 (177) hide show
  1. package/README.md +38 -24
  2. package/dist/adapters/ie11.cjs +1 -2
  3. package/dist/adapters/ie11.js +1 -2
  4. package/dist/adapters/node.cjs +1 -2
  5. package/dist/adapters/node.js +1 -2
  6. package/dist/adapters/webcrypto.cjs +1 -2
  7. package/dist/adapters/webcrypto.js +1 -2
  8. package/dist/index.cjs +1 -2
  9. package/dist/index.d.ts +149 -5
  10. package/dist/index.js +3 -2
  11. package/dist/md5.cjs +1 -0
  12. package/dist/md5.d.ts +20 -0
  13. package/dist/md5.js +1 -0
  14. package/dist/stream/md5-stream.cjs +1 -2
  15. package/dist/stream/md5-stream.js +1 -2
  16. package/dist/stream/whatwg-stream.cjs +1 -2
  17. package/dist/stream/whatwg-stream.js +1 -2
  18. package/dist/utils/detect.cjs +1 -2
  19. package/dist/utils/detect.js +3 -2
  20. package/package.json +10 -15
  21. package/pure-md5-0.2.1.tgz +0 -0
  22. package/test-tree-shake.mjs +12 -0
  23. package/.aliases +0 -19
  24. package/.bash_profile +0 -12
  25. package/.bash_prompt +0 -56
  26. package/.changeset/README.md +0 -32
  27. package/.changeset/config.json +0 -16
  28. package/.continue/mcpServers/new-mcp-server.yaml +0 -10
  29. package/.continue/rules +0 -29
  30. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -35
  31. package/.github/ISSUE_TEMPLATE/documentation.md +0 -20
  32. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  33. package/.github/PULL_REQUEST_TEMPLATE.md +0 -35
  34. package/.github/workflows/npm-publish.yml +0 -33
  35. package/.github/workflows/release.yml +0 -42
  36. package/CHANGELOG.md +0 -9
  37. package/CONTRIBUTING.md +0 -203
  38. package/MIGRATION_GUIDE_STREAMS.md +0 -374
  39. package/STREAM_API.md +0 -582
  40. package/STREAM_BENCHMARKS.md +0 -232
  41. package/STREAM_EXAMPLES.md +0 -669
  42. package/STREAM_OPTIMIZATION_REPORT.md +0 -136
  43. package/STREAM_TROUBLESHOOTING.md +0 -537
  44. package/WEB_CRYPTO_TESTS_SUMMARY.md +0 -140
  45. package/WHATWG_STREAMS.md +0 -191
  46. package/__tests__/adapters/node-crypto.test.ts +0 -167
  47. package/__tests__/adapters/web-crypto-node.test.ts +0 -73
  48. package/__tests__/adapters/web-crypto.test.ts +0 -195
  49. package/__tests__/add32.test.ts +0 -33
  50. package/__tests__/fallback.test.ts +0 -345
  51. package/__tests__/hex.test.ts +0 -38
  52. package/__tests__/hex_chr.test.ts +0 -20
  53. package/__tests__/index.test.ts +0 -87
  54. package/__tests__/integration/fixtures/test-file.txt +0 -1
  55. package/__tests__/integration/md5-stream-file.test.ts +0 -293
  56. package/__tests__/integration/node-crypto-file.test.ts +0 -86
  57. package/__tests__/integration/web-crypto.test.ts +0 -38
  58. package/__tests__/md51.test.ts +0 -73
  59. package/__tests__/md5block.test.ts +0 -61
  60. package/__tests__/md5cycle.test.ts +0 -48
  61. package/__tests__/round-functions.test.ts +0 -87
  62. package/__tests__/stream/fs-utils.test.ts +0 -209
  63. package/__tests__/stream/md5-stream-edge-cases.test.ts +0 -461
  64. package/__tests__/stream/md5-stream.test.ts +0 -418
  65. package/__tests__/stream/whatwg-stream.test.ts +0 -355
  66. package/__tests__/stream/whatwg-stream.test.ts.bak2 +0 -335
  67. package/benchmarks/md5-stream.bench.ts +0 -212
  68. package/benchmarks/whatwg-stream.bench.ts +0 -180
  69. package/dist/adapters/ie11.cjs.map +0 -1
  70. package/dist/adapters/ie11.js.map +0 -1
  71. package/dist/adapters/node.cjs.map +0 -1
  72. package/dist/adapters/node.js.map +0 -1
  73. package/dist/adapters/webcrypto.cjs.map +0 -1
  74. package/dist/adapters/webcrypto.js.map +0 -1
  75. package/dist/chunk-2YXXFGBV.js +0 -2
  76. package/dist/chunk-2YXXFGBV.js.map +0 -1
  77. package/dist/chunk-4KSCMS4Q.js +0 -2
  78. package/dist/chunk-4KSCMS4Q.js.map +0 -1
  79. package/dist/chunk-6P2QV5SR.js +0 -4
  80. package/dist/chunk-6P2QV5SR.js.map +0 -1
  81. package/dist/chunk-G5WHEAIQ.js +0 -2
  82. package/dist/chunk-G5WHEAIQ.js.map +0 -1
  83. package/dist/chunk-H2K353LR.js +0 -2
  84. package/dist/chunk-H2K353LR.js.map +0 -1
  85. package/dist/chunk-JKVD5LHZ.js +0 -2
  86. package/dist/chunk-JKVD5LHZ.js.map +0 -1
  87. package/dist/chunk-NWQ4N5RX.js +0 -2
  88. package/dist/chunk-NWQ4N5RX.js.map +0 -1
  89. package/dist/chunk-PHZ7FTYF.js +0 -2
  90. package/dist/chunk-PHZ7FTYF.js.map +0 -1
  91. package/dist/chunk-PNZTVQA7.js +0 -2
  92. package/dist/chunk-PNZTVQA7.js.map +0 -1
  93. package/dist/chunk-R4JB5MBR.js +0 -2
  94. package/dist/chunk-R4JB5MBR.js.map +0 -1
  95. package/dist/chunk-VFOAY6XI.js +0 -2
  96. package/dist/chunk-VFOAY6XI.js.map +0 -1
  97. package/dist/chunk-XB5BQIEX.js +0 -2
  98. package/dist/chunk-XB5BQIEX.js.map +0 -1
  99. package/dist/core/index.cjs +0 -2
  100. package/dist/core/index.cjs.map +0 -1
  101. package/dist/core/index.d.cts +0 -19
  102. package/dist/core/index.d.ts +0 -19
  103. package/dist/core/index.js +0 -2
  104. package/dist/core/index.js.map +0 -1
  105. package/dist/index.cjs.map +0 -1
  106. package/dist/index.d.cts +0 -84
  107. package/dist/index.js.map +0 -1
  108. package/dist/stream/adapter.cjs +0 -2
  109. package/dist/stream/adapter.cjs.map +0 -1
  110. package/dist/stream/adapter.d.cts +0 -63
  111. package/dist/stream/adapter.d.ts +0 -63
  112. package/dist/stream/adapter.js +0 -2
  113. package/dist/stream/adapter.js.map +0 -1
  114. package/dist/stream/fs-utils.cjs +0 -2
  115. package/dist/stream/fs-utils.cjs.map +0 -1
  116. package/dist/stream/fs-utils.d.cts +0 -137
  117. package/dist/stream/fs-utils.d.ts +0 -137
  118. package/dist/stream/fs-utils.js +0 -2
  119. package/dist/stream/fs-utils.js.map +0 -1
  120. package/dist/stream/index.cjs +0 -2
  121. package/dist/stream/index.cjs.map +0 -1
  122. package/dist/stream/index.d.cts +0 -4
  123. package/dist/stream/index.d.ts +0 -4
  124. package/dist/stream/index.js +0 -2
  125. package/dist/stream/index.js.map +0 -1
  126. package/dist/stream/light/index.cjs +0 -2
  127. package/dist/stream/light/index.cjs.map +0 -1
  128. package/dist/stream/light/index.d.cts +0 -4
  129. package/dist/stream/light/index.d.ts +0 -4
  130. package/dist/stream/light/index.js +0 -2
  131. package/dist/stream/light/index.js.map +0 -1
  132. package/dist/stream/md5-stream.cjs.map +0 -1
  133. package/dist/stream/md5-stream.js.map +0 -1
  134. package/dist/stream/whatwg-stream.cjs.map +0 -1
  135. package/dist/stream/whatwg-stream.js.map +0 -1
  136. package/dist/types-edGoGJ5V.d.cts +0 -42
  137. package/dist/types-edGoGJ5V.d.ts +0 -42
  138. package/dist/utils/detect.cjs.map +0 -1
  139. package/dist/utils/detect.js.map +0 -1
  140. package/planning/03-optimization-size-tree-shaking/01-es-modules-tree-shaking.md +0 -152
  141. package/planning/03-optimization-size-tree-shaking/02-consolidate-modules.md +0 -65
  142. package/planning/03-optimization-size-tree-shaking/03-remove-duplicate-add32.md +0 -93
  143. package/planning/03-optimization-size-tree-shaking/04-remove-runtime-check.md +0 -102
  144. package/planning/03-optimization-size-tree-shaking/05-optimize-loops-performance.md +0 -107
  145. package/planning/03-optimization-size-tree-shaking/06-tsup-formats-configuration.md +0 -227
  146. package/planning/03-optimization-size-tree-shaking/07-multiple-build-formats.md +0 -228
  147. package/planning/03-optimization-size-tree-shaking/08-benchmarks-metrics.md +0 -34
  148. package/planning/03-optimization-size-tree-shaking/MIGRATION_GUIDE.md +0 -260
  149. package/planning/03-optimization-size-tree-shaking/README.md +0 -173
  150. package/planning/03-optimization-size-tree-shaking/SUMMARY.md +0 -168
  151. package/planning/04-adapter-backend/03-backend-web-crypto.md +0 -149
  152. package/planning/04-adapter-backend/04-backend-node-crypto.md +0 -181
  153. package/planning/04-adapter-backend/05-backend-pure-js.md +0 -174
  154. package/planning/04-adapter-backend/06-backend-ie11.md +0 -158
  155. package/planning/04-adapter-backend/07-detection-environment.md +0 -232
  156. package/planning/04-adapter-backend/08-detection-backend.md +0 -210
  157. package/planning/04-adapter-backend/09-adapter-unified.md +0 -255
  158. package/planning/04-adapter-backend/10-fallback-mechanism.md +0 -333
  159. package/planning/04-adapter-backend/11-tests-backend-web-crypto.md +0 -191
  160. package/planning/04-adapter-backend/12-tests-backend-node-crypto.md +0 -222
  161. package/planning/04-adapter-backend/README.md +0 -45
  162. package/planning/05-documentation-publishing/01-README-optimization.md +0 -105
  163. package/planning/05-documentation-publishing/02-VitePress-site-evaluation.md +0 -136
  164. package/planning/05-documentation-publishing/03-Changeset-setup.md +0 -192
  165. package/planning/05-documentation-publishing/04-GitHub-templates.md +0 -252
  166. package/planning/05-documentation-publishing/README.md +0 -22
  167. package/planning/05-documentation-publishing/STATUS.md +0 -222
  168. package/planning/prd.md +0 -405
  169. package/planning/streams/01-create-md5stream-class.md +0 -69
  170. package/planning/streams/02-create-factory-api.md +0 -65
  171. package/planning/streams/03-fs-integration.md +0 -37
  172. package/planning/streams/04-whatwg-streams-support.md +0 -37
  173. package/planning/streams/05-audit-optimization.md +0 -121
  174. package/planning/streams/06-comprehensive-tests-docs.md +0 -137
  175. package/planning/streams/07-architecture-integration.md +0 -38
  176. package/planning/streams/README.md +0 -98
  177. package/tsup.config.ts +0 -24
@@ -1,158 +0,0 @@
1
- # Task 06: Support for Internet Explorer 11 (msCrypto)
2
-
3
- ## Goal
4
-
5
- Создать адаптер для использования устаревшего `window.msCrypto` в Internet Explorer 11.
6
-
7
- ## Важные замечания
8
-
9
- - IE11 поддерживает только подмножество Web Crypto API
10
- - Некоторые алгоритмы могут отличаться
11
- - Проверить совместимость с MD5
12
-
13
- ## Implementation
14
-
15
- ### 1. Создать файл src/adapters/ie11.ts
16
-
17
- ```typescript
18
- export class IE11Backend implements MD5Backend {
19
- static name = 'ie11';
20
- static version = '1.0.0';
21
-
22
- private crypto: Crypto;
23
- private algorithm: string = 'MD5';
24
-
25
- constructor() {
26
- if (!this.isAvailable()) {
27
- throw new Error('IE11 Crypto is not available');
28
- }
29
- this.crypto = (window as any).msCrypto;
30
- }
31
-
32
- async hash(data: string): Promise<string> {
33
- const encoder = new TextEncoder();
34
- const buffer = encoder.encode(data);
35
- const hashBuffer = await this.crypto.subtle.digest(this.algorithm, buffer);
36
- return this.bufferToHex(hashBuffer);
37
- }
38
-
39
- async hashBinary(data: ArrayBuffer | Uint8Array): Promise<string> {
40
- const buffer = data instanceof Uint8Array
41
- ? data.buffer
42
- : data;
43
- const hashBuffer = await this.crypto.subtle.digest(this.algorithm, buffer);
44
- return this.bufferToHex(hashBuffer);
45
- }
46
-
47
- static async isAvailable(): Promise<boolean> {
48
- if (typeof window === 'undefined') {
49
- return false;
50
- }
51
-
52
- const msCrypto = (window as any).msCrypto;
53
- if (!msCrypto) {
54
- return false;
55
- }
56
-
57
- if (!msCrypto.subtle) {
58
- return false;
59
- }
60
-
61
- try {
62
- // Checking поддержки MD5
63
- const testBuffer = new Uint8Array([1, 2, 3, 4]);
64
- await msCrypto.subtle.digest('MD5', testBuffer);
65
- return true;
66
- } catch {
67
- return false;
68
- }
69
- }
70
-
71
- private bufferToHex(buffer: ArrayBuffer): string {
72
- const bytes = new Uint8Array(buffer);
73
- return Array.from(bytes)
74
- .map(b => b.toString(16).padStart(2, '0'))
75
- .join('');
76
- }
77
- }
78
- ```
79
-
80
- ### 2. Tests
81
-
82
- Создать файл `__tests__/adapters/ie11.test.ts`:
83
-
84
- ```typescript
85
- describe('IE11Backend', () => {
86
- let backend: IE11Backend;
87
-
88
- beforeAll(async () => {
89
- if (!await IE11Backend.isAvailable()) {
90
- console.log('IE11 Crypto not available, skipping tests');
91
- return;
92
- }
93
- backend = new IE11Backend();
94
- });
95
-
96
- it('should hash string correctly', async () => {
97
- const result = await backend.hash('hello');
98
- expect(result).toBe('5d41402abc4b2a76b9719d911017c592');
99
- });
100
-
101
- it('should hash empty string', async () => {
102
- const result = await backend.hash('');
103
- expect(result).toBe('d41d8cd98f00b204e9800998ecf8427e');
104
- });
105
-
106
- it('should be available in IE11', async () => {
107
- const available = await IE11Backend.isAvailable();
108
- // В реальных тестах этот тест будет пропущен в modern browsers
109
- if (available) {
110
- expect(true).toBe(true);
111
- }
112
- });
113
- });
114
- ```
115
-
116
- ### 3. Integration
117
-
118
- В `src/adapters/index.ts`:
119
-
120
- ```typescript
121
- export { IE11Backend } from './ie11.js';
122
- ```
123
-
124
- ### 4. Conditional exports
125
-
126
- В `package.json`:
127
-
128
- ```json
129
- {
130
- "exports": {
131
- "./adapters/ie11": {
132
- "types": "./dist/adapters/ie11.d.ts",
133
- "import": "./dist/adapters/ie11.js"
134
- }
135
- }
136
- }
137
- ```
138
-
139
- ### 5. Обработка ошибок
140
-
141
- В IE11 могут возникнуть ошибки, поэтому обернуть в try-catch:
142
-
143
- ```typescript
144
- try {
145
- const backend = new IE11Backend();
146
- const result = await backend.hash('data');
147
- } catch (error) {
148
- console.warn('IE11 backend failed:', error);
149
- // Fallback to pure JS
150
- }
151
- ```
152
-
153
- ## Ожидаемый результат
154
-
155
- - ✅ IE11Backend реализован
156
- - ✅ Tests проходят успешно (если IE11 доступен)
157
- - ✅ Интегрирован в общую систему адаптеров
158
- - ✅ Обработка ошибок при отсутствии поддержки
@@ -1,232 +0,0 @@
1
- # Task 07: Environment Detection and Available Backends Implementation
2
-
3
- ## Goal
4
-
5
- Создать систему обнаружения окружения (браузер, Node.js) и проверки доступности backend'ов.
6
-
7
- ## Implementation
8
-
9
- ### 1. Создать файл src/detection/environment.ts
10
-
11
- ```typescript
12
- export enum RuntimeEnvironment {
13
- BROWSER = 'browser',
14
- NODE = 'node',
15
- WEBWORKER = 'webworker',
16
- UNKNOWN = 'unknown'
17
- }
18
-
19
- export function detectEnvironment(): RuntimeEnvironment {
20
- // Check Node.js environment
21
- if (typeof process !== 'undefined' && process.versions && process.versions.node) {
22
- return RuntimeEnvironment.NODE;
23
- }
24
-
25
- // Check web worker
26
- if (typeof importScripts !== 'undefined') {
27
- return RuntimeEnvironment.WEBWORKER;
28
- }
29
-
30
- // Check browser
31
- if (typeof window !== 'undefined' && window.document) {
32
- return RuntimeEnvironment.BROWSER;
33
- }
34
-
35
- return RuntimeEnvironment.UNKNOWN;
36
- }
37
-
38
- export function isNode(): boolean {
39
- return typeof process !== 'undefined' &&
40
- process.versions !== undefined &&
41
- 'node' in process.versions;
42
- }
43
-
44
- export function isBrowser(): boolean {
45
- return typeof window !== 'undefined' &&
46
- typeof document !== 'undefined';
47
- }
48
-
49
- export function isWebWorker(): boolean {
50
- return typeof importScripts !== 'undefined';
51
- }
52
- ```
53
-
54
- ### 2. Checking конкретных backend'ов
55
-
56
- Создать файл `src/detection/backend-availability.ts`:
57
-
58
- ```typescript
59
- import { PureJSBackend } from '../adapters/pure-js.js';
60
- import { WebCryptoBackend } from '../adapters/web-crypto.js';
61
- import { NodeCryptoBackend } from '../adapters/node-crypto.js';
62
- import { IE11Backend } from '../adapters/ie11.js';
63
-
64
- export interface BackendAvailability {
65
- backend: string;
66
- available: boolean;
67
- reason?: string;
68
- }
69
-
70
- export async function checkBackendAvailability(backend: string): Promise<BackendAvailability> {
71
- switch (backend) {
72
- case 'webcrypto':
73
- const webCryptoAvailable = await WebCryptoBackend.isAvailable();
74
- return {
75
- backend: 'webcrypto',
76
- available: webCryptoAvailable,
77
- reason: webCryptoAvailable ? undefined : 'Web Crypto API not available'
78
- };
79
-
80
- case 'nodecrypto':
81
- const nodeCryptoAvailable = NodeCryptoBackend.isAvailable();
82
- return {
83
- backend: 'nodecrypto',
84
- available: nodeCryptoAvailable,
85
- reason: nodeCryptoAvailable ? undefined : 'Node.js crypto not available'
86
- };
87
-
88
- case 'ie11':
89
- const ie11Available = await IE11Backend.isAvailable();
90
- return {
91
- backend: 'ie11',
92
- available: ie11Available,
93
- reason: ie11Available ? undefined : 'IE11 msCrypto not available'
94
- };
95
-
96
- case 'purejs':
97
- return {
98
- backend: 'purejs',
99
- available: PureJSBackend.isAvailable(),
100
- reason: 'Always available'
101
- };
102
-
103
- default:
104
- return {
105
- backend,
106
- available: false,
107
- reason: 'Unknown backend'
108
- };
109
- }
110
- }
111
-
112
- export async function getAllAvailableBackends(): Promise<string[]> {
113
- const backends = ['webcrypto', 'nodecrypto', 'ie11', 'purejs'];
114
- const available: string[] = [];
115
-
116
- for (const backend of backends) {
117
- const { available: isAvailable } = await checkBackendAvailability(backend);
118
- if (isAvailable) {
119
- available.push(backend);
120
- }
121
- }
122
-
123
- return available;
124
- }
125
- ```
126
-
127
- ### 3. Rating backend'ов по приоритету
128
-
129
- Создать файл `src/detection/backend-ranking.ts`:
130
-
131
- ```typescript
132
- export interface BackendPriority {
133
- name: string;
134
- priority: number;
135
- description: string;
136
- }
137
-
138
- export const BACKEND_PRIORITY: BackendPriority[] = [
139
- {
140
- name: 'nodecrypto',
141
- priority: 1,
142
- description: 'Node.js native crypto (fastest)'
143
- },
144
- {
145
- name: 'webcrypto',
146
- priority: 2,
147
- description: 'Web Crypto API (fast, hardware accelerated)'
148
- },
149
- {
150
- name: 'ie11',
151
- priority: 3,
152
- description: 'IE11 msCrypto (legacy)'
153
- },
154
- {
155
- name: 'purejs',
156
- priority: 4,
157
- description: 'Pure JavaScript (always available, slower)'
158
- }
159
- ];
160
-
161
- export function getBestAvailableBackend(availableBackends: string[]): string {
162
- const sortedPriority = [...BACKEND_PRIORITY].sort((a, b) => a.priority - b.priority);
163
-
164
- for (const { name } of sortedPriority) {
165
- if (availableBackends.includes(name)) {
166
- return name;
167
- }
168
- }
169
-
170
- return 'purejs'; // Fallback
171
- }
172
- ```
173
-
174
- ### 4. Integration с фабрикой адаптеров
175
-
176
- В `src/detection/index.ts`:
177
-
178
- ```typescript
179
- export { detectEnvironment, isNode, isBrowser, isWebWorker, RuntimeEnvironment } from './environment.js';
180
- export { checkBackendAvailability, getAllAvailableBackends } from './backend-availability.js';
181
- export { BACKEND_PRIORITY, getBestAvailableBackend } from './backend-ranking.js';
182
- ```
183
-
184
- ### 5. Tests
185
-
186
- Создать файл `__tests__/detection/environment.test.ts`:
187
-
188
- ```typescript
189
- describe('Environment Detection', () => {
190
- it('should detect Node.js environment', () => {
191
- const env = detectEnvironment();
192
- expect(env).toBeDefined();
193
- });
194
-
195
- it('should detect browser environment', () => {
196
- const isBrowser = detectEnvironment() === RuntimeEnvironment.BROWSER;
197
- // May be true or false depending on test environment
198
- expect(typeof isBrowser).toBe('boolean');
199
- });
200
- });
201
-
202
- describe('Backend Availability', () => {
203
- it('should check pure JS availability', async () => {
204
- const result = await checkBackendAvailability('purejs');
205
- expect(result.available).toBe(true);
206
- });
207
-
208
- it('should check web crypto availability', async () => {
209
- const result = await checkBackendAvailability('webcrypto');
210
- expect(typeof result.available).toBe('boolean');
211
- });
212
-
213
- it('should get all available backends', async () => {
214
- const backends = await getAllAvailableBackends();
215
- expect(Array.isArray(backends)).toBe(true);
216
- expect(backends.length).toBeGreaterThan(0);
217
- });
218
-
219
- it('should get best available backend', async () => {
220
- const available = await getAllAvailableBackends();
221
- const best = getBestAvailableBackend(available);
222
- expect(typeof best).toBe('string');
223
- });
224
- });
225
- ```
226
-
227
- ## Ожидаемый результат
228
-
229
- - ✅ System обнаружения окружения реализована
230
- - ✅ Checking доступности backend'ов работает корректно
231
- - ✅ Rating backend'ов по приоритету настроен
232
- - ✅ Tests проходят успешно
@@ -1,210 +0,0 @@
1
- # Task 08: Optimal Backend Detection System Implementation
2
-
3
- ## Goal
4
-
5
- Создать систему интеллектуального выбора оптимального backend'а на основе окружения и приоритетов.
6
-
7
- ## Implementation
8
-
9
- ### 1. Создать файл src/detection/backend-detector.ts
10
-
11
- ```typescript
12
- import { detectEnvironment, RuntimeEnvironment } from './environment.js';
13
- import { checkBackendAvailability, getAllAvailableBackends } from './backend-availability.js';
14
- import { BACKEND_PRIORITY, getBestAvailableBackend } from './backend-ranking.js';
15
- import { PureJSBackend } from '../adapters/pure-js.js';
16
- import { WebCryptoBackend } from '../adapters/web-crypto.js';
17
- import { NodeCryptoBackend } from '../adapters/node-crypto.js';
18
- import { IE11Backend } from '../adapters/ie11.js';
19
-
20
- export interface DetectionResult {
21
- backend: string;
22
- environment: RuntimeEnvironment;
23
- availableBackends: string[];
24
- selectedBy: string;
25
- }
26
-
27
- export class BackendDetector {
28
- private static instance: BackendDetector;
29
-
30
- private constructor() {}
31
-
32
- static getInstance(): BackendDetector {
33
- if (!BackendDetector.instance) {
34
- BackendDetector.instance = new BackendDetector();
35
- }
36
- return BackendDetector.instance;
37
- }
38
-
39
- async detect(): Promise<DetectionResult> {
40
- const environment = detectEnvironment();
41
- const availableBackends = await getAllAvailableBackends();
42
- const selectedBackend = getBestAvailableBackend(availableBackends);
43
-
44
- // Determine why this backend was selected
45
- let selectedBy = 'priority';
46
- if (availableBackends.length === 1) {
47
- selectedBy = 'only_available';
48
- } else if (selectedBackend === 'nodecrypto') {
49
- selectedBy = 'fastest_available';
50
- } else if (selectedBackend === 'webcrypto') {
51
- selectedBy = 'fastest_available';
52
- }
53
-
54
- return {
55
- backend: selectedBackend,
56
- environment,
57
- availableBackends,
58
- selectedBy
59
- };
60
- }
61
-
62
- async createBackend(detectedBackend?: string): Promise<any> {
63
- const { backend } = detectedBackend
64
- ? { backend: detectedBackend }
65
- : await this.detect();
66
-
67
- switch (backend) {
68
- case 'nodecrypto':
69
- return new NodeCryptoBackend();
70
- case 'webcrypto':
71
- return new WebCryptoBackend();
72
- case 'ie11':
73
- return new IE11Backend();
74
- case 'purejs':
75
- default:
76
- return new PureJSBackend();
77
- }
78
- }
79
-
80
- async createBackendByName(name: string): Promise<any> {
81
- switch (name) {
82
- case 'nodecrypto':
83
- return new NodeCryptoBackend();
84
- case 'webcrypto':
85
- return new WebCryptoBackend();
86
- case 'ie11':
87
- return new IE11Backend();
88
- case 'purejs':
89
- default:
90
- return new PureJSBackend();
91
- }
92
- }
93
- }
94
-
95
- export const detector = BackendDetector.getInstance();
96
- ```
97
-
98
- ### 2. Упрощенная функция для быстрого использования
99
-
100
- Создать файл `src/detection/index.ts`:
101
-
102
- ```typescript
103
- export { detectEnvironment, isNode, isBrowser, isWebWorker, RuntimeEnvironment } from './environment.js';
104
- export { checkBackendAvailability, getAllAvailableBackends } from './backend-availability.js';
105
- export { BACKEND_PRIORITY, getBestAvailableBackend } from './backend-ranking.js';
106
- export { BackendDetector, detector } from './backend-detector.js';
107
-
108
- // Quick access functions
109
- export async function detectBackend(detectedBackend?: string): Promise<any> {
110
- return detector.createBackend(detectedBackend);
111
- }
112
-
113
- export async function getAvailableBackends(): Promise<string[]> {
114
- return getAllAvailableBackends();
115
- }
116
-
117
- export function getBackendPriority(): string[] {
118
- return BACKEND_PRIORITY.map(b => b.name);
119
- }
120
- ```
121
-
122
- ### 3. Integration с основным API
123
-
124
- В `src/index.ts`:
125
-
126
- ```typescript
127
- import { detector } from './detection/backend-detector.js';
128
-
129
- export async function md5(data: string, options?: { backend?: string }): Promise<string> {
130
- const backend = options?.backend
131
- ? await detector.createBackendByName(options.backend)
132
- : await detector.createBackend();
133
-
134
- return backend.hash(data);
135
- }
136
-
137
- // Export backend factory
138
- export { detector as backendDetector } from './detection/backend-detector.js';
139
- ```
140
-
141
- ### 4. Tests
142
-
143
- Создать файл `__tests__/detection/backend-detector.test.ts`:
144
-
145
- ```typescript
146
- describe('BackendDetector', () => {
147
- let detector: BackendDetector;
148
-
149
- beforeAll(() => {
150
- detector = BackendDetector.getInstance();
151
- });
152
-
153
- it('should detect backend', async () => {
154
- const result = await detector.detect();
155
- expect(result).toBeDefined();
156
- expect(result.backend).toBeDefined();
157
- expect(result.environment).toBeDefined();
158
- expect(result.availableBackends).toBeInstanceOf(Array);
159
- });
160
-
161
- it('should create backend by name', async () => {
162
- const backend = await detector.createBackendByName('purejs');
163
- expect(backend).toBeDefined();
164
- expect(typeof backend.hash).toBe('function');
165
- });
166
-
167
- it('should create default backend', async () => {
168
- const backend = await detector.createBackend();
169
- expect(backend).toBeDefined();
170
- expect(typeof backend.hash).toBe('function');
171
- });
172
-
173
- it('should cache singleton instance', () => {
174
- const instance1 = BackendDetector.getInstance();
175
- const instance2 = BackendDetector.getInstance();
176
- expect(instance1).toBe(instance2);
177
- });
178
-
179
- it('should handle backend name override', async () => {
180
- const backend = await detector.createBackendByName('purejs');
181
- const result = backend.hash('test');
182
- expect(result).toBeDefined();
183
- });
184
- });
185
- ```
186
-
187
- ### 5. Documentation API
188
-
189
- Добавить JSDoc комментарии:
190
-
191
- ```typescript
192
- /**
193
- * Detects the optimal backend for MD5 computation
194
- * @returns Promise<DetectionResult> Object containing detected backend info
195
- *
196
- * @example
197
- * const result = await detector.detect();
198
- * console.log(result.backend); // 'nodecrypto'
199
- * console.log(result.environment); // 'node'
200
- * console.log(result.availableBackends); // ['nodecrypto', 'purejs']
201
- */
202
- ```
203
-
204
- ## Ожидаемый результат
205
-
206
- - ✅ BackendDetector реализован
207
- - ✅ Intelligent выбор backend'а работает
208
- - ✅ Tests проходят успешно
209
- - ✅ Интегрирован в основной API
210
- - ✅ Documentation создана