pure-md5 0.2.0 → 0.2.1
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/dist/adapters/ie11.cjs +1 -2
- package/dist/adapters/ie11.js +1 -2
- package/dist/adapters/node.cjs +1 -2
- package/dist/adapters/node.js +1 -2
- package/dist/adapters/webcrypto.cjs +1 -2
- package/dist/adapters/webcrypto.js +1 -2
- package/dist/core/index.cjs +1 -2
- package/dist/core/index.js +1 -2
- package/dist/index.cjs +1 -2
- package/dist/index.js +1 -2
- package/dist/stream/adapter.cjs +1 -2
- package/dist/stream/adapter.js +1 -2
- package/dist/stream/fs-utils.cjs +1 -2
- package/dist/stream/fs-utils.js +1 -2
- package/dist/stream/index.cjs +1 -2
- package/dist/stream/index.js +1 -2
- package/dist/stream/light/index.cjs +1 -2
- package/dist/stream/light/index.js +1 -2
- package/dist/stream/md5-stream.cjs +1 -2
- package/dist/stream/md5-stream.js +1 -2
- package/dist/stream/whatwg-stream.cjs +1 -2
- package/dist/stream/whatwg-stream.js +1 -2
- package/dist/utils/detect.cjs +1 -2
- package/dist/utils/detect.js +1 -2
- package/package.json +1 -1
- package/pure-md5-0.2.0.tgz +0 -0
- package/.aliases +0 -19
- package/.bash_profile +0 -12
- package/.bash_prompt +0 -56
- package/.changeset/README.md +0 -32
- package/.changeset/config.json +0 -16
- package/.continue/mcpServers/new-mcp-server.yaml +0 -10
- package/.continue/rules +0 -29
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -35
- package/.github/ISSUE_TEMPLATE/documentation.md +0 -20
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -35
- package/.github/workflows/npm-publish.yml +0 -33
- package/.github/workflows/release.yml +0 -42
- package/CHANGELOG.md +0 -9
- package/CONTRIBUTING.md +0 -203
- package/MIGRATION_GUIDE_STREAMS.md +0 -374
- package/STREAM_API.md +0 -582
- package/STREAM_BENCHMARKS.md +0 -232
- package/STREAM_EXAMPLES.md +0 -669
- package/STREAM_OPTIMIZATION_REPORT.md +0 -136
- package/STREAM_TROUBLESHOOTING.md +0 -537
- package/WEB_CRYPTO_TESTS_SUMMARY.md +0 -140
- package/WHATWG_STREAMS.md +0 -191
- package/__tests__/adapters/node-crypto.test.ts +0 -167
- package/__tests__/adapters/web-crypto-node.test.ts +0 -73
- package/__tests__/adapters/web-crypto.test.ts +0 -195
- package/__tests__/add32.test.ts +0 -33
- package/__tests__/fallback.test.ts +0 -345
- package/__tests__/hex.test.ts +0 -38
- package/__tests__/hex_chr.test.ts +0 -20
- package/__tests__/index.test.ts +0 -87
- package/__tests__/integration/fixtures/test-file.txt +0 -1
- package/__tests__/integration/md5-stream-file.test.ts +0 -293
- package/__tests__/integration/node-crypto-file.test.ts +0 -86
- package/__tests__/integration/web-crypto.test.ts +0 -38
- package/__tests__/md51.test.ts +0 -73
- package/__tests__/md5block.test.ts +0 -61
- package/__tests__/md5cycle.test.ts +0 -48
- package/__tests__/round-functions.test.ts +0 -87
- package/__tests__/stream/fs-utils.test.ts +0 -209
- package/__tests__/stream/md5-stream-edge-cases.test.ts +0 -461
- package/__tests__/stream/md5-stream.test.ts +0 -418
- package/__tests__/stream/whatwg-stream.test.ts +0 -355
- package/__tests__/stream/whatwg-stream.test.ts.bak2 +0 -335
- package/benchmarks/md5-stream.bench.ts +0 -212
- package/benchmarks/whatwg-stream.bench.ts +0 -180
- package/dist/adapters/ie11.cjs.map +0 -1
- package/dist/adapters/ie11.js.map +0 -1
- package/dist/adapters/node.cjs.map +0 -1
- package/dist/adapters/node.js.map +0 -1
- package/dist/adapters/webcrypto.cjs.map +0 -1
- package/dist/adapters/webcrypto.js.map +0 -1
- package/dist/chunk-2YXXFGBV.js +0 -2
- package/dist/chunk-2YXXFGBV.js.map +0 -1
- package/dist/chunk-4KSCMS4Q.js +0 -2
- package/dist/chunk-4KSCMS4Q.js.map +0 -1
- package/dist/chunk-6P2QV5SR.js +0 -4
- package/dist/chunk-6P2QV5SR.js.map +0 -1
- package/dist/chunk-G5WHEAIQ.js +0 -2
- package/dist/chunk-G5WHEAIQ.js.map +0 -1
- package/dist/chunk-H2K353LR.js +0 -2
- package/dist/chunk-H2K353LR.js.map +0 -1
- package/dist/chunk-JKVD5LHZ.js +0 -2
- package/dist/chunk-JKVD5LHZ.js.map +0 -1
- package/dist/chunk-NWQ4N5RX.js +0 -2
- package/dist/chunk-NWQ4N5RX.js.map +0 -1
- package/dist/chunk-PHZ7FTYF.js +0 -2
- package/dist/chunk-PHZ7FTYF.js.map +0 -1
- package/dist/chunk-PNZTVQA7.js +0 -2
- package/dist/chunk-PNZTVQA7.js.map +0 -1
- package/dist/chunk-R4JB5MBR.js +0 -2
- package/dist/chunk-R4JB5MBR.js.map +0 -1
- package/dist/chunk-VFOAY6XI.js +0 -2
- package/dist/chunk-VFOAY6XI.js.map +0 -1
- package/dist/chunk-XB5BQIEX.js +0 -2
- package/dist/chunk-XB5BQIEX.js.map +0 -1
- package/dist/core/index.cjs.map +0 -1
- package/dist/core/index.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/stream/adapter.cjs.map +0 -1
- package/dist/stream/adapter.js.map +0 -1
- package/dist/stream/fs-utils.cjs.map +0 -1
- package/dist/stream/fs-utils.js.map +0 -1
- package/dist/stream/index.cjs.map +0 -1
- package/dist/stream/index.js.map +0 -1
- package/dist/stream/light/index.cjs.map +0 -1
- package/dist/stream/light/index.js.map +0 -1
- package/dist/stream/md5-stream.cjs.map +0 -1
- package/dist/stream/md5-stream.js.map +0 -1
- package/dist/stream/whatwg-stream.cjs.map +0 -1
- package/dist/stream/whatwg-stream.js.map +0 -1
- package/dist/utils/detect.cjs.map +0 -1
- package/dist/utils/detect.js.map +0 -1
- package/planning/03-optimization-size-tree-shaking/01-es-modules-tree-shaking.md +0 -152
- package/planning/03-optimization-size-tree-shaking/02-consolidate-modules.md +0 -65
- package/planning/03-optimization-size-tree-shaking/03-remove-duplicate-add32.md +0 -93
- package/planning/03-optimization-size-tree-shaking/04-remove-runtime-check.md +0 -102
- package/planning/03-optimization-size-tree-shaking/05-optimize-loops-performance.md +0 -107
- package/planning/03-optimization-size-tree-shaking/06-tsup-formats-configuration.md +0 -227
- package/planning/03-optimization-size-tree-shaking/07-multiple-build-formats.md +0 -228
- package/planning/03-optimization-size-tree-shaking/08-benchmarks-metrics.md +0 -34
- package/planning/03-optimization-size-tree-shaking/MIGRATION_GUIDE.md +0 -260
- package/planning/03-optimization-size-tree-shaking/README.md +0 -173
- package/planning/03-optimization-size-tree-shaking/SUMMARY.md +0 -168
- package/planning/04-adapter-backend/03-backend-web-crypto.md +0 -149
- package/planning/04-adapter-backend/04-backend-node-crypto.md +0 -181
- package/planning/04-adapter-backend/05-backend-pure-js.md +0 -174
- package/planning/04-adapter-backend/06-backend-ie11.md +0 -158
- package/planning/04-adapter-backend/07-detection-environment.md +0 -232
- package/planning/04-adapter-backend/08-detection-backend.md +0 -210
- package/planning/04-adapter-backend/09-adapter-unified.md +0 -255
- package/planning/04-adapter-backend/10-fallback-mechanism.md +0 -333
- package/planning/04-adapter-backend/11-tests-backend-web-crypto.md +0 -191
- package/planning/04-adapter-backend/12-tests-backend-node-crypto.md +0 -222
- package/planning/04-adapter-backend/README.md +0 -45
- package/planning/05-documentation-publishing/01-README-optimization.md +0 -105
- package/planning/05-documentation-publishing/02-VitePress-site-evaluation.md +0 -136
- package/planning/05-documentation-publishing/03-Changeset-setup.md +0 -192
- package/planning/05-documentation-publishing/04-GitHub-templates.md +0 -252
- package/planning/05-documentation-publishing/README.md +0 -22
- package/planning/05-documentation-publishing/STATUS.md +0 -222
- package/planning/prd.md +0 -405
- package/planning/streams/01-create-md5stream-class.md +0 -69
- package/planning/streams/02-create-factory-api.md +0 -65
- package/planning/streams/03-fs-integration.md +0 -37
- package/planning/streams/04-whatwg-streams-support.md +0 -37
- package/planning/streams/05-audit-optimization.md +0 -121
- package/planning/streams/06-comprehensive-tests-docs.md +0 -137
- package/planning/streams/07-architecture-integration.md +0 -38
- package/planning/streams/README.md +0 -98
- package/tsup.config.ts +0 -24
|
@@ -1,374 +0,0 @@
|
|
|
1
|
-
# Migration Guide: Node.js Streams to pure-md5
|
|
2
|
-
|
|
3
|
-
This guide helps you migrate from native Node.js crypto or other MD5 libraries to the pure-md5 streaming API.
|
|
4
|
-
|
|
5
|
-
## From crypto.createHash()
|
|
6
|
-
|
|
7
|
-
### Basic String Hashing
|
|
8
|
-
|
|
9
|
-
**Before:**
|
|
10
|
-
```typescript
|
|
11
|
-
import crypto from 'crypto';
|
|
12
|
-
|
|
13
|
-
const data = 'Hello, World!';
|
|
14
|
-
const hash = crypto.createHash('md5').update(data).digest('hex');
|
|
15
|
-
console.log(hash); // 65a8e27d8879283831b664bd8b7f0ad4
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
**After:**
|
|
19
|
-
```typescript
|
|
20
|
-
import { MD5Stream, fromStream } from 'pure-md5';
|
|
21
|
-
import { Readable } from 'stream';
|
|
22
|
-
|
|
23
|
-
// Method 1: Using fromStream
|
|
24
|
-
const { result } = fromStream(Readable.from([data]));
|
|
25
|
-
console.log(result.digest); // 65a8e27d8879283831b664bd8b7f0ad4
|
|
26
|
-
|
|
27
|
-
// Method 2: Using MD5Stream with manual piping
|
|
28
|
-
const stream = new MD5Stream();
|
|
29
|
-
let digest = '';
|
|
30
|
-
stream.on('md5', (r) => digest = r.digest);
|
|
31
|
-
stream.end(data);
|
|
32
|
-
|
|
33
|
-
// Method 3: Using pipeThroughMD5
|
|
34
|
-
const result = await pipeThroughMD5(Readable.from([data]));
|
|
35
|
-
console.log(result.digest);
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### File Hashing
|
|
39
|
-
|
|
40
|
-
**Before:**
|
|
41
|
-
```typescript
|
|
42
|
-
import crypto from 'crypto';
|
|
43
|
-
import fs from 'fs';
|
|
44
|
-
|
|
45
|
-
const hash = crypto.createHash('md5');
|
|
46
|
-
const stream = fs.createReadStream('file.txt');
|
|
47
|
-
|
|
48
|
-
stream.on('data', (chunk) => {
|
|
49
|
-
hash.update(chunk);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
stream.on('end', () => {
|
|
53
|
-
console.log(hash.digest('hex'));
|
|
54
|
-
});
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
**After:**
|
|
58
|
-
```typescript
|
|
59
|
-
import { MD5Stream, hashFile } from 'pure-md5';
|
|
60
|
-
import fs from 'fs';
|
|
61
|
-
|
|
62
|
-
// Method 1: Using MD5Stream
|
|
63
|
-
const stream = new MD5Stream();
|
|
64
|
-
stream.on('md5', (result) => {
|
|
65
|
-
console.log(result.digest);
|
|
66
|
-
});
|
|
67
|
-
fs.createReadStream('file.txt').pipe(stream);
|
|
68
|
-
|
|
69
|
-
// Method 2: Using hashFile (simpler)
|
|
70
|
-
const result = await hashFile('file.txt');
|
|
71
|
-
console.log(result.digest);
|
|
72
|
-
|
|
73
|
-
// Method 3: Using pipeThroughMD5
|
|
74
|
-
const source = fs.createReadStream('file.txt');
|
|
75
|
-
const result = await pipeThroughMD5(source);
|
|
76
|
-
console.log(result.digest);
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## From crypto.createHash() with Progress
|
|
80
|
-
|
|
81
|
-
**Before:**
|
|
82
|
-
```typescript
|
|
83
|
-
import crypto from 'crypto';
|
|
84
|
-
import fs from 'fs';
|
|
85
|
-
|
|
86
|
-
const hash = crypto.createHash('md5');
|
|
87
|
-
const stream = fs.createReadStream('large-file.bin');
|
|
88
|
-
let total = 0;
|
|
89
|
-
const fileSize = fs.statSync('large-file.bin').size;
|
|
90
|
-
|
|
91
|
-
stream.on('data', (chunk) => {
|
|
92
|
-
hash.update(chunk);
|
|
93
|
-
total += chunk.length;
|
|
94
|
-
const progress = ((total / fileSize) * 100).toFixed(1);
|
|
95
|
-
console.log(`Progress: ${progress}%`);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
stream.on('end', () => {
|
|
99
|
-
console.log('MD5:', hash.digest('hex'));
|
|
100
|
-
});
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
**After:**
|
|
104
|
-
```typescript
|
|
105
|
-
import { MD5Stream, createProgressTracker } from 'pure-md5';
|
|
106
|
-
import fs from 'fs';
|
|
107
|
-
|
|
108
|
-
const fileSize = fs.statSync('large-file.bin').size;
|
|
109
|
-
const progress = createProgressTracker(fileSize, (percent) => {
|
|
110
|
-
console.log(`Progress: ${percent.toFixed(1)}%`);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
const stream = new MD5Stream();
|
|
114
|
-
stream.on('md5', (result) => {
|
|
115
|
-
console.log('MD5:', result.digest);
|
|
116
|
-
console.log('Bytes:', result.bytesProcessed);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
// Note: Current version doesn't have built-in progress
|
|
120
|
-
// You can still track progress manually:
|
|
121
|
-
let processed = 0;
|
|
122
|
-
stream.on('data', (chunk) => {
|
|
123
|
-
processed += chunk.length;
|
|
124
|
-
const percent = ((processed / fileSize) * 100).toFixed(1);
|
|
125
|
-
console.log(`Progress: ${percent}%`);
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
fs.createReadStream('large-file.bin').pipe(stream);
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## From Third-Party MD5 Libraries
|
|
132
|
-
|
|
133
|
-
### From js-md5
|
|
134
|
-
|
|
135
|
-
**Before:**
|
|
136
|
-
```javascript
|
|
137
|
-
import md5 from 'js-md5';
|
|
138
|
-
|
|
139
|
-
// String
|
|
140
|
-
console.log(md5('Hello'));
|
|
141
|
-
|
|
142
|
-
// ArrayBuffer
|
|
143
|
-
const arrayBuffer = new TextEncoder().encode('Hello').buffer;
|
|
144
|
-
console.log(md5(arrayBuffer));
|
|
145
|
-
|
|
146
|
-
// Uint8Array
|
|
147
|
-
const uint8Array = new TextEncoder().encode('Hello');
|
|
148
|
-
console.log(md5(uint8Array));
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
**After:**
|
|
152
|
-
```typescript
|
|
153
|
-
import { MD5Stream } from 'pure-md5';
|
|
154
|
-
|
|
155
|
-
// String
|
|
156
|
-
const stream1 = new MD5Stream();
|
|
157
|
-
let result1 = '';
|
|
158
|
-
stream1.on('md5', (r) => result1 = r.digest);
|
|
159
|
-
stream1.end('Hello');
|
|
160
|
-
|
|
161
|
-
// ArrayBuffer
|
|
162
|
-
const stream2 = new MD5Stream();
|
|
163
|
-
let result2 = '';
|
|
164
|
-
stream2.on('md5', (r) => result2 = r.digest);
|
|
165
|
-
const buffer = new TextEncoder().encode('Hello').buffer;
|
|
166
|
-
stream2.end(new Uint8Array(buffer));
|
|
167
|
-
|
|
168
|
-
// Uint8Array
|
|
169
|
-
const stream3 = new MD5Stream();
|
|
170
|
-
let result3 = '';
|
|
171
|
-
stream3.on('md5', (r) => result3 = r.digest);
|
|
172
|
-
const uint8Array = new TextEncoder().encode('Hello');
|
|
173
|
-
stream3.end(uint8Array);
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
### From blueimp-md5
|
|
177
|
-
|
|
178
|
-
**Before:**
|
|
179
|
-
```javascript
|
|
180
|
-
import md5 from 'blueimp-md5';
|
|
181
|
-
|
|
182
|
-
// String
|
|
183
|
-
md5('Hello'); // "8b1a9953c4611296a827abf8c47804d7"
|
|
184
|
-
|
|
185
|
-
// File (browser)
|
|
186
|
-
const file = document.querySelector('input').files[0];
|
|
187
|
-
const reader = new FileReader();
|
|
188
|
-
reader.onload = function() {
|
|
189
|
-
const hash = md5(reader.result);
|
|
190
|
-
console.log(hash);
|
|
191
|
-
};
|
|
192
|
-
reader.readAsBinaryString(file);
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
**After:**
|
|
196
|
-
```typescript
|
|
197
|
-
import { MD5Stream, hashFile, hashBlob } from 'pure-md5';
|
|
198
|
-
|
|
199
|
-
// String
|
|
200
|
-
const stream = new MD5Stream();
|
|
201
|
-
let result = '';
|
|
202
|
-
stream.on('md5', (r) => result = r.digest);
|
|
203
|
-
stream.end('Hello');
|
|
204
|
-
|
|
205
|
-
// File (browser)
|
|
206
|
-
const file = document.querySelector('input').files[0];
|
|
207
|
-
const result = await hashFile(file);
|
|
208
|
-
console.log(result.digest);
|
|
209
|
-
|
|
210
|
-
// Blob (browser)
|
|
211
|
-
const blob = new Blob(['Hello']);
|
|
212
|
-
const result = await hashBlob(blob);
|
|
213
|
-
console.log(result.digest);
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
## Browser Migration
|
|
217
|
-
|
|
218
|
-
### From Manual MD5 Implementation
|
|
219
|
-
|
|
220
|
-
**Before:**
|
|
221
|
-
```javascript
|
|
222
|
-
async function md5Browser(data) {
|
|
223
|
-
const buffer = await data.arrayBuffer();
|
|
224
|
-
const hashBuffer = await crypto.subtle.digest('MD5', buffer);
|
|
225
|
-
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
226
|
-
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
|
227
|
-
return hashHex;
|
|
228
|
-
}
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
**After:**
|
|
232
|
-
```typescript
|
|
233
|
-
import { hashFile, hashBlob, MD5ReadableStream } from 'pure-md5';
|
|
234
|
-
|
|
235
|
-
// For File
|
|
236
|
-
const file = document.querySelector('input').files[0];
|
|
237
|
-
const result = await hashFile(file);
|
|
238
|
-
|
|
239
|
-
// For Blob
|
|
240
|
-
const blob = new Blob([data]);
|
|
241
|
-
const result = await hashBlob(blob);
|
|
242
|
-
|
|
243
|
-
// For custom ReadableStream
|
|
244
|
-
const source = new ReadableStream({ ... });
|
|
245
|
-
const result = await MD5ReadableStream.hash(source);
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
## API Comparison
|
|
249
|
-
|
|
250
|
-
### crypto.createHash() Style
|
|
251
|
-
|
|
252
|
-
| crypto | pure-md5 |
|
|
253
|
-
|--------|----------|
|
|
254
|
-
| `update(chunk)` | `stream.write(chunk)` |
|
|
255
|
-
| `digest('hex')` | Listen to `md5` event |
|
|
256
|
-
| No built-in streaming | Built-in Transform stream |
|
|
257
|
-
| No progress tracking | Manual progress via 'data' event |
|
|
258
|
-
|
|
259
|
-
### File Operations
|
|
260
|
-
|
|
261
|
-
| crypto | pure-md5 |
|
|
262
|
-
|--------|----------|
|
|
263
|
-
| Manual file stream | `hashFile('path')` |
|
|
264
|
-
| Manual hash computation | `hashFileSync('path')` |
|
|
265
|
-
| Manual verification | `verifyFile('path', hash)` |
|
|
266
|
-
|
|
267
|
-
## Migration Checklist
|
|
268
|
-
|
|
269
|
-
- [ ] Identify all uses of `crypto.createHash('md5')`
|
|
270
|
-
- [ ] Replace with `MD5Stream` or `fromStream` for streaming
|
|
271
|
-
- [ ] Use `hashFile` for simple file hashing
|
|
272
|
-
- [ ] Update event handlers from 'end' to 'md5'
|
|
273
|
-
- [ ] Replace 'data' handler usage with MD5 event
|
|
274
|
-
- [ ] Update type imports
|
|
275
|
-
- [ ] Test with various input sizes
|
|
276
|
-
- [ ] Verify hash outputs match expected values
|
|
277
|
-
|
|
278
|
-
## Common Patterns
|
|
279
|
-
|
|
280
|
-
### Pattern 1: Simple File Hash
|
|
281
|
-
|
|
282
|
-
```typescript
|
|
283
|
-
// All of these are equivalent:
|
|
284
|
-
const result1 = await hashFile('file.txt');
|
|
285
|
-
const result2 = await pipeThroughMD5(fs.createReadStream('file.txt'));
|
|
286
|
-
const { result } = fromStream(fs.createReadStream('file.txt'));
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
### Pattern 2: Memory-Efficient Large File Hash
|
|
290
|
-
|
|
291
|
-
```typescript
|
|
292
|
-
const stream = new MD5Stream();
|
|
293
|
-
stream.on('md5', (result) => {
|
|
294
|
-
console.log('Hash:', result.digest);
|
|
295
|
-
console.log('Size:', result.bytesProcessed);
|
|
296
|
-
});
|
|
297
|
-
fs.createReadStream('large-file.bin').pipe(stream);
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
### Pattern 3: Concurrent File Hashing
|
|
301
|
-
|
|
302
|
-
```typescript
|
|
303
|
-
const files = ['file1.txt', 'file2.txt', 'file3.txt'];
|
|
304
|
-
const results = await Promise.all(files.map(f => hashFile(f)));
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
## Troubleshooting
|
|
308
|
-
|
|
309
|
-
### Issue: "digest is not a function"
|
|
310
|
-
|
|
311
|
-
**Cause:** Using crypto API incorrectly
|
|
312
|
-
|
|
313
|
-
**Solution:**
|
|
314
|
-
```typescript
|
|
315
|
-
// Wrong
|
|
316
|
-
const stream = crypto.createHash('md5');
|
|
317
|
-
stream.end(data);
|
|
318
|
-
console.log(stream.digest); // Error: digest is not a function
|
|
319
|
-
|
|
320
|
-
// Right
|
|
321
|
-
const stream = crypto.createHash('md5');
|
|
322
|
-
stream.end(data);
|
|
323
|
-
console.log(stream.digest('hex')); // Pass 'hex' argument
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
### Issue: Hash values don't match
|
|
327
|
-
|
|
328
|
-
**Cause:** Different encoding or data format
|
|
329
|
-
|
|
330
|
-
**Solution:**
|
|
331
|
-
```typescript
|
|
332
|
-
// Ensure consistent encoding
|
|
333
|
-
const data = 'Hello';
|
|
334
|
-
const stream = new MD5Stream();
|
|
335
|
-
let result = '';
|
|
336
|
-
stream.on('md5', (r) => result = r.digest);
|
|
337
|
-
stream.end(data); // This matches crypto.createHash('md5').update(data, 'utf8')
|
|
338
|
-
|
|
339
|
-
// For binary data, use Buffer
|
|
340
|
-
const binaryData = Buffer.from([0x48, 0x65, 0x6c, 0x6c, 0x6f]);
|
|
341
|
-
stream.end(binaryData);
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
### Issue: Stream not emitting 'md5' event
|
|
345
|
-
|
|
346
|
-
**Cause:** Not ending the stream
|
|
347
|
-
|
|
348
|
-
**Solution:**
|
|
349
|
-
```typescript
|
|
350
|
-
const stream = new MD5Stream();
|
|
351
|
-
stream.on('md5', (result) => console.log(result.digest));
|
|
352
|
-
stream.write('Hello');
|
|
353
|
-
stream.end(); // Must call end() to trigger 'md5' event
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
## Performance Notes
|
|
357
|
-
|
|
358
|
-
The pure-md5 streaming implementation is designed for:
|
|
359
|
-
|
|
360
|
-
- **Memory efficiency:** Processes data in chunks, doesn't load entire file
|
|
361
|
-
- **Compatibility:** Works in both Node.js and browser environments
|
|
362
|
-
- **Flexibility:** Multiple API styles for different use cases
|
|
363
|
-
|
|
364
|
-
For maximum performance with large files:
|
|
365
|
-
|
|
366
|
-
1. Use 64KB chunk sizes when manually writing
|
|
367
|
-
2. Reuse stream instances with `reset()`
|
|
368
|
-
3. Avoid unnecessary data copies
|
|
369
|
-
|
|
370
|
-
## See Also
|
|
371
|
-
|
|
372
|
-
- [STREAM_API.md](STREAM_API.md) - Complete API documentation
|
|
373
|
-
- [README.md](README.md) - Basic usage examples
|
|
374
|
-
- [WHATWG_STREAMS.md](WHATWG_STREAMS.md) - Browser streaming guide
|