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
package/planning/prd.md DELETED
@@ -1,405 +0,0 @@
1
- ## 1. Stream Support (Streams) for Node.js
2
-
3
- Stream processing allows hashing files of any size (videos, databases, logs) without loading the entire file into memory. This is critically important for server applications.
4
-
5
- ### How it works
6
-
7
- In Node.js, streams read files in parts (chunks). Our task is to update the hash for each chunk and finalize it at the end.
8
-
9
- ### Implementation
10
-
11
- ```javascript
12
- const { createHash } = require('node:crypto');
13
- const { Readable } = require('node:stream');
14
-
15
- class MD5Stream extends Readable {
16
- constructor(options = {}) {
17
- super(options);
18
- this.hash = createHash('md5');
19
- this.bytesProcessed = 0;
20
- }
21
-
22
- // This method is called automatically when reading the stream
23
- _transform(chunk, encoding, callback) {
24
- this.hash.update(chunk);
25
- this.bytesProcessed += chunk.length;
26
- this.push(chunk); // Pass the chunk further down the stream
27
- callback();
28
- }
29
-
30
- // Called at the end of the stream
31
- _flush(callback) {
32
- const digest = this.hash.digest('hex');
33
- // Add metadata to the end of the stream or emit an event
34
- this.emit('md5', { digest, bytes: this.bytesProcessed });
35
- callback();
36
- }
37
- }
38
-
39
- // Convenient API for users
40
- function createMD5Stream() {
41
- return new MD5Stream();
42
- }
43
-
44
- // Usage example:
45
- const fs = require('node:fs');
46
-
47
- const readStream = fs.createReadStream('large-file.iso');
48
- const hasher = createMD5Stream();
49
-
50
- readStream.pipe(hasher).on('md5', (result) => {
51
- console.log(`MD5: ${result.digest}`);
52
- console.log(`Size: ${result.bytes} bytes`);
53
- });
54
- ```
55
-
56
- ### What this gives `pure-md5`
57
-
58
- - **Competitive advantage**: None of the competitors (`md5`, `crypto-js`) offer built-in stream processing.
59
- - **Memory efficiency**: Can hash 100 GB files on a server with 512 MB RAM.
60
- - **Versatility**: Suitable for integration with any Node.js streams (HTTP requests, file system, network streams).
61
-
62
- ### Additionally: browser stream support
63
-
64
- For browsers, you can add support for `ReadableStream` (WHATWG Streams):
65
-
66
- ```javascript
67
- // browser-stream.js
68
- async function hashFileThroughStream(file) {
69
- const stream = file.stream();
70
- const reader = stream.getReader();
71
- const hash = await initializeMD5(); // your MD5 implementation
72
-
73
- while (true) {
74
- const { done, value } = await reader.read();
75
- if (done) break;
76
- hash.update(value);
77
- }
78
-
79
- return hash.digest('hex');
80
- }
81
- ```
82
-
83
- ## 2. Web Crypto API Detection and Fallback Mechanisms
84
-
85
- Web Crypto API is a cryptographic interface built into browsers and Node.js. It works dozens of times faster than pure JavaScript implementation and uses hardware acceleration.
86
-
87
- ### Smart Environment Detection
88
-
89
- We need to determine which runtime environment and what level of support is available:
90
-
91
- ```javascript
92
- // crypto-detect.js
93
- export const CryptoBackend = {
94
- WEB_CRYPTO: 'webcrypto', // Modern browsers, Node.js (with flags)
95
- NODE_CRYPTO: 'nodecrypto', // Native Node.js crypto
96
- IE11_MS_CRYPTO: 'ie11', // Internet Explorer 11 (window.msCrypto)
97
- FALLBACK_JS: 'purejs' // Pure JS implementation (your current one)
98
- };
99
-
100
- export async function detectCryptoBackend() {
101
- // 1. Check Node.js environment
102
- if (typeof globalThis.crypto?.subtle?.digest === 'function') {
103
- // Node.js 15+ with WebCrypto enabled
104
- return CryptoBackend.WEB_CRYPTO;
105
- }
106
-
107
- if (typeof require === 'function') {
108
- try {
109
- const nodeCrypto = require('node:crypto');
110
- if (nodeCrypto?.createHash) {
111
- return CryptoBackend.NODE_CRYPTO;
112
- }
113
- } catch {
114
- // node:crypto is not available
115
- }
116
- }
117
-
118
- // 2. Check browser environment
119
- if (typeof window !== 'undefined') {
120
- // Modern browsers
121
- if (window.crypto?.subtle?.digest) {
122
- return CryptoBackend.WEB_CRYPTO;
123
- }
124
-
125
- // Internet Explorer 11 (uses msCrypto)
126
- if (window.msCrypto?.subtle?.digest) {
127
- return CryptoBackend.IE11_MS_CRYPTO;
128
- }
129
- }
130
-
131
- // 3. Nothing found — use pure JS
132
- return CryptoBackend.FALLBACK_JS;
133
- }
134
- ```
135
-
136
- ### Adapter for Different Backends
137
-
138
- We create a unified interface that hides implementation details:
139
-
140
- ```javascript
141
- // md5-adapter.js
142
- import { CryptoBackend, detectCryptoBackend } from './crypto-detect.js';
143
- import { md5 as pureJSMD5 } from './pure-md5.js';
144
-
145
- class MD5Adapter {
146
- constructor() {
147
- this.backend = null;
148
- this.initialized = false;
149
- }
150
-
151
- async initialize() {
152
- if (this.initialized) return;
153
- this.backend = await detectCryptoBackend();
154
- this.initialized = true;
155
- }
156
-
157
- async hash(data) {
158
- await this.initialize();
159
-
160
- switch (this.backend) {
161
- case CryptoBackend.WEB_CRYPTO:
162
- return this.hashWithWebCrypto(data);
163
- case CryptoBackend.NODE_CRYPTO:
164
- return this.hashWithNodeCrypto(data);
165
- case CryptoBackend.IE11_MS_CRYPTO:
166
- return this.hashWithMsCrypto(data);
167
- default:
168
- return pureJSMD5(data);
169
- }
170
- }
171
-
172
- async hashWithWebCrypto(data) {
173
- const encoder = new TextEncoder();
174
- const buffer = encoder.encode(data);
175
- const hashBuffer = await crypto.subtle.digest('MD5', buffer);
176
- return this.bufferToHex(hashBuffer);
177
- }
178
-
179
- async hashWithNodeCrypto(data) {
180
- const crypto = require('node:crypto');
181
- return crypto.createHash('md5').update(data).digest('hex');
182
- }
183
-
184
- // For IE11
185
- async hashWithMsCrypto(data) {
186
- const encoder = new TextEncoder();
187
- const buffer = encoder.encode(data);
188
- const hashBuffer = await window.msCrypto.subtle.digest('MD5', buffer);
189
- return this.bufferToHex(hashBuffer);
190
- }
191
-
192
- bufferToHex(buffer) {
193
- return Array.from(new Uint8Array(buffer))
194
- .map((b) => b.toString(16).padStart(2, '0'))
195
- .join('');
196
- }
197
- }
198
-
199
- export const md5 = new MD5Adapter();
200
- ```
201
-
202
- ### Graceful Degradation
203
-
204
- It's important not just to fail with an error, but to try alternative paths:
205
-
206
- ```javascript
207
- async function robustHash(input, options = {}) {
208
- const errors = [];
209
-
210
- // Try to use WebCrypto
211
- if (!options.forcePureJS) {
212
- try {
213
- return await hashWithWebCrypto(input);
214
- } catch (e) {
215
- errors.push({ backend: 'webcrypto', error: e.message });
216
- // Log for monitoring but continue
217
- console.warn('WebCrypto failed, falling back:', e.message);
218
- }
219
- }
220
-
221
- // Try Node.js crypto
222
- try {
223
- return await hashWithNodeCrypto(input);
224
- } catch (e) {
225
- errors.push({ backend: 'nodecrypto', error: e.message });
226
- }
227
-
228
- // Final fallback — pure JS implementation
229
- try {
230
- const result = pureJSMD5(input);
231
-
232
- // If there were errors but we managed to work — inform
233
- if (errors.length > 0 && options.reportFallback) {
234
- console.info('MD5 used fallback. Previous errors:', errors);
235
- }
236
-
237
- return result;
238
- } catch (e) {
239
- // Complete failure
240
- throw new Error(
241
- `MD5 hash failed after all attempts: ${errors.map((e) => e.error).join(', ')}`
242
- );
243
- }
244
- }
245
- ```
246
-
247
- ### Fallback Usage Monitoring
248
-
249
- For production systems, it's important to track how often fallback mechanisms are triggered:
250
-
251
- ```javascript
252
- const metrics = {
253
- webcrypto: { success: 0, fail: 0 },
254
- nodecrypto: { success: 0, fail: 0 },
255
- purejs: { success: 0, fail: 0 }
256
- };
257
-
258
- // Wrapper with metrics
259
- async function monitoredHash(input) {
260
- for (const backend of ['webcrypto', 'nodecrypto', 'purejs']) {
261
- try {
262
- const result = await hashWithBackend(backend, input);
263
- metrics[backend].success++;
264
- return result;
265
- } catch (e) {
266
- metrics[backend].fail++;
267
- // continue to the next backend
268
- }
269
- }
270
- throw new Error('All backends failed');
271
- }
272
-
273
- // Periodic report
274
- setInterval(() => {
275
- console.log('MD5 Backend Metrics:', metrics);
276
- }, 60000); // Every minute
277
- ```
278
-
279
- ## 3. Size Optimization and Tree-Shaking Configuration
280
-
281
- Tree-shaking allows bundlers (webpack, Rollup, Vite) to remove unused code from the final bundle. Here's how to make `pure-md5` fully "shakable".
282
-
283
- ### ESM Module Structure
284
-
285
- We switch to the modern ES module format:
286
-
287
- ```javascript
288
- // package.json
289
- {
290
- "name": "pure-md5",
291
- "version": "2.0.0",
292
- "type": "module", // <-- Entire package as ESM
293
- "sideEffects": false, // <-- Critically important for tree-shaking!
294
- "exports": {
295
- ".": {
296
- "import": "./dist/index.js",
297
- "require": "./dist/index.cjs",
298
- "types": "./dist/index.d.ts"
299
- },
300
- "./stream": {
301
- "import": "./dist/stream.js",
302
- "require": "./dist/stream.cjs"
303
- },
304
- "./light": {
305
- "import": "./dist/light.js" // Only basic function, without adapters
306
- },
307
- "./package.json": "./package.json"
308
- },
309
- "module": "./dist/index.js",
310
- "main": "./dist/index.cjs",
311
- "types": "./dist/index.d.ts"
312
- }
313
- ```
314
-
315
- ### Modular Architecture
316
-
317
- We split the code into separate files so that only what's needed can be imported:
318
-
319
- ```javascript
320
- // src/core/md5.js - pure algorithm implementation (no dependencies)
321
- export function md5Core(input) {
322
- // Only the algorithm, without environment detection
323
- // ~2KB gzipped
324
- }
325
-
326
- // src/adapters/webcrypto.js
327
- export async function md5WebCrypto(input) {
328
- // Uses Web Crypto API
329
- // ~0.5KB gzipped
330
- }
331
-
332
- // src/adapters/node.js
333
- export function md5Node(input) {
334
- // Uses node:crypto
335
- // ~0.5KB gzipped
336
- }
337
-
338
- // src/index.js - smart version with auto-detection
339
- import { md5Core } from './core/md5.js';
340
- import { detectBackend } from './utils/detect.js';
341
-
342
- export async function md5(input) {
343
- const backend = await detectBackend();
344
- return backend(input);
345
- }
346
-
347
- // src/light.js - only pure JS implementation, minimal code
348
- export { md5Core as md5 } from './core/md5.js';
349
- ```
350
-
351
- ### Optimization via "pure" Annotations
352
-
353
- We help the bundler understand that functions are pure and can be safely removed:
354
-
355
- ```javascript
356
- // Add comments in the code for Terser/webpack
357
- const fastMD5 = /*#__PURE__*/ createMD5Function();
358
-
359
- // For complex computations that can be removed if the result is not used
360
- const precomputedTable = /*#__PURE__*/ (() => {
361
- // Constant table for MD5
362
- return [0x67452301, 0xefcdab89 /* ... */];
363
- })();
364
- ```
365
-
366
- ### Minimization via Conditional Exports
367
-
368
- We create "entry points" with different functionality:
369
-
370
- ```javascript
371
- // Example usage in a user's project
372
- // 1. Maximum compatibility (auto-detection)
373
- import { md5 } from 'pure-md5';
374
- await md5('hello');
375
-
376
- // 2. Only stream processing (for Node.js)
377
- import { createMD5Stream } from 'pure-md5/stream';
378
- fs.createReadStream('big.iso').pipe(createMD5Stream());
379
-
380
- // 3. Ultra-light version (for microcontrollers/small scripts)
381
- import { md5 } from 'pure-md5/light'; // ~2KB!
382
- console.log(md5('hello'));
383
-
384
- // 4. Only WebCrypto (for modern browsers)
385
- import { md5 } from 'pure-md5/webcrypto'; // ~0.5KB!
386
- ```
387
-
388
- ### Size Comparison After Optimization
389
-
390
- | Version | Size (gzipped) | What's Included |
391
- | -------------------- | -------------- | ----------------------------- |
392
- | `pure-md5/light` | **~2 KB** | Only pure JS algorithm |
393
- | `pure-md5/webcrypto` | **~0.5 KB** | Only Web Crypto API wrapper |
394
- | `pure-md5` (full) | **~4 KB** | Auto-detection + all adapters |
395
- | **Competitors** | | |
396
- | `md5` | ~15 KB | Only JS implementation |
397
- | `crypto-js/md5` | ~25 KB | MD5 + additional code |
398
-
399
- ## Summary: What This Optimization Provides
400
-
401
- 1. **Streams** — a unique feature that competitors don't have. Attracts server developers.
402
- 2. **WebCrypto + fallback** — security and speed on modern platforms + guaranteed operation everywhere.
403
- 3. **Tree-shaking** — ability to use `pure-md5` even in the smallest projects without fear of bloating the bundle.
404
-
405
- The package becomes not just "another MD5 library", but **a tool with clear positioning**: modern, lightweight, smart, and performant.
@@ -1,69 +0,0 @@
1
- # Task 1: Creating the MD5Stream Base Class
2
-
3
- ## Goal
4
- Create a base `MD5Stream` class extending `stream.Transform` for streaming MD5 hash computation.
5
-
6
- ## Implementation Requirements
7
- 1. **SRP**: The class should only be responsible for computing MD5 hash in streaming mode
8
- 2. **Performance**: Minimal overhead when processing each chunk
9
- 3. **Compatibility**: Works with any Node.js streams (Readable, Writable, Transform)
10
-
11
- ## Implementation Details
12
- - Extends `stream.Transform`
13
- - Initializes MD5 hash in constructor
14
- - Updates hash in `_transform` method
15
- - Finalizes hash in `_flush` method
16
- - Emits 'md5' event with result (digest and bytesProcessed)
17
-
18
- ## Acceptance Criteria
19
- - [x] Created `MD5Stream` class in `src/stream/md5-stream.ts`
20
- - [x] Class correctly extends `stream.Transform`
21
- - [x] Implemented `_transform` method for hash updates
22
- - [x] Implemented `_flush` method for hash finalization
23
- - [x] Added `'md5'` event with result (digest and bytesProcessed)
24
- - [x] Basic tests written for class functionality
25
-
26
- ## Implementation Status
27
- - [x] Examined existing MD5 implementation structure
28
- - [x] Created stream directory structure
29
- - [x] Created MD5Stream class in src/stream/md5-stream.ts
30
- - [x] Exported MD5Stream from index.ts
31
- - [x] Added stream entry to tsup.config.ts
32
- - [x] Created tests for MD5Stream
33
- - [x] Verified implementation with tests
34
- - [x] Documentation updated
35
-
36
- ## Implementation Summary
37
- - **Location**: `src/stream/md5-stream.ts`
38
- - **Exports**: `MD5Stream` and `createMD5Stream` (factory function)
39
- - **Features**:
40
- - Efficient chunk processing with 64-byte block optimization
41
- - Automatic padding and length handling
42
- - Configurable add32 function for testing
43
- - State management with `reset()` method
44
- - State inspection via `getCurrentState()` and `getBytesProcessed()`
45
-
46
- ## Test Results
47
- All 19 MD5Stream tests pass:
48
- - Empty string handling
49
- - Simple and longer strings
50
- - Chunked data processing
51
- - 64-byte block alignment
52
- - Special characters
53
- - Binary buffer input
54
- - Large file simulation
55
- - Factory function
56
- - Custom add32 function
57
- - Sequential processing
58
- - Single byte chunks
59
- - Hex digest validation
60
- - State reset functionality
61
- - Current state inspection
62
- - Empty chunks handling
63
-
64
- ## Notes for Agent
65
- - Uses native MD5 implementation from `src/core/index.ts`
66
- - Minimal performance overhead
67
- - Compatible with all Node.js stream types
68
- - Stream is marked as completed in the planning document
69
-
@@ -1,65 +0,0 @@
1
- # Задача 2: Создание фабричной функции и удобного API
2
-
3
- ## Цель
4
- Создать удобный API для работы с MD5 потоками через фабричные функции и упрощенные методы.
5
-
6
- ## Требования к реализации
7
- 1. **SRP**: Функции должны предоставлять простой интерфейс без внутренней логики
8
- 2. **Удобство использования**: API должен быть интуитивно понятен
9
- 3. **Гибкость**: Поддержка различных сценариев использования
10
-
11
- ## Детали реализации
12
- - Фабричная функция `createMD5Stream()` для создания экземпляров
13
- - Метод `pipeThroughMD5()` для удобной интеграции в цепочки pipe
14
- - Статический метод `MD5Stream.fromStream()` для создания из существующего потока
15
- - Экспорт всех необходимых компонентов
16
-
17
- ## Критерии выполнения
18
- - [x] Создана фабричная функция `createMD5Stream()` в `src/stream/index.js`
19
- - [x] Реализован метод `pipeThroughMD5()` для обертки потоков
20
- - [x] Добавлен статический метод `MD5Stream.fromStream()`
21
- - [x] Экспортированы все публичные API в основном экспорте
22
- - [x] Написаны примеры использования в документации
23
- - [x] Добавлены тесты для фабричных функций
24
-
25
- ## Прогресс выполнения
26
- - [x] Начало работы
27
- - [x] Фабричные функции созданы
28
- - [x] API документирован
29
- - [x] Тесты написаны
30
- - [x] Код проверен на соответствие SRP
31
- - [x] Задача завершена
32
-
33
- ## Реализовано
34
-
35
- ### Фабричные функции
36
- - ✅ `createMD5Stream()` - создание экземпляра MD5Stream
37
- - ✅ `fromStream()` - создание stream из существующего readable stream
38
- - ✅ `MD5Stream.fromStream()` - статический метод класса
39
-
40
- ### Методы и утилиты
41
- - ✅ `pipeThroughMD5()` - удобная обертка для pipe
42
- - ✅ `hashFile()` - хэширование файла по пути
43
- - ✅ `hashFileDigest()` - хэширование с возвратом только digest
44
- - ✅ `hashFileStream()` - хэширование потока
45
- - ✅ `hashFileSync()` - синхронное хэширование
46
- - ✅ `verifyFile()` - проверка целостности файла
47
- - ✅ `createProgressTracker()` - отслеживание прогресса
48
-
49
- ### Документация
50
- - ✅ Примеры использования в README.md
51
- - ✅ Комментарии JSDoc в коде
52
- - ✅ Примеры для всех функций
53
-
54
- ### Тесты
55
- - ✅ Тесты `createMD5Stream()`
56
- - ✅ Тесты `pipeThroughMD5()`
57
- - ✅ Тесты `fromStream()`
58
- - ✅ Тесты `MD5Stream.fromStream()`
59
- - ✅ Тесты файловых утилит
60
-
61
- ## Примечания для агента
62
- - API должен быть согласован с существующим интерфейсом библиотеки
63
- - Функции должны быть чистыми и не иметь побочных эффектов
64
- - Учесть различные сценарии использования (файлы, HTTP, пользовательские потоки)
65
- - Отметить прогресс в чеклисте выше
@@ -1,37 +0,0 @@
1
- # Задача 3: Интеграция с файловой системой Node.js
2
-
3
- ## Цель
4
- Создать удобные утилиты для хэширования файлов через потоки файловой системы.
5
-
6
- ## Требования к реализации
7
- 1. **SRP**: Утилиты должны отвечать только за работу с файловой системой
8
- 2. **Эффективность**: Минимальное использование памяти при работе с большими файлами
9
- 3. **Обработка ошибок**: Корректная обработка ошибок файловой системы
10
-
11
- ## Детали реализации
12
- - Функция `hashFile(filePath)` для хэширования файла по пути
13
- - Функция `hashFileStream(readStream)` для хэширования существующего потока
14
- - Поддержка прогресса хэширования (опционально)
15
- - Обработка ошибок чтения файлов
16
-
17
- ## Критерии выполнения
18
- - [ ] Создана функция `hashFile()` в `src/stream/fs-utils.js`
19
- - [ ] Создана функция `hashFileStream()`
20
- - [ ] Реализована обработка ошибок файловой системы
21
- - [ ] Добавлена опциональная поддержка прогресса
22
- - [ ] Написаны тесты с реальными файлами
23
- - [ ] Добавлены примеры использования
24
-
25
- ## Прогресс выполнения
26
- - [ ] Начало работы
27
- - [ ] Функции созданы
28
- - [ ] Обработка ошибок реализована
29
- - [ ] Тесты написаны
30
- - [ ] Код проверен на соответствие SRP
31
- - [ ] Задача завершена
32
-
33
- ## Примечания для агента
34
- - Использовать `fs.createReadStream` для эффективного чтения
35
- - Учесть различные кодировки и типы файлов
36
- - Обеспечить корректное освобождение ресурсов
37
- - Отметить прогресс в чеклисте выше
@@ -1,37 +0,0 @@
1
- # Задача 4: Поддержка WHATWG Streams для браузеров
2
-
3
- ## Цель
4
- Добавить поддержку браузерных потоков (WHATWG Streams) для использования в веб-приложениях.
5
-
6
- ## Требования к реализации
7
- 1. **SRP**: Отдельная реализация для браузерных потоков
8
- 2. **Совместимость**: Работа с современными браузерами
9
- 3. **Производительность**: Эффективная работа в браузерной среде
10
-
11
- ## Детали реализации
12
- - Класс `MD5ReadableStream` для работы с WHATWG Streams
13
- - Функция `hashReadableStream()` для хэширования существующих потоков
14
- - Поддержка `ReadableStream`, `File`, `Blob` объектов
15
- - Адаптер для конвертации между Node.js и WHATWG потоками
16
-
17
- ## Критерии выполнения
18
- - [ ] Создан класс `MD5ReadableStream` в `src/stream/whatwg-stream.js`
19
- - [ ] Реализована функция `hashReadableStream()`
20
- - [ ] Добавлена поддержка `File` и `Blob` объектов
21
- - [ ] Создан адаптер для конвертации потоков
22
- - [ ] Написаны тесты для браузерной среды
23
- - [ ] Добавлена документация по использованию
24
-
25
- ## Прогресс выполнения
26
- - [ ] Начало работы
27
- - [ ] WHATWG Streams поддержка реализована
28
- - [ ] Адаптеры созданы
29
- - [ ] Тесты написаны
30
- - [ ] Код проверен на соответствие SRP
31
- - [ ] Задача завершена
32
-
33
- ## Примечания для агента
34
- - Учесть различия между Node.js и WHATWG Streams API
35
- - Обеспечить кросс-браузерную совместимость
36
- - Минимизировать размер кода для браузерной сборки
37
- - Отметить прогресс в чеклисте выше