@storacha/encrypt-upload-client 1.1.56 → 1.1.58

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 (72) hide show
  1. package/dist/config/constants.d.ts +3 -3
  2. package/dist/config/constants.js +4 -3
  3. package/dist/config/env.d.ts +9 -6
  4. package/dist/config/service.d.ts +13 -13
  5. package/dist/core/client.d.ts +54 -41
  6. package/dist/core/client.js +68 -56
  7. package/dist/core/errors.d.ts +6 -6
  8. package/dist/core/metadata/encrypted-metadata.d.ts +13 -8
  9. package/dist/core/metadata/kms-metadata.d.ts +68 -36
  10. package/dist/core/metadata/lit-metadata.d.ts +63 -28
  11. package/dist/crypto/adapters/kms-crypto-adapter.d.ts +172 -137
  12. package/dist/crypto/adapters/lit-crypto-adapter.d.ts +107 -86
  13. package/dist/crypto/factories.browser.d.ts +9 -5
  14. package/dist/crypto/factories.browser.js +15 -7
  15. package/dist/crypto/factories.node.d.ts +13 -6
  16. package/dist/crypto/factories.node.js +19 -13
  17. package/dist/crypto/index.d.ts +5 -5
  18. package/dist/crypto/index.js +5 -5
  19. package/dist/crypto/symmetric/generic-aes-ctr-streaming-crypto.d.ts +58 -54
  20. package/dist/crypto/symmetric/generic-aes-ctr-streaming-crypto.js +174 -146
  21. package/dist/crypto/symmetric/node-aes-cbc-crypto.d.ts +36 -32
  22. package/dist/crypto/symmetric/node-aes-cbc-crypto.js +101 -95
  23. package/dist/examples/decrypt-test.d.ts +2 -2
  24. package/dist/examples/decrypt-test.js +78 -69
  25. package/dist/examples/encrypt-test.d.ts +5 -3
  26. package/dist/examples/encrypt-test.js +58 -55
  27. package/dist/handlers/decrypt-handler.d.ts +19 -5
  28. package/dist/handlers/encrypt-handler.d.ts +9 -3
  29. package/dist/handlers/encrypt-handler.js +93 -57
  30. package/dist/index.d.ts +2 -2
  31. package/dist/index.js +2 -2
  32. package/dist/protocols/lit.d.ts +33 -9
  33. package/dist/protocols/lit.js +134 -98
  34. package/dist/test/cid-verification.spec.d.ts +2 -2
  35. package/dist/test/cid-verification.spec.js +341 -313
  36. package/dist/test/crypto-compatibility.spec.d.ts +2 -2
  37. package/dist/test/crypto-compatibility.spec.js +184 -120
  38. package/dist/test/crypto-counter-security.spec.d.ts +2 -2
  39. package/dist/test/crypto-counter-security.spec.js +177 -138
  40. package/dist/test/crypto-streaming.spec.d.ts +2 -2
  41. package/dist/test/crypto-streaming.spec.js +208 -126
  42. package/dist/test/encrypted-metadata.spec.d.ts +2 -2
  43. package/dist/test/encrypted-metadata.spec.js +89 -62
  44. package/dist/test/factories.spec.d.ts +2 -2
  45. package/dist/test/factories.spec.js +275 -139
  46. package/dist/test/file-metadata.spec.d.ts +2 -2
  47. package/dist/test/file-metadata.spec.js +472 -416
  48. package/dist/test/fixtures/test-fixtures.d.ts +25 -20
  49. package/dist/test/fixtures/test-fixtures.js +61 -53
  50. package/dist/test/helpers/test-file-utils.d.ts +19 -14
  51. package/dist/test/helpers/test-file-utils.js +78 -76
  52. package/dist/test/https-enforcement.spec.d.ts +2 -2
  53. package/dist/test/https-enforcement.spec.js +278 -124
  54. package/dist/test/kms-crypto-adapter.spec.d.ts +2 -2
  55. package/dist/test/kms-crypto-adapter.spec.js +473 -304
  56. package/dist/test/lit-crypto-adapter.spec.d.ts +2 -2
  57. package/dist/test/lit-crypto-adapter.spec.js +206 -118
  58. package/dist/test/memory-efficiency.spec.d.ts +2 -2
  59. package/dist/test/memory-efficiency.spec.js +100 -87
  60. package/dist/test/mocks/key-manager.d.ts +71 -38
  61. package/dist/test/mocks/key-manager.js +129 -113
  62. package/dist/test/node-crypto-adapter.spec.d.ts +2 -2
  63. package/dist/test/node-crypto-adapter.spec.js +155 -102
  64. package/dist/test/node-generic-crypto-adapter.spec.d.ts +2 -2
  65. package/dist/test/node-generic-crypto-adapter.spec.js +134 -94
  66. package/dist/test/setup.d.ts +2 -2
  67. package/dist/test/setup.js +8 -9
  68. package/dist/tsconfig.spec.tsbuildinfo +1 -1
  69. package/dist/types.d.ts +219 -181
  70. package/dist/utils/file-metadata.d.ts +19 -13
  71. package/dist/utils.d.ts +14 -5
  72. package/package.json +4 -4
@@ -1,2 +1,2 @@
1
- export {};
2
- //# sourceMappingURL=lit-crypto-adapter.spec.d.ts.map
1
+ export {}
2
+ //# sourceMappingURL=lit-crypto-adapter.spec.d.ts.map
@@ -1,120 +1,208 @@
1
- import './setup.js';
2
- import { test, describe } from 'node:test';
3
- import assert from 'node:assert';
4
- import { GenericAesCtrStreamingCrypto } from '../src/crypto/symmetric/generic-aes-ctr-streaming-crypto.js';
5
- import { NodeAesCbcCrypto } from '../src/crypto/symmetric/node-aes-cbc-crypto.js';
6
- import { LitCryptoAdapter } from '../src/crypto/adapters/lit-crypto-adapter.js';
7
- import { stringToUint8Array, streamToUint8Array, uint8ArrayToString, } from './helpers/test-file-utils.js';
1
+ import './setup.js'
2
+ import { test, describe } from 'node:test'
3
+ import assert from 'node:assert'
4
+ import { GenericAesCtrStreamingCrypto } from '../src/crypto/symmetric/generic-aes-ctr-streaming-crypto.js'
5
+ import { NodeAesCbcCrypto } from '../src/crypto/symmetric/node-aes-cbc-crypto.js'
6
+ import { LitCryptoAdapter } from '../src/crypto/adapters/lit-crypto-adapter.js'
7
+ import {
8
+ stringToUint8Array,
9
+ streamToUint8Array,
10
+ uint8ArrayToString,
11
+ } from './helpers/test-file-utils.js'
8
12
  // Mock Lit client - cast to any for testing
9
- const mockLitClient = /** @type {any} */ ({
10
- // Add mock methods as needed
11
- });
13
+ const mockLitClient = /** @type {any} */ (
14
+ {
15
+ // Add mock methods as needed
16
+ }
17
+ )
12
18
  await describe('LitCryptoAdapter', async () => {
13
- await describe('Generic AES-CTR Crypto Implementation', async () => {
14
- await test('should delegate symmetric crypto operations to the generic implementation', async () => {
15
- const symmetricCrypto = new GenericAesCtrStreamingCrypto();
16
- const adapter = new LitCryptoAdapter(symmetricCrypto, mockLitClient);
17
- const originalText = 'Op, this is a test for strategy-based encryption!';
18
- const blob = new Blob([stringToUint8Array(originalText)]);
19
- // Test that it delegates to the symmetric crypto implementation
20
- const { key, iv, encryptedStream } = await adapter.encryptStream(blob);
21
- assert(key instanceof Uint8Array, 'Key should be a Uint8Array');
22
- assert(iv instanceof Uint8Array, 'IV should be a Uint8Array');
23
- assert(encryptedStream instanceof ReadableStream, 'Encrypted stream should be a ReadableStream');
24
- // Test decryption delegation
25
- const decryptedStream = await adapter.decryptStream(encryptedStream, key, iv);
26
- const decryptedBytes = await streamToUint8Array(decryptedStream);
27
- const decryptedText = uint8ArrayToString(decryptedBytes);
28
- assert.strictEqual(decryptedText, originalText, 'Decrypted text should match original');
29
- });
30
- await test('should initialize Generic Lit adapter with correct configuration', async () => {
31
- const symmetricCrypto = new GenericAesCtrStreamingCrypto();
32
- const adapter = new LitCryptoAdapter(symmetricCrypto, mockLitClient);
33
- // Test that the adapter has the required methods
34
- assert(typeof adapter.encryptSymmetricKey === 'function', 'encryptSymmetricKey should be a function');
35
- assert(typeof adapter.decryptSymmetricKey === 'function', 'decryptSymmetricKey should be a function');
36
- // Verify adapter has the lit client
37
- assert.strictEqual(adapter.litClient, mockLitClient, 'Adapter should store the Lit client');
38
- // Verify it uses the correct crypto implementation
39
- assert(adapter.symmetricCrypto instanceof GenericAesCtrStreamingCrypto, 'Should use GenericAesCtrStreamingCrypto');
40
- });
41
- });
42
- await describe('Node.js AES-CBC Crypto Implementation (Legacy)', async () => {
43
- await test('should delegate symmetric crypto operations to the Node.js implementation', async () => {
44
- const symmetricCrypto = new NodeAesCbcCrypto();
45
- const adapter = new LitCryptoAdapter(symmetricCrypto, mockLitClient);
46
- const originalText = 'Op, this is a test for legacy Node.js encryption!';
47
- const blob = new Blob([stringToUint8Array(originalText)]);
48
- // Test that it delegates to the symmetric crypto implementation
49
- const { key, iv, encryptedStream } = await adapter.encryptStream(blob);
50
- assert(key instanceof Uint8Array, 'Key should be a Uint8Array');
51
- assert(iv instanceof Uint8Array, 'IV should be a Uint8Array');
52
- assert(encryptedStream instanceof ReadableStream, 'Encrypted stream should be a ReadableStream');
53
- // Test decryption delegation
54
- const decryptedStream = await adapter.decryptStream(encryptedStream, key, iv);
55
- const decryptedBytes = await streamToUint8Array(decryptedStream);
56
- const decryptedText = uint8ArrayToString(decryptedBytes);
57
- assert.strictEqual(decryptedText, originalText, 'Decrypted text should match original');
58
- });
59
- await test('should initialize Node.js Lit adapter with correct configuration', async () => {
60
- const symmetricCrypto = new NodeAesCbcCrypto();
61
- const adapter = new LitCryptoAdapter(symmetricCrypto, mockLitClient);
62
- // Test that the adapter has the required methods
63
- assert(typeof adapter.encryptSymmetricKey === 'function', 'encryptSymmetricKey should be a function');
64
- assert(typeof adapter.decryptSymmetricKey === 'function', 'decryptSymmetricKey should be a function');
65
- // Verify adapter has the lit client
66
- assert.strictEqual(adapter.litClient, mockLitClient, 'Adapter should store the Lit client');
67
- // Verify it uses the correct crypto implementation
68
- assert(adapter.symmetricCrypto instanceof NodeAesCbcCrypto, 'Should use NodeAesCbcCrypto');
69
- });
70
- });
71
- await describe('Cross-Implementation Compatibility', async () => {
72
- await test('should demonstrate algorithm differences between implementations', async () => {
73
- const genericCrypto = new GenericAesCtrStreamingCrypto();
74
- const nodeCrypto = new NodeAesCbcCrypto();
75
- const genericAdapter = new LitCryptoAdapter(genericCrypto, mockLitClient);
76
- const nodeAdapter = new LitCryptoAdapter(nodeCrypto, mockLitClient);
77
- const originalText = 'Test data for algorithm comparison';
78
- const blob = new Blob([stringToUint8Array(originalText)]);
79
- // Encrypt with both adapters
80
- const genericResult = await genericAdapter.encryptStream(blob);
81
- const nodeResult = await nodeAdapter.encryptStream(blob);
82
- // Convert streams to bytes
83
- const genericEncrypted = await streamToUint8Array(genericResult.encryptedStream);
84
- const nodeEncrypted = await streamToUint8Array(nodeResult.encryptedStream);
85
- // Verify they produce different results (different algorithms)
86
- assert.notDeepEqual(genericEncrypted, nodeEncrypted, 'AES-CTR and AES-CBC should produce different encrypted outputs');
87
- // Verify both can decrypt their own data
88
- const genericDecryptStream = new ReadableStream({
89
- start(controller) {
90
- controller.enqueue(genericEncrypted);
91
- controller.close();
92
- },
93
- });
94
- const nodeDecryptStream = new ReadableStream({
95
- start(controller) {
96
- controller.enqueue(nodeEncrypted);
97
- controller.close();
98
- },
99
- });
100
- const genericDecrypted = await genericAdapter.decryptStream(genericDecryptStream, genericResult.key, genericResult.iv);
101
- const nodeDecrypted = await nodeAdapter.decryptStream(nodeDecryptStream, nodeResult.key, nodeResult.iv);
102
- const genericDecryptedBytes = await streamToUint8Array(genericDecrypted);
103
- const nodeDecryptedBytes = await streamToUint8Array(nodeDecrypted);
104
- // Both should decrypt to the same original text
105
- assert.strictEqual(uint8ArrayToString(genericDecryptedBytes), originalText, 'Generic adapter should decrypt correctly');
106
- assert.strictEqual(uint8ArrayToString(nodeDecryptedBytes), originalText, 'Node adapter should decrypt correctly');
107
- console.log('Both crypto implementations work with Lit adapter but produce different encrypted outputs');
108
- });
109
- await test('should verify factory function behavior', async () => {
110
- const { createGenericLitAdapter, createNodeLitAdapter } = await import('../src/crypto/factories.node.js');
111
- const genericAdapter = createGenericLitAdapter(mockLitClient);
112
- const nodeAdapter = createNodeLitAdapter(mockLitClient);
113
- // Verify factory functions create adapters with correct crypto implementations
114
- assert(genericAdapter.symmetricCrypto instanceof GenericAesCtrStreamingCrypto, 'Generic factory should create adapter with GenericAesCtrStreamingCrypto');
115
- assert(nodeAdapter.symmetricCrypto instanceof NodeAesCbcCrypto, 'Node factory should create adapter with NodeAesCbcCrypto');
116
- console.log('Factory functions create adapters with correct crypto implementations');
117
- });
118
- });
119
- });
120
- //# sourceMappingURL=lit-crypto-adapter.spec.js.map
19
+ await describe('Generic AES-CTR Crypto Implementation', async () => {
20
+ await test('should delegate symmetric crypto operations to the generic implementation', async () => {
21
+ const symmetricCrypto = new GenericAesCtrStreamingCrypto()
22
+ const adapter = new LitCryptoAdapter(symmetricCrypto, mockLitClient)
23
+ const originalText = 'Op, this is a test for strategy-based encryption!'
24
+ const blob = new Blob([stringToUint8Array(originalText)])
25
+ // Test that it delegates to the symmetric crypto implementation
26
+ const { key, iv, encryptedStream } = await adapter.encryptStream(blob)
27
+ assert(key instanceof Uint8Array, 'Key should be a Uint8Array')
28
+ assert(iv instanceof Uint8Array, 'IV should be a Uint8Array')
29
+ assert(
30
+ encryptedStream instanceof ReadableStream,
31
+ 'Encrypted stream should be a ReadableStream'
32
+ )
33
+ // Test decryption delegation
34
+ const decryptedStream = await adapter.decryptStream(
35
+ encryptedStream,
36
+ key,
37
+ iv
38
+ )
39
+ const decryptedBytes = await streamToUint8Array(decryptedStream)
40
+ const decryptedText = uint8ArrayToString(decryptedBytes)
41
+ assert.strictEqual(
42
+ decryptedText,
43
+ originalText,
44
+ 'Decrypted text should match original'
45
+ )
46
+ })
47
+ await test('should initialize Generic Lit adapter with correct configuration', async () => {
48
+ const symmetricCrypto = new GenericAesCtrStreamingCrypto()
49
+ const adapter = new LitCryptoAdapter(symmetricCrypto, mockLitClient)
50
+ // Test that the adapter has the required methods
51
+ assert(
52
+ typeof adapter.encryptSymmetricKey === 'function',
53
+ 'encryptSymmetricKey should be a function'
54
+ )
55
+ assert(
56
+ typeof adapter.decryptSymmetricKey === 'function',
57
+ 'decryptSymmetricKey should be a function'
58
+ )
59
+ // Verify adapter has the lit client
60
+ assert.strictEqual(
61
+ adapter.litClient,
62
+ mockLitClient,
63
+ 'Adapter should store the Lit client'
64
+ )
65
+ // Verify it uses the correct crypto implementation
66
+ assert(
67
+ adapter.symmetricCrypto instanceof GenericAesCtrStreamingCrypto,
68
+ 'Should use GenericAesCtrStreamingCrypto'
69
+ )
70
+ })
71
+ })
72
+ await describe('Node.js AES-CBC Crypto Implementation (Legacy)', async () => {
73
+ await test('should delegate symmetric crypto operations to the Node.js implementation', async () => {
74
+ const symmetricCrypto = new NodeAesCbcCrypto()
75
+ const adapter = new LitCryptoAdapter(symmetricCrypto, mockLitClient)
76
+ const originalText = 'Op, this is a test for legacy Node.js encryption!'
77
+ const blob = new Blob([stringToUint8Array(originalText)])
78
+ // Test that it delegates to the symmetric crypto implementation
79
+ const { key, iv, encryptedStream } = await adapter.encryptStream(blob)
80
+ assert(key instanceof Uint8Array, 'Key should be a Uint8Array')
81
+ assert(iv instanceof Uint8Array, 'IV should be a Uint8Array')
82
+ assert(
83
+ encryptedStream instanceof ReadableStream,
84
+ 'Encrypted stream should be a ReadableStream'
85
+ )
86
+ // Test decryption delegation
87
+ const decryptedStream = await adapter.decryptStream(
88
+ encryptedStream,
89
+ key,
90
+ iv
91
+ )
92
+ const decryptedBytes = await streamToUint8Array(decryptedStream)
93
+ const decryptedText = uint8ArrayToString(decryptedBytes)
94
+ assert.strictEqual(
95
+ decryptedText,
96
+ originalText,
97
+ 'Decrypted text should match original'
98
+ )
99
+ })
100
+ await test('should initialize Node.js Lit adapter with correct configuration', async () => {
101
+ const symmetricCrypto = new NodeAesCbcCrypto()
102
+ const adapter = new LitCryptoAdapter(symmetricCrypto, mockLitClient)
103
+ // Test that the adapter has the required methods
104
+ assert(
105
+ typeof adapter.encryptSymmetricKey === 'function',
106
+ 'encryptSymmetricKey should be a function'
107
+ )
108
+ assert(
109
+ typeof adapter.decryptSymmetricKey === 'function',
110
+ 'decryptSymmetricKey should be a function'
111
+ )
112
+ // Verify adapter has the lit client
113
+ assert.strictEqual(
114
+ adapter.litClient,
115
+ mockLitClient,
116
+ 'Adapter should store the Lit client'
117
+ )
118
+ // Verify it uses the correct crypto implementation
119
+ assert(
120
+ adapter.symmetricCrypto instanceof NodeAesCbcCrypto,
121
+ 'Should use NodeAesCbcCrypto'
122
+ )
123
+ })
124
+ })
125
+ await describe('Cross-Implementation Compatibility', async () => {
126
+ await test('should demonstrate algorithm differences between implementations', async () => {
127
+ const genericCrypto = new GenericAesCtrStreamingCrypto()
128
+ const nodeCrypto = new NodeAesCbcCrypto()
129
+ const genericAdapter = new LitCryptoAdapter(genericCrypto, mockLitClient)
130
+ const nodeAdapter = new LitCryptoAdapter(nodeCrypto, mockLitClient)
131
+ const originalText = 'Test data for algorithm comparison'
132
+ const blob = new Blob([stringToUint8Array(originalText)])
133
+ // Encrypt with both adapters
134
+ const genericResult = await genericAdapter.encryptStream(blob)
135
+ const nodeResult = await nodeAdapter.encryptStream(blob)
136
+ // Convert streams to bytes
137
+ const genericEncrypted = await streamToUint8Array(
138
+ genericResult.encryptedStream
139
+ )
140
+ const nodeEncrypted = await streamToUint8Array(nodeResult.encryptedStream)
141
+ // Verify they produce different results (different algorithms)
142
+ assert.notDeepEqual(
143
+ genericEncrypted,
144
+ nodeEncrypted,
145
+ 'AES-CTR and AES-CBC should produce different encrypted outputs'
146
+ )
147
+ // Verify both can decrypt their own data
148
+ const genericDecryptStream = new ReadableStream({
149
+ start(controller) {
150
+ controller.enqueue(genericEncrypted)
151
+ controller.close()
152
+ },
153
+ })
154
+ const nodeDecryptStream = new ReadableStream({
155
+ start(controller) {
156
+ controller.enqueue(nodeEncrypted)
157
+ controller.close()
158
+ },
159
+ })
160
+ const genericDecrypted = await genericAdapter.decryptStream(
161
+ genericDecryptStream,
162
+ genericResult.key,
163
+ genericResult.iv
164
+ )
165
+ const nodeDecrypted = await nodeAdapter.decryptStream(
166
+ nodeDecryptStream,
167
+ nodeResult.key,
168
+ nodeResult.iv
169
+ )
170
+ const genericDecryptedBytes = await streamToUint8Array(genericDecrypted)
171
+ const nodeDecryptedBytes = await streamToUint8Array(nodeDecrypted)
172
+ // Both should decrypt to the same original text
173
+ assert.strictEqual(
174
+ uint8ArrayToString(genericDecryptedBytes),
175
+ originalText,
176
+ 'Generic adapter should decrypt correctly'
177
+ )
178
+ assert.strictEqual(
179
+ uint8ArrayToString(nodeDecryptedBytes),
180
+ originalText,
181
+ 'Node adapter should decrypt correctly'
182
+ )
183
+ console.log(
184
+ 'Both crypto implementations work with Lit adapter but produce different encrypted outputs'
185
+ )
186
+ })
187
+ await test('should verify factory function behavior', async () => {
188
+ const { createGenericLitAdapter, createNodeLitAdapter } = await import(
189
+ '../src/crypto/factories.node.js'
190
+ )
191
+ const genericAdapter = createGenericLitAdapter(mockLitClient)
192
+ const nodeAdapter = createNodeLitAdapter(mockLitClient)
193
+ // Verify factory functions create adapters with correct crypto implementations
194
+ assert(
195
+ genericAdapter.symmetricCrypto instanceof GenericAesCtrStreamingCrypto,
196
+ 'Generic factory should create adapter with GenericAesCtrStreamingCrypto'
197
+ )
198
+ assert(
199
+ nodeAdapter.symmetricCrypto instanceof NodeAesCbcCrypto,
200
+ 'Node factory should create adapter with NodeAesCbcCrypto'
201
+ )
202
+ console.log(
203
+ 'Factory functions create adapters with correct crypto implementations'
204
+ )
205
+ })
206
+ })
207
+ })
208
+ //# sourceMappingURL=lit-crypto-adapter.spec.js.map
@@ -1,2 +1,2 @@
1
- export {};
2
- //# sourceMappingURL=memory-efficiency.spec.d.ts.map
1
+ export {}
2
+ //# sourceMappingURL=memory-efficiency.spec.d.ts.map
@@ -1,93 +1,106 @@
1
- import './setup.js';
2
- import { test, describe } from 'node:test';
3
- import assert from 'node:assert';
4
- import { GenericAesCtrStreamingCrypto } from '../src/crypto/symmetric/generic-aes-ctr-streaming-crypto.js';
5
- import { createTestFile } from './helpers/test-file-utils.js';
1
+ import './setup.js'
2
+ import { test, describe } from 'node:test'
3
+ import assert from 'node:assert'
4
+ import { GenericAesCtrStreamingCrypto } from '../src/crypto/symmetric/generic-aes-ctr-streaming-crypto.js'
5
+ import { createTestFile } from './helpers/test-file-utils.js'
6
6
  /**
7
7
  * These tests demonstrate why streaming is necessary for large files.
8
8
  * They show that buffered approaches fail with memory errors while streaming succeeds.
9
9
  */
10
10
  await describe('Memory Efficiency - Why Streaming Matters', async () => {
11
- await test('should show streaming handles progressively larger files', async () => {
12
- const streamingCrypto = new GenericAesCtrStreamingCrypto();
13
- // Test with multiple sizes to show streaming scales linearly
14
- const testSizes = [5, 10, 15, 20, 50, 100, 500, 1000]; // MB - sizes that would challenge buffered approaches
15
- for (const sizeMB of testSizes) {
16
- console.log(`Processing ${sizeMB}MB file...`);
17
- const testFile = createTestFile(sizeMB);
18
- const startTime = Date.now();
19
- const { encryptedStream } = await streamingCrypto.encryptStream(testFile);
20
- let processedBytes = 0;
21
- let chunkCount = 0;
22
- const reader = encryptedStream.getReader();
23
- try {
24
- // eslint-disable-next-line no-constant-condition
25
- while (true) {
26
- const { done, value } = await reader.read();
27
- if (done)
28
- break;
29
- processedBytes += value.length;
30
- chunkCount++;
31
- }
32
- }
33
- finally {
34
- reader.releaseLock();
35
- }
36
- const processingTime = Date.now() - startTime;
37
- const throughput = processedBytes / 1024 / 1024 / (processingTime / 1000); // MB/s
38
- assert.strictEqual(processedBytes, testFile.size, `Should process entire ${sizeMB}MB file`);
39
- console.log(`✓ ${sizeMB}MB: ${chunkCount} chunks, ${throughput.toFixed(1)} MB/s`);
11
+ await test('should show streaming handles progressively larger files', async () => {
12
+ const streamingCrypto = new GenericAesCtrStreamingCrypto()
13
+ // Test with multiple sizes to show streaming scales linearly
14
+ const testSizes = [5, 10, 15, 20, 50, 100, 500, 1000] // MB - sizes that would challenge buffered approaches
15
+ for (const sizeMB of testSizes) {
16
+ console.log(`Processing ${sizeMB}MB file...`)
17
+ const testFile = createTestFile(sizeMB)
18
+ const startTime = Date.now()
19
+ const { encryptedStream } = await streamingCrypto.encryptStream(testFile)
20
+ let processedBytes = 0
21
+ let chunkCount = 0
22
+ const reader = encryptedStream.getReader()
23
+ try {
24
+ // eslint-disable-next-line no-constant-condition
25
+ while (true) {
26
+ const { done, value } = await reader.read()
27
+ if (done) break
28
+ processedBytes += value.length
29
+ chunkCount++
40
30
  }
41
- console.log('DEMONSTRATED: Streaming handles large files with consistent performance');
42
- });
43
- await test('should project memory behavior for realistic file sizes', async () => {
44
- const streamingCrypto = new GenericAesCtrStreamingCrypto();
45
- // Test with a size we can actually handle to project larger files
46
- const testFile = createTestFile(5); // 5MB
47
- const getMemoryUsage = () => {
48
- if (globalThis.gc)
49
- globalThis.gc();
50
- return process.memoryUsage ? process.memoryUsage().heapUsed : 0;
51
- };
52
- const baseMemory = getMemoryUsage();
53
- const { encryptedStream } = await streamingCrypto.encryptStream(testFile);
54
- let peakMemoryDelta = 0;
55
- let processedBytes = 0;
56
- const reader = encryptedStream.getReader();
57
- try {
58
- // eslint-disable-next-line no-constant-condition
59
- while (true) {
60
- const { done, value } = await reader.read();
61
- if (done)
62
- break;
63
- processedBytes += value.length;
64
- // Sample memory usage
65
- const currentMemory = getMemoryUsage();
66
- const memoryDelta = currentMemory - baseMemory;
67
- peakMemoryDelta = Math.max(peakMemoryDelta, memoryDelta);
68
- }
69
- }
70
- finally {
71
- reader.releaseLock();
72
- }
73
- const peakMemoryMB = peakMemoryDelta / 1024 / 1024;
74
- const fileSize = testFile.size / 1024 / 1024;
75
- const memoryEfficiency = (peakMemoryDelta / testFile.size) * 100;
76
- console.log(`File size: ${fileSize.toFixed(1)}MB`);
77
- console.log(`Peak memory delta: ${peakMemoryMB.toFixed(2)}MB`);
78
- console.log(`Memory efficiency: ${memoryEfficiency.toFixed(1)}% of file size`);
79
- // Project to larger file sizes
80
- console.log('\nProjected memory usage:');
81
- const projectedSizes = [100, 1000, 5000]; // MB = 100MB, 1GB, 5GB
82
- for (const sizeMB of projectedSizes) {
83
- const projectedMemory = (memoryEfficiency / 100) * sizeMB;
84
- const sizeLabel = sizeMB >= 1000 ? `${sizeMB / 1000}GB` : `${sizeMB}MB`;
85
- console.log(` ${sizeLabel}: ~${projectedMemory.toFixed(1)}MB memory`);
86
- }
87
- // Memory should be bounded (much less than file size)
88
- assert(peakMemoryMB < fileSize, 'Streaming should use less memory than file size');
89
- assert(memoryEfficiency < 50, 'Memory usage should be less than 50% of file size');
90
- console.log('DEMONSTRATED: Streaming memory usage scales sub-linearly with file size');
91
- });
92
- });
93
- //# sourceMappingURL=memory-efficiency.spec.js.map
31
+ } finally {
32
+ reader.releaseLock()
33
+ }
34
+ const processingTime = Date.now() - startTime
35
+ const throughput = processedBytes / 1024 / 1024 / (processingTime / 1000) // MB/s
36
+ assert.strictEqual(
37
+ processedBytes,
38
+ testFile.size,
39
+ `Should process entire ${sizeMB}MB file`
40
+ )
41
+ console.log(
42
+ `✓ ${sizeMB}MB: ${chunkCount} chunks, ${throughput.toFixed(1)} MB/s`
43
+ )
44
+ }
45
+ console.log(
46
+ 'DEMONSTRATED: Streaming handles large files with consistent performance'
47
+ )
48
+ })
49
+ await test('should project memory behavior for realistic file sizes', async () => {
50
+ const streamingCrypto = new GenericAesCtrStreamingCrypto()
51
+ // Test with a size we can actually handle to project larger files
52
+ const testFile = createTestFile(5) // 5MB
53
+ const getMemoryUsage = () => {
54
+ if (globalThis.gc) globalThis.gc()
55
+ return process.memoryUsage ? process.memoryUsage().heapUsed : 0
56
+ }
57
+ const baseMemory = getMemoryUsage()
58
+ const { encryptedStream } = await streamingCrypto.encryptStream(testFile)
59
+ let peakMemoryDelta = 0
60
+ let processedBytes = 0
61
+ const reader = encryptedStream.getReader()
62
+ try {
63
+ // eslint-disable-next-line no-constant-condition
64
+ while (true) {
65
+ const { done, value } = await reader.read()
66
+ if (done) break
67
+ processedBytes += value.length
68
+ // Sample memory usage
69
+ const currentMemory = getMemoryUsage()
70
+ const memoryDelta = currentMemory - baseMemory
71
+ peakMemoryDelta = Math.max(peakMemoryDelta, memoryDelta)
72
+ }
73
+ } finally {
74
+ reader.releaseLock()
75
+ }
76
+ const peakMemoryMB = peakMemoryDelta / 1024 / 1024
77
+ const fileSize = testFile.size / 1024 / 1024
78
+ const memoryEfficiency = (peakMemoryDelta / testFile.size) * 100
79
+ console.log(`File size: ${fileSize.toFixed(1)}MB`)
80
+ console.log(`Peak memory delta: ${peakMemoryMB.toFixed(2)}MB`)
81
+ console.log(
82
+ `Memory efficiency: ${memoryEfficiency.toFixed(1)}% of file size`
83
+ )
84
+ // Project to larger file sizes
85
+ console.log('\nProjected memory usage:')
86
+ const projectedSizes = [100, 1000, 5000] // MB = 100MB, 1GB, 5GB
87
+ for (const sizeMB of projectedSizes) {
88
+ const projectedMemory = (memoryEfficiency / 100) * sizeMB
89
+ const sizeLabel = sizeMB >= 1000 ? `${sizeMB / 1000}GB` : `${sizeMB}MB`
90
+ console.log(` ${sizeLabel}: ~${projectedMemory.toFixed(1)}MB memory`)
91
+ }
92
+ // Memory should be bounded (much less than file size)
93
+ assert(
94
+ peakMemoryMB < fileSize,
95
+ 'Streaming should use less memory than file size'
96
+ )
97
+ assert(
98
+ memoryEfficiency < 50,
99
+ 'Memory usage should be less than 50% of file size'
100
+ )
101
+ console.log(
102
+ 'DEMONSTRATED: Streaming memory usage scales sub-linearly with file size'
103
+ )
104
+ })
105
+ })
106
+ //# sourceMappingURL=memory-efficiency.spec.js.map