cborg 4.5.3 → 4.5.5
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/bench/bench.js +16 -12
- package/lib/3string.js +32 -2
- package/lib/7float.js +4 -4
- package/lib/byte-utils.js +1 -111
- package/lib/encode.js +152 -3
- package/package.json +1 -1
- package/types/lib/3string.d.ts.map +1 -1
- package/types/lib/7float.d.ts +9 -0
- package/types/lib/7float.d.ts.map +1 -1
- package/types/lib/byte-utils.d.ts +0 -6
- package/types/lib/byte-utils.d.ts.map +1 -1
- package/types/lib/encode.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [4.5.5](https://github.com/rvagg/cborg/compare/v4.5.4...v4.5.5) (2026-01-20)
|
|
2
|
+
|
|
3
|
+
### Trivial Changes
|
|
4
|
+
|
|
5
|
+
* **bench:** output json to file ([ca32690](https://github.com/rvagg/cborg/commit/ca326908643ce9bc2ac56dd06b6c64502b8a4f03))
|
|
6
|
+
|
|
7
|
+
## [4.5.4](https://github.com/rvagg/cborg/compare/v4.5.3...v4.5.4) (2026-01-20)
|
|
8
|
+
|
|
1
9
|
## [4.5.3](https://github.com/rvagg/cborg/compare/v4.5.2...v4.5.3) (2026-01-20)
|
|
2
10
|
|
|
3
11
|
## [4.5.2](https://github.com/rvagg/cborg/compare/v4.5.1...v4.5.2) (2026-01-20)
|
package/bench/bench.js
CHANGED
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
* Works in both Node.js and browser environments.
|
|
6
6
|
*
|
|
7
7
|
* Usage:
|
|
8
|
-
* node bench/bench
|
|
9
|
-
* node bench/bench
|
|
10
|
-
* node bench/bench
|
|
11
|
-
* node bench/bench
|
|
12
|
-
* node bench/bench
|
|
13
|
-
* node bench/bench
|
|
8
|
+
* node bench/bench.js # run all benchmarks (dag-cbor mode)
|
|
9
|
+
* node bench/bench.js --mode=raw # run with raw cborg (no tags)
|
|
10
|
+
* node bench/bench.js --suite=bsky # run only bluesky suite
|
|
11
|
+
* node bench/bench.js --json=output.json # write JSON results to file
|
|
12
|
+
* node bench/bench.js --compare=baseline.json # compare to baseline
|
|
13
|
+
* node bench/bench.js --encode-into # use encodeInto instead of encode
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import { encode, decode, encodeInto, Token, Type } from '../cborg.js'
|
|
@@ -129,7 +129,7 @@ const FIXTURE_SEED = 12345
|
|
|
129
129
|
// Parse CLI args (Node.js only, ignored in browser)
|
|
130
130
|
const args = typeof process !== 'undefined' ? process.argv.slice(2) : []
|
|
131
131
|
const opts = {
|
|
132
|
-
json: args.
|
|
132
|
+
json: args.find(a => a.startsWith('--json='))?.split('=')[1] || null,
|
|
133
133
|
suite: args.find(a => a.startsWith('--suite='))?.split('=')[1] || null,
|
|
134
134
|
compare: args.find(a => a.startsWith('--compare='))?.split('=')[1] || null,
|
|
135
135
|
duration: parseInt(args.find(a => a.startsWith('--duration='))?.split('=')[1] || DEFAULT_DURATION_MS),
|
|
@@ -184,11 +184,11 @@ function getOptions (suiteType = 'default') {
|
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
// Output helpers
|
|
188
|
-
const log =
|
|
187
|
+
// Output helpers - always show progress to console
|
|
188
|
+
const log = console.log.bind(console)
|
|
189
189
|
const write = typeof process !== 'undefined' && process.stdout
|
|
190
190
|
? (s) => process.stdout.write(s)
|
|
191
|
-
: (s) => log(s)
|
|
191
|
+
: (s) => console.log(s)
|
|
192
192
|
|
|
193
193
|
/**
|
|
194
194
|
* Run a benchmark function for a duration, return ops/sec
|
|
@@ -364,7 +364,7 @@ async function main () {
|
|
|
364
364
|
const avgDecode = Math.round(allDecodeRates.reduce((a, b) => a + b, 0) / allDecodeRates.length * 10) / 10
|
|
365
365
|
log(`Average throughput: encode ${avgEncode} MB/s, decode ${avgDecode} MB/s`)
|
|
366
366
|
|
|
367
|
-
// JSON output
|
|
367
|
+
// JSON output to file
|
|
368
368
|
if (opts.json) {
|
|
369
369
|
const output = {
|
|
370
370
|
timestamp: new Date().toISOString(),
|
|
@@ -375,7 +375,11 @@ async function main () {
|
|
|
375
375
|
suites: allResults,
|
|
376
376
|
summary: { avgEncodeMBps: avgEncode, avgDecodeMBps: avgDecode }
|
|
377
377
|
}
|
|
378
|
-
|
|
378
|
+
if (typeof process !== 'undefined') {
|
|
379
|
+
const fs = await import('fs')
|
|
380
|
+
fs.writeFileSync(opts.json, JSON.stringify(output, null, 2) + '\n')
|
|
381
|
+
log(`\nResults written to ${opts.json}`)
|
|
382
|
+
}
|
|
379
383
|
}
|
|
380
384
|
|
|
381
385
|
// Compare to baseline
|
package/lib/3string.js
CHANGED
|
@@ -2,13 +2,43 @@ import { Token, Type } from './token.js'
|
|
|
2
2
|
import { assertEnoughData, decodeErrPrefix } from './common.js'
|
|
3
3
|
import * as uint from './0uint.js'
|
|
4
4
|
import { encodeBytes } from './2bytes.js'
|
|
5
|
-
import {
|
|
5
|
+
import { slice } from './byte-utils.js'
|
|
6
|
+
|
|
7
|
+
const textDecoder = new TextDecoder()
|
|
8
|
+
|
|
9
|
+
// Threshold for ASCII fast-path vs TextDecoder. Short ASCII strings (common for
|
|
10
|
+
// map keys) are faster to decode with a simple loop than TextDecoder overhead.
|
|
11
|
+
const ASCII_THRESHOLD = 32
|
|
6
12
|
|
|
7
13
|
/**
|
|
8
14
|
* @typedef {import('../interface').ByteWriter} ByteWriter
|
|
9
15
|
* @typedef {import('../interface').DecodeOptions} DecodeOptions
|
|
10
16
|
*/
|
|
11
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Decode UTF-8 bytes to string. For short ASCII strings (common case for map keys),
|
|
20
|
+
* a simple loop is faster than TextDecoder.
|
|
21
|
+
* @param {Uint8Array} bytes
|
|
22
|
+
* @param {number} start
|
|
23
|
+
* @param {number} end
|
|
24
|
+
* @returns {string}
|
|
25
|
+
*/
|
|
26
|
+
function toStr (bytes, start, end) {
|
|
27
|
+
const len = end - start
|
|
28
|
+
if (len < ASCII_THRESHOLD) {
|
|
29
|
+
let str = ''
|
|
30
|
+
for (let i = start; i < end; i++) {
|
|
31
|
+
const c = bytes[i]
|
|
32
|
+
if (c & 0x80) { // non-ASCII, fall back to TextDecoder
|
|
33
|
+
return textDecoder.decode(bytes.subarray(start, end))
|
|
34
|
+
}
|
|
35
|
+
str += String.fromCharCode(c)
|
|
36
|
+
}
|
|
37
|
+
return str
|
|
38
|
+
}
|
|
39
|
+
return textDecoder.decode(bytes.subarray(start, end))
|
|
40
|
+
}
|
|
41
|
+
|
|
12
42
|
/**
|
|
13
43
|
* @param {Uint8Array} data
|
|
14
44
|
* @param {number} pos
|
|
@@ -20,7 +50,7 @@ import { toString, slice } from './byte-utils.js'
|
|
|
20
50
|
function toToken (data, pos, prefix, length, options) {
|
|
21
51
|
const totLength = prefix + length
|
|
22
52
|
assertEnoughData(data, pos, totLength)
|
|
23
|
-
const tok = new Token(Type.string,
|
|
53
|
+
const tok = new Token(Type.string, toStr(data, pos + prefix, pos + totLength), totLength)
|
|
24
54
|
if (options.retainStringBytes === true) {
|
|
25
55
|
tok.byteValue = slice(data, pos + prefix, pos + totLength)
|
|
26
56
|
}
|
package/lib/7float.js
CHANGED
|
@@ -11,10 +11,10 @@ import { encodeUint } from './0uint.js'
|
|
|
11
11
|
* @typedef {import('../interface').EncodeOptions} EncodeOptions
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
const MINOR_FALSE = 20
|
|
15
|
-
const MINOR_TRUE = 21
|
|
16
|
-
const MINOR_NULL = 22
|
|
17
|
-
const MINOR_UNDEFINED = 23
|
|
14
|
+
export const MINOR_FALSE = 20
|
|
15
|
+
export const MINOR_TRUE = 21
|
|
16
|
+
export const MINOR_NULL = 22
|
|
17
|
+
export const MINOR_UNDEFINED = 23
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* @param {Uint8Array} _data
|
package/lib/byte-utils.js
CHANGED
|
@@ -10,7 +10,6 @@ export const useBuffer = globalThis.process &&
|
|
|
10
10
|
// @ts-ignore
|
|
11
11
|
typeof globalThis.Buffer.isBuffer === 'function'
|
|
12
12
|
|
|
13
|
-
const textDecoder = new TextDecoder()
|
|
14
13
|
const textEncoder = new TextEncoder()
|
|
15
14
|
|
|
16
15
|
/**
|
|
@@ -34,37 +33,6 @@ export function asU8A (buf) {
|
|
|
34
33
|
return isBuffer(buf) ? new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength) : buf
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
// Threshold for switching between manual utf8Slice and native TextDecoder/Buffer
|
|
38
|
-
// Manual decoding has overhead from array building; native is fast for strings > 32 bytes
|
|
39
|
-
const UTF8_THRESHOLD = 32
|
|
40
|
-
|
|
41
|
-
export const toString = useBuffer
|
|
42
|
-
? // eslint-disable-line operator-linebreak
|
|
43
|
-
/**
|
|
44
|
-
* @param {Uint8Array} bytes
|
|
45
|
-
* @param {number} start
|
|
46
|
-
* @param {number} end
|
|
47
|
-
*/
|
|
48
|
-
(bytes, start, end) => {
|
|
49
|
-
return end - start > UTF8_THRESHOLD
|
|
50
|
-
? // eslint-disable-line operator-linebreak
|
|
51
|
-
// @ts-ignore
|
|
52
|
-
globalThis.Buffer.from(bytes.subarray(start, end)).toString('utf8')
|
|
53
|
-
: utf8Slice(bytes, start, end)
|
|
54
|
-
}
|
|
55
|
-
/* c8 ignore next 11 */
|
|
56
|
-
: // eslint-disable-line operator-linebreak
|
|
57
|
-
/**
|
|
58
|
-
* @param {Uint8Array} bytes
|
|
59
|
-
* @param {number} start
|
|
60
|
-
* @param {number} end
|
|
61
|
-
*/
|
|
62
|
-
(bytes, start, end) => {
|
|
63
|
-
return end - start > UTF8_THRESHOLD
|
|
64
|
-
? textDecoder.decode(bytes.subarray(start, end))
|
|
65
|
-
: utf8Slice(bytes, start, end)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
36
|
export const fromString = useBuffer
|
|
69
37
|
? // eslint-disable-line operator-linebreak
|
|
70
38
|
/**
|
|
@@ -102,6 +70,7 @@ export const slice = useBuffer
|
|
|
102
70
|
* @param {number} start
|
|
103
71
|
* @param {number} end
|
|
104
72
|
*/
|
|
73
|
+
// Buffer.slice() returns a view, not a copy, so we need special handling
|
|
105
74
|
(bytes, start, end) => {
|
|
106
75
|
if (isBuffer(bytes)) {
|
|
107
76
|
return new Uint8Array(bytes.subarray(start, end))
|
|
@@ -317,85 +286,6 @@ function utf8ToBytes (str) {
|
|
|
317
286
|
return out
|
|
318
287
|
}
|
|
319
288
|
|
|
320
|
-
// The below code is mostly taken from https://github.com/feross/buffer
|
|
321
|
-
// Licensed MIT. Copyright (c) Feross Aboukhadijeh
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* @param {Uint8Array} buf
|
|
325
|
-
* @param {number} offset
|
|
326
|
-
* @param {number} end
|
|
327
|
-
* @returns {string}
|
|
328
|
-
*/
|
|
329
|
-
function utf8Slice (buf, offset, end) {
|
|
330
|
-
const res = []
|
|
331
|
-
|
|
332
|
-
while (offset < end) {
|
|
333
|
-
const firstByte = buf[offset]
|
|
334
|
-
let codePoint = null
|
|
335
|
-
let bytesPerSequence = (firstByte > 0xef) ? 4 : (firstByte > 0xdf) ? 3 : (firstByte > 0xbf) ? 2 : 1
|
|
336
|
-
|
|
337
|
-
if (offset + bytesPerSequence <= end) {
|
|
338
|
-
let secondByte, thirdByte, fourthByte, tempCodePoint
|
|
339
|
-
|
|
340
|
-
switch (bytesPerSequence) {
|
|
341
|
-
case 1:
|
|
342
|
-
if (firstByte < 0x80) {
|
|
343
|
-
codePoint = firstByte
|
|
344
|
-
}
|
|
345
|
-
break
|
|
346
|
-
case 2:
|
|
347
|
-
secondByte = buf[offset + 1]
|
|
348
|
-
if ((secondByte & 0xc0) === 0x80) {
|
|
349
|
-
tempCodePoint = (firstByte & 0x1f) << 0x6 | (secondByte & 0x3f)
|
|
350
|
-
if (tempCodePoint > 0x7f) {
|
|
351
|
-
codePoint = tempCodePoint
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
break
|
|
355
|
-
case 3:
|
|
356
|
-
secondByte = buf[offset + 1]
|
|
357
|
-
thirdByte = buf[offset + 2]
|
|
358
|
-
if ((secondByte & 0xc0) === 0x80 && (thirdByte & 0xc0) === 0x80) {
|
|
359
|
-
tempCodePoint = (firstByte & 0xf) << 0xc | (secondByte & 0x3f) << 0x6 | (thirdByte & 0x3f)
|
|
360
|
-
/* c8 ignore next 3 */
|
|
361
|
-
if (tempCodePoint > 0x7ff && (tempCodePoint < 0xd800 || tempCodePoint > 0xdfff)) {
|
|
362
|
-
codePoint = tempCodePoint
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
break
|
|
366
|
-
case 4:
|
|
367
|
-
secondByte = buf[offset + 1]
|
|
368
|
-
thirdByte = buf[offset + 2]
|
|
369
|
-
fourthByte = buf[offset + 3]
|
|
370
|
-
if ((secondByte & 0xc0) === 0x80 && (thirdByte & 0xc0) === 0x80 && (fourthByte & 0xc0) === 0x80) {
|
|
371
|
-
tempCodePoint = (firstByte & 0xf) << 0x12 | (secondByte & 0x3f) << 0xc | (thirdByte & 0x3f) << 0x6 | (fourthByte & 0x3f)
|
|
372
|
-
if (tempCodePoint > 0xffff && tempCodePoint < 0x110000) {
|
|
373
|
-
codePoint = tempCodePoint
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
/* c8 ignore next 5 */
|
|
380
|
-
if (codePoint === null) {
|
|
381
|
-
// we did not generate a valid codePoint so insert a
|
|
382
|
-
// replacement char (U+FFFD) and advance only 1 byte
|
|
383
|
-
codePoint = 0xfffd
|
|
384
|
-
bytesPerSequence = 1
|
|
385
|
-
} else if (codePoint > 0xffff) {
|
|
386
|
-
// encode to utf16 (surrogate pair dance)
|
|
387
|
-
codePoint -= 0x10000
|
|
388
|
-
res.push(codePoint >>> 10 & 0x3ff | 0xd800)
|
|
389
|
-
codePoint = 0xdc00 | codePoint & 0x3ff
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
res.push(codePoint)
|
|
393
|
-
offset += bytesPerSequence
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
return decodeCodePointsArray(res)
|
|
397
|
-
}
|
|
398
|
-
|
|
399
289
|
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
|
|
400
290
|
// the lowest limit is Chrome, with 0x10000 args.
|
|
401
291
|
// We go 1 magnitude less, for safety
|
package/lib/encode.js
CHANGED
|
@@ -3,16 +3,16 @@ import { Token, Type } from './token.js'
|
|
|
3
3
|
import { Bl, U8Bl } from './bl.js'
|
|
4
4
|
import { encodeErrPrefix } from './common.js'
|
|
5
5
|
import { quickEncodeToken } from './jump.js'
|
|
6
|
-
import { asU8A, compare } from './byte-utils.js'
|
|
6
|
+
import { asU8A, compare, fromString } from './byte-utils.js'
|
|
7
7
|
|
|
8
|
-
import { encodeUint } from './0uint.js'
|
|
8
|
+
import { encodeUint, encodeUintValue } from './0uint.js'
|
|
9
9
|
import { encodeNegint } from './1negint.js'
|
|
10
10
|
import { encodeBytes } from './2bytes.js'
|
|
11
11
|
import { encodeString } from './3string.js'
|
|
12
12
|
import { encodeArray } from './4array.js'
|
|
13
13
|
import { encodeMap } from './5map.js'
|
|
14
14
|
import { encodeTag } from './6tag.js'
|
|
15
|
-
import { encodeFloat } from './7float.js'
|
|
15
|
+
import { encodeFloat, MINOR_FALSE, MINOR_TRUE, MINOR_NULL, MINOR_UNDEFINED } from './7float.js'
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @typedef {import('../interface').EncodeOptions} EncodeOptions
|
|
@@ -468,6 +468,139 @@ function tokensToEncoded (writer, tokens, encoders, options) {
|
|
|
468
468
|
}
|
|
469
469
|
}
|
|
470
470
|
|
|
471
|
+
// CBOR major type prefixes, cached from Type for hot path performance
|
|
472
|
+
const MAJOR_UINT = Type.uint.majorEncoded
|
|
473
|
+
const MAJOR_NEGINT = Type.negint.majorEncoded
|
|
474
|
+
const MAJOR_BYTES = Type.bytes.majorEncoded
|
|
475
|
+
const MAJOR_STRING = Type.string.majorEncoded
|
|
476
|
+
const MAJOR_ARRAY = Type.array.majorEncoded
|
|
477
|
+
|
|
478
|
+
// Simple value bytes (CBOR major type 7 + minor value)
|
|
479
|
+
const SIMPLE_FALSE = Type.float.majorEncoded | MINOR_FALSE
|
|
480
|
+
const SIMPLE_TRUE = Type.float.majorEncoded | MINOR_TRUE
|
|
481
|
+
const SIMPLE_NULL = Type.float.majorEncoded | MINOR_NULL
|
|
482
|
+
const SIMPLE_UNDEFINED = Type.float.majorEncoded | MINOR_UNDEFINED
|
|
483
|
+
|
|
484
|
+
const neg1b = BigInt(-1)
|
|
485
|
+
const pos1b = BigInt(1)
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Check if direct encoding can be used for the given options.
|
|
489
|
+
* Direct encoding bypasses token creation for most values.
|
|
490
|
+
* @param {EncodeOptions} options
|
|
491
|
+
* @returns {boolean}
|
|
492
|
+
*/
|
|
493
|
+
function canDirectEncode (options) {
|
|
494
|
+
// Cannot use direct encode with addBreakTokens (needs special break token handling).
|
|
495
|
+
// Direct encode checks typeEncoders per-value, falling back to tokens as needed.
|
|
496
|
+
// Maps fall back to token-based encoding for efficient key sorting.
|
|
497
|
+
return options.addBreakTokens !== true
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Direct encode a value to the writer, bypassing token creation for most types.
|
|
502
|
+
* Falls back to token-based encoding for custom type encoders.
|
|
503
|
+
* @param {ByteWriter} writer
|
|
504
|
+
* @param {any} data
|
|
505
|
+
* @param {EncodeOptions} options
|
|
506
|
+
* @param {Reference|undefined} refStack
|
|
507
|
+
*/
|
|
508
|
+
function directEncode (writer, data, options, refStack) {
|
|
509
|
+
const typ = is(data)
|
|
510
|
+
|
|
511
|
+
// Check for custom encoder for THIS specific type
|
|
512
|
+
const customEncoder = options.typeEncoders && options.typeEncoders[typ]
|
|
513
|
+
if (customEncoder) {
|
|
514
|
+
const tokens = customEncoder(data, typ, options, refStack)
|
|
515
|
+
if (tokens != null) {
|
|
516
|
+
// Custom encoder returned tokens, serialize immediately
|
|
517
|
+
tokensToEncoded(writer, tokens, cborEncoders, options)
|
|
518
|
+
return
|
|
519
|
+
}
|
|
520
|
+
// Custom encoder returned null, fall through to default handling
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// Direct encode based on type
|
|
524
|
+
switch (typ) {
|
|
525
|
+
case 'null':
|
|
526
|
+
writer.push([SIMPLE_NULL])
|
|
527
|
+
return
|
|
528
|
+
|
|
529
|
+
case 'undefined':
|
|
530
|
+
writer.push([SIMPLE_UNDEFINED])
|
|
531
|
+
return
|
|
532
|
+
|
|
533
|
+
case 'boolean':
|
|
534
|
+
writer.push([data ? SIMPLE_TRUE : SIMPLE_FALSE])
|
|
535
|
+
return
|
|
536
|
+
|
|
537
|
+
case 'number':
|
|
538
|
+
if (!Number.isInteger(data) || !Number.isSafeInteger(data)) {
|
|
539
|
+
// Float, use token encoder for complex float encoding
|
|
540
|
+
encodeFloat(writer, new Token(Type.float, data), options)
|
|
541
|
+
} else if (data >= 0) {
|
|
542
|
+
encodeUintValue(writer, MAJOR_UINT, data)
|
|
543
|
+
} else {
|
|
544
|
+
// Negative integer
|
|
545
|
+
encodeUintValue(writer, MAJOR_NEGINT, data * -1 - 1)
|
|
546
|
+
}
|
|
547
|
+
return
|
|
548
|
+
|
|
549
|
+
case 'bigint':
|
|
550
|
+
if (data >= BigInt(0)) {
|
|
551
|
+
encodeUintValue(writer, MAJOR_UINT, data)
|
|
552
|
+
} else {
|
|
553
|
+
encodeUintValue(writer, MAJOR_NEGINT, data * neg1b - pos1b)
|
|
554
|
+
}
|
|
555
|
+
return
|
|
556
|
+
|
|
557
|
+
case 'string': {
|
|
558
|
+
const bytes = fromString(data)
|
|
559
|
+
encodeUintValue(writer, MAJOR_STRING, bytes.length)
|
|
560
|
+
writer.push(bytes)
|
|
561
|
+
return
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
case 'Uint8Array':
|
|
565
|
+
encodeUintValue(writer, MAJOR_BYTES, data.length)
|
|
566
|
+
writer.push(data)
|
|
567
|
+
return
|
|
568
|
+
|
|
569
|
+
case 'Array':
|
|
570
|
+
if (!data.length) {
|
|
571
|
+
writer.push([MAJOR_ARRAY]) // Empty array: 0x80
|
|
572
|
+
return
|
|
573
|
+
}
|
|
574
|
+
refStack = Ref.createCheck(refStack, data)
|
|
575
|
+
encodeUintValue(writer, MAJOR_ARRAY, data.length)
|
|
576
|
+
for (const elem of data) {
|
|
577
|
+
directEncode(writer, elem, options, refStack)
|
|
578
|
+
}
|
|
579
|
+
return
|
|
580
|
+
|
|
581
|
+
case 'Object':
|
|
582
|
+
case 'Map':
|
|
583
|
+
// Maps require key sorting, use token-based encoding for efficiency
|
|
584
|
+
// (pre-encoding all keys for sorting is expensive)
|
|
585
|
+
{
|
|
586
|
+
const tokens = typeEncoders.Object(data, typ, options, refStack)
|
|
587
|
+
tokensToEncoded(writer, tokens, cborEncoders, options)
|
|
588
|
+
}
|
|
589
|
+
return
|
|
590
|
+
|
|
591
|
+
default:
|
|
592
|
+
// Fall back to token-based encoding for other types (DataView, TypedArrays, etc.)
|
|
593
|
+
{
|
|
594
|
+
const typeEncoder = typeEncoders[typ]
|
|
595
|
+
if (!typeEncoder) {
|
|
596
|
+
throw new Error(`${encodeErrPrefix} unsupported type: ${typ}`)
|
|
597
|
+
}
|
|
598
|
+
const tokens = typeEncoder(data, typ, options, refStack)
|
|
599
|
+
tokensToEncoded(writer, tokens, cborEncoders, options)
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
471
604
|
/**
|
|
472
605
|
* @param {any} data
|
|
473
606
|
* @param {TokenTypeEncoder[]} encoders
|
|
@@ -518,6 +651,14 @@ function encodeCustom (data, encoders, options, destination) {
|
|
|
518
651
|
*/
|
|
519
652
|
function encode (data, options) {
|
|
520
653
|
options = Object.assign({}, defaultEncodeOptions, options)
|
|
654
|
+
|
|
655
|
+
// Use direct encode path when possible
|
|
656
|
+
if (canDirectEncode(options)) {
|
|
657
|
+
defaultWriter.reset()
|
|
658
|
+
directEncode(defaultWriter, data, options, undefined)
|
|
659
|
+
return defaultWriter.toBytes(true)
|
|
660
|
+
}
|
|
661
|
+
|
|
521
662
|
return encodeCustom(data, cborEncoders, options)
|
|
522
663
|
}
|
|
523
664
|
|
|
@@ -529,6 +670,14 @@ function encode (data, options) {
|
|
|
529
670
|
*/
|
|
530
671
|
function encodeInto (data, destination, options) {
|
|
531
672
|
options = Object.assign({}, defaultEncodeOptions, options)
|
|
673
|
+
|
|
674
|
+
// Use direct encode path when possible
|
|
675
|
+
if (canDirectEncode(options)) {
|
|
676
|
+
const writer = new U8Bl(destination)
|
|
677
|
+
directEncode(writer, data, options, undefined)
|
|
678
|
+
return { written: writer.toBytes().length }
|
|
679
|
+
}
|
|
680
|
+
|
|
532
681
|
const result = encodeCustom(data, cborEncoders, options, destination)
|
|
533
682
|
return { written: result.length }
|
|
534
683
|
}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"3string.d.ts","sourceRoot":"","sources":["../../lib/3string.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"3string.d.ts","sourceRoot":"","sources":["../../lib/3string.js"],"names":[],"mappings":"AA2DA;;;;;;GAMG;AACH,0CANW,UAAU,OACV,MAAM,SACN,MAAM,WACN,aAAa,GACX,KAAK,CAIjB;AAED;;;;;;GAMG;AACH,oCANW,UAAU,OACV,MAAM,UACN,MAAM,WACN,aAAa,GACX,KAAK,CAIjB;AAED;;;;;;GAMG;AACH,qCANW,UAAU,OACV,MAAM,UACN,MAAM,WACN,aAAa,GACX,KAAK,CAIjB;AAED;;;;;;GAMG;AACH,qCANW,UAAU,OACV,MAAM,UACN,MAAM,WACN,aAAa,GACX,KAAK,CAIjB;AAGD;;;;;;GAMG;AACH,qCANW,UAAU,OACV,MAAM,UACN,MAAM,WACN,aAAa,GACX,KAAK,CAQjB;AAED,8CAAuC;yBA1G1B,OAAO,cAAc,EAAE,UAAU;4BACjC,OAAO,cAAc,EAAE,aAAa;sBAdrB,YAAY;4BAGZ,aAAa"}
|
package/types/lib/7float.d.ts
CHANGED
|
@@ -53,6 +53,15 @@ export namespace encodeFloat {
|
|
|
53
53
|
function encodedSize(token: Token, options: EncodeOptions): number;
|
|
54
54
|
let compareTokens: (tok1: Token, tok2: Token) => number;
|
|
55
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* @typedef {import('../interface').ByteWriter} ByteWriter
|
|
58
|
+
* @typedef {import('../interface').DecodeOptions} DecodeOptions
|
|
59
|
+
* @typedef {import('../interface').EncodeOptions} EncodeOptions
|
|
60
|
+
*/
|
|
61
|
+
export const MINOR_FALSE: 20;
|
|
62
|
+
export const MINOR_TRUE: 21;
|
|
63
|
+
export const MINOR_NULL: 22;
|
|
64
|
+
export const MINOR_UNDEFINED: 23;
|
|
56
65
|
export type ByteWriter = import("../interface").ByteWriter;
|
|
57
66
|
export type DecodeOptions = import("../interface").DecodeOptions;
|
|
58
67
|
export type EncodeOptions = import("../interface").EncodeOptions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"7float.d.ts","sourceRoot":"","sources":["../../lib/7float.js"],"names":[],"mappings":"AAkBA;;;;;;GAMG;AACH,uCANW,UAAU,QACV,MAAM,UACN,MAAM,WACN,aAAa,GACX,KAAK,CASjB;AAED;;;;;;GAMG;AACH,mCANW,UAAU,QACV,MAAM,UACN,MAAM,WACN,aAAa,GACX,KAAK,CAOjB;AAoBD;;;;;;GAMG;AACH,oCANW,UAAU,OACV,MAAM,UACN,MAAM,WACN,aAAa,GACX,KAAK,CAIjB;AAED;;;;;;GAMG;AACH,oCANW,UAAU,OACV,MAAM,UACN,MAAM,WACN,aAAa,GACX,KAAK,CAIjB;AAED;;;;;;GAMG;AACH,oCANW,UAAU,OACV,MAAM,UACN,MAAM,WACN,aAAa,GACX,KAAK,CAIjB;AAED;;;;GAIG;AACH,oCAJW,UAAU,SACV,KAAK,WACL,aAAa,QAwCvB;;IAED;;;;OAIG;IACH,4BAJW,KAAK,WACL,aAAa,GACX,MAAM,CAsBlB;;;
|
|
1
|
+
{"version":3,"file":"7float.d.ts","sourceRoot":"","sources":["../../lib/7float.js"],"names":[],"mappings":"AAkBA;;;;;;GAMG;AACH,uCANW,UAAU,QACV,MAAM,UACN,MAAM,WACN,aAAa,GACX,KAAK,CASjB;AAED;;;;;;GAMG;AACH,mCANW,UAAU,QACV,MAAM,UACN,MAAM,WACN,aAAa,GACX,KAAK,CAOjB;AAoBD;;;;;;GAMG;AACH,oCANW,UAAU,OACV,MAAM,UACN,MAAM,WACN,aAAa,GACX,KAAK,CAIjB;AAED;;;;;;GAMG;AACH,oCANW,UAAU,OACV,MAAM,UACN,MAAM,WACN,aAAa,GACX,KAAK,CAIjB;AAED;;;;;;GAMG;AACH,oCANW,UAAU,OACV,MAAM,UACN,MAAM,WACN,aAAa,GACX,KAAK,CAIjB;AAED;;;;GAIG;AACH,oCAJW,UAAU,SACV,KAAK,WACL,aAAa,QAwCvB;;IAED;;;;OAIG;IACH,4BAJW,KAAK,WACL,aAAa,GACX,MAAM,CAsBlB;;;AAlKD;;;;GAIG;AAEH,0BAA2B,EAAE,CAAA;AAC7B,yBAA0B,EAAE,CAAA;AAC5B,yBAA0B,EAAE,CAAA;AAC5B,8BAA+B,EAAE,CAAA;yBARpB,OAAO,cAAc,EAAE,UAAU;4BACjC,OAAO,cAAc,EAAE,aAAa;4BACpC,OAAO,cAAc,EAAE,aAAa;sBAPrB,YAAY"}
|
|
@@ -15,12 +15,6 @@ export function compare(b1: Uint8Array, b2: Uint8Array): number;
|
|
|
15
15
|
*/
|
|
16
16
|
export function decodeCodePointsArray(codePoints: number[]): string;
|
|
17
17
|
export const useBuffer: boolean;
|
|
18
|
-
/**
|
|
19
|
-
* @param {Uint8Array} bytes
|
|
20
|
-
* @param {number} start
|
|
21
|
-
* @param {number} end
|
|
22
|
-
*/
|
|
23
|
-
export function toString(bytes: Uint8Array, start: number, end: number): string;
|
|
24
18
|
export const fromString: ((string: string) => number[] | Buffer<ArrayBuffer>) | ((string: string) => number[] | Uint8Array<ArrayBuffer>);
|
|
25
19
|
export function fromArray(arr: number[]): Uint8Array;
|
|
26
20
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"byte-utils.d.ts","sourceRoot":"","sources":["../../lib/byte-utils.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"byte-utils.d.ts","sourceRoot":"","sources":["../../lib/byte-utils.js"],"names":[],"mappings":"AAuBA;;;GAGG;AACH,2BAHW,UAAU,GAAC,MAAM,EAAE,GACjB,UAAU,CAQtB;AAoMD;;;;GAIG;AACH,4BAJW,UAAU,MACV,UAAU,GACR,MAAM,CAgBlB;AA6CD;;;GAGG;AACH,kDAHW,MAAM,EAAE,GACN,MAAM,CAkBlB;AArTD,gCAMkD;AAyBlD,mCAGe,MAAM,iDAYN,MAAM,yCAIhB;AAOE,+BAHI,MAAM,EAAE,GACN,UAAU,CAItB;AAIG;;;;GAIG;AAEH,6BALW,UAAU,SACV,MAAM,OACN,MAAM,2BAQhB;AAcD;;;;GAIG;AACH,+BAJW,UAAU,EAAE,UACZ,MAAM,GACJ,UAAU,CActB;AAwBD;;;GAGG;AACH,4BAHW,MAAM,GACJ,UAAU,CAMtB;AAaD;;;GAGG;AACH,yBAHW,UAAU,GACR,MAAM,CAQlB;AAiBH;;;GAGG;AACD,6BAHS,MAAM,GAAC,UAAU,GACf,UAAU,CAQpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encode.d.ts","sourceRoot":"","sources":["../../lib/encode.js"],"names":[],"mappings":"AAwCA,oCAAoC;AACpC,oCADc,gBAAgB,EAAE,CAY/B;AAnBD,4BAA4B;AAC5B,mCADW,aAAa,CAKtB;sBA+XW,KAAK,GAAG;IAAE,SAAS,CAAC,EAAE,UAAU,CAAA;CAAE;4BApZlC,OAAO,cAAc,EAAE,aAAa;kCACpC,OAAO,cAAc,EAAE,mBAAmB;wBAC1C,OAAO,cAAc,EAAE,SAAS;gCAChC,OAAO,cAAc,EAAE,iBAAiB;+BACxC,OAAO,cAAc,EAAE,gBAAgB;kCACvC,OAAO,cAAc,EAAE,mBAAmB;yBAC1C,OAAO,cAAc,EAAE,UAAU;AA0R9C;;;;;GAKG;AACH,oCALW,GAAG,YACH,aAAa,aACb,SAAS,GACP,mBAAmB,CAgB/B;
|
|
1
|
+
{"version":3,"file":"encode.d.ts","sourceRoot":"","sources":["../../lib/encode.js"],"names":[],"mappings":"AAwCA,oCAAoC;AACpC,oCADc,gBAAgB,EAAE,CAY/B;AAnBD,4BAA4B;AAC5B,mCADW,aAAa,CAKtB;sBA+XW,KAAK,GAAG;IAAE,SAAS,CAAC,EAAE,UAAU,CAAA;CAAE;4BApZlC,OAAO,cAAc,EAAE,aAAa;kCACpC,OAAO,cAAc,EAAE,mBAAmB;wBAC1C,OAAO,cAAc,EAAE,SAAS;gCAChC,OAAO,cAAc,EAAE,iBAAiB;+BACxC,OAAO,cAAc,EAAE,gBAAgB;kCACvC,OAAO,cAAc,EAAE,mBAAmB;yBAC1C,OAAO,cAAc,EAAE,UAAU;AA0R9C;;;;;GAKG;AACH,oCALW,GAAG,YACH,aAAa,aACb,SAAS,GACP,mBAAmB,CAgB/B;AAiUD;;;;GAIG;AACH,6BAJW,GAAG,YACH,aAAa,GACX,UAAU,CAatB;AA3DD;;;;;;GAMG;AACH,mCANW,GAAG,YACH,gBAAgB,EAAE,WAClB,aAAa,gBACb,UAAU,GACR,UAAU,CAoCtB;AAoBD;;;;;GAKG;AACH,iCALW,GAAG,eACH,UAAU,YACV,aAAa,GACX;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAc/B;AAhnBD,8BAA8B;AAC9B,4BADiB,SAAS;IA0BxB;;;;OAIG;IACH,0BAJW,SAAS,GAAC,SAAS,OACnB,MAAM,GAAC,GAAG,EAAE,GACV,SAAS,CAOrB;IAlCD;;;OAGG;IACH,iBAHW,MAAM,GAAC,GAAG,EAAE,UACZ,SAAS,GAAC,SAAS,EAK7B;IAFC,oBAAc;IACd,qDAAoB;IAGtB;;;OAGG;IACH,cAHW,MAAM,GAAC,GAAG,EAAE,GACV,OAAO,CAWnB;CAaF;sBA9F2B,YAAY"}
|