@atproto/common 0.2.0 → 0.3.0

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.
@@ -0,0 +1,279 @@
1
+ import { CID } from 'multiformats/cid'
2
+
3
+ export const vectors = [
4
+ {
5
+ name: 'basic',
6
+ json: {
7
+ string: 'abc',
8
+ unicode: 'a~öñ©⽘☎𓋓😀👨‍👩‍👧‍👧',
9
+ integer: 123,
10
+ bool: true,
11
+ null: null,
12
+ array: ['abc', 'def', 'ghi'],
13
+ object: {
14
+ string: 'abc',
15
+ number: 123,
16
+ bool: true,
17
+ arr: ['abc', 'def', 'ghi'],
18
+ },
19
+ },
20
+ ipld: {
21
+ string: 'abc',
22
+ unicode: 'a~öñ©⽘☎𓋓😀👨‍👩‍👧‍👧',
23
+ integer: 123,
24
+ bool: true,
25
+ null: null,
26
+ array: ['abc', 'def', 'ghi'],
27
+ object: {
28
+ string: 'abc',
29
+ number: 123,
30
+ bool: true,
31
+ arr: ['abc', 'def', 'ghi'],
32
+ },
33
+ },
34
+ cbor: new Uint8Array([
35
+ 167, 100, 98, 111, 111, 108, 245, 100, 110, 117, 108, 108, 246, 101, 97,
36
+ 114, 114, 97, 121, 131, 99, 97, 98, 99, 99, 100, 101, 102, 99, 103, 104,
37
+ 105, 102, 111, 98, 106, 101, 99, 116, 164, 99, 97, 114, 114, 131, 99, 97,
38
+ 98, 99, 99, 100, 101, 102, 99, 103, 104, 105, 100, 98, 111, 111, 108, 245,
39
+ 102, 110, 117, 109, 98, 101, 114, 24, 123, 102, 115, 116, 114, 105, 110,
40
+ 103, 99, 97, 98, 99, 102, 115, 116, 114, 105, 110, 103, 99, 97, 98, 99,
41
+ 103, 105, 110, 116, 101, 103, 101, 114, 24, 123, 103, 117, 110, 105, 99,
42
+ 111, 100, 101, 120, 47, 97, 126, 195, 182, 195, 177, 194, 169, 226, 189,
43
+ 152, 226, 152, 142, 240, 147, 139, 147, 240, 159, 152, 128, 240, 159, 145,
44
+ 168, 226, 128, 141, 240, 159, 145, 169, 226, 128, 141, 240, 159, 145, 167,
45
+ 226, 128, 141, 240, 159, 145, 167,
46
+ ]),
47
+ cid: 'bafyreiclp443lavogvhj3d2ob2cxbfuscni2k5jk7bebjzg7khl3esabwq',
48
+ },
49
+ {
50
+ name: 'ipld',
51
+ json: {
52
+ a: {
53
+ $link: 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
54
+ },
55
+ b: {
56
+ $bytes: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
57
+ },
58
+ c: {
59
+ $type: 'blob',
60
+ ref: {
61
+ $link: 'bafkreiccldh766hwcnuxnf2wh6jgzepf2nlu2lvcllt63eww5p6chi4ity',
62
+ },
63
+ mimeType: 'image/jpeg',
64
+ size: 10000,
65
+ },
66
+ },
67
+ ipld: {
68
+ a: CID.parse(
69
+ 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
70
+ ),
71
+ b: new Uint8Array([
72
+ 156, 81, 17, 142, 242, 203, 139, 15, 106, 155, 142, 73, 174, 161, 253,
73
+ 65, 60, 242, 11, 98, 238, 213, 118, 248, 157, 238, 190, 176, 26, 194,
74
+ 204, 141,
75
+ ]),
76
+ c: {
77
+ $type: 'blob',
78
+ ref: CID.parse(
79
+ 'bafkreiccldh766hwcnuxnf2wh6jgzepf2nlu2lvcllt63eww5p6chi4ity',
80
+ ),
81
+ mimeType: 'image/jpeg',
82
+ size: 10000,
83
+ },
84
+ },
85
+ cbor: new Uint8Array([
86
+ 163, 97, 97, 216, 42, 88, 37, 0, 1, 113, 18, 32, 101, 6, 42, 90, 90, 0,
87
+ 252, 22, 215, 60, 105, 68, 35, 124, 203, 193, 91, 28, 74, 114, 52, 72,
88
+ 147, 54, 137, 29, 9, 23, 65, 162, 57, 208, 97, 98, 88, 32, 156, 81, 17,
89
+ 142, 242, 203, 139, 15, 106, 155, 142, 73, 174, 161, 253, 65, 60, 242, 11,
90
+ 98, 238, 213, 118, 248, 157, 238, 190, 176, 26, 194, 204, 141, 97, 99,
91
+ 164, 99, 114, 101, 102, 216, 42, 88, 37, 0, 1, 85, 18, 32, 66, 88, 207,
92
+ 255, 120, 246, 19, 105, 118, 151, 86, 63, 146, 108, 145, 229, 211, 87, 77,
93
+ 46, 162, 90, 231, 237, 146, 214, 235, 252, 35, 163, 136, 158, 100, 115,
94
+ 105, 122, 101, 25, 39, 16, 101, 36, 116, 121, 112, 101, 100, 98, 108, 111,
95
+ 98, 104, 109, 105, 109, 101, 84, 121, 112, 101, 106, 105, 109, 97, 103,
96
+ 101, 47, 106, 112, 101, 103,
97
+ ]),
98
+ cid: 'bafyreihldkhcwijkde7gx4rpkkuw7pl6lbyu5gieunyc7ihactn5bkd2nm',
99
+ },
100
+ {
101
+ name: 'ipldArray',
102
+ json: [
103
+ {
104
+ $link: 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
105
+ },
106
+ {
107
+ $link: 'bafyreigoxt64qghytzkr6ik7qvtzc7lyytiq5xbbrokbxjows2wp7vmo6q',
108
+ },
109
+ {
110
+ $link: 'bafyreiaizynclnqiolq7byfpjjtgqzn4sfrsgn7z2hhf6bo4utdwkin7ke',
111
+ },
112
+ {
113
+ $link: 'bafyreifd4w4tcr5tluxz7osjtnofffvtsmgdqcfrfi6evjde4pl27lrjpy',
114
+ },
115
+ ],
116
+ ipld: [
117
+ CID.parse('bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a'),
118
+ CID.parse('bafyreigoxt64qghytzkr6ik7qvtzc7lyytiq5xbbrokbxjows2wp7vmo6q'),
119
+ CID.parse('bafyreiaizynclnqiolq7byfpjjtgqzn4sfrsgn7z2hhf6bo4utdwkin7ke'),
120
+ CID.parse('bafyreifd4w4tcr5tluxz7osjtnofffvtsmgdqcfrfi6evjde4pl27lrjpy'),
121
+ ],
122
+ cbor: new Uint8Array([
123
+ 132, 216, 42, 88, 37, 0, 1, 113, 18, 32, 101, 6, 42, 90, 90, 0, 252, 22,
124
+ 215, 60, 105, 68, 35, 124, 203, 193, 91, 28, 74, 114, 52, 72, 147, 54,
125
+ 137, 29, 9, 23, 65, 162, 57, 208, 216, 42, 88, 37, 0, 1, 113, 18, 32, 206,
126
+ 188, 253, 200, 24, 248, 158, 85, 31, 33, 95, 133, 103, 145, 125, 120, 196,
127
+ 209, 14, 220, 33, 139, 148, 27, 165, 214, 150, 172, 255, 213, 142, 244,
128
+ 216, 42, 88, 37, 0, 1, 113, 18, 32, 8, 206, 26, 37, 182, 8, 114, 225, 240,
129
+ 224, 175, 74, 102, 104, 101, 188, 145, 99, 35, 55, 249, 209, 206, 95, 5,
130
+ 220, 164, 199, 101, 33, 191, 81, 216, 42, 88, 37, 0, 1, 113, 18, 32, 163,
131
+ 229, 185, 49, 71, 179, 93, 47, 159, 186, 73, 155, 92, 82, 150, 179, 147,
132
+ 12, 56, 8, 177, 42, 60, 74, 164, 100, 227, 215, 175, 174, 41, 126,
133
+ ]),
134
+ cid: 'bafyreiaj3udmqlqrcbjxjayzuxwp64gt64olcbjfrkldzoqponpru6gq4m',
135
+ },
136
+ {
137
+ name: 'ipldNested',
138
+ json: {
139
+ a: {
140
+ b: [
141
+ {
142
+ d: [
143
+ {
144
+ $link:
145
+ 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
146
+ },
147
+ {
148
+ $link:
149
+ 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
150
+ },
151
+ ],
152
+ e: [
153
+ {
154
+ $bytes: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
155
+ },
156
+ {
157
+ $bytes: 'iE+sPoHobU9tSIqGI+309LLCcWQIRmEXwxcoDt19tas',
158
+ },
159
+ ],
160
+ },
161
+ ],
162
+ },
163
+ },
164
+ ipld: {
165
+ a: {
166
+ b: [
167
+ {
168
+ d: [
169
+ CID.parse(
170
+ 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
171
+ ),
172
+ CID.parse(
173
+ 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
174
+ ),
175
+ ],
176
+ e: [
177
+ new Uint8Array([
178
+ 156, 81, 17, 142, 242, 203, 139, 15, 106, 155, 142, 73, 174,
179
+ 161, 253, 65, 60, 242, 11, 98, 238, 213, 118, 248, 157, 238,
180
+ 190, 176, 26, 194, 204, 141,
181
+ ]),
182
+ new Uint8Array([
183
+ 136, 79, 172, 62, 129, 232, 109, 79, 109, 72, 138, 134, 35, 237,
184
+ 244, 244, 178, 194, 113, 100, 8, 70, 97, 23, 195, 23, 40, 14,
185
+ 221, 125, 181, 171,
186
+ ]),
187
+ ],
188
+ },
189
+ ],
190
+ },
191
+ },
192
+ cbor: new Uint8Array([
193
+ 161, 97, 97, 161, 97, 98, 129, 162, 97, 100, 130, 216, 42, 88, 37, 0, 1,
194
+ 113, 18, 32, 101, 6, 42, 90, 90, 0, 252, 22, 215, 60, 105, 68, 35, 124,
195
+ 203, 193, 91, 28, 74, 114, 52, 72, 147, 54, 137, 29, 9, 23, 65, 162, 57,
196
+ 208, 216, 42, 88, 37, 0, 1, 113, 18, 32, 101, 6, 42, 90, 90, 0, 252, 22,
197
+ 215, 60, 105, 68, 35, 124, 203, 193, 91, 28, 74, 114, 52, 72, 147, 54,
198
+ 137, 29, 9, 23, 65, 162, 57, 208, 97, 101, 130, 88, 32, 156, 81, 17, 142,
199
+ 242, 203, 139, 15, 106, 155, 142, 73, 174, 161, 253, 65, 60, 242, 11, 98,
200
+ 238, 213, 118, 248, 157, 238, 190, 176, 26, 194, 204, 141, 88, 32, 136,
201
+ 79, 172, 62, 129, 232, 109, 79, 109, 72, 138, 134, 35, 237, 244, 244, 178,
202
+ 194, 113, 100, 8, 70, 97, 23, 195, 23, 40, 14, 221, 125, 181, 171,
203
+ ]),
204
+ cid: 'bafyreid3imdulnhgeytpf6uk7zahjvrsqlofkmm5b5ub2maw4kqus6jp4i',
205
+ },
206
+ {
207
+ name: 'poorlyFormatted',
208
+ json: {
209
+ a: 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
210
+ b: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
211
+ c: {
212
+ $link: 'bafyreigoxt64qghytzkr6ik7qvtzc7lyytiq5xbbrokbxjows2wp7vmo6q',
213
+ another: 'bad value',
214
+ },
215
+ d: {
216
+ $bytes: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
217
+ another: 'bad value',
218
+ },
219
+ e: {
220
+ '/': 'bafyreigoxt64qghytzkr6ik7qvtzc7lyytiq5xbbrokbxjows2wp7vmo6q',
221
+ },
222
+ f: {
223
+ '/': {
224
+ bytes: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
225
+ },
226
+ },
227
+ },
228
+ ipld: {
229
+ a: 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
230
+ b: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
231
+ c: {
232
+ $link: 'bafyreigoxt64qghytzkr6ik7qvtzc7lyytiq5xbbrokbxjows2wp7vmo6q',
233
+ another: 'bad value',
234
+ },
235
+ d: {
236
+ $bytes: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
237
+ another: 'bad value',
238
+ },
239
+ e: {
240
+ '/': 'bafyreigoxt64qghytzkr6ik7qvtzc7lyytiq5xbbrokbxjows2wp7vmo6q',
241
+ },
242
+ f: {
243
+ '/': {
244
+ bytes: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
245
+ },
246
+ },
247
+ },
248
+ cbor: new Uint8Array([
249
+ 166, 97, 97, 120, 59, 98, 97, 102, 121, 114, 101, 105, 100, 102, 97, 121,
250
+ 118, 102, 117, 119, 113, 97, 55, 113, 108, 110, 111, 112, 100, 106, 105,
251
+ 113, 114, 120, 122, 115, 54, 98, 108, 109, 111, 101, 117, 52, 114, 117,
252
+ 106, 99, 106, 116, 110, 99, 105, 53, 98, 101, 108, 117, 100, 105, 114,
253
+ 122, 50, 97, 97, 98, 120, 43, 110, 70, 69, 82, 106, 118, 76, 76, 105, 119,
254
+ 57, 113, 109, 52, 53, 74, 114, 113, 72, 57, 81, 84, 122, 121, 67, 50, 76,
255
+ 117, 49, 88, 98, 52, 110, 101, 54, 43, 115, 66, 114, 67, 122, 73, 48, 97,
256
+ 99, 162, 101, 36, 108, 105, 110, 107, 120, 59, 98, 97, 102, 121, 114, 101,
257
+ 105, 103, 111, 120, 116, 54, 52, 113, 103, 104, 121, 116, 122, 107, 114,
258
+ 54, 105, 107, 55, 113, 118, 116, 122, 99, 55, 108, 121, 121, 116, 105,
259
+ 113, 53, 120, 98, 98, 114, 111, 107, 98, 120, 106, 111, 119, 115, 50, 119,
260
+ 112, 55, 118, 109, 111, 54, 113, 103, 97, 110, 111, 116, 104, 101, 114,
261
+ 105, 98, 97, 100, 32, 118, 97, 108, 117, 101, 97, 100, 162, 102, 36, 98,
262
+ 121, 116, 101, 115, 120, 43, 110, 70, 69, 82, 106, 118, 76, 76, 105, 119,
263
+ 57, 113, 109, 52, 53, 74, 114, 113, 72, 57, 81, 84, 122, 121, 67, 50, 76,
264
+ 117, 49, 88, 98, 52, 110, 101, 54, 43, 115, 66, 114, 67, 122, 73, 48, 103,
265
+ 97, 110, 111, 116, 104, 101, 114, 105, 98, 97, 100, 32, 118, 97, 108, 117,
266
+ 101, 97, 101, 161, 97, 47, 120, 59, 98, 97, 102, 121, 114, 101, 105, 103,
267
+ 111, 120, 116, 54, 52, 113, 103, 104, 121, 116, 122, 107, 114, 54, 105,
268
+ 107, 55, 113, 118, 116, 122, 99, 55, 108, 121, 121, 116, 105, 113, 53,
269
+ 120, 98, 98, 114, 111, 107, 98, 120, 106, 111, 119, 115, 50, 119, 112, 55,
270
+ 118, 109, 111, 54, 113, 97, 102, 161, 97, 47, 161, 101, 98, 121, 116, 101,
271
+ 115, 120, 43, 110, 70, 69, 82, 106, 118, 76, 76, 105, 119, 57, 113, 109,
272
+ 52, 53, 74, 114, 113, 72, 57, 81, 84, 122, 121, 67, 50, 76, 117, 49, 88,
273
+ 98, 52, 110, 101, 54, 43, 115, 66, 114, 67, 122, 73, 48,
274
+ ]),
275
+ cid: 'bafyreico7wgbbfe6dpfsuednrtrlh6t2yjl6xq5rf32gl3pgwhwxk77cn4',
276
+ },
277
+ ]
278
+
279
+ export default vectors
@@ -1,89 +1,29 @@
1
- import { CID } from 'multiformats/cid'
2
1
  import * as ui8 from 'uint8arrays'
3
- import { ipldToJson, jsonToIpld } from '../src'
2
+ import vectors from './ipld-vectors'
3
+ import {
4
+ cborDecode,
5
+ cborEncode,
6
+ cidForCbor,
7
+ ipldEquals,
8
+ ipldToJson,
9
+ jsonToIpld,
10
+ } from '../src'
4
11
 
5
12
  describe('ipld', () => {
6
- it('converts ipld to json', () => {
7
- const ipld = {
8
- one: 1,
9
- two: CID.parse(
10
- 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
11
- ),
12
- three: new Uint8Array([0, 1, 2, 3]),
13
- }
14
- const json = ipldToJson(ipld)
15
- expect(json).toEqual({
16
- one: 1,
17
- two: {
18
- $link: 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
19
- },
20
- three: {
21
- $bytes: 'AAECAw',
22
- },
13
+ for (const vector of vectors) {
14
+ it(`passes test vector: ${vector.name}`, async () => {
15
+ const ipld = jsonToIpld(vector.json)
16
+ const json = ipldToJson(ipld)
17
+ const cbor = cborEncode(ipld)
18
+ const ipldAgain = cborDecode(cbor)
19
+ const jsonAgain = ipldToJson(ipldAgain)
20
+ const cid = await cidForCbor(ipld)
21
+ expect(json).toEqual(vector.json)
22
+ expect(jsonAgain).toEqual(vector.json)
23
+ expect(ipldEquals(ipld, vector.ipld)).toBeTruthy()
24
+ expect(ipldEquals(ipldAgain, vector.ipld)).toBeTruthy()
25
+ expect(ui8.equals(cbor, vector.cbor)).toBeTruthy()
26
+ expect(cid.toString()).toEqual(vector.cid)
23
27
  })
24
- })
25
-
26
- it('converts json to ipld', () => {
27
- const json = {
28
- one: 1,
29
- two: {
30
- $link: 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
31
- },
32
- three: {
33
- $bytes: 'AAECAw',
34
- },
35
- }
36
- const expectedCid = CID.parse(
37
- 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
38
- )
39
-
40
- const ipld = jsonToIpld(json)
41
- if (!ipld) {
42
- throw new Error()
43
- }
44
- expect(ipld['one']).toBe(1)
45
- expect(expectedCid.equals(ipld['two'])).toBeTruthy()
46
- expect(ui8.equals(ipld['three'], new Uint8Array([0, 1, 2, 3]))).toBeTruthy()
47
- })
48
-
49
- it('converts nested ipld to json', () => {
50
- const ipld = {
51
- a: {
52
- b: [
53
- CID.parse(
54
- 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
55
- ),
56
- ],
57
- },
58
- }
59
- const json = ipldToJson(ipld)
60
- expect(json).toEqual({
61
- a: {
62
- b: [
63
- {
64
- $link:
65
- 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
66
- },
67
- ],
68
- },
69
- })
70
- })
71
-
72
- it('converts nested json to ipld', () => {
73
- const json = {
74
- a: {
75
- b: [
76
- {
77
- $link:
78
- 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
79
- },
80
- ],
81
- },
82
- }
83
- const ipld = jsonToIpld(json)
84
- const expectedCid = CID.parse(
85
- 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
86
- )
87
- expect(ipld && expectedCid.equals(ipld['a']['b']))
88
- })
28
+ }
89
29
  })
@@ -0,0 +1,136 @@
1
+ import * as streams from '../src/streams'
2
+ import { PassThrough, Readable, pipeline } from 'node:stream'
3
+
4
+ describe('streams', () => {
5
+ describe('forwardStreamErrors', () => {
6
+ it('forwards errors through a set of streams', () => {
7
+ const streamA = new PassThrough()
8
+ const streamB = new PassThrough()
9
+ let streamBError: Error | null = null
10
+ const err = new Error('foo')
11
+
12
+ streamB.on('error', (err) => {
13
+ streamBError = err
14
+ })
15
+
16
+ streams.forwardStreamErrors(streamA, streamB)
17
+
18
+ streamA.emit('error', err)
19
+
20
+ expect(streamBError).toBe(err)
21
+ })
22
+ })
23
+
24
+ describe('cloneStream', () => {
25
+ it('should clone stream', () => {
26
+ const stream = new PassThrough()
27
+ let clonedError: Error | undefined
28
+ let clonedData: string | undefined
29
+
30
+ const cloned = streams.cloneStream(stream)
31
+
32
+ cloned.on('data', (data) => {
33
+ clonedData = String(data)
34
+ })
35
+ cloned.on('error', (err) => {
36
+ clonedError = err
37
+ })
38
+
39
+ stream.emit('data', 'foo')
40
+ stream.emit('error', new Error('foo error'))
41
+
42
+ expect(clonedData).toEqual('foo')
43
+ expect(clonedError?.message).toEqual('foo error')
44
+ })
45
+ })
46
+
47
+ describe('streamSize', () => {
48
+ it('reads entire stream and computes size', async () => {
49
+ const stream = Readable.from(['f', 'o', 'o'])
50
+
51
+ const size = await streams.streamSize(stream)
52
+
53
+ expect(size).toBe(3)
54
+ })
55
+
56
+ it('returns 0 for empty streams', async () => {
57
+ const stream = Readable.from([])
58
+ const size = await streams.streamSize(stream)
59
+
60
+ expect(size).toBe(0)
61
+ })
62
+ })
63
+
64
+ describe('streamToBytes', () => {
65
+ it('converts stream to byte array', async () => {
66
+ const stream = Readable.from(Buffer.from('foo'))
67
+ const bytes = await streams.streamToBytes(stream)
68
+
69
+ expect(bytes[0]).toBe('f'.charCodeAt(0))
70
+ expect(bytes[1]).toBe('o'.charCodeAt(0))
71
+ expect(bytes[2]).toBe('o'.charCodeAt(0))
72
+ })
73
+ })
74
+
75
+ describe('byteIterableToStream', () => {
76
+ it('converts byte iterable to stream', async () => {
77
+ const iterable: AsyncIterable<Uint8Array> = {
78
+ async *[Symbol.asyncIterator]() {
79
+ yield new Uint8Array([0xa, 0xb])
80
+ },
81
+ }
82
+
83
+ const stream = streams.byteIterableToStream(iterable)
84
+
85
+ for await (const chunk of stream) {
86
+ expect(chunk[0]).toBe(0xa)
87
+ expect(chunk[1]).toBe(0xb)
88
+ }
89
+ })
90
+ })
91
+
92
+ describe('bytesToStream', () => {
93
+ it('converts byte array to readable stream', async () => {
94
+ const bytes = new Uint8Array([0xa, 0xb])
95
+ const stream = streams.bytesToStream(bytes)
96
+
97
+ for await (const chunk of stream) {
98
+ expect(chunk[0]).toBe(0xa)
99
+ expect(chunk[1]).toBe(0xb)
100
+ }
101
+ })
102
+ })
103
+
104
+ describe('MaxSizeChecker', () => {
105
+ it('destroys once max size is met', async () => {
106
+ const stream = new Readable()
107
+ const err = new Error('foo')
108
+ const checker = new streams.MaxSizeChecker(1, () => err)
109
+ let lastError: Error | undefined
110
+
111
+ const outStream = stream.pipe(checker)
112
+
113
+ outStream.on('error', (err) => {
114
+ lastError = err
115
+ })
116
+
117
+ const waitForStream = new Promise<void>((resolve) => {
118
+ stream.on('end', () => {
119
+ resolve()
120
+ })
121
+ })
122
+
123
+ expect(checker.totalSize).toBe(0)
124
+
125
+ stream.push(new Uint8Array([0xa]))
126
+ stream.push(new Uint8Array([0xb]))
127
+ stream.push(null)
128
+
129
+ await waitForStream
130
+
131
+ expect(checker.totalSize).toBe(2)
132
+ expect(checker.destroyed).toBe(true)
133
+ expect(lastError).toBe(err)
134
+ })
135
+ })
136
+ })