+16
-12
@@ -8,8 +8,8 @@ /** | ||
| * Usage: | ||
| * node bench/bench-new.js # run all benchmarks (dag-cbor mode) | ||
| * node bench/bench-new.js --mode=raw # run with raw cborg (no tags) | ||
| * node bench/bench-new.js --suite=bsky # run only bluesky suite | ||
| * node bench/bench-new.js --json # output JSON for comparison | ||
| * node bench/bench-new.js --compare=baseline.json # compare to baseline | ||
| * node bench/bench-new.js --encode-into # use encodeInto instead of encode | ||
| * node bench/bench.js # run all benchmarks (dag-cbor mode) | ||
| * node bench/bench.js --mode=raw # run with raw cborg (no tags) | ||
| * node bench/bench.js --suite=bsky # run only bluesky suite | ||
| * node bench/bench.js --json=output.json # write JSON results to file | ||
| * node bench/bench.js --compare=baseline.json # compare to baseline | ||
| * node bench/bench.js --encode-into # use encodeInto instead of encode | ||
| */ | ||
@@ -133,3 +133,3 @@ | ||
| const opts = { | ||
| json: args.includes('--json'), | ||
| json: args.find(a => a.startsWith('--json='))?.split('=')[1] || null, | ||
| suite: args.find(a => a.startsWith('--suite='))?.split('=')[1] || null, | ||
@@ -189,7 +189,7 @@ compare: args.find(a => a.startsWith('--compare='))?.split('=')[1] || null, | ||
| // Output helpers | ||
| const log = opts.json ? () => {} : console.log.bind(console) | ||
| // Output helpers - always show progress to console | ||
| const log = console.log.bind(console) | ||
| const write = typeof process !== 'undefined' && process.stdout | ||
| ? (s) => process.stdout.write(s) | ||
| : (s) => log(s) | ||
| : (s) => console.log(s) | ||
@@ -370,3 +370,3 @@ /** | ||
| // JSON output | ||
| // JSON output to file | ||
| if (opts.json) { | ||
@@ -382,3 +382,7 @@ const output = { | ||
| } | ||
| console.log(JSON.stringify(output, null, 2)) | ||
| if (typeof process !== 'undefined') { | ||
| const fs = await import('fs') | ||
| fs.writeFileSync(opts.json, JSON.stringify(output, null, 2) + '\n') | ||
| log(`\nResults written to ${opts.json}`) | ||
| } | ||
| } | ||
@@ -385,0 +389,0 @@ |
+6
-0
@@ -0,1 +1,7 @@ | ||
| ## [4.5.5](https://github.com/rvagg/cborg/compare/v4.5.4...v4.5.5) (2026-01-20) | ||
| ### Trivial Changes | ||
| * **bench:** output json to file ([ca32690](https://github.com/rvagg/cborg/commit/ca326908643ce9bc2ac56dd06b6c64502b8a4f03)) | ||
| ## [4.5.4](https://github.com/rvagg/cborg/compare/v4.5.3...v4.5.4) (2026-01-20) | ||
@@ -2,0 +8,0 @@ |
+32
-2
@@ -5,4 +5,10 @@ import { Token, Type } from './token.js' | ||
| import { encodeBytes } from './2bytes.js' | ||
| import { toString, slice } from './byte-utils.js' | ||
| import { slice } from './byte-utils.js' | ||
| const textDecoder = new TextDecoder() | ||
| // Threshold for ASCII fast-path vs TextDecoder. Short ASCII strings (common for | ||
| // map keys) are faster to decode with a simple loop than TextDecoder overhead. | ||
| const ASCII_THRESHOLD = 32 | ||
| /** | ||
@@ -14,2 +20,26 @@ * @typedef {import('../interface').ByteWriter} ByteWriter | ||
| /** | ||
| * Decode UTF-8 bytes to string. For short ASCII strings (common case for map keys), | ||
| * a simple loop is faster than TextDecoder. | ||
| * @param {Uint8Array} bytes | ||
| * @param {number} start | ||
| * @param {number} end | ||
| * @returns {string} | ||
| */ | ||
| function toStr (bytes, start, end) { | ||
| const len = end - start | ||
| if (len < ASCII_THRESHOLD) { | ||
| let str = '' | ||
| for (let i = start; i < end; i++) { | ||
| const c = bytes[i] | ||
| if (c & 0x80) { // non-ASCII, fall back to TextDecoder | ||
| return textDecoder.decode(bytes.subarray(start, end)) | ||
| } | ||
| str += String.fromCharCode(c) | ||
| } | ||
| return str | ||
| } | ||
| return textDecoder.decode(bytes.subarray(start, end)) | ||
| } | ||
| /** | ||
| * @param {Uint8Array} data | ||
@@ -25,3 +55,3 @@ * @param {number} pos | ||
| assertEnoughData(data, pos, totLength) | ||
| const tok = new Token(Type.string, toString(data, pos + prefix, pos + totLength), totLength) | ||
| const tok = new Token(Type.string, toStr(data, pos + prefix, pos + totLength), totLength) | ||
| if (options.retainStringBytes === true) { | ||
@@ -28,0 +58,0 @@ tok.byteValue = slice(data, pos + prefix, pos + totLength) |
+1
-111
@@ -13,3 +13,2 @@ // Use Uint8Array directly in the browser, use Buffer in Node.js but don't | ||
| const textDecoder = new TextDecoder() | ||
| const textEncoder = new TextEncoder() | ||
@@ -38,33 +37,2 @@ | ||
| // Threshold for switching between manual utf8Slice and native TextDecoder/Buffer | ||
| // Manual decoding has overhead from array building; native is fast for strings > 32 bytes | ||
| const UTF8_THRESHOLD = 32 | ||
| export const toString = useBuffer | ||
| ? // eslint-disable-line operator-linebreak | ||
| /** | ||
| * @param {Uint8Array} bytes | ||
| * @param {number} start | ||
| * @param {number} end | ||
| */ | ||
| (bytes, start, end) => { | ||
| return end - start > UTF8_THRESHOLD | ||
| ? // eslint-disable-line operator-linebreak | ||
| // @ts-ignore | ||
| globalThis.Buffer.from(bytes.subarray(start, end)).toString('utf8') | ||
| : utf8Slice(bytes, start, end) | ||
| } | ||
| /* c8 ignore next 11 */ | ||
| : // eslint-disable-line operator-linebreak | ||
| /** | ||
| * @param {Uint8Array} bytes | ||
| * @param {number} start | ||
| * @param {number} end | ||
| */ | ||
| (bytes, start, end) => { | ||
| return end - start > UTF8_THRESHOLD | ||
| ? textDecoder.decode(bytes.subarray(start, end)) | ||
| : utf8Slice(bytes, start, end) | ||
| } | ||
| export const fromString = useBuffer | ||
@@ -107,2 +75,3 @@ ? // eslint-disable-line operator-linebreak | ||
| */ | ||
| // Buffer.slice() returns a view, not a copy, so we need special handling | ||
| (bytes, start, end) => { | ||
@@ -323,81 +292,2 @@ if (isBuffer(bytes)) { | ||
| // The below code is mostly taken from https://github.com/feross/buffer | ||
| // Licensed MIT. Copyright (c) Feross Aboukhadijeh | ||
| /** | ||
| * @param {Uint8Array} buf | ||
| * @param {number} offset | ||
| * @param {number} end | ||
| * @returns {string} | ||
| */ | ||
| function utf8Slice (buf, offset, end) { | ||
| const res = [] | ||
| while (offset < end) { | ||
| const firstByte = buf[offset] | ||
| let codePoint = null | ||
| let bytesPerSequence = (firstByte > 0xef) ? 4 : (firstByte > 0xdf) ? 3 : (firstByte > 0xbf) ? 2 : 1 | ||
| if (offset + bytesPerSequence <= end) { | ||
| let secondByte, thirdByte, fourthByte, tempCodePoint | ||
| switch (bytesPerSequence) { | ||
| case 1: | ||
| if (firstByte < 0x80) { | ||
| codePoint = firstByte | ||
| } | ||
| break | ||
| case 2: | ||
| secondByte = buf[offset + 1] | ||
| if ((secondByte & 0xc0) === 0x80) { | ||
| tempCodePoint = (firstByte & 0x1f) << 0x6 | (secondByte & 0x3f) | ||
| if (tempCodePoint > 0x7f) { | ||
| codePoint = tempCodePoint | ||
| } | ||
| } | ||
| break | ||
| case 3: | ||
| secondByte = buf[offset + 1] | ||
| thirdByte = buf[offset + 2] | ||
| if ((secondByte & 0xc0) === 0x80 && (thirdByte & 0xc0) === 0x80) { | ||
| tempCodePoint = (firstByte & 0xf) << 0xc | (secondByte & 0x3f) << 0x6 | (thirdByte & 0x3f) | ||
| /* c8 ignore next 3 */ | ||
| if (tempCodePoint > 0x7ff && (tempCodePoint < 0xd800 || tempCodePoint > 0xdfff)) { | ||
| codePoint = tempCodePoint | ||
| } | ||
| } | ||
| break | ||
| case 4: | ||
| secondByte = buf[offset + 1] | ||
| thirdByte = buf[offset + 2] | ||
| fourthByte = buf[offset + 3] | ||
| if ((secondByte & 0xc0) === 0x80 && (thirdByte & 0xc0) === 0x80 && (fourthByte & 0xc0) === 0x80) { | ||
| tempCodePoint = (firstByte & 0xf) << 0x12 | (secondByte & 0x3f) << 0xc | (thirdByte & 0x3f) << 0x6 | (fourthByte & 0x3f) | ||
| if (tempCodePoint > 0xffff && tempCodePoint < 0x110000) { | ||
| codePoint = tempCodePoint | ||
| } | ||
| } | ||
| } | ||
| } | ||
| /* c8 ignore next 5 */ | ||
| if (codePoint === null) { | ||
| // we did not generate a valid codePoint so insert a | ||
| // replacement char (U+FFFD) and advance only 1 byte | ||
| codePoint = 0xfffd | ||
| bytesPerSequence = 1 | ||
| } else if (codePoint > 0xffff) { | ||
| // encode to utf16 (surrogate pair dance) | ||
| codePoint -= 0x10000 | ||
| res.push(codePoint >>> 10 & 0x3ff | 0xd800) | ||
| codePoint = 0xdc00 | codePoint & 0x3ff | ||
| } | ||
| res.push(codePoint) | ||
| offset += bytesPerSequence | ||
| } | ||
| return decodeCodePointsArray(res) | ||
| } | ||
| // Based on http://stackoverflow.com/a/22747272/680742, the browser with | ||
@@ -404,0 +294,0 @@ // the lowest limit is Chrome, with 0x10000 args. |
+1
-1
| { | ||
| "name": "cborg", | ||
| "version": "4.5.4", | ||
| "version": "4.5.5", | ||
| "description": "Fast CBOR with a focus on strictness", | ||
@@ -5,0 +5,0 @@ "main": "cborg.js", |
@@ -18,8 +18,2 @@ /** | ||
| export const useBuffer: boolean; | ||
| /** | ||
| * @param {Uint8Array} bytes | ||
| * @param {number} start | ||
| * @param {number} end | ||
| */ | ||
| export function toString(bytes: Uint8Array, start: number, end: number): string; | ||
| export const fromString: ((string: string) => number[] | Buffer<ArrayBuffer>) | ((string: string) => number[] | Uint8Array<ArrayBuffer>); | ||
@@ -26,0 +20,0 @@ export function fromArray(arr: number[]): Uint8Array; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
13
-13.33%431969
-0.56%9565
-0.78%