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/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
|