@atproto/lex-json 0.0.15 → 0.1.0-next.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,581 @@
1
+ import { fromBase64, parseCid } from '@atproto/lex-data';
2
+ import { parseTypedBlobRef } from './blob.js';
3
+ const CHAR_TAB = 0x09;
4
+ const CHAR_NEWLINE = 0x0a;
5
+ const CHAR_CARRIAGE_RETURN = 0x0d;
6
+ const CHAR_SPACE = 0x20;
7
+ const CHAR_DOUBLE_QUOTE = 0x22;
8
+ const CHAR_PLUS = 0x2b;
9
+ const CHAR_COMMA = 0x2c;
10
+ const CHAR_MINUS = 0x2d;
11
+ const CHAR_PERIOD = 0x2e;
12
+ const CHAR_SLASH = 0x2f;
13
+ const CHAR_DIGIT_0 = 0x30;
14
+ const CHAR_DIGIT_1 = 0x31;
15
+ const CHAR_DIGIT_9 = 0x39;
16
+ const CHAR_COLON = 0x3a;
17
+ const CHAR_EQUAL = 0x3d;
18
+ const CHAR_UPPER_A = 0x41;
19
+ const CHAR_UPPER_E = 0x45;
20
+ const CHAR_UPPER_F = 0x46;
21
+ const CHAR_UPPER_Z = 0x5a;
22
+ const CHAR_LEFT_BRACKET = 0x5b;
23
+ const CHAR_BACKSLASH = 0x5c;
24
+ const CHAR_RIGHT_BRACKET = 0x5d;
25
+ const CHAR_UNDERSCORE = 0x5f;
26
+ const CHAR_DOLLAR = 0x24;
27
+ const CHAR_LOWER_A = 0x61;
28
+ const CHAR_LOWER_B = 0x62;
29
+ const CHAR_LOWER_E = 0x65;
30
+ const CHAR_LOWER_F = 0x66;
31
+ const CHAR_LOWER_L = 0x6c;
32
+ const CHAR_LOWER_N = 0x6e;
33
+ const CHAR_LOWER_R = 0x72;
34
+ const CHAR_LOWER_S = 0x73;
35
+ const CHAR_LOWER_T = 0x74;
36
+ const CHAR_LOWER_U = 0x75;
37
+ const CHAR_LOWER_Z = 0x7a;
38
+ const CHAR_LEFT_BRACE = 0x7b;
39
+ const CHAR_RIGHT_BRACE = 0x7d;
40
+ const DECODER = new TextDecoder('utf-8', { fatal: true });
41
+ const BASE64_LOOKUP = new Int8Array(256);
42
+ BASE64_LOOKUP.fill(-1);
43
+ for (let i = CHAR_UPPER_A; i <= CHAR_UPPER_Z; i++)
44
+ BASE64_LOOKUP[i] = i - CHAR_UPPER_A;
45
+ for (let i = CHAR_LOWER_A; i <= CHAR_LOWER_Z; i++)
46
+ BASE64_LOOKUP[i] = i - CHAR_LOWER_A + 26;
47
+ for (let i = CHAR_DIGIT_0; i <= CHAR_DIGIT_9; i++)
48
+ BASE64_LOOKUP[i] = i - CHAR_DIGIT_0 + 52;
49
+ BASE64_LOOKUP[CHAR_PLUS] = 62;
50
+ BASE64_LOOKUP[CHAR_MINUS] = 62;
51
+ BASE64_LOOKUP[CHAR_SLASH] = 63;
52
+ BASE64_LOOKUP[CHAR_UNDERSCORE] = 63;
53
+ const HEX_LOOKUP = new Int8Array(256);
54
+ HEX_LOOKUP.fill(-1);
55
+ for (let i = CHAR_DIGIT_0; i <= CHAR_DIGIT_9; i++)
56
+ HEX_LOOKUP[i] = i - CHAR_DIGIT_0;
57
+ for (let i = CHAR_UPPER_A; i <= CHAR_UPPER_F; i++)
58
+ HEX_LOOKUP[i] = i - CHAR_UPPER_A + 10;
59
+ for (let i = CHAR_LOWER_A; i <= CHAR_LOWER_F; i++)
60
+ HEX_LOOKUP[i] = i - CHAR_LOWER_A + 10;
61
+ // Thresholds for optimization heuristics
62
+ export const BASE64_NATIVE_THRESHOLD = 256; // Use native decoding for base64 strings > this length
63
+ export class JsonBytesDecoder {
64
+ constructor(data, strict = true) {
65
+ this.data = data;
66
+ this.strict = strict;
67
+ this.pos = 0;
68
+ }
69
+ decode() {
70
+ this.skipWhitespace();
71
+ const value = this.parseValue();
72
+ this.skipWhitespace();
73
+ if (this.pos < this.data.length) {
74
+ throw new TypeError(`Unexpected data after JSON at position ${this.pos}`);
75
+ }
76
+ return value;
77
+ }
78
+ parseValue() {
79
+ const ch = this.data[this.pos];
80
+ // Optimize by checking most common value types first
81
+ // Strings and objects are very common in real JSON
82
+ if (ch === CHAR_DOUBLE_QUOTE) {
83
+ return this.parseString();
84
+ }
85
+ else if (ch === CHAR_LEFT_BRACE) {
86
+ return this.parseObject();
87
+ }
88
+ else if (ch === CHAR_LEFT_BRACKET) {
89
+ return this.parseArray();
90
+ }
91
+ else if (ch === CHAR_LOWER_T) {
92
+ return this.parseTrue();
93
+ }
94
+ else if (ch === CHAR_LOWER_F) {
95
+ return this.parseFalse();
96
+ }
97
+ else if (ch === CHAR_LOWER_N) {
98
+ return this.parseNull();
99
+ }
100
+ else {
101
+ // Fallback for unexpected input
102
+ return this.parseNumber();
103
+ }
104
+ }
105
+ parseObject() {
106
+ this.pos++; // skip '{'
107
+ this.skipWhitespace();
108
+ // Check for empty object
109
+ if (this.data[this.pos] === CHAR_RIGHT_BRACE) {
110
+ this.pos++;
111
+ return {};
112
+ }
113
+ let obj;
114
+ let hasDollarKey = false; // Track if we've seen any $ key for validation
115
+ for (let i = 0;; i++) {
116
+ this.skipWhitespace();
117
+ // Parse key
118
+ if (this.data[this.pos] !== CHAR_DOUBLE_QUOTE) {
119
+ throw new TypeError(`Expected string key at position ${this.pos}`);
120
+ }
121
+ // Track special keys for later validation
122
+ if (this.data[this.pos + 1] === CHAR_DOLLAR) {
123
+ hasDollarKey = true;
124
+ }
125
+ const key = this.parseString();
126
+ // Prevent prototype pollution
127
+ if (key === '__proto__') {
128
+ throw new TypeError('JSON object keys cannot be "__proto__"');
129
+ }
130
+ this.skipWhitespace();
131
+ // Parse colon
132
+ if (this.data[this.pos] !== CHAR_COLON) {
133
+ throw new TypeError(`Expected ':' at position ${this.pos}`);
134
+ }
135
+ this.pos++;
136
+ this.skipWhitespace();
137
+ // Parse $bytes or $link if it's the first and only key
138
+ if (i === 0) {
139
+ if (key === '$bytes' && this.data[this.pos] === CHAR_DOUBLE_QUOTE) {
140
+ const initialPos = this.pos;
141
+ const b64Start = initialPos + 1;
142
+ const b64End = this.data.indexOf(CHAR_DOUBLE_QUOTE, b64Start);
143
+ if (b64End !== -1) {
144
+ this.pos = b64End + 1;
145
+ this.skipWhitespace();
146
+ if (this.data[this.pos] === CHAR_RIGHT_BRACE) {
147
+ this.pos++;
148
+ const base64Len = b64End - b64Start;
149
+ try {
150
+ // Use native decoding for large base64 strings (much faster
151
+ // based on benchmarks)
152
+ if (base64Len > BASE64_NATIVE_THRESHOLD) {
153
+ const b64Str = this.decodeUnescapedString(b64Start, b64End);
154
+ return fromBase64(b64Str); // Validate and convert to LexValue bytes
155
+ }
156
+ // Manual decoding for smaller strings (optimized path)
157
+ // Skip padding characters
158
+ let b64EndNoPadding = b64End;
159
+ while (b64EndNoPadding > b64Start &&
160
+ this.data[b64EndNoPadding - 1] === CHAR_EQUAL) {
161
+ b64EndNoPadding--;
162
+ }
163
+ const base64LenNoPadding = b64EndNoPadding - b64Start;
164
+ const bytesLen = Math.floor((base64LenNoPadding * 3) / 4);
165
+ const result = new Uint8Array(bytesLen);
166
+ for (let i = b64Start, j = 0; i <= b64EndNoPadding - 4; i += 4) {
167
+ const chunk = (this.base64Value(this.data[i]) << 18) |
168
+ (this.base64Value(this.data[i + 1]) << 12) |
169
+ (this.base64Value(this.data[i + 2]) << 6) |
170
+ this.base64Value(this.data[i + 3]);
171
+ result[j++] = (chunk >> 16) & 0xff;
172
+ result[j++] = (chunk >> 8) & 0xff;
173
+ result[j++] = chunk & 0xff;
174
+ }
175
+ // Handle remaining characters (if any)
176
+ if (base64LenNoPadding % 4 === 2) {
177
+ const chunk = (this.base64Value(this.data[b64EndNoPadding - 2]) << 18) |
178
+ (this.base64Value(this.data[b64EndNoPadding - 1]) << 12);
179
+ result[bytesLen - 1] = (chunk >> 16) & 0xff;
180
+ }
181
+ else if (base64LenNoPadding % 4 === 3) {
182
+ const chunk = (this.base64Value(this.data[b64EndNoPadding - 3]) << 18) |
183
+ (this.base64Value(this.data[b64EndNoPadding - 2]) << 12) |
184
+ (this.base64Value(this.data[b64EndNoPadding - 1]) << 6);
185
+ result[bytesLen - 2] = (chunk >> 16) & 0xff;
186
+ result[bytesLen - 1] = (chunk >> 8) & 0xff;
187
+ }
188
+ return result;
189
+ }
190
+ catch (cause) {
191
+ if (this.strict) {
192
+ throw new TypeError('Invalid $bytes object', { cause });
193
+ }
194
+ // ignore and parse as regular object
195
+ }
196
+ }
197
+ }
198
+ this.pos = initialPos; // reset position to parse string properly
199
+ }
200
+ else if (key === '$link' &&
201
+ this.data[this.pos] === CHAR_DOUBLE_QUOTE) {
202
+ const initialPos = this.pos;
203
+ const cidStart = initialPos + 1;
204
+ const cidEnd = this.data.indexOf(CHAR_DOUBLE_QUOTE, cidStart);
205
+ if (cidEnd !== -1) {
206
+ this.pos = cidEnd + 1;
207
+ this.skipWhitespace();
208
+ if (this.data[this.pos] === CHAR_RIGHT_BRACE) {
209
+ this.pos++;
210
+ const cidStr = this.decodeUnescapedString(cidStart, cidEnd);
211
+ try {
212
+ return parseCid(cidStr);
213
+ }
214
+ catch (cause) {
215
+ if (this.strict) {
216
+ throw new TypeError('Invalid $link object', { cause });
217
+ }
218
+ // ignore
219
+ }
220
+ }
221
+ }
222
+ this.pos = initialPos; // reset position to parse string properly
223
+ }
224
+ }
225
+ // Parse value
226
+ obj ??= {};
227
+ obj[key] = this.parseValue();
228
+ this.skipWhitespace();
229
+ const next = this.data[this.pos];
230
+ if (next === CHAR_RIGHT_BRACE) {
231
+ this.pos++;
232
+ break;
233
+ }
234
+ else if (next === CHAR_COMMA) {
235
+ this.pos++;
236
+ }
237
+ else {
238
+ throw new TypeError(`Expected ',' or '}' at position ${this.pos}`);
239
+ }
240
+ }
241
+ // In strict mode, validate special objects with extra keys
242
+ // Only check if we've seen a $ key (optimization)
243
+ if (hasDollarKey && this.strict) {
244
+ if (obj.$bytes !== undefined) {
245
+ throw new TypeError('Invalid $bytes object');
246
+ }
247
+ else if (obj.$link !== undefined) {
248
+ throw new TypeError('Invalid $link object');
249
+ }
250
+ else if (obj.$type === 'blob') {
251
+ const blob = parseTypedBlobRef(obj, { strict: this.strict });
252
+ if (blob)
253
+ return blob;
254
+ throw new TypeError(`Invalid blob object`);
255
+ }
256
+ else if (obj.$type !== undefined) {
257
+ if (typeof obj.$type !== 'string') {
258
+ throw new TypeError(`Invalid $type property (${typeof obj.$type})`);
259
+ }
260
+ else if (obj.$type.length === 0) {
261
+ throw new TypeError(`Empty $type property`);
262
+ }
263
+ }
264
+ }
265
+ return obj;
266
+ }
267
+ parseArray() {
268
+ this.pos++; // skip '['
269
+ this.skipWhitespace();
270
+ const arr = [];
271
+ // Check for empty array
272
+ if (this.data[this.pos] === CHAR_RIGHT_BRACKET) {
273
+ this.pos++;
274
+ return arr;
275
+ }
276
+ for (;;) {
277
+ this.skipWhitespace();
278
+ arr.push(this.parseValue());
279
+ this.skipWhitespace();
280
+ const next = this.data[this.pos];
281
+ if (next === CHAR_RIGHT_BRACKET) {
282
+ this.pos++;
283
+ break;
284
+ }
285
+ else if (next === CHAR_COMMA) {
286
+ this.pos++;
287
+ }
288
+ else {
289
+ throw new TypeError(`Expected ',' or ']' at position ${this.pos}`);
290
+ }
291
+ }
292
+ return arr;
293
+ }
294
+ parseString() {
295
+ this.pos++; // skip opening quote
296
+ const start = this.pos;
297
+ // Fast path: scan for quote, checking for escapes and control chars inline
298
+ // Optimized for the common case of strings without escapes
299
+ let i = this.pos;
300
+ while (i < this.data.length) {
301
+ const ch = this.data[i];
302
+ if (ch === CHAR_DOUBLE_QUOTE) {
303
+ // Found end quote - fast path success
304
+ this.pos = i + 1;
305
+ return this.decodeUnescapedString(start, i);
306
+ }
307
+ else if (ch === CHAR_BACKSLASH) {
308
+ // Found escape or control character - need slow path
309
+ break;
310
+ }
311
+ else if (ch < 0x20) {
312
+ throw new TypeError(`Unescaped control character at position ${i}`);
313
+ }
314
+ i++;
315
+ }
316
+ // Slow path: handle escapes or control characters
317
+ if (i >= this.data.length) {
318
+ throw new TypeError('Unterminated string');
319
+ }
320
+ // We hit a backslash - need to process escape sequences
321
+ let result = '';
322
+ let segmentStart = start;
323
+ this.pos = i;
324
+ while (this.pos < this.data.length) {
325
+ const ch = this.data[this.pos];
326
+ if (ch === CHAR_DOUBLE_QUOTE) {
327
+ // Found end of string
328
+ if (segmentStart < this.pos) {
329
+ result += this.decodeUnescapedString(segmentStart, this.pos);
330
+ }
331
+ this.pos++;
332
+ return result;
333
+ }
334
+ else if (ch === CHAR_BACKSLASH) {
335
+ // Process escape sequence
336
+ if (segmentStart < this.pos) {
337
+ result += this.decodeUnescapedString(segmentStart, this.pos);
338
+ }
339
+ this.pos++; // skip backslash
340
+ result += this.parseEscapeSequence();
341
+ segmentStart = this.pos;
342
+ }
343
+ else if (ch < 0x20) {
344
+ throw new TypeError(`Unescaped control character at position ${this.pos}`);
345
+ }
346
+ else {
347
+ this.pos++;
348
+ }
349
+ }
350
+ throw new TypeError('Unterminated string');
351
+ }
352
+ parseEscapeSequence() {
353
+ const ch = this.data[this.pos++];
354
+ switch (ch) {
355
+ case CHAR_DOUBLE_QUOTE:
356
+ return '"';
357
+ case CHAR_BACKSLASH:
358
+ return '\\';
359
+ case CHAR_SLASH:
360
+ return '/';
361
+ case CHAR_LOWER_B:
362
+ return '\b';
363
+ case CHAR_LOWER_F:
364
+ return '\f';
365
+ case CHAR_LOWER_N:
366
+ return '\n';
367
+ case CHAR_LOWER_R:
368
+ return '\r';
369
+ case CHAR_LOWER_T:
370
+ return '\t';
371
+ case CHAR_LOWER_U:
372
+ return this.parseUnicodeEscape();
373
+ default:
374
+ throw new TypeError(`Invalid escape sequence at position ${this.pos}`);
375
+ }
376
+ }
377
+ parseUnicodeEscape() {
378
+ // Parse \uXXXX
379
+ let codePoint = 0;
380
+ for (let i = 0; i < 4; i++) {
381
+ const ch = this.data[this.pos++];
382
+ const hex = this.hexValue(ch);
383
+ codePoint = (codePoint << 4) | hex;
384
+ }
385
+ // Handle surrogate pairs
386
+ if (codePoint >= 0xd800 && codePoint <= 0xdbff) {
387
+ // High surrogate, check if followed by low surrogate
388
+ if (this.pos + 5 < this.data.length &&
389
+ this.data[this.pos] === CHAR_BACKSLASH &&
390
+ this.data[this.pos + 1] === CHAR_LOWER_U) {
391
+ // Save position in case we need to backtrack
392
+ const savedPos = this.pos;
393
+ this.pos += 2;
394
+ let low = 0;
395
+ for (let i = 0; i < 4; i++) {
396
+ const ch = this.data[this.pos++];
397
+ const hex = this.hexValue(ch);
398
+ low = (low << 4) | hex;
399
+ }
400
+ // Check if it's a valid low surrogate
401
+ if (low >= 0xdc00 && low <= 0xdfff) {
402
+ // Valid pair - combine into single codepoint
403
+ codePoint = 0x10000 + ((codePoint - 0xd800) << 10) + (low - 0xdc00);
404
+ }
405
+ else {
406
+ // Not a low surrogate - backtrack so it gets processed separately
407
+ this.pos = savedPos;
408
+ }
409
+ }
410
+ }
411
+ return String.fromCodePoint(codePoint);
412
+ }
413
+ hexValue(ch) {
414
+ const value = HEX_LOOKUP[ch];
415
+ if (value !== -1)
416
+ return value;
417
+ throw new TypeError(`Invalid unicode escape at position ${this.pos}`);
418
+ }
419
+ base64Value(ch) {
420
+ const value = BASE64_LOOKUP[ch];
421
+ if (value !== -1)
422
+ return value;
423
+ throw new TypeError(`Invalid base64 character: ${String.fromCharCode(ch)} at position ${this.pos}`);
424
+ }
425
+ decodeUnescapedString(start, end) {
426
+ const len = end - start;
427
+ if (len === 0)
428
+ return '';
429
+ // Fast path for very short ASCII strings (common for object keys like "id", "name", etc.)
430
+ // Heuristic: only worth it for strings <= 20 chars where String.fromCharCode is faster
431
+ // This is a hot path for object keys
432
+ if (len <= 20) {
433
+ let result = '';
434
+ for (let i = start; i < end; i++) {
435
+ const byte = this.data[i];
436
+ if (byte > 0x7f) {
437
+ // Hit non-ASCII, fall back to TextDecoder for full UTF-8 decoding
438
+ const subView = new Uint8Array(this.data.buffer, this.data.byteOffset + start, len);
439
+ return DECODER.decode(subView);
440
+ }
441
+ result += String.fromCharCode(byte);
442
+ }
443
+ return result;
444
+ }
445
+ // For longer strings, use utf8FromBytes directly (it's highly optimized)
446
+ const subView = new Uint8Array(this.data.buffer, this.data.byteOffset + start, len);
447
+ return DECODER.decode(subView);
448
+ }
449
+ parseNumber() {
450
+ const start = this.pos;
451
+ let sign = 1;
452
+ let int = 0;
453
+ let decimal = 0;
454
+ let expSign = 1;
455
+ let exp = 0;
456
+ // Parse sign
457
+ if (this.data[this.pos] === CHAR_MINUS) {
458
+ sign = -1;
459
+ this.pos++;
460
+ }
461
+ // Parse integer part
462
+ if (this.data[this.pos] === CHAR_DIGIT_0) {
463
+ this.pos++;
464
+ // Leading zero must be followed by decimal, exponent, or end
465
+ }
466
+ else if (
467
+ // Note: cannot start with "0"
468
+ this.data[this.pos] >= CHAR_DIGIT_1 &&
469
+ this.data[this.pos] <= CHAR_DIGIT_9) {
470
+ do {
471
+ int = int * 10 + (this.data[this.pos] - CHAR_DIGIT_0);
472
+ this.pos++;
473
+ } while (this.pos < this.data.length &&
474
+ this.data[this.pos] >= CHAR_DIGIT_0 &&
475
+ this.data[this.pos] <= CHAR_DIGIT_9);
476
+ }
477
+ else {
478
+ throw new TypeError(`Unexpected character at position ${this.pos}`);
479
+ }
480
+ // Strict mode validation is deferred until after decimal/exponent parsing
481
+ // so that we can include the complete number value in the error message.
482
+ // Parse decimal part
483
+ if (this.pos < this.data.length && this.data[this.pos] === CHAR_PERIOD) {
484
+ this.pos++;
485
+ if (this.pos >= this.data.length ||
486
+ this.data[this.pos] < CHAR_DIGIT_0 ||
487
+ this.data[this.pos] > CHAR_DIGIT_9) {
488
+ throw new TypeError(`Invalid number at position ${start}`);
489
+ }
490
+ let decimalPlace = 0.1;
491
+ do {
492
+ decimal += (this.data[this.pos] - CHAR_DIGIT_0) * decimalPlace;
493
+ decimalPlace *= 0.1;
494
+ this.pos++;
495
+ } while (this.pos < this.data.length &&
496
+ this.data[this.pos] >= CHAR_DIGIT_0 &&
497
+ this.data[this.pos] <= CHAR_DIGIT_9);
498
+ }
499
+ // Parse exponent part
500
+ if (this.pos < this.data.length &&
501
+ (this.data[this.pos] === CHAR_LOWER_E ||
502
+ this.data[this.pos] === CHAR_UPPER_E)) {
503
+ this.pos++;
504
+ if (this.pos < this.data.length &&
505
+ (this.data[this.pos] === CHAR_PLUS ||
506
+ this.data[this.pos] === CHAR_MINUS)) {
507
+ expSign = this.data[this.pos] === CHAR_MINUS ? -1 : 1;
508
+ this.pos++; // skip + or -
509
+ }
510
+ if (this.pos >= this.data.length ||
511
+ this.data[this.pos] < CHAR_DIGIT_0 ||
512
+ this.data[this.pos] > CHAR_DIGIT_9) {
513
+ throw new TypeError(`Invalid number at position ${start}`);
514
+ }
515
+ do {
516
+ exp = exp * 10 + (this.data[this.pos] - CHAR_DIGIT_0);
517
+ this.pos++;
518
+ } while (this.pos < this.data.length &&
519
+ this.data[this.pos] >= CHAR_DIGIT_0 &&
520
+ this.data[this.pos] <= CHAR_DIGIT_9);
521
+ }
522
+ const num = sign * (int + decimal) * Math.pow(10, expSign * exp);
523
+ if (this.strict && !Number.isSafeInteger(num)) {
524
+ throw new TypeError(`Invalid non-integer number: ${num}`);
525
+ }
526
+ return num;
527
+ }
528
+ parseTrue() {
529
+ if (this.pos + 4 <= this.data.length &&
530
+ this.data[this.pos] === CHAR_LOWER_T &&
531
+ this.data[this.pos + 1] === CHAR_LOWER_R &&
532
+ this.data[this.pos + 2] === CHAR_LOWER_U &&
533
+ this.data[this.pos + 3] === CHAR_LOWER_E) {
534
+ this.pos += 4;
535
+ return true;
536
+ }
537
+ throw new TypeError(`Unexpected token at position ${this.pos}`);
538
+ }
539
+ parseFalse() {
540
+ if (this.pos + 5 <= this.data.length &&
541
+ this.data[this.pos] === CHAR_LOWER_F &&
542
+ this.data[this.pos + 1] === CHAR_LOWER_A &&
543
+ this.data[this.pos + 2] === CHAR_LOWER_L &&
544
+ this.data[this.pos + 3] === CHAR_LOWER_S &&
545
+ this.data[this.pos + 4] === CHAR_LOWER_E) {
546
+ this.pos += 5;
547
+ return false;
548
+ }
549
+ throw new TypeError(`Unexpected token at position ${this.pos}`);
550
+ }
551
+ parseNull() {
552
+ if (this.pos + 4 <= this.data.length &&
553
+ this.data[this.pos] === CHAR_LOWER_N &&
554
+ this.data[this.pos + 1] === CHAR_LOWER_U &&
555
+ this.data[this.pos + 2] === CHAR_LOWER_L &&
556
+ this.data[this.pos + 3] === CHAR_LOWER_L) {
557
+ this.pos += 4;
558
+ return null;
559
+ }
560
+ throw new TypeError(`Unexpected token at position ${this.pos}`);
561
+ }
562
+ skipWhitespace() {
563
+ // Optimized: check most common case (space) first, and use <= for compact check
564
+ while (this.pos < this.data.length) {
565
+ const ch = this.data[this.pos];
566
+ // Optimize for the most common case: space (0x20)
567
+ if (ch === CHAR_SPACE) {
568
+ this.pos++;
569
+ }
570
+ else if (ch === CHAR_TAB ||
571
+ ch === CHAR_NEWLINE ||
572
+ ch === CHAR_CARRIAGE_RETURN) {
573
+ this.pos++;
574
+ }
575
+ else {
576
+ break;
577
+ }
578
+ }
579
+ }
580
+ }
581
+ //# sourceMappingURL=json-bytes-decoder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-bytes-decoder.js","sourceRoot":"","sources":["../src/json-bytes-decoder.ts"],"names":[],"mappings":"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","sourcesContent":["import { LexValue, fromBase64, parseCid } from '@atproto/lex-data'\nimport { parseTypedBlobRef } from './blob.js'\n\nconst CHAR_TAB = 0x09\nconst CHAR_NEWLINE = 0x0a\nconst CHAR_CARRIAGE_RETURN = 0x0d\nconst CHAR_SPACE = 0x20\nconst CHAR_DOUBLE_QUOTE = 0x22\nconst CHAR_PLUS = 0x2b\nconst CHAR_COMMA = 0x2c\nconst CHAR_MINUS = 0x2d\nconst CHAR_PERIOD = 0x2e\nconst CHAR_SLASH = 0x2f\nconst CHAR_DIGIT_0 = 0x30\nconst CHAR_DIGIT_1 = 0x31\nconst CHAR_DIGIT_9 = 0x39\nconst CHAR_COLON = 0x3a\nconst CHAR_EQUAL = 0x3d\nconst CHAR_UPPER_A = 0x41\nconst CHAR_UPPER_E = 0x45\nconst CHAR_UPPER_F = 0x46\nconst CHAR_UPPER_Z = 0x5a\nconst CHAR_LEFT_BRACKET = 0x5b\nconst CHAR_BACKSLASH = 0x5c\nconst CHAR_RIGHT_BRACKET = 0x5d\nconst CHAR_UNDERSCORE = 0x5f\nconst CHAR_DOLLAR = 0x24\nconst CHAR_LOWER_A = 0x61\nconst CHAR_LOWER_B = 0x62\nconst CHAR_LOWER_E = 0x65\nconst CHAR_LOWER_F = 0x66\nconst CHAR_LOWER_L = 0x6c\nconst CHAR_LOWER_N = 0x6e\nconst CHAR_LOWER_R = 0x72\nconst CHAR_LOWER_S = 0x73\nconst CHAR_LOWER_T = 0x74\nconst CHAR_LOWER_U = 0x75\nconst CHAR_LOWER_Z = 0x7a\nconst CHAR_LEFT_BRACE = 0x7b\nconst CHAR_RIGHT_BRACE = 0x7d\n\nconst DECODER = new TextDecoder('utf-8', { fatal: true })\n\nconst BASE64_LOOKUP = new Int8Array(256)\nBASE64_LOOKUP.fill(-1)\nfor (let i = CHAR_UPPER_A; i <= CHAR_UPPER_Z; i++)\n BASE64_LOOKUP[i] = i - CHAR_UPPER_A\nfor (let i = CHAR_LOWER_A; i <= CHAR_LOWER_Z; i++)\n BASE64_LOOKUP[i] = i - CHAR_LOWER_A + 26\nfor (let i = CHAR_DIGIT_0; i <= CHAR_DIGIT_9; i++)\n BASE64_LOOKUP[i] = i - CHAR_DIGIT_0 + 52\nBASE64_LOOKUP[CHAR_PLUS] = 62\nBASE64_LOOKUP[CHAR_MINUS] = 62\nBASE64_LOOKUP[CHAR_SLASH] = 63\nBASE64_LOOKUP[CHAR_UNDERSCORE] = 63\n\nconst HEX_LOOKUP = new Int8Array(256)\nHEX_LOOKUP.fill(-1)\nfor (let i = CHAR_DIGIT_0; i <= CHAR_DIGIT_9; i++)\n HEX_LOOKUP[i] = i - CHAR_DIGIT_0\nfor (let i = CHAR_UPPER_A; i <= CHAR_UPPER_F; i++)\n HEX_LOOKUP[i] = i - CHAR_UPPER_A + 10\nfor (let i = CHAR_LOWER_A; i <= CHAR_LOWER_F; i++)\n HEX_LOOKUP[i] = i - CHAR_LOWER_A + 10\n\n// Thresholds for optimization heuristics\nexport const BASE64_NATIVE_THRESHOLD = 256 // Use native decoding for base64 strings > this length\n\nexport class JsonBytesDecoder {\n private pos = 0\n\n constructor(\n private readonly data: Uint8Array,\n private readonly strict = true,\n ) {}\n\n decode(): LexValue {\n this.skipWhitespace()\n const value = this.parseValue()\n this.skipWhitespace()\n\n if (this.pos < this.data.length) {\n throw new TypeError(`Unexpected data after JSON at position ${this.pos}`)\n }\n\n return value\n }\n\n private parseValue(): LexValue {\n const ch = this.data[this.pos]\n\n // Optimize by checking most common value types first\n // Strings and objects are very common in real JSON\n if (ch === CHAR_DOUBLE_QUOTE) {\n return this.parseString()\n } else if (ch === CHAR_LEFT_BRACE) {\n return this.parseObject()\n } else if (ch === CHAR_LEFT_BRACKET) {\n return this.parseArray()\n } else if (ch === CHAR_LOWER_T) {\n return this.parseTrue()\n } else if (ch === CHAR_LOWER_F) {\n return this.parseFalse()\n } else if (ch === CHAR_LOWER_N) {\n return this.parseNull()\n } else {\n // Fallback for unexpected input\n return this.parseNumber()\n }\n }\n\n private parseObject(): LexValue {\n this.pos++ // skip '{'\n this.skipWhitespace()\n\n // Check for empty object\n if (this.data[this.pos] === CHAR_RIGHT_BRACE) {\n this.pos++\n return {}\n }\n\n let obj: Record<string, LexValue>\n let hasDollarKey = false // Track if we've seen any $ key for validation\n\n for (let i = 0; ; i++) {\n this.skipWhitespace()\n\n // Parse key\n if (this.data[this.pos] !== CHAR_DOUBLE_QUOTE) {\n throw new TypeError(`Expected string key at position ${this.pos}`)\n }\n\n // Track special keys for later validation\n if (this.data[this.pos + 1] === CHAR_DOLLAR) {\n hasDollarKey = true\n }\n\n const key = this.parseString()\n\n // Prevent prototype pollution\n if (key === '__proto__') {\n throw new TypeError('JSON object keys cannot be \"__proto__\"')\n }\n\n this.skipWhitespace()\n\n // Parse colon\n if (this.data[this.pos] !== CHAR_COLON) {\n throw new TypeError(`Expected ':' at position ${this.pos}`)\n }\n this.pos++\n this.skipWhitespace()\n\n // Parse $bytes or $link if it's the first and only key\n if (i === 0) {\n if (key === '$bytes' && this.data[this.pos] === CHAR_DOUBLE_QUOTE) {\n const initialPos = this.pos\n const b64Start = initialPos + 1\n const b64End = this.data.indexOf(CHAR_DOUBLE_QUOTE, b64Start)\n if (b64End !== -1) {\n this.pos = b64End + 1\n this.skipWhitespace()\n if (this.data[this.pos] === CHAR_RIGHT_BRACE) {\n this.pos++\n\n const base64Len = b64End - b64Start\n\n try {\n // Use native decoding for large base64 strings (much faster\n // based on benchmarks)\n if (base64Len > BASE64_NATIVE_THRESHOLD) {\n const b64Str = this.decodeUnescapedString(b64Start, b64End)\n return fromBase64(b64Str) // Validate and convert to LexValue bytes\n }\n\n // Manual decoding for smaller strings (optimized path)\n // Skip padding characters\n let b64EndNoPadding = b64End\n while (\n b64EndNoPadding > b64Start &&\n this.data[b64EndNoPadding - 1] === CHAR_EQUAL\n ) {\n b64EndNoPadding--\n }\n\n const base64LenNoPadding = b64EndNoPadding - b64Start\n const bytesLen = Math.floor((base64LenNoPadding * 3) / 4)\n const result = new Uint8Array(bytesLen)\n\n for (\n let i = b64Start, j = 0;\n i <= b64EndNoPadding - 4;\n i += 4\n ) {\n const chunk =\n (this.base64Value(this.data[i]) << 18) |\n (this.base64Value(this.data[i + 1]) << 12) |\n (this.base64Value(this.data[i + 2]) << 6) |\n this.base64Value(this.data[i + 3])\n\n result[j++] = (chunk >> 16) & 0xff\n result[j++] = (chunk >> 8) & 0xff\n result[j++] = chunk & 0xff\n }\n\n // Handle remaining characters (if any)\n if (base64LenNoPadding % 4 === 2) {\n const chunk =\n (this.base64Value(this.data[b64EndNoPadding - 2]) << 18) |\n (this.base64Value(this.data[b64EndNoPadding - 1]) << 12)\n result[bytesLen - 1] = (chunk >> 16) & 0xff\n } else if (base64LenNoPadding % 4 === 3) {\n const chunk =\n (this.base64Value(this.data[b64EndNoPadding - 3]) << 18) |\n (this.base64Value(this.data[b64EndNoPadding - 2]) << 12) |\n (this.base64Value(this.data[b64EndNoPadding - 1]) << 6)\n result[bytesLen - 2] = (chunk >> 16) & 0xff\n result[bytesLen - 1] = (chunk >> 8) & 0xff\n }\n\n return result\n } catch (cause) {\n if (this.strict) {\n throw new TypeError('Invalid $bytes object', { cause })\n }\n // ignore and parse as regular object\n }\n }\n }\n\n this.pos = initialPos // reset position to parse string properly\n } else if (\n key === '$link' &&\n this.data[this.pos] === CHAR_DOUBLE_QUOTE\n ) {\n const initialPos = this.pos\n const cidStart = initialPos + 1\n const cidEnd = this.data.indexOf(CHAR_DOUBLE_QUOTE, cidStart)\n if (cidEnd !== -1) {\n this.pos = cidEnd + 1\n this.skipWhitespace()\n if (this.data[this.pos] === CHAR_RIGHT_BRACE) {\n this.pos++\n const cidStr = this.decodeUnescapedString(cidStart, cidEnd)\n try {\n return parseCid(cidStr)\n } catch (cause) {\n if (this.strict) {\n throw new TypeError('Invalid $link object', { cause })\n }\n // ignore\n }\n }\n }\n\n this.pos = initialPos // reset position to parse string properly\n }\n }\n\n // Parse value\n obj ??= {}\n obj[key] = this.parseValue()\n\n this.skipWhitespace()\n\n const next = this.data[this.pos]\n if (next === CHAR_RIGHT_BRACE) {\n this.pos++\n break\n } else if (next === CHAR_COMMA) {\n this.pos++\n } else {\n throw new TypeError(`Expected ',' or '}' at position ${this.pos}`)\n }\n }\n\n // In strict mode, validate special objects with extra keys\n // Only check if we've seen a $ key (optimization)\n if (hasDollarKey && this.strict) {\n if (obj.$bytes !== undefined) {\n throw new TypeError('Invalid $bytes object')\n } else if (obj.$link !== undefined) {\n throw new TypeError('Invalid $link object')\n } else if (obj.$type === 'blob') {\n const blob = parseTypedBlobRef(obj, { strict: this.strict })\n if (blob) return blob\n throw new TypeError(`Invalid blob object`)\n } else if (obj.$type !== undefined) {\n if (typeof obj.$type !== 'string') {\n throw new TypeError(`Invalid $type property (${typeof obj.$type})`)\n } else if (obj.$type.length === 0) {\n throw new TypeError(`Empty $type property`)\n }\n }\n }\n\n return obj\n }\n\n private parseArray(): LexValue[] {\n this.pos++ // skip '['\n this.skipWhitespace()\n\n const arr: LexValue[] = []\n\n // Check for empty array\n if (this.data[this.pos] === CHAR_RIGHT_BRACKET) {\n this.pos++\n return arr\n }\n\n for (;;) {\n this.skipWhitespace()\n arr.push(this.parseValue())\n this.skipWhitespace()\n\n const next = this.data[this.pos]\n if (next === CHAR_RIGHT_BRACKET) {\n this.pos++\n break\n } else if (next === CHAR_COMMA) {\n this.pos++\n } else {\n throw new TypeError(`Expected ',' or ']' at position ${this.pos}`)\n }\n }\n\n return arr\n }\n\n private parseString(): string {\n this.pos++ // skip opening quote\n const start = this.pos\n\n // Fast path: scan for quote, checking for escapes and control chars inline\n // Optimized for the common case of strings without escapes\n let i = this.pos\n while (i < this.data.length) {\n const ch = this.data[i]\n\n if (ch === CHAR_DOUBLE_QUOTE) {\n // Found end quote - fast path success\n this.pos = i + 1\n return this.decodeUnescapedString(start, i)\n } else if (ch === CHAR_BACKSLASH) {\n // Found escape or control character - need slow path\n break\n } else if (ch < 0x20) {\n throw new TypeError(`Unescaped control character at position ${i}`)\n }\n i++\n }\n\n // Slow path: handle escapes or control characters\n if (i >= this.data.length) {\n throw new TypeError('Unterminated string')\n }\n\n // We hit a backslash - need to process escape sequences\n let result = ''\n let segmentStart = start\n\n this.pos = i\n while (this.pos < this.data.length) {\n const ch = this.data[this.pos]\n\n if (ch === CHAR_DOUBLE_QUOTE) {\n // Found end of string\n if (segmentStart < this.pos) {\n result += this.decodeUnescapedString(segmentStart, this.pos)\n }\n this.pos++\n return result\n } else if (ch === CHAR_BACKSLASH) {\n // Process escape sequence\n if (segmentStart < this.pos) {\n result += this.decodeUnescapedString(segmentStart, this.pos)\n }\n this.pos++ // skip backslash\n result += this.parseEscapeSequence()\n segmentStart = this.pos\n } else if (ch < 0x20) {\n throw new TypeError(\n `Unescaped control character at position ${this.pos}`,\n )\n } else {\n this.pos++\n }\n }\n\n throw new TypeError('Unterminated string')\n }\n\n private parseEscapeSequence(): string {\n const ch = this.data[this.pos++]\n\n switch (ch) {\n case CHAR_DOUBLE_QUOTE:\n return '\"'\n case CHAR_BACKSLASH:\n return '\\\\'\n case CHAR_SLASH:\n return '/'\n case CHAR_LOWER_B:\n return '\\b'\n case CHAR_LOWER_F:\n return '\\f'\n case CHAR_LOWER_N:\n return '\\n'\n case CHAR_LOWER_R:\n return '\\r'\n case CHAR_LOWER_T:\n return '\\t'\n case CHAR_LOWER_U:\n return this.parseUnicodeEscape()\n default:\n throw new TypeError(`Invalid escape sequence at position ${this.pos}`)\n }\n }\n\n private parseUnicodeEscape(): string {\n // Parse \\uXXXX\n let codePoint = 0\n for (let i = 0; i < 4; i++) {\n const ch = this.data[this.pos++]\n const hex = this.hexValue(ch)\n codePoint = (codePoint << 4) | hex\n }\n\n // Handle surrogate pairs\n if (codePoint >= 0xd800 && codePoint <= 0xdbff) {\n // High surrogate, check if followed by low surrogate\n if (\n this.pos + 5 < this.data.length &&\n this.data[this.pos] === CHAR_BACKSLASH &&\n this.data[this.pos + 1] === CHAR_LOWER_U\n ) {\n // Save position in case we need to backtrack\n const savedPos = this.pos\n this.pos += 2\n let low = 0\n for (let i = 0; i < 4; i++) {\n const ch = this.data[this.pos++]\n const hex = this.hexValue(ch)\n low = (low << 4) | hex\n }\n // Check if it's a valid low surrogate\n if (low >= 0xdc00 && low <= 0xdfff) {\n // Valid pair - combine into single codepoint\n codePoint = 0x10000 + ((codePoint - 0xd800) << 10) + (low - 0xdc00)\n } else {\n // Not a low surrogate - backtrack so it gets processed separately\n this.pos = savedPos\n }\n }\n }\n\n return String.fromCodePoint(codePoint)\n }\n\n private hexValue(ch: number): number {\n const value = HEX_LOOKUP[ch]\n if (value !== -1) return value\n throw new TypeError(`Invalid unicode escape at position ${this.pos}`)\n }\n\n private base64Value(ch: number): number {\n const value = BASE64_LOOKUP[ch]\n if (value !== -1) return value\n throw new TypeError(\n `Invalid base64 character: ${String.fromCharCode(ch)} at position ${this.pos}`,\n )\n }\n\n private decodeUnescapedString(start: number, end: number): string {\n const len = end - start\n if (len === 0) return ''\n\n // Fast path for very short ASCII strings (common for object keys like \"id\", \"name\", etc.)\n // Heuristic: only worth it for strings <= 20 chars where String.fromCharCode is faster\n // This is a hot path for object keys\n if (len <= 20) {\n let result = ''\n for (let i = start; i < end; i++) {\n const byte = this.data[i]\n if (byte > 0x7f) {\n // Hit non-ASCII, fall back to TextDecoder for full UTF-8 decoding\n const subView = new Uint8Array(\n this.data.buffer,\n this.data.byteOffset + start,\n len,\n )\n return DECODER.decode(subView)\n }\n result += String.fromCharCode(byte)\n }\n return result\n }\n\n // For longer strings, use utf8FromBytes directly (it's highly optimized)\n const subView = new Uint8Array(\n this.data.buffer,\n this.data.byteOffset + start,\n len,\n )\n return DECODER.decode(subView)\n }\n\n private parseNumber(): number {\n const start = this.pos\n\n let sign = 1\n let int = 0\n let decimal = 0\n let expSign = 1\n let exp = 0\n\n // Parse sign\n if (this.data[this.pos] === CHAR_MINUS) {\n sign = -1\n this.pos++\n }\n\n // Parse integer part\n if (this.data[this.pos] === CHAR_DIGIT_0) {\n this.pos++\n // Leading zero must be followed by decimal, exponent, or end\n } else if (\n // Note: cannot start with \"0\"\n this.data[this.pos] >= CHAR_DIGIT_1 &&\n this.data[this.pos] <= CHAR_DIGIT_9\n ) {\n do {\n int = int * 10 + (this.data[this.pos] - CHAR_DIGIT_0)\n this.pos++\n } while (\n this.pos < this.data.length &&\n this.data[this.pos] >= CHAR_DIGIT_0 &&\n this.data[this.pos] <= CHAR_DIGIT_9\n )\n } else {\n throw new TypeError(`Unexpected character at position ${this.pos}`)\n }\n\n // Strict mode validation is deferred until after decimal/exponent parsing\n // so that we can include the complete number value in the error message.\n\n // Parse decimal part\n if (this.pos < this.data.length && this.data[this.pos] === CHAR_PERIOD) {\n this.pos++\n if (\n this.pos >= this.data.length ||\n this.data[this.pos] < CHAR_DIGIT_0 ||\n this.data[this.pos] > CHAR_DIGIT_9\n ) {\n throw new TypeError(`Invalid number at position ${start}`)\n }\n let decimalPlace = 0.1\n do {\n decimal += (this.data[this.pos] - CHAR_DIGIT_0) * decimalPlace\n decimalPlace *= 0.1\n this.pos++\n } while (\n this.pos < this.data.length &&\n this.data[this.pos] >= CHAR_DIGIT_0 &&\n this.data[this.pos] <= CHAR_DIGIT_9\n )\n }\n\n // Parse exponent part\n if (\n this.pos < this.data.length &&\n (this.data[this.pos] === CHAR_LOWER_E ||\n this.data[this.pos] === CHAR_UPPER_E)\n ) {\n this.pos++\n if (\n this.pos < this.data.length &&\n (this.data[this.pos] === CHAR_PLUS ||\n this.data[this.pos] === CHAR_MINUS)\n ) {\n expSign = this.data[this.pos] === CHAR_MINUS ? -1 : 1\n this.pos++ // skip + or -\n }\n if (\n this.pos >= this.data.length ||\n this.data[this.pos] < CHAR_DIGIT_0 ||\n this.data[this.pos] > CHAR_DIGIT_9\n ) {\n throw new TypeError(`Invalid number at position ${start}`)\n }\n do {\n exp = exp * 10 + (this.data[this.pos] - CHAR_DIGIT_0)\n this.pos++\n } while (\n this.pos < this.data.length &&\n this.data[this.pos] >= CHAR_DIGIT_0 &&\n this.data[this.pos] <= CHAR_DIGIT_9\n )\n }\n\n const num = sign * (int + decimal) * Math.pow(10, expSign * exp)\n\n if (this.strict && !Number.isSafeInteger(num)) {\n throw new TypeError(`Invalid non-integer number: ${num}`)\n }\n\n return num\n }\n\n private parseTrue(): boolean {\n if (\n this.pos + 4 <= this.data.length &&\n this.data[this.pos] === CHAR_LOWER_T &&\n this.data[this.pos + 1] === CHAR_LOWER_R &&\n this.data[this.pos + 2] === CHAR_LOWER_U &&\n this.data[this.pos + 3] === CHAR_LOWER_E\n ) {\n this.pos += 4\n return true\n }\n throw new TypeError(`Unexpected token at position ${this.pos}`)\n }\n\n private parseFalse(): boolean {\n if (\n this.pos + 5 <= this.data.length &&\n this.data[this.pos] === CHAR_LOWER_F &&\n this.data[this.pos + 1] === CHAR_LOWER_A &&\n this.data[this.pos + 2] === CHAR_LOWER_L &&\n this.data[this.pos + 3] === CHAR_LOWER_S &&\n this.data[this.pos + 4] === CHAR_LOWER_E\n ) {\n this.pos += 5\n return false\n }\n throw new TypeError(`Unexpected token at position ${this.pos}`)\n }\n\n private parseNull(): null {\n if (\n this.pos + 4 <= this.data.length &&\n this.data[this.pos] === CHAR_LOWER_N &&\n this.data[this.pos + 1] === CHAR_LOWER_U &&\n this.data[this.pos + 2] === CHAR_LOWER_L &&\n this.data[this.pos + 3] === CHAR_LOWER_L\n ) {\n this.pos += 4\n return null\n }\n throw new TypeError(`Unexpected token at position ${this.pos}`)\n }\n\n private skipWhitespace(): void {\n // Optimized: check most common case (space) first, and use <= for compact check\n while (this.pos < this.data.length) {\n const ch = this.data[this.pos]\n // Optimize for the most common case: space (0x20)\n if (ch === CHAR_SPACE) {\n this.pos++\n } else if (\n ch === CHAR_TAB ||\n ch === CHAR_NEWLINE ||\n ch === CHAR_CARRIAGE_RETURN\n ) {\n this.pos++\n } else {\n break\n }\n }\n }\n}\n"]}