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/CONTRIBUTING.md DELETED
@@ -1,203 +0,0 @@
1
- # Contributing to pure-md5
2
-
3
- Thank you for your interest in contributing to pure-md5! 🎉
4
-
5
- ## Table of Contents
6
-
7
- - [Code of Conduct](#code-of-conduct)
8
- - [How Can I Contribute?](#how-can-i-contribute)
9
- - [Development Setup](#development-setup)
10
- - [Running Tests](#running-tests)
11
- - [Creating Changesets](#creating-changesets)
12
- - [Pull Request Process](#pull-request-process)
13
- - [Coding Standards](#coding-standards)
14
-
15
- ## Code of Conduct
16
-
17
- This project and everyone participating in it is governed by our Code of Conduct. By participating, you are expected to uphold this code.
18
-
19
- ## How Can I Contribute?
20
-
21
- ### Reporting Bugs
22
-
23
- Before creating bug reports, please check the existing issues to avoid duplicates. When you create a bug report, please include as many details as possible:
24
-
25
- - A clear, descriptive title
26
- - Steps to reproduce the issue
27
- - Expected behavior
28
- - Actual behavior
29
- - Environment details (OS, Node.js version, package version)
30
- - Code example that reproduces the issue
31
-
32
- ### Suggesting Features
33
-
34
- Feature requests are welcome! Please provide:
35
-
36
- - A clear description of the feature
37
- - The problem it solves
38
- - Any alternative solutions you've considered
39
- - Examples of how the feature would be used
40
-
41
- ### Pull Requests
42
-
43
- 1. Fork the repository
44
- 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
45
- 3. Make your changes
46
- 4. Run tests (`npm test`)
47
- 5. Create a changeset (`npx changeset`)
48
- 6. Push your branch (`git push origin feature/amazing-feature`)
49
- 7. Open a Pull Request
50
-
51
- ## Development Setup
52
-
53
- ### Prerequisites
54
-
55
- - Node.js >= 16
56
- - npm >= 8
57
-
58
- ### Installation
59
-
60
- ```bash
61
- # Fork the repository first
62
- git clone https://github.com/eustatos/pure-md5.git
63
- cd pure-md5
64
-
65
- # Install dependencies
66
- npm install
67
-
68
- # Build the project
69
- npm run build
70
-
71
- # Run tests
72
- npm test
73
- ```
74
-
75
- ### Available Scripts
76
-
77
- | Command | Description |
78
- |---------|-------------|
79
- | `npm run build` | Build the project |
80
- | `npm run build:watch` | Build in watch mode |
81
- | `npm run build:prod` | Build with minification |
82
- | `npm run dev` | Run in dev mode |
83
- | `npm test` | Run all tests |
84
- | `npm run coverage` | Generate coverage report |
85
- | `npx changeset` | Create a changeset |
86
-
87
- ## Running Tests
88
-
89
- ### All Tests
90
-
91
- ```bash
92
- npm test
93
- ```
94
-
95
- ### Specific Test File
96
-
97
- ```bash
98
- npm test __tests__/index.test.ts
99
- ```
100
-
101
- ### With Coverage
102
-
103
- ```bash
104
- npm run coverage
105
- ```
106
-
107
- ### Watch Mode
108
-
109
- ```bash
110
- npm test -- --watch
111
- ```
112
-
113
- ## Creating Changesets
114
-
115
- Changesets are used to manage versioning and changelog generation.
116
-
117
- ### Creating a Changeset
118
-
119
- ```bash
120
- npx changeset
121
- ```
122
-
123
- This will prompt you to:
124
-
125
- 1. Select the version bump type:
126
- - `major` - Breaking changes
127
- - `minor` - New features
128
- - `patch` - Bug fixes
129
-
130
- 2. Write a description of your changes
131
-
132
- ### Example
133
-
134
- ```
135
- ? Which packages would you like to include in this changeset? pure-md5
136
- ? Which type of change is this?
137
- patch Patch release (bug fixes)
138
- minor Minor release (new features)
139
- major Major release (breaking changes)
140
- ```
141
-
142
- ## Pull Request Process
143
-
144
- 1. **Update Documentation**: Update README.md or other docs if needed
145
- 2. **Run Tests**: Ensure all tests pass
146
- 3. **Code Review**: Wait for review from maintainers
147
- 4. **Address Feedback**: Make requested changes
148
- 5. **Merge**: Maintainers will merge when approved
149
-
150
- ### PR Title Format
151
-
152
- Use conventional commit format:
153
-
154
- ```
155
- type: description
156
- ```
157
-
158
- Types:
159
- - `feat`: New feature
160
- - `fix`: Bug fix
161
- - `docs`: Documentation changes
162
- - `style`: Code style changes
163
- - `refactor`: Code refactoring
164
- - `perf`: Performance improvements
165
- - `test`: Adding tests
166
- - `chore`: Maintenance tasks
167
-
168
- Examples:
169
- ```
170
- feat: add streaming API for large files
171
- fix: handle edge case in MD5 calculation
172
- docs: update installation instructions
173
- refactor: optimize performance
174
- ```
175
-
176
- ## Coding Standards
177
-
178
- ### JavaScript/TypeScript
179
-
180
- - Use ES6+ features
181
- - Follow Airbnb JavaScript Style Guide
182
- - Use TypeScript for new code
183
- - Add JSDoc comments for public APIs
184
-
185
- ### Commit Messages
186
-
187
- - Use conventional commits
188
- - Use present tense
189
- - Be descriptive but concise
190
-
191
- ### File Structure
192
-
193
- - Place tests in `__tests__/` directory
194
- - Name test files `<module>.test.ts`
195
- - Keep files focused on single responsibility
196
-
197
- ## Questions?
198
-
199
- Feel free to open an issue or ask in the pull request if you have questions!
200
-
201
- ## Acknowledgments
202
-
203
- Thank you for contributing to pure-md5! 🙏
@@ -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