@atproto/lex-data 0.1.3 → 0.1.4
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/CHANGELOG.md +8 -0
- package/dist/blob.d.ts +2 -2
- package/dist/blob.d.ts.map +1 -1
- package/dist/blob.js +1 -1
- package/dist/blob.js.map +1 -1
- package/dist/lex-equals.d.ts +1 -1
- package/dist/lex-equals.d.ts.map +1 -1
- package/dist/lex-equals.js.map +1 -1
- package/dist/lex.d.ts +1 -1
- package/dist/lex.d.ts.map +1 -1
- package/dist/lex.js.map +1 -1
- package/dist/lib/nodejs-buffer.js.map +1 -1
- package/dist/uint8array-from-base64.d.ts +1 -1
- package/dist/uint8array-from-base64.d.ts.map +1 -1
- package/dist/uint8array-from-base64.js.map +1 -1
- package/dist/uint8array-to-base64.d.ts +1 -1
- package/dist/uint8array-to-base64.d.ts.map +1 -1
- package/dist/uint8array-to-base64.js.map +1 -1
- package/dist/uint8array.d.ts +1 -1
- package/dist/uint8array.d.ts.map +1 -1
- package/dist/uint8array.js.map +1 -1
- package/dist/utf8-from-base64.d.ts +1 -1
- package/dist/utf8-from-base64.d.ts.map +1 -1
- package/dist/utf8-from-base64.js.map +1 -1
- package/dist/utf8-to-base64.d.ts +1 -1
- package/dist/utf8-to-base64.d.ts.map +1 -1
- package/dist/utf8-to-base64.js.map +1 -1
- package/dist/utf8.d.ts +1 -1
- package/dist/utf8.d.ts.map +1 -1
- package/dist/utf8.js.map +1 -1
- package/package.json +4 -8
- package/src/blob.test.ts +0 -405
- package/src/blob.ts +0 -478
- package/src/cid-implementation.test.ts +0 -129
- package/src/cid.test.ts +0 -350
- package/src/cid.ts +0 -603
- package/src/core-js.d.ts +0 -2
- package/src/index.ts +0 -8
- package/src/lex-equals.test.ts +0 -183
- package/src/lex-equals.ts +0 -123
- package/src/lex-error.test.ts +0 -54
- package/src/lex-error.ts +0 -83
- package/src/lex.test.ts +0 -279
- package/src/lex.ts +0 -253
- package/src/lib/nodejs-buffer.ts +0 -46
- package/src/lib/util.test.ts +0 -49
- package/src/lib/util.ts +0 -7
- package/src/object.test.ts +0 -80
- package/src/object.ts +0 -83
- package/src/uint8array-base64.ts +0 -2
- package/src/uint8array-concat.test.ts +0 -197
- package/src/uint8array-concat.ts +0 -25
- package/src/uint8array-from-base64.test.ts +0 -130
- package/src/uint8array-from-base64.ts +0 -98
- package/src/uint8array-to-base64.test.ts +0 -170
- package/src/uint8array-to-base64.ts +0 -55
- package/src/uint8array.test.ts +0 -503
- package/src/uint8array.ts +0 -197
- package/src/utf8-from-base64.test.ts +0 -39
- package/src/utf8-from-base64.ts +0 -23
- package/src/utf8-from-bytes.test.ts +0 -43
- package/src/utf8-from-bytes.ts +0 -21
- package/src/utf8-grapheme-len.test.ts +0 -38
- package/src/utf8-grapheme-len.ts +0 -21
- package/src/utf8-len.test.ts +0 -21
- package/src/utf8-len.ts +0 -51
- package/src/utf8-to-base64.test.ts +0 -35
- package/src/utf8-to-base64.ts +0 -22
- package/src/utf8.ts +0 -128
- package/tsconfig.build.json +0 -12
- package/tsconfig.json +0 -7
- package/tsconfig.tests.json +0 -8
package/src/uint8array.test.ts
DELETED
|
@@ -1,503 +0,0 @@
|
|
|
1
|
-
import 'core-js/es/typed-array/from-base64.js'
|
|
2
|
-
import 'core-js/es/typed-array/to-base64.js'
|
|
3
|
-
|
|
4
|
-
import { describe, expect, it } from 'vitest'
|
|
5
|
-
import {
|
|
6
|
-
asUint8Array,
|
|
7
|
-
fromBase64,
|
|
8
|
-
ifUint8Array,
|
|
9
|
-
toBase64,
|
|
10
|
-
ui8Concat,
|
|
11
|
-
ui8Equals,
|
|
12
|
-
} from './uint8array.js'
|
|
13
|
-
|
|
14
|
-
describe(toBase64, () => {
|
|
15
|
-
it('encodes empty Uint8Array', () => {
|
|
16
|
-
const encoded = toBase64(new Uint8Array(0))
|
|
17
|
-
expect(typeof encoded).toBe('string')
|
|
18
|
-
expect(encoded).toBe('')
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('encodes single byte', () => {
|
|
22
|
-
const encoded = toBase64(new Uint8Array([0x4d]))
|
|
23
|
-
expect(encoded).toBe('TQ')
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
it('encodes multiple bytes', () => {
|
|
27
|
-
const encoded = toBase64(new Uint8Array([0x4d, 0x61, 0x6e]))
|
|
28
|
-
expect(encoded).toBe('TWFu')
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('encodes with default alphabet (base64)', () => {
|
|
32
|
-
const bytes = new Uint8Array([0xfb, 0xff, 0xbf])
|
|
33
|
-
const encoded = toBase64(bytes)
|
|
34
|
-
expect(encoded).toContain('+')
|
|
35
|
-
expect(encoded).toContain('/')
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('encodes with base64url alphabet', () => {
|
|
39
|
-
const bytes = new Uint8Array([0xfb, 0xff, 0xbf])
|
|
40
|
-
const encoded = toBase64(bytes, 'base64url')
|
|
41
|
-
expect(encoded).toContain('-')
|
|
42
|
-
expect(encoded).toContain('_')
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it('handles large data', () => {
|
|
46
|
-
const bytes = new Uint8Array(10000).fill(0xaa)
|
|
47
|
-
const encoded = toBase64(bytes)
|
|
48
|
-
expect(typeof encoded).toBe('string')
|
|
49
|
-
expect(encoded.length).toBeGreaterThan(0)
|
|
50
|
-
})
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
describe(fromBase64, () => {
|
|
54
|
-
it('decodes empty string', () => {
|
|
55
|
-
const decoded = fromBase64('')
|
|
56
|
-
expect(decoded).toBeInstanceOf(Uint8Array)
|
|
57
|
-
expect(decoded.length).toBe(0)
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
it('decodes single character', () => {
|
|
61
|
-
const decoded = fromBase64('TQ')
|
|
62
|
-
expect(decoded).toBeInstanceOf(Uint8Array)
|
|
63
|
-
expect(ui8Equals(decoded, new Uint8Array([0x4d]))).toBe(true)
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
it('decodes multiple characters', () => {
|
|
67
|
-
const decoded = fromBase64('TWFu')
|
|
68
|
-
expect(decoded).toBeInstanceOf(Uint8Array)
|
|
69
|
-
expect(ui8Equals(decoded, new Uint8Array([0x4d, 0x61, 0x6e]))).toBe(true)
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('decodes base64url alphabet', () => {
|
|
73
|
-
const decoded = fromBase64('-_-_', 'base64url')
|
|
74
|
-
expect(decoded).toBeInstanceOf(Uint8Array)
|
|
75
|
-
expect(ui8Equals(decoded, new Uint8Array([0xfb, 0xff, 0xbf]))).toBe(true)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
it('decodes padded base64', () => {
|
|
79
|
-
const decoded = fromBase64('TQ==')
|
|
80
|
-
expect(decoded).toBeInstanceOf(Uint8Array)
|
|
81
|
-
expect(ui8Equals(decoded, new Uint8Array([0x4d]))).toBe(true)
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
it('decodes unpadded base64', () => {
|
|
85
|
-
const decoded = fromBase64('TQ')
|
|
86
|
-
expect(decoded).toBeInstanceOf(Uint8Array)
|
|
87
|
-
expect(ui8Equals(decoded, new Uint8Array([0x4d]))).toBe(true)
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
it('throws on invalid base64 string', () => {
|
|
91
|
-
expect(() => fromBase64('@@@@')).toThrow()
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
it('handles large data', () => {
|
|
95
|
-
const bytes = new Uint8Array(10000).fill(0xbb)
|
|
96
|
-
const encoded = toBase64(bytes)
|
|
97
|
-
const decoded = fromBase64(encoded)
|
|
98
|
-
expect(ui8Equals(decoded, bytes)).toBe(true)
|
|
99
|
-
})
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
describe('roundtrip toBase64 <-> fromBase64', () => {
|
|
103
|
-
it('roundtrips empty array', () => {
|
|
104
|
-
const original = new Uint8Array(0)
|
|
105
|
-
const encoded = toBase64(original)
|
|
106
|
-
const decoded = fromBase64(encoded)
|
|
107
|
-
expect(ui8Equals(decoded, original)).toBe(true)
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
it('roundtrips all byte values', () => {
|
|
111
|
-
const allBytes = new Uint8Array(256)
|
|
112
|
-
for (let i = 0; i < 256; i++) {
|
|
113
|
-
allBytes[i] = i
|
|
114
|
-
}
|
|
115
|
-
const encoded = toBase64(allBytes)
|
|
116
|
-
const decoded = fromBase64(encoded)
|
|
117
|
-
expect(ui8Equals(decoded, allBytes)).toBe(true)
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
it('roundtrips with base64url alphabet', () => {
|
|
121
|
-
const original = new Uint8Array([0xfb, 0xff, 0xbf, 0x00, 0xff])
|
|
122
|
-
const encoded = toBase64(original, 'base64url')
|
|
123
|
-
const decoded = fromBase64(encoded, 'base64url')
|
|
124
|
-
expect(ui8Equals(decoded, original)).toBe(true)
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
it('roundtrips random-like data', () => {
|
|
128
|
-
const data = new Uint8Array([
|
|
129
|
-
0x00, 0x01, 0x7f, 0x80, 0xfe, 0xff, 0x10, 0x20, 0x30, 0x40,
|
|
130
|
-
])
|
|
131
|
-
const encoded = toBase64(data)
|
|
132
|
-
const decoded = fromBase64(encoded)
|
|
133
|
-
expect(ui8Equals(decoded, data)).toBe(true)
|
|
134
|
-
})
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
describe(asUint8Array, () => {
|
|
138
|
-
describe('Uint8Array input', () => {
|
|
139
|
-
it('returns same Uint8Array instance', () => {
|
|
140
|
-
const input = new Uint8Array([1, 2, 3])
|
|
141
|
-
const result = asUint8Array(input)
|
|
142
|
-
expect(result).toBe(input)
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
it('returns same empty Uint8Array instance', () => {
|
|
146
|
-
const input = new Uint8Array(0)
|
|
147
|
-
const result = asUint8Array(input)
|
|
148
|
-
expect(result).toBe(input)
|
|
149
|
-
})
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
describe('ArrayBuffer input', () => {
|
|
153
|
-
it('converts ArrayBuffer to Uint8Array', () => {
|
|
154
|
-
const buffer = new ArrayBuffer(4)
|
|
155
|
-
const view = new Uint8Array(buffer)
|
|
156
|
-
view.set([1, 2, 3, 4])
|
|
157
|
-
const result = asUint8Array(buffer)
|
|
158
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
159
|
-
expect(ui8Equals(result!, new Uint8Array([1, 2, 3, 4]))).toBe(true)
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
it('converts empty ArrayBuffer to empty Uint8Array', () => {
|
|
163
|
-
const buffer = new ArrayBuffer(0)
|
|
164
|
-
const result = asUint8Array(buffer)
|
|
165
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
166
|
-
expect(result!.length).toBe(0)
|
|
167
|
-
})
|
|
168
|
-
})
|
|
169
|
-
|
|
170
|
-
describe('TypedArray (ArrayBufferView) input', () => {
|
|
171
|
-
it('converts Int8Array to Uint8Array', () => {
|
|
172
|
-
const input = new Int8Array([1, 2, 3, 4])
|
|
173
|
-
const result = asUint8Array(input)
|
|
174
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
175
|
-
expect(result!.length).toBe(4)
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
it('converts Int16Array to Uint8Array', () => {
|
|
179
|
-
const input = new Int16Array([1, 2])
|
|
180
|
-
const result = asUint8Array(input)
|
|
181
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
182
|
-
// Int16Array has 2 bytes per element, so 2 elements = 4 bytes
|
|
183
|
-
expect(result!.length).toBe(4)
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
it('converts Int32Array to Uint8Array', () => {
|
|
187
|
-
const input = new Int32Array([1])
|
|
188
|
-
const result = asUint8Array(input)
|
|
189
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
190
|
-
// Int32Array has 4 bytes per element, so 1 element = 4 bytes
|
|
191
|
-
expect(result!.length).toBe(4)
|
|
192
|
-
})
|
|
193
|
-
|
|
194
|
-
it('converts Float32Array to Uint8Array', () => {
|
|
195
|
-
const input = new Float32Array([1.5])
|
|
196
|
-
const result = asUint8Array(input)
|
|
197
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
198
|
-
// Float32Array has 4 bytes per element
|
|
199
|
-
expect(result!.length).toBe(4)
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
it('converts Float64Array to Uint8Array', () => {
|
|
203
|
-
const input = new Float64Array([1.5])
|
|
204
|
-
const result = asUint8Array(input)
|
|
205
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
206
|
-
// Float64Array has 8 bytes per element
|
|
207
|
-
expect(result!.length).toBe(8)
|
|
208
|
-
})
|
|
209
|
-
|
|
210
|
-
it('converts DataView to Uint8Array', () => {
|
|
211
|
-
const buffer = new ArrayBuffer(4)
|
|
212
|
-
const view = new DataView(buffer)
|
|
213
|
-
view.setUint8(0, 1)
|
|
214
|
-
view.setUint8(1, 2)
|
|
215
|
-
view.setUint8(2, 3)
|
|
216
|
-
view.setUint8(3, 4)
|
|
217
|
-
const result = asUint8Array(view)
|
|
218
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
219
|
-
expect(ui8Equals(result!, new Uint8Array([1, 2, 3, 4]))).toBe(true)
|
|
220
|
-
})
|
|
221
|
-
|
|
222
|
-
it('handles TypedArray with byteOffset', () => {
|
|
223
|
-
const buffer = new ArrayBuffer(8)
|
|
224
|
-
const fullView = new Uint8Array(buffer)
|
|
225
|
-
fullView.set([0, 0, 1, 2, 3, 4, 0, 0])
|
|
226
|
-
// Create a view with offset
|
|
227
|
-
const offsetView = new Uint8Array(buffer, 2, 4)
|
|
228
|
-
const result = asUint8Array(offsetView)
|
|
229
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
230
|
-
expect(result).toBe(offsetView) // Uint8Array returns same instance
|
|
231
|
-
})
|
|
232
|
-
|
|
233
|
-
it('handles Int16Array with byteOffset correctly', () => {
|
|
234
|
-
const buffer = new ArrayBuffer(8)
|
|
235
|
-
const fullView = new Uint8Array(buffer)
|
|
236
|
-
fullView.set([0, 0, 1, 0, 2, 0, 0, 0])
|
|
237
|
-
// Create Int16Array starting at byte 2, with 2 elements
|
|
238
|
-
const int16View = new Int16Array(buffer, 2, 2)
|
|
239
|
-
const result = asUint8Array(int16View)
|
|
240
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
241
|
-
expect(result!.length).toBe(4) // 2 Int16 elements = 4 bytes
|
|
242
|
-
})
|
|
243
|
-
})
|
|
244
|
-
|
|
245
|
-
describe('invalid inputs', () => {
|
|
246
|
-
it('returns undefined for null', () => {
|
|
247
|
-
const result = asUint8Array(null)
|
|
248
|
-
expect(result).toBeUndefined()
|
|
249
|
-
})
|
|
250
|
-
|
|
251
|
-
it('returns undefined for undefined', () => {
|
|
252
|
-
const result = asUint8Array(undefined)
|
|
253
|
-
expect(result).toBeUndefined()
|
|
254
|
-
})
|
|
255
|
-
|
|
256
|
-
it('returns undefined for string', () => {
|
|
257
|
-
const result = asUint8Array('hello')
|
|
258
|
-
expect(result).toBeUndefined()
|
|
259
|
-
})
|
|
260
|
-
|
|
261
|
-
it('returns undefined for number', () => {
|
|
262
|
-
const result = asUint8Array(42)
|
|
263
|
-
expect(result).toBeUndefined()
|
|
264
|
-
})
|
|
265
|
-
|
|
266
|
-
it('returns undefined for boolean', () => {
|
|
267
|
-
const result = asUint8Array(true)
|
|
268
|
-
expect(result).toBeUndefined()
|
|
269
|
-
})
|
|
270
|
-
|
|
271
|
-
it('returns undefined for plain object', () => {
|
|
272
|
-
const result = asUint8Array({ foo: 'bar' })
|
|
273
|
-
expect(result).toBeUndefined()
|
|
274
|
-
})
|
|
275
|
-
|
|
276
|
-
it('returns undefined for array', () => {
|
|
277
|
-
const result = asUint8Array([1, 2, 3])
|
|
278
|
-
expect(result).toBeUndefined()
|
|
279
|
-
})
|
|
280
|
-
|
|
281
|
-
it('returns undefined for function', () => {
|
|
282
|
-
const result = asUint8Array(() => {})
|
|
283
|
-
expect(result).toBeUndefined()
|
|
284
|
-
})
|
|
285
|
-
|
|
286
|
-
it('returns undefined for symbol', () => {
|
|
287
|
-
const result = asUint8Array(Symbol('test'))
|
|
288
|
-
expect(result).toBeUndefined()
|
|
289
|
-
})
|
|
290
|
-
|
|
291
|
-
it('returns undefined for BigInt', () => {
|
|
292
|
-
const result = asUint8Array(BigInt(42))
|
|
293
|
-
expect(result).toBeUndefined()
|
|
294
|
-
})
|
|
295
|
-
})
|
|
296
|
-
})
|
|
297
|
-
|
|
298
|
-
describe(ui8Equals, () => {
|
|
299
|
-
describe('equal arrays', () => {
|
|
300
|
-
it('returns true for identical arrays', () => {
|
|
301
|
-
const a = new Uint8Array([1, 2, 3])
|
|
302
|
-
const b = new Uint8Array([1, 2, 3])
|
|
303
|
-
expect(ui8Equals(a, b)).toBe(true)
|
|
304
|
-
})
|
|
305
|
-
|
|
306
|
-
it('returns true for same instance', () => {
|
|
307
|
-
const a = new Uint8Array([1, 2, 3])
|
|
308
|
-
expect(ui8Equals(a, a)).toBe(true)
|
|
309
|
-
})
|
|
310
|
-
|
|
311
|
-
it('returns true for empty arrays', () => {
|
|
312
|
-
const a = new Uint8Array(0)
|
|
313
|
-
const b = new Uint8Array(0)
|
|
314
|
-
expect(ui8Equals(a, b)).toBe(true)
|
|
315
|
-
})
|
|
316
|
-
|
|
317
|
-
it('returns true for single element arrays', () => {
|
|
318
|
-
const a = new Uint8Array([255])
|
|
319
|
-
const b = new Uint8Array([255])
|
|
320
|
-
expect(ui8Equals(a, b)).toBe(true)
|
|
321
|
-
})
|
|
322
|
-
|
|
323
|
-
it('returns true for arrays with all zeros', () => {
|
|
324
|
-
const a = new Uint8Array([0, 0, 0])
|
|
325
|
-
const b = new Uint8Array([0, 0, 0])
|
|
326
|
-
expect(ui8Equals(a, b)).toBe(true)
|
|
327
|
-
})
|
|
328
|
-
|
|
329
|
-
it('returns true for arrays with all 255s', () => {
|
|
330
|
-
const a = new Uint8Array([255, 255, 255])
|
|
331
|
-
const b = new Uint8Array([255, 255, 255])
|
|
332
|
-
expect(ui8Equals(a, b)).toBe(true)
|
|
333
|
-
})
|
|
334
|
-
})
|
|
335
|
-
|
|
336
|
-
describe('unequal arrays - different lengths', () => {
|
|
337
|
-
it('returns false when first is longer', () => {
|
|
338
|
-
const a = new Uint8Array([1, 2, 3, 4])
|
|
339
|
-
const b = new Uint8Array([1, 2, 3])
|
|
340
|
-
expect(ui8Equals(a, b)).toBe(false)
|
|
341
|
-
})
|
|
342
|
-
|
|
343
|
-
it('returns false when second is longer', () => {
|
|
344
|
-
const a = new Uint8Array([1, 2, 3])
|
|
345
|
-
const b = new Uint8Array([1, 2, 3, 4])
|
|
346
|
-
expect(ui8Equals(a, b)).toBe(false)
|
|
347
|
-
})
|
|
348
|
-
|
|
349
|
-
it('returns false when one is empty', () => {
|
|
350
|
-
const a = new Uint8Array([1])
|
|
351
|
-
const b = new Uint8Array(0)
|
|
352
|
-
expect(ui8Equals(a, b)).toBe(false)
|
|
353
|
-
})
|
|
354
|
-
|
|
355
|
-
it('returns false when comparing empty to non-empty', () => {
|
|
356
|
-
const a = new Uint8Array(0)
|
|
357
|
-
const b = new Uint8Array([1])
|
|
358
|
-
expect(ui8Equals(a, b)).toBe(false)
|
|
359
|
-
})
|
|
360
|
-
})
|
|
361
|
-
|
|
362
|
-
describe('unequal arrays - different content', () => {
|
|
363
|
-
it('returns false when first byte differs', () => {
|
|
364
|
-
const a = new Uint8Array([1, 2, 3])
|
|
365
|
-
const b = new Uint8Array([0, 2, 3])
|
|
366
|
-
expect(ui8Equals(a, b)).toBe(false)
|
|
367
|
-
})
|
|
368
|
-
|
|
369
|
-
it('returns false when middle byte differs', () => {
|
|
370
|
-
const a = new Uint8Array([1, 2, 3])
|
|
371
|
-
const b = new Uint8Array([1, 0, 3])
|
|
372
|
-
expect(ui8Equals(a, b)).toBe(false)
|
|
373
|
-
})
|
|
374
|
-
|
|
375
|
-
it('returns false when last byte differs', () => {
|
|
376
|
-
const a = new Uint8Array([1, 2, 3])
|
|
377
|
-
const b = new Uint8Array([1, 2, 0])
|
|
378
|
-
expect(ui8Equals(a, b)).toBe(false)
|
|
379
|
-
})
|
|
380
|
-
|
|
381
|
-
it('returns false for completely different arrays', () => {
|
|
382
|
-
const a = new Uint8Array([0, 0, 0])
|
|
383
|
-
const b = new Uint8Array([255, 255, 255])
|
|
384
|
-
expect(ui8Equals(a, b)).toBe(false)
|
|
385
|
-
})
|
|
386
|
-
|
|
387
|
-
it('returns false when single values differ', () => {
|
|
388
|
-
const a = new Uint8Array([0])
|
|
389
|
-
const b = new Uint8Array([1])
|
|
390
|
-
expect(ui8Equals(a, b)).toBe(false)
|
|
391
|
-
})
|
|
392
|
-
})
|
|
393
|
-
|
|
394
|
-
describe('edge cases', () => {
|
|
395
|
-
it('handles boundary byte values', () => {
|
|
396
|
-
const a = new Uint8Array([0x00, 0x7f, 0x80, 0xff])
|
|
397
|
-
const b = new Uint8Array([0x00, 0x7f, 0x80, 0xff])
|
|
398
|
-
expect(ui8Equals(a, b)).toBe(true)
|
|
399
|
-
})
|
|
400
|
-
|
|
401
|
-
it('detects difference at boundary values', () => {
|
|
402
|
-
const a = new Uint8Array([0x7f])
|
|
403
|
-
const b = new Uint8Array([0x80])
|
|
404
|
-
expect(ui8Equals(a, b)).toBe(false)
|
|
405
|
-
})
|
|
406
|
-
|
|
407
|
-
it('handles large arrays efficiently', () => {
|
|
408
|
-
const size = 100000
|
|
409
|
-
const a = new Uint8Array(size).fill(0xaa)
|
|
410
|
-
const b = new Uint8Array(size).fill(0xaa)
|
|
411
|
-
expect(ui8Equals(a, b)).toBe(true)
|
|
412
|
-
})
|
|
413
|
-
|
|
414
|
-
it('detects single byte difference in large arrays', () => {
|
|
415
|
-
const size = 100000
|
|
416
|
-
const a = new Uint8Array(size).fill(0xaa)
|
|
417
|
-
const b = new Uint8Array(size).fill(0xaa)
|
|
418
|
-
b[size - 1] = 0xbb // Difference at the end
|
|
419
|
-
expect(ui8Equals(a, b)).toBe(false)
|
|
420
|
-
})
|
|
421
|
-
|
|
422
|
-
it('compares subarrays correctly', () => {
|
|
423
|
-
const full = new Uint8Array([0, 1, 2, 3, 4, 5])
|
|
424
|
-
const sub1 = full.subarray(1, 4) // [1, 2, 3]
|
|
425
|
-
const sub2 = new Uint8Array([1, 2, 3])
|
|
426
|
-
expect(ui8Equals(sub1, sub2)).toBe(true)
|
|
427
|
-
})
|
|
428
|
-
|
|
429
|
-
it('detects difference in subarrays', () => {
|
|
430
|
-
const full = new Uint8Array([0, 1, 2, 3, 4, 5])
|
|
431
|
-
const sub1 = full.subarray(1, 4) // [1, 2, 3]
|
|
432
|
-
const sub2 = new Uint8Array([1, 2, 4]) // Different last byte
|
|
433
|
-
expect(ui8Equals(sub1, sub2)).toBe(false)
|
|
434
|
-
})
|
|
435
|
-
})
|
|
436
|
-
})
|
|
437
|
-
|
|
438
|
-
describe(ifUint8Array, () => {
|
|
439
|
-
it('returns the input if it is a Uint8Array', () => {
|
|
440
|
-
const input = new Uint8Array([1, 2, 3])
|
|
441
|
-
const result = ifUint8Array(input)
|
|
442
|
-
expect(result).toBe(input)
|
|
443
|
-
})
|
|
444
|
-
|
|
445
|
-
it('returns undefined for non-Uint8Array inputs', () => {
|
|
446
|
-
expect(ifUint8Array(null)).toBeUndefined()
|
|
447
|
-
expect(ifUint8Array(undefined)).toBeUndefined()
|
|
448
|
-
expect(ifUint8Array({})).toBeUndefined()
|
|
449
|
-
expect(ifUint8Array([])).toBeUndefined()
|
|
450
|
-
expect(ifUint8Array('string')).toBeUndefined()
|
|
451
|
-
expect(ifUint8Array(123)).toBeUndefined()
|
|
452
|
-
expect(ifUint8Array(true)).toBeUndefined()
|
|
453
|
-
})
|
|
454
|
-
})
|
|
455
|
-
|
|
456
|
-
describe(ui8Concat, () => {
|
|
457
|
-
it('concatenates empty array', () => {
|
|
458
|
-
const result = ui8Concat([])
|
|
459
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
460
|
-
expect(result.length).toBe(0)
|
|
461
|
-
})
|
|
462
|
-
|
|
463
|
-
it('concatenates single array', () => {
|
|
464
|
-
const input = new Uint8Array([1, 2, 3])
|
|
465
|
-
const result = ui8Concat([input])
|
|
466
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
467
|
-
expect(ui8Equals(result, input)).toBe(true)
|
|
468
|
-
})
|
|
469
|
-
|
|
470
|
-
it('concatenates two arrays', () => {
|
|
471
|
-
const a = new Uint8Array([1, 2])
|
|
472
|
-
const b = new Uint8Array([3, 4])
|
|
473
|
-
const result = ui8Concat([a, b])
|
|
474
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
475
|
-
expect(ui8Equals(result, new Uint8Array([1, 2, 3, 4]))).toBe(true)
|
|
476
|
-
})
|
|
477
|
-
|
|
478
|
-
it('concatenates multiple arrays', () => {
|
|
479
|
-
const arrays = [
|
|
480
|
-
new Uint8Array([1]),
|
|
481
|
-
new Uint8Array([2, 3]),
|
|
482
|
-
new Uint8Array([4, 5, 6]),
|
|
483
|
-
]
|
|
484
|
-
const result = ui8Concat(arrays)
|
|
485
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
486
|
-
expect(ui8Equals(result, new Uint8Array([1, 2, 3, 4, 5, 6]))).toBe(true)
|
|
487
|
-
})
|
|
488
|
-
|
|
489
|
-
it('handles empty arrays in input', () => {
|
|
490
|
-
const a = new Uint8Array(0)
|
|
491
|
-
const b = new Uint8Array([1, 2])
|
|
492
|
-
const c = new Uint8Array(0)
|
|
493
|
-
const result = ui8Concat([a, b, c])
|
|
494
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
495
|
-
expect(ui8Equals(result, new Uint8Array([1, 2]))).toBe(true)
|
|
496
|
-
})
|
|
497
|
-
|
|
498
|
-
it('handles all empty arrays', () => {
|
|
499
|
-
const result = ui8Concat([new Uint8Array(0), new Uint8Array(0)])
|
|
500
|
-
expect(result).toBeInstanceOf(Uint8Array)
|
|
501
|
-
expect(result.length).toBe(0)
|
|
502
|
-
})
|
|
503
|
-
})
|
package/src/uint8array.ts
DELETED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
import { Base64Alphabet } from './uint8array-base64.js'
|
|
2
|
-
import { ui8ConcatNode, ui8ConcatPonyfill } from './uint8array-concat.js'
|
|
3
|
-
import {
|
|
4
|
-
fromBase64Native,
|
|
5
|
-
fromBase64Node,
|
|
6
|
-
fromBase64Ponyfill,
|
|
7
|
-
} from './uint8array-from-base64.js'
|
|
8
|
-
import {
|
|
9
|
-
toBase64Native,
|
|
10
|
-
toBase64Node,
|
|
11
|
-
toBase64Ponyfill,
|
|
12
|
-
} from './uint8array-to-base64.js'
|
|
13
|
-
|
|
14
|
-
export type { Base64Alphabet }
|
|
15
|
-
|
|
16
|
-
// @TODO drop dependency on uint8arrays package once Uint8Array.fromBase64 /
|
|
17
|
-
// Uint8Array.prototype.toBase64 is widely supported, and mark fromBase64 /
|
|
18
|
-
// toBase64 as deprecated. We can also drop NodeJS specific implementations
|
|
19
|
-
// once NodeJS <24 is no longer supported.
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Encodes a Uint8Array into a base64 string.
|
|
23
|
-
*
|
|
24
|
-
* Uses native Uint8Array.prototype.toBase64 when available (Node.js 24+, modern browsers),
|
|
25
|
-
* falling back to Node.js Buffer or a ponyfill implementation.
|
|
26
|
-
*
|
|
27
|
-
* @param bytes - The binary data to encode
|
|
28
|
-
* @param alphabet - The base64 alphabet to use ('base64' or 'base64url'), defaults to 'base64'
|
|
29
|
-
* @returns The base64 encoded string
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* ```typescript
|
|
33
|
-
* import { toBase64 } from '@atproto/lex-data'
|
|
34
|
-
*
|
|
35
|
-
* const bytes = new Uint8Array([72, 101, 108, 108, 111])
|
|
36
|
-
* toBase64(bytes) // 'SGVsbG8='
|
|
37
|
-
* toBase64(bytes, 'base64url') // 'SGVsbG8' (URL-safe, no padding)
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
export const toBase64: (
|
|
41
|
-
bytes: Uint8Array,
|
|
42
|
-
alphabet?: Base64Alphabet,
|
|
43
|
-
) => string =
|
|
44
|
-
/* v8 ignore next -- @preserve */ toBase64Native ??
|
|
45
|
-
toBase64Node ??
|
|
46
|
-
toBase64Ponyfill
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Decodes a base64 string into a Uint8Array.
|
|
50
|
-
*
|
|
51
|
-
* Supports both padded and unpadded base64 strings. Uses native
|
|
52
|
-
* Uint8Array.fromBase64 when available, falling back to Node.js Buffer
|
|
53
|
-
* or a ponyfill implementation.
|
|
54
|
-
*
|
|
55
|
-
* @param b64 - The base64 string to decode
|
|
56
|
-
* @param alphabet - The base64 alphabet to use ('base64' or 'base64url'), defaults to 'base64'
|
|
57
|
-
* @returns The decoded binary data
|
|
58
|
-
* @throws If the input is not a valid base64 string
|
|
59
|
-
*
|
|
60
|
-
* @example
|
|
61
|
-
* ```typescript
|
|
62
|
-
* import { fromBase64 } from '@atproto/lex-data'
|
|
63
|
-
*
|
|
64
|
-
* fromBase64('SGVsbG8=') // Uint8Array([72, 101, 108, 108, 111])
|
|
65
|
-
* fromBase64('SGVsbG8', 'base64url') // Same, URL-safe alphabet
|
|
66
|
-
* ```
|
|
67
|
-
*/
|
|
68
|
-
export const fromBase64: (
|
|
69
|
-
b64: string,
|
|
70
|
-
alphabet?: Base64Alphabet,
|
|
71
|
-
) => Uint8Array =
|
|
72
|
-
/* v8 ignore next -- @preserve */ fromBase64Native ??
|
|
73
|
-
fromBase64Node ??
|
|
74
|
-
fromBase64Ponyfill
|
|
75
|
-
|
|
76
|
-
/* v8 ignore next -- @preserve */
|
|
77
|
-
if (toBase64 === toBase64Ponyfill || fromBase64 === fromBase64Ponyfill) {
|
|
78
|
-
/*#__PURE__*/
|
|
79
|
-
console.warn(
|
|
80
|
-
'[@atproto/lex-data]: Uint8Array.fromBase64 / Uint8Array.prototype.toBase64 not available in this environment. Falling back to ponyfill implementation.',
|
|
81
|
-
)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Returns the input if it is a Uint8Array, otherwise returns undefined.
|
|
86
|
-
*
|
|
87
|
-
* @param input - The value to check
|
|
88
|
-
* @returns The input if it's a Uint8Array, otherwise undefined
|
|
89
|
-
*
|
|
90
|
-
* @example
|
|
91
|
-
* ```typescript
|
|
92
|
-
* import { ifUint8Array } from '@atproto/lex-data'
|
|
93
|
-
*
|
|
94
|
-
* ifUint8Array(new Uint8Array([1, 2])) // Uint8Array([1, 2])
|
|
95
|
-
* ifUint8Array('not binary') // undefined
|
|
96
|
-
* ifUint8Array(new ArrayBuffer(4)) // undefined
|
|
97
|
-
* ```
|
|
98
|
-
*/
|
|
99
|
-
export function ifUint8Array(input: unknown): Uint8Array | undefined {
|
|
100
|
-
if (input instanceof Uint8Array) {
|
|
101
|
-
return input
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return undefined
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Coerces various binary data representations into a Uint8Array.
|
|
109
|
-
*
|
|
110
|
-
* Handles the following input types:
|
|
111
|
-
* - `Uint8Array` - Returned as-is
|
|
112
|
-
* - `ArrayBufferView` (e.g., DataView, other TypedArrays) - Converted to Uint8Array
|
|
113
|
-
* - `ArrayBuffer` - Wrapped in a Uint8Array
|
|
114
|
-
*
|
|
115
|
-
* @param input - The value to convert
|
|
116
|
-
* @returns A Uint8Array, or `undefined` if the input could not be converted
|
|
117
|
-
*
|
|
118
|
-
* @example
|
|
119
|
-
* ```typescript
|
|
120
|
-
* import { asUint8Array } from '@atproto/lex-data'
|
|
121
|
-
*
|
|
122
|
-
* asUint8Array(new Uint8Array([1, 2])) // Uint8Array([1, 2])
|
|
123
|
-
* asUint8Array(new ArrayBuffer(4)) // Uint8Array of length 4
|
|
124
|
-
* asUint8Array(new Int16Array([1, 2])) // Uint8Array view of the buffer
|
|
125
|
-
* asUint8Array('string') // undefined
|
|
126
|
-
* ```
|
|
127
|
-
*/
|
|
128
|
-
export function asUint8Array(input: unknown): Uint8Array | undefined {
|
|
129
|
-
if (input instanceof Uint8Array) {
|
|
130
|
-
return input
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (ArrayBuffer.isView(input)) {
|
|
134
|
-
return new Uint8Array(
|
|
135
|
-
input.buffer,
|
|
136
|
-
input.byteOffset,
|
|
137
|
-
input.byteLength / Uint8Array.BYTES_PER_ELEMENT,
|
|
138
|
-
)
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if (input instanceof ArrayBuffer) {
|
|
142
|
-
return new Uint8Array(input)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return undefined
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Compares two Uint8Arrays for byte-by-byte equality.
|
|
150
|
-
*
|
|
151
|
-
* @param a - First Uint8Array to compare
|
|
152
|
-
* @param b - Second Uint8Array to compare
|
|
153
|
-
* @returns `true` if both arrays have the same length and identical bytes
|
|
154
|
-
*
|
|
155
|
-
* @example
|
|
156
|
-
* ```typescript
|
|
157
|
-
* import { ui8Equals } from '@atproto/lex-data'
|
|
158
|
-
*
|
|
159
|
-
* ui8Equals(new Uint8Array([1, 2]), new Uint8Array([1, 2])) // true
|
|
160
|
-
* ui8Equals(new Uint8Array([1, 2]), new Uint8Array([1, 3])) // false
|
|
161
|
-
* ui8Equals(new Uint8Array([1]), new Uint8Array([1, 2])) // false
|
|
162
|
-
* ```
|
|
163
|
-
*/
|
|
164
|
-
export function ui8Equals(a: Uint8Array, b: Uint8Array): boolean {
|
|
165
|
-
if (a.byteLength !== b.byteLength) {
|
|
166
|
-
return false
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
for (let i = 0; i < a.byteLength; i++) {
|
|
170
|
-
if (a[i] !== b[i]) {
|
|
171
|
-
return false
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return true
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Concatenates multiple Uint8Arrays into a single Uint8Array.
|
|
180
|
-
*
|
|
181
|
-
* Uses Node.js Buffer.concat when available for performance,
|
|
182
|
-
* falling back to a ponyfill implementation.
|
|
183
|
-
*
|
|
184
|
-
* @param arrays - The Uint8Arrays to concatenate
|
|
185
|
-
* @returns A new Uint8Array containing all input bytes in order
|
|
186
|
-
*
|
|
187
|
-
* @example
|
|
188
|
-
* ```typescript
|
|
189
|
-
* import { ui8Concat } from '@atproto/lex-data'
|
|
190
|
-
*
|
|
191
|
-
* const a = new Uint8Array([1, 2])
|
|
192
|
-
* const b = new Uint8Array([3, 4])
|
|
193
|
-
* ui8Concat([a, b]) // Uint8Array([1, 2, 3, 4])
|
|
194
|
-
* ```
|
|
195
|
-
*/
|
|
196
|
-
export const ui8Concat =
|
|
197
|
-
/* v8 ignore next -- @preserve */ ui8ConcatNode ?? ui8ConcatPonyfill
|