@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.
Files changed (72) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/blob.d.ts +2 -2
  3. package/dist/blob.d.ts.map +1 -1
  4. package/dist/blob.js +1 -1
  5. package/dist/blob.js.map +1 -1
  6. package/dist/lex-equals.d.ts +1 -1
  7. package/dist/lex-equals.d.ts.map +1 -1
  8. package/dist/lex-equals.js.map +1 -1
  9. package/dist/lex.d.ts +1 -1
  10. package/dist/lex.d.ts.map +1 -1
  11. package/dist/lex.js.map +1 -1
  12. package/dist/lib/nodejs-buffer.js.map +1 -1
  13. package/dist/uint8array-from-base64.d.ts +1 -1
  14. package/dist/uint8array-from-base64.d.ts.map +1 -1
  15. package/dist/uint8array-from-base64.js.map +1 -1
  16. package/dist/uint8array-to-base64.d.ts +1 -1
  17. package/dist/uint8array-to-base64.d.ts.map +1 -1
  18. package/dist/uint8array-to-base64.js.map +1 -1
  19. package/dist/uint8array.d.ts +1 -1
  20. package/dist/uint8array.d.ts.map +1 -1
  21. package/dist/uint8array.js.map +1 -1
  22. package/dist/utf8-from-base64.d.ts +1 -1
  23. package/dist/utf8-from-base64.d.ts.map +1 -1
  24. package/dist/utf8-from-base64.js.map +1 -1
  25. package/dist/utf8-to-base64.d.ts +1 -1
  26. package/dist/utf8-to-base64.d.ts.map +1 -1
  27. package/dist/utf8-to-base64.js.map +1 -1
  28. package/dist/utf8.d.ts +1 -1
  29. package/dist/utf8.d.ts.map +1 -1
  30. package/dist/utf8.js.map +1 -1
  31. package/package.json +4 -8
  32. package/src/blob.test.ts +0 -405
  33. package/src/blob.ts +0 -478
  34. package/src/cid-implementation.test.ts +0 -129
  35. package/src/cid.test.ts +0 -350
  36. package/src/cid.ts +0 -603
  37. package/src/core-js.d.ts +0 -2
  38. package/src/index.ts +0 -8
  39. package/src/lex-equals.test.ts +0 -183
  40. package/src/lex-equals.ts +0 -123
  41. package/src/lex-error.test.ts +0 -54
  42. package/src/lex-error.ts +0 -83
  43. package/src/lex.test.ts +0 -279
  44. package/src/lex.ts +0 -253
  45. package/src/lib/nodejs-buffer.ts +0 -46
  46. package/src/lib/util.test.ts +0 -49
  47. package/src/lib/util.ts +0 -7
  48. package/src/object.test.ts +0 -80
  49. package/src/object.ts +0 -83
  50. package/src/uint8array-base64.ts +0 -2
  51. package/src/uint8array-concat.test.ts +0 -197
  52. package/src/uint8array-concat.ts +0 -25
  53. package/src/uint8array-from-base64.test.ts +0 -130
  54. package/src/uint8array-from-base64.ts +0 -98
  55. package/src/uint8array-to-base64.test.ts +0 -170
  56. package/src/uint8array-to-base64.ts +0 -55
  57. package/src/uint8array.test.ts +0 -503
  58. package/src/uint8array.ts +0 -197
  59. package/src/utf8-from-base64.test.ts +0 -39
  60. package/src/utf8-from-base64.ts +0 -23
  61. package/src/utf8-from-bytes.test.ts +0 -43
  62. package/src/utf8-from-bytes.ts +0 -21
  63. package/src/utf8-grapheme-len.test.ts +0 -38
  64. package/src/utf8-grapheme-len.ts +0 -21
  65. package/src/utf8-len.test.ts +0 -21
  66. package/src/utf8-len.ts +0 -51
  67. package/src/utf8-to-base64.test.ts +0 -35
  68. package/src/utf8-to-base64.ts +0 -22
  69. package/src/utf8.ts +0 -128
  70. package/tsconfig.build.json +0 -12
  71. package/tsconfig.json +0 -7
  72. package/tsconfig.tests.json +0 -8
@@ -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