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.
- package/README.md +38 -24
- 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/index.cjs +1 -2
- package/dist/index.d.ts +149 -5
- package/dist/index.js +3 -2
- package/dist/md5.cjs +1 -0
- package/dist/md5.d.ts +20 -0
- package/dist/md5.js +1 -0
- 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 +3 -2
- package/package.json +10 -15
- package/pure-md5-0.2.1.tgz +0 -0
- package/test-tree-shake.mjs +12 -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 +0 -2
- package/dist/core/index.cjs.map +0 -1
- package/dist/core/index.d.cts +0 -19
- package/dist/core/index.d.ts +0 -19
- package/dist/core/index.js +0 -2
- package/dist/core/index.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -84
- package/dist/index.js.map +0 -1
- package/dist/stream/adapter.cjs +0 -2
- package/dist/stream/adapter.cjs.map +0 -1
- package/dist/stream/adapter.d.cts +0 -63
- package/dist/stream/adapter.d.ts +0 -63
- package/dist/stream/adapter.js +0 -2
- package/dist/stream/adapter.js.map +0 -1
- package/dist/stream/fs-utils.cjs +0 -2
- package/dist/stream/fs-utils.cjs.map +0 -1
- package/dist/stream/fs-utils.d.cts +0 -137
- package/dist/stream/fs-utils.d.ts +0 -137
- package/dist/stream/fs-utils.js +0 -2
- package/dist/stream/fs-utils.js.map +0 -1
- package/dist/stream/index.cjs +0 -2
- package/dist/stream/index.cjs.map +0 -1
- package/dist/stream/index.d.cts +0 -4
- package/dist/stream/index.d.ts +0 -4
- package/dist/stream/index.js +0 -2
- package/dist/stream/index.js.map +0 -1
- package/dist/stream/light/index.cjs +0 -2
- package/dist/stream/light/index.cjs.map +0 -1
- package/dist/stream/light/index.d.cts +0 -4
- package/dist/stream/light/index.d.ts +0 -4
- package/dist/stream/light/index.js +0 -2
- 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/types-edGoGJ5V.d.cts +0 -42
- package/dist/types-edGoGJ5V.d.ts +0 -42
- 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
package/STREAM_API.md
DELETED
|
@@ -1,582 +0,0 @@
|
|
|
1
|
-
# Streaming API Documentation
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
The `pure-md5` library provides comprehensive streaming support for hashing large files and data streams. This includes both Node.js Streams and WHATWG Streams (for browser environments).
|
|
6
|
-
|
|
7
|
-
## Node.js Streams API
|
|
8
|
-
|
|
9
|
-
### MD5Stream Class
|
|
10
|
-
|
|
11
|
-
A Node.js Transform stream for computing MD5 hashes while processing data.
|
|
12
|
-
|
|
13
|
-
#### Constructor
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
new MD5Stream(options?: MD5StreamOptions)
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
**Parameters:**
|
|
20
|
-
|
|
21
|
-
- `options` (optional): Stream options
|
|
22
|
-
- `add32` (optional): Custom add32 function for testing/compatibility
|
|
23
|
-
|
|
24
|
-
**Example:**
|
|
25
|
-
|
|
26
|
-
```typescript
|
|
27
|
-
import { MD5Stream } from 'pure-md5';
|
|
28
|
-
import fs from 'fs';
|
|
29
|
-
|
|
30
|
-
const stream = new MD5Stream();
|
|
31
|
-
stream.on('md5', (result) => {
|
|
32
|
-
console.log('MD5:', result.digest);
|
|
33
|
-
console.log('Bytes:', result.bytesProcessed);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
fs.createReadStream('file.txt').pipe(stream);
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
#### Events
|
|
40
|
-
|
|
41
|
-
**`md5` Event**
|
|
42
|
-
|
|
43
|
-
Emitted when MD5 computation is complete.
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
stream.on('md5', (result: MD5Result) => {
|
|
47
|
-
console.log('MD5:', result.digest); // 32-character hex string
|
|
48
|
-
console.log('Bytes:', result.bytesProcessed); // Total bytes processed
|
|
49
|
-
});
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
#### Methods
|
|
53
|
-
|
|
54
|
-
**`getCurrentState(): { state: number[]; bytesProcessed: number }`**
|
|
55
|
-
|
|
56
|
-
Get current internal MD5 state (for debugging/testing).
|
|
57
|
-
|
|
58
|
-
```typescript
|
|
59
|
-
const stream = new MD5Stream();
|
|
60
|
-
stream.write('test');
|
|
61
|
-
const state = stream.getCurrentState();
|
|
62
|
-
console.log('State:', state.state); // [1732584193, -271733879, ...]
|
|
63
|
-
console.log('Bytes:', state.bytesProcessed); // 4
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
**`getBytesProcessed(): number`**
|
|
67
|
-
|
|
68
|
-
Get the total number of bytes processed so far.
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
const stream = new MD5Stream();
|
|
72
|
-
stream.write('hello');
|
|
73
|
-
console.log(stream.getBytesProcessed()); // 5
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
**`reset(): void`**
|
|
77
|
-
|
|
78
|
-
Reset the internal MD5 state. Allows reusing the stream instance.
|
|
79
|
-
|
|
80
|
-
```typescript
|
|
81
|
-
const stream = new MD5Stream();
|
|
82
|
-
|
|
83
|
-
// First computation
|
|
84
|
-
stream.write('first');
|
|
85
|
-
stream.end();
|
|
86
|
-
|
|
87
|
-
// Reset and start new computation
|
|
88
|
-
stream.reset();
|
|
89
|
-
stream.write('second');
|
|
90
|
-
stream.end();
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
#### Static Methods
|
|
94
|
-
|
|
95
|
-
**`fromStream(source: Readable, options?: MD5StreamOptions): { stream: MD5Stream; result: Promise<MD5Result> }`**
|
|
96
|
-
|
|
97
|
-
Create an MD5Stream from an existing readable stream.
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
import { Readable } from 'stream';
|
|
101
|
-
|
|
102
|
-
const source = Readable.from(['hello', ' ', 'world']);
|
|
103
|
-
const { stream, result } = MD5Stream.fromStream(source);
|
|
104
|
-
|
|
105
|
-
result.then(r => {
|
|
106
|
-
console.log('MD5:', r.digest);
|
|
107
|
-
console.log('Bytes:', r.bytesProcessed);
|
|
108
|
-
});
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### Factory Functions
|
|
112
|
-
|
|
113
|
-
**`createMD5Stream(options?: MD5StreamOptions): MD5Stream`**
|
|
114
|
-
|
|
115
|
-
Create a new MD5Stream instance.
|
|
116
|
-
|
|
117
|
-
```typescript
|
|
118
|
-
import { createMD5Stream } from 'pure-md5';
|
|
119
|
-
|
|
120
|
-
const stream = createMD5Stream();
|
|
121
|
-
// Use stream...
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### Helper Functions
|
|
125
|
-
|
|
126
|
-
**`pipeThroughMD5(source: Readable, options?: MD5StreamOptions): Promise<MD5Result>`**
|
|
127
|
-
|
|
128
|
-
Pipe a readable stream through an MD5 computation and return the result.
|
|
129
|
-
|
|
130
|
-
```typescript
|
|
131
|
-
import { Readable, Transform } from 'stream';
|
|
132
|
-
import { pipeThroughMD5 } from 'pure-md5';
|
|
133
|
-
|
|
134
|
-
const source = Readable.from(['hello', ' ', 'world']);
|
|
135
|
-
const result = await pipeThroughMD5(source);
|
|
136
|
-
|
|
137
|
-
console.log('MD5:', result.digest);
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
**`fromStream(source: Readable, options?: MD5StreamOptions): { stream: MD5Stream; result: Promise<MD5Result> }`**
|
|
141
|
-
|
|
142
|
-
Create an MD5Stream and pipe a source through it.
|
|
143
|
-
|
|
144
|
-
```typescript
|
|
145
|
-
import { fromStream } from 'pure-md5';
|
|
146
|
-
import fs from 'fs';
|
|
147
|
-
|
|
148
|
-
const { stream, result } = fromStream(fs.createReadStream('file.txt'));
|
|
149
|
-
|
|
150
|
-
result.then(r => console.log('MD5:', r.digest));
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### Result Type
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
156
|
-
interface MD5Result {
|
|
157
|
-
digest: string; // MD5 hash as hex string (32 characters)
|
|
158
|
-
bytesProcessed: number; // Total bytes processed
|
|
159
|
-
}
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
## File System Utilities
|
|
163
|
-
|
|
164
|
-
### hashFile
|
|
165
|
-
|
|
166
|
-
Async file hashing with full result.
|
|
167
|
-
|
|
168
|
-
```typescript
|
|
169
|
-
import { hashFile } from 'pure-md5';
|
|
170
|
-
|
|
171
|
-
const result = await hashFile('path/to/file.txt');
|
|
172
|
-
console.log('MD5:', result.digest);
|
|
173
|
-
console.log('Bytes:', result.bytesProcessed);
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
**Options:**
|
|
177
|
-
|
|
178
|
-
```typescript
|
|
179
|
-
interface HashFileOptions {
|
|
180
|
-
add32?: (x: number, y: number) => number; // Custom add32 function
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### hashFileSync
|
|
185
|
-
|
|
186
|
-
Synchronous file hashing (for small files).
|
|
187
|
-
|
|
188
|
-
```typescript
|
|
189
|
-
import { hashFileSync } from 'pure-md5';
|
|
190
|
-
|
|
191
|
-
const digest = hashFileSync('path/to/file.txt');
|
|
192
|
-
console.log('MD5:', digest);
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### hashFileDigest
|
|
196
|
-
|
|
197
|
-
Get only the digest string (no bytes processed info).
|
|
198
|
-
|
|
199
|
-
```typescript
|
|
200
|
-
import { hashFileDigest } from 'pure-md5';
|
|
201
|
-
|
|
202
|
-
const digest = await hashFileDigest('path/to/file.txt');
|
|
203
|
-
console.log('MD5:', digest);
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
### verifyFile
|
|
207
|
-
|
|
208
|
-
Verify file integrity against a known hash.
|
|
209
|
-
|
|
210
|
-
```typescript
|
|
211
|
-
import { verifyFile } from 'pure-md5';
|
|
212
|
-
|
|
213
|
-
const isVerified = await verifyFile(
|
|
214
|
-
'path/to/file.txt',
|
|
215
|
-
'5d41402abc4b2a76b9719d911017c592'
|
|
216
|
-
);
|
|
217
|
-
|
|
218
|
-
if (isVerified) {
|
|
219
|
-
console.log('File verified successfully!');
|
|
220
|
-
} else {
|
|
221
|
-
console.log('File verification failed!');
|
|
222
|
-
}
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
## WHATWG Streams API (Browser)
|
|
226
|
-
|
|
227
|
-
### MD5ReadableStream
|
|
228
|
-
|
|
229
|
-
A wrapper for computing MD5 while reading from a ReadableStream.
|
|
230
|
-
|
|
231
|
-
#### Constructor
|
|
232
|
-
|
|
233
|
-
```typescript
|
|
234
|
-
new MD5ReadableStream(source: ReadableStream, options?: MD5ReadableStreamOptions)
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
**Example:**
|
|
238
|
-
|
|
239
|
-
```typescript
|
|
240
|
-
import { MD5ReadableStream } from 'pure-md5';
|
|
241
|
-
|
|
242
|
-
const source = new ReadableStream({
|
|
243
|
-
start(controller) {
|
|
244
|
-
controller.enqueue(new TextEncoder().encode('Hello World'));
|
|
245
|
-
controller.close();
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
const stream = new MD5ReadableStream(source);
|
|
250
|
-
const result = await stream.getResult();
|
|
251
|
-
console.log('MD5:', result.digest);
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
#### Methods
|
|
255
|
-
|
|
256
|
-
**`getReader(): ReadableStreamDefaultReader<Uint8Array>`**
|
|
257
|
-
|
|
258
|
-
Get a reader for the stream.
|
|
259
|
-
|
|
260
|
-
**`getResult(): Promise<MD5Result>`**
|
|
261
|
-
|
|
262
|
-
Get the MD5 result.
|
|
263
|
-
|
|
264
|
-
**`getCurrentState(): { state: number[]; bytesProcessed: number }`**
|
|
265
|
-
|
|
266
|
-
Get current internal state.
|
|
267
|
-
|
|
268
|
-
**`getBytesProcessed(): number`**
|
|
269
|
-
|
|
270
|
-
Get bytes processed so far.
|
|
271
|
-
|
|
272
|
-
#### Static Methods
|
|
273
|
-
|
|
274
|
-
**`hash(source: ReadableStream, options?: MD5ReadableStreamOptions): Promise<MD5Result>`**
|
|
275
|
-
|
|
276
|
-
Hash a stream directly.
|
|
277
|
-
|
|
278
|
-
```typescript
|
|
279
|
-
const result = await MD5ReadableStream.hash(source);
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
**`hashFile(file: File, options?: MD5ReadableStreamOptions): Promise<MD5Result>`**
|
|
283
|
-
|
|
284
|
-
Hash a File object.
|
|
285
|
-
|
|
286
|
-
```typescript
|
|
287
|
-
const input = document.querySelector('input[type="file"]');
|
|
288
|
-
const file = input.files[0];
|
|
289
|
-
const result = await MD5ReadableStream.hashFile(file);
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
**`hashBlob(blob: Blob, options?: MD5ReadableStreamOptions): Promise<MD5Result>`**
|
|
293
|
-
|
|
294
|
-
Hash a Blob object.
|
|
295
|
-
|
|
296
|
-
```typescript
|
|
297
|
-
const canvas = document.querySelector('canvas');
|
|
298
|
-
canvas.toBlob(async (blob) => {
|
|
299
|
-
const result = await MD5ReadableStream.hashBlob(blob!);
|
|
300
|
-
console.log('MD5:', result.digest);
|
|
301
|
-
});
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
### Factory Functions
|
|
305
|
-
|
|
306
|
-
**`createMD5ReadableStream(source: ReadableStream, options?: MD5ReadableStreamOptions): MD5ReadableStream`**
|
|
307
|
-
|
|
308
|
-
Create a new MD5ReadableStream instance.
|
|
309
|
-
|
|
310
|
-
### Standalone Functions
|
|
311
|
-
|
|
312
|
-
**`hashReadableStream(stream: ReadableStream, options?: MD5ReadableStreamOptions): Promise<MD5Result>`**
|
|
313
|
-
|
|
314
|
-
Hash a ReadableStream.
|
|
315
|
-
|
|
316
|
-
**`hashFile(file: File, options?: MD5ReadableStreamOptions): Promise<MD5Result>`**
|
|
317
|
-
|
|
318
|
-
Hash a File object.
|
|
319
|
-
|
|
320
|
-
**`hashBlob(blob: Blob, options?: MD5ReadableStreamOptions): Promise<MD5Result>`**
|
|
321
|
-
|
|
322
|
-
Hash a Blob object.
|
|
323
|
-
|
|
324
|
-
**`consumeWithMD5(source: ReadableStream, options?: MD5ReadableStreamOptions): Promise<MD5Result>`**
|
|
325
|
-
|
|
326
|
-
Consume a stream while computing MD5.
|
|
327
|
-
|
|
328
|
-
## Usage Examples
|
|
329
|
-
|
|
330
|
-
### Example 1: Hash a Large File
|
|
331
|
-
|
|
332
|
-
```typescript
|
|
333
|
-
import { MD5Stream } from 'pure-md5';
|
|
334
|
-
import fs from 'fs';
|
|
335
|
-
|
|
336
|
-
const stream = new MD5Stream();
|
|
337
|
-
let bytesProcessed = 0;
|
|
338
|
-
|
|
339
|
-
stream.on('md5', (result) => {
|
|
340
|
-
console.log('MD5:', result.digest);
|
|
341
|
-
console.log('Total bytes:', result.bytesProcessed);
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
stream.on('data', (chunk) => {
|
|
345
|
-
bytesProcessed += chunk.length;
|
|
346
|
-
const progress = (bytesProcessed / fileSize * 100).toFixed(1);
|
|
347
|
-
console.log(`Progress: ${progress}%`);
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
fs.createReadStream('large-file.bin').pipe(stream);
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
### Example 2: Browser File Upload with Progress
|
|
354
|
-
|
|
355
|
-
```typescript
|
|
356
|
-
import { MD5ReadableStream } from 'pure-md5';
|
|
357
|
-
|
|
358
|
-
async function uploadWithHash(file: File): Promise<void> {
|
|
359
|
-
const fileStream = file.stream();
|
|
360
|
-
const md5Stream = new MD5ReadableStream(fileStream);
|
|
361
|
-
|
|
362
|
-
const reader = md5Stream.getReader();
|
|
363
|
-
let bytesProcessed = 0;
|
|
364
|
-
|
|
365
|
-
while (true) {
|
|
366
|
-
const { done, value } = await reader.read();
|
|
367
|
-
if (done) break;
|
|
368
|
-
|
|
369
|
-
bytesProcessed += value.length;
|
|
370
|
-
const progress = (bytesProcessed / file.size * 100).toFixed(1);
|
|
371
|
-
console.log(`Upload progress: ${progress}%`);
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
const result = await md5Stream.getResult();
|
|
375
|
-
console.log('Upload complete. MD5:', result.digest);
|
|
376
|
-
|
|
377
|
-
// Upload file with hash...
|
|
378
|
-
}
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
### Example 3: Verify Downloaded File
|
|
382
|
-
|
|
383
|
-
```typescript
|
|
384
|
-
import { verifyFile } from 'pure-md5';
|
|
385
|
-
|
|
386
|
-
async function verifyDownload(url: string, expectedHash: string): Promise<boolean> {
|
|
387
|
-
const response = await fetch(url);
|
|
388
|
-
const blob = await response.blob();
|
|
389
|
-
|
|
390
|
-
// Create a File from Blob
|
|
391
|
-
const file = new File([blob], 'downloaded-file.bin', { type: blob.type });
|
|
392
|
-
|
|
393
|
-
const isVerified = await verifyFile(file, expectedHash);
|
|
394
|
-
return isVerified;
|
|
395
|
-
}
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
### Example 4: Hash Multiple Files Concurrently
|
|
399
|
-
|
|
400
|
-
```typescript
|
|
401
|
-
import { hashFile } from 'pure-md5';
|
|
402
|
-
import fs from 'fs';
|
|
403
|
-
|
|
404
|
-
async function hashFilesConcurrently(files: string[]): Promise<Map<string, string>> {
|
|
405
|
-
const results = new Map<string, string>();
|
|
406
|
-
|
|
407
|
-
const promises = files.map(async (file) => {
|
|
408
|
-
const result = await hashFile(file);
|
|
409
|
-
return [file, result.digest] as const;
|
|
410
|
-
});
|
|
411
|
-
|
|
412
|
-
const resolved = await Promise.all(promises);
|
|
413
|
-
resolved.forEach(([file, digest]) => results.set(file, digest));
|
|
414
|
-
|
|
415
|
-
return results;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
// Usage
|
|
419
|
-
const fileHashes = await hashFilesConcurrently(['file1.txt', 'file2.txt', 'file3.txt']);
|
|
420
|
-
fileHashes.forEach((hash, file) => console.log(`${file}: ${hash}`));
|
|
421
|
-
```
|
|
422
|
-
|
|
423
|
-
### Example 5: Streaming Data with Progress
|
|
424
|
-
|
|
425
|
-
```typescript
|
|
426
|
-
import { MD5Stream } from 'pure-md5';
|
|
427
|
-
|
|
428
|
-
async function streamWithProgress(source: NodeJS.ReadableStream): Promise<string> {
|
|
429
|
-
return new Promise((resolve, reject) => {
|
|
430
|
-
const stream = new MD5Stream();
|
|
431
|
-
const totalSize = 1000000; // Known total size
|
|
432
|
-
let processed = 0;
|
|
433
|
-
|
|
434
|
-
stream.on('md5', (result) => {
|
|
435
|
-
console.log('Complete! MD5:', result.digest);
|
|
436
|
-
resolve(result.digest);
|
|
437
|
-
});
|
|
438
|
-
|
|
439
|
-
stream.on('data', (chunk) => {
|
|
440
|
-
processed += chunk.length;
|
|
441
|
-
const progress = ((processed / totalSize) * 100).toFixed(1);
|
|
442
|
-
console.log(`Processing: ${progress}%`);
|
|
443
|
-
});
|
|
444
|
-
|
|
445
|
-
source.pipe(stream);
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
## Error Handling
|
|
451
|
-
|
|
452
|
-
### Node.js Streams
|
|
453
|
-
|
|
454
|
-
```typescript
|
|
455
|
-
import { MD5Stream } from 'pure-md5';
|
|
456
|
-
|
|
457
|
-
const stream = new MD5Stream();
|
|
458
|
-
|
|
459
|
-
stream.on('error', (error) => {
|
|
460
|
-
console.error('Stream error:', error.message);
|
|
461
|
-
});
|
|
462
|
-
|
|
463
|
-
stream.on('md5', (result) => {
|
|
464
|
-
console.log('Success:', result.digest);
|
|
465
|
-
});
|
|
466
|
-
|
|
467
|
-
// Error will be caught by 'error' handler
|
|
468
|
-
fs.createReadStream('nonexistent.txt').pipe(stream);
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
### WHATWG Streams
|
|
472
|
-
|
|
473
|
-
```typescript
|
|
474
|
-
import { MD5ReadableStream } from 'pure-md5';
|
|
475
|
-
|
|
476
|
-
try {
|
|
477
|
-
const stream = new MD5ReadableStream(source);
|
|
478
|
-
const result = await stream.getResult();
|
|
479
|
-
console.log('Success:', result.digest);
|
|
480
|
-
} catch (error) {
|
|
481
|
-
console.error('Stream error:', error.message);
|
|
482
|
-
}
|
|
483
|
-
```
|
|
484
|
-
|
|
485
|
-
## Performance Tips
|
|
486
|
-
|
|
487
|
-
1. **Use 64KB chunks** for optimal performance with Node.js streams
|
|
488
|
-
2. **Reuse stream instances** with `reset()` when processing multiple files
|
|
489
|
-
3. **For browser**, use `hashBlob()` or `hashFile()` directly for File/Blob objects
|
|
490
|
-
4. **Monitor memory usage** with very large files (use streaming, not full load)
|
|
491
|
-
5. **Consider parallel processing** for multiple independent files
|
|
492
|
-
|
|
493
|
-
## Migration Guide
|
|
494
|
-
|
|
495
|
-
### From crypto.createHash()
|
|
496
|
-
|
|
497
|
-
**Before:**
|
|
498
|
-
```typescript
|
|
499
|
-
import crypto from 'crypto';
|
|
500
|
-
|
|
501
|
-
const hash = crypto.createHash('md5').update(data).digest('hex');
|
|
502
|
-
```
|
|
503
|
-
|
|
504
|
-
**After:**
|
|
505
|
-
```typescript
|
|
506
|
-
import { MD5Stream } from 'pure-md5';
|
|
507
|
-
|
|
508
|
-
// For strings
|
|
509
|
-
const stream = new MD5Stream();
|
|
510
|
-
let digest = '';
|
|
511
|
-
stream.on('md5', (result) => digest = result.digest);
|
|
512
|
-
stream.end(data);
|
|
513
|
-
|
|
514
|
-
// Or use fromStream
|
|
515
|
-
const { result } = fromStream(Readable.from([data]));
|
|
516
|
-
const digest = await result;
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
### From browser-based hashing
|
|
520
|
-
|
|
521
|
-
**Before:**
|
|
522
|
-
```typescript
|
|
523
|
-
// Manual implementation
|
|
524
|
-
const buffer = await file.arrayBuffer();
|
|
525
|
-
const hashBuffer = await crypto.subtle.digest('MD5', buffer);
|
|
526
|
-
// ... convert to hex
|
|
527
|
-
```
|
|
528
|
-
|
|
529
|
-
**After:**
|
|
530
|
-
```typescript
|
|
531
|
-
import { hashFile } from 'pure-md5';
|
|
532
|
-
|
|
533
|
-
const result = await hashFile(file);
|
|
534
|
-
const digest = result.digest;
|
|
535
|
-
```
|
|
536
|
-
|
|
537
|
-
## Browser Compatibility
|
|
538
|
-
|
|
539
|
-
WHATWG Streams API requires modern browsers:
|
|
540
|
-
- Chrome 52+
|
|
541
|
-
- Firefox 57+
|
|
542
|
-
- Safari 12.1+
|
|
543
|
-
- Edge 79+
|
|
544
|
-
|
|
545
|
-
For older browsers, consider using a WHATWG Streams polyfill.
|
|
546
|
-
|
|
547
|
-
## FAQ
|
|
548
|
-
|
|
549
|
-
**Q: Which API should I use for Node.js?**
|
|
550
|
-
A: Use `MD5Stream` or the file utilities (`hashFile`, `hashFileSync`).
|
|
551
|
-
|
|
552
|
-
**Q: Which API should I use in the browser?**
|
|
553
|
-
A: Use `MD5ReadableStream` or the standalone functions (`hashFile`, `hashBlob`).
|
|
554
|
-
|
|
555
|
-
**Q: How do I track progress?**
|
|
556
|
-
A: Listen to 'data' events in Node.js or use the reader in WHATWG streams.
|
|
557
|
-
|
|
558
|
-
**Q: Can I hash data that doesn't fit in memory?**
|
|
559
|
-
A: Yes! Use streaming APIs to process data in chunks.
|
|
560
|
-
|
|
561
|
-
**Q: Is the stream API thread-safe?**
|
|
562
|
-
A: Yes, each stream instance maintains its own state.
|
|
563
|
-
|
|
564
|
-
**Q: What's the difference between `fromStream` and `pipeThroughMD5`?**
|
|
565
|
-
A: `fromStream` returns both stream and result for more control, while `pipeThroughMD5` is a convenience function that handles piping automatically.
|
|
566
|
-
|
|
567
|
-
## Performance Benchmarks
|
|
568
|
-
|
|
569
|
-
See `STREAM_OPTIMIZATION_REPORT.md` for detailed performance metrics.
|
|
570
|
-
|
|
571
|
-
| File Size | MD5Stream (ms) | Native (ms) | Ratio |
|
|
572
|
-
|-----------|----------------|-------------|-------|
|
|
573
|
-
| 1 KB | 0.15 | 0.08 | 1.88x |
|
|
574
|
-
| 1 MB | 5.23 | 4.12 | 1.27x |
|
|
575
|
-
| 10 MB | 48.67 | 38.45 | 1.27x |
|
|
576
|
-
| 100 MB | 482.34 | 389.21 | 1.24x |
|
|
577
|
-
|
|
578
|
-
## See Also
|
|
579
|
-
|
|
580
|
-
- [README.md](README.md) - Basic MD5 usage
|
|
581
|
-
- [STREAM_OPTIMIZATION_REPORT.md](STREAM_OPTIMIZATION_REPORT.md) - Performance details
|
|
582
|
-
- [WHATWG_STREAMS.md](WHATWG_STREAMS.md) - Browser streaming guide
|