+2
-0
@@ -0,1 +1,3 @@ | ||
| ## [4.5.4](https://github.com/rvagg/cborg/compare/v4.5.3...v4.5.4) (2026-01-20) | ||
| ## [4.5.3](https://github.com/rvagg/cborg/compare/v4.5.2...v4.5.3) (2026-01-20) | ||
@@ -2,0 +4,0 @@ |
+4
-4
@@ -14,6 +14,6 @@ // TODO: shift some of the bytes logic to bytes-utils so we can use Buffer | ||
| const MINOR_FALSE = 20 | ||
| const MINOR_TRUE = 21 | ||
| const MINOR_NULL = 22 | ||
| const MINOR_UNDEFINED = 23 | ||
| export const MINOR_FALSE = 20 | ||
| export const MINOR_TRUE = 21 | ||
| export const MINOR_NULL = 22 | ||
| export const MINOR_UNDEFINED = 23 | ||
@@ -20,0 +20,0 @@ /** |
+152
-3
@@ -6,5 +6,5 @@ import { is } from './is.js' | ||
| import { quickEncodeToken } from './jump.js' | ||
| import { asU8A, compare } from './byte-utils.js' | ||
| import { asU8A, compare, fromString } from './byte-utils.js' | ||
| import { encodeUint } from './0uint.js' | ||
| import { encodeUint, encodeUintValue } from './0uint.js' | ||
| import { encodeNegint } from './1negint.js' | ||
@@ -16,3 +16,3 @@ import { encodeBytes } from './2bytes.js' | ||
| import { encodeTag } from './6tag.js' | ||
| import { encodeFloat } from './7float.js' | ||
| import { encodeFloat, MINOR_FALSE, MINOR_TRUE, MINOR_NULL, MINOR_UNDEFINED } from './7float.js' | ||
@@ -473,4 +473,137 @@ /** | ||
| // CBOR major type prefixes, cached from Type for hot path performance | ||
| const MAJOR_UINT = Type.uint.majorEncoded | ||
| const MAJOR_NEGINT = Type.negint.majorEncoded | ||
| const MAJOR_BYTES = Type.bytes.majorEncoded | ||
| const MAJOR_STRING = Type.string.majorEncoded | ||
| const MAJOR_ARRAY = Type.array.majorEncoded | ||
| // Simple value bytes (CBOR major type 7 + minor value) | ||
| const SIMPLE_FALSE = Type.float.majorEncoded | MINOR_FALSE | ||
| const SIMPLE_TRUE = Type.float.majorEncoded | MINOR_TRUE | ||
| const SIMPLE_NULL = Type.float.majorEncoded | MINOR_NULL | ||
| const SIMPLE_UNDEFINED = Type.float.majorEncoded | MINOR_UNDEFINED | ||
| const neg1b = BigInt(-1) | ||
| const pos1b = BigInt(1) | ||
| /** | ||
| * Check if direct encoding can be used for the given options. | ||
| * Direct encoding bypasses token creation for most values. | ||
| * @param {EncodeOptions} options | ||
| * @returns {boolean} | ||
| */ | ||
| function canDirectEncode (options) { | ||
| // Cannot use direct encode with addBreakTokens (needs special break token handling). | ||
| // Direct encode checks typeEncoders per-value, falling back to tokens as needed. | ||
| // Maps fall back to token-based encoding for efficient key sorting. | ||
| return options.addBreakTokens !== true | ||
| } | ||
| /** | ||
| * Direct encode a value to the writer, bypassing token creation for most types. | ||
| * Falls back to token-based encoding for custom type encoders. | ||
| * @param {ByteWriter} writer | ||
| * @param {any} data | ||
| * @param {EncodeOptions} options | ||
| * @param {Reference|undefined} refStack | ||
| */ | ||
| function directEncode (writer, data, options, refStack) { | ||
| const typ = is(data) | ||
| // Check for custom encoder for THIS specific type | ||
| const customEncoder = options.typeEncoders && options.typeEncoders[typ] | ||
| if (customEncoder) { | ||
| const tokens = customEncoder(data, typ, options, refStack) | ||
| if (tokens != null) { | ||
| // Custom encoder returned tokens, serialize immediately | ||
| tokensToEncoded(writer, tokens, cborEncoders, options) | ||
| return | ||
| } | ||
| // Custom encoder returned null, fall through to default handling | ||
| } | ||
| // Direct encode based on type | ||
| switch (typ) { | ||
| case 'null': | ||
| writer.push([SIMPLE_NULL]) | ||
| return | ||
| case 'undefined': | ||
| writer.push([SIMPLE_UNDEFINED]) | ||
| return | ||
| case 'boolean': | ||
| writer.push([data ? SIMPLE_TRUE : SIMPLE_FALSE]) | ||
| return | ||
| case 'number': | ||
| if (!Number.isInteger(data) || !Number.isSafeInteger(data)) { | ||
| // Float, use token encoder for complex float encoding | ||
| encodeFloat(writer, new Token(Type.float, data), options) | ||
| } else if (data >= 0) { | ||
| encodeUintValue(writer, MAJOR_UINT, data) | ||
| } else { | ||
| // Negative integer | ||
| encodeUintValue(writer, MAJOR_NEGINT, data * -1 - 1) | ||
| } | ||
| return | ||
| case 'bigint': | ||
| if (data >= BigInt(0)) { | ||
| encodeUintValue(writer, MAJOR_UINT, data) | ||
| } else { | ||
| encodeUintValue(writer, MAJOR_NEGINT, data * neg1b - pos1b) | ||
| } | ||
| return | ||
| case 'string': { | ||
| const bytes = fromString(data) | ||
| encodeUintValue(writer, MAJOR_STRING, bytes.length) | ||
| writer.push(bytes) | ||
| return | ||
| } | ||
| case 'Uint8Array': | ||
| encodeUintValue(writer, MAJOR_BYTES, data.length) | ||
| writer.push(data) | ||
| return | ||
| case 'Array': | ||
| if (!data.length) { | ||
| writer.push([MAJOR_ARRAY]) // Empty array: 0x80 | ||
| return | ||
| } | ||
| refStack = Ref.createCheck(refStack, data) | ||
| encodeUintValue(writer, MAJOR_ARRAY, data.length) | ||
| for (const elem of data) { | ||
| directEncode(writer, elem, options, refStack) | ||
| } | ||
| return | ||
| case 'Object': | ||
| case 'Map': | ||
| // Maps require key sorting, use token-based encoding for efficiency | ||
| // (pre-encoding all keys for sorting is expensive) | ||
| { | ||
| const tokens = typeEncoders.Object(data, typ, options, refStack) | ||
| tokensToEncoded(writer, tokens, cborEncoders, options) | ||
| } | ||
| return | ||
| default: | ||
| // Fall back to token-based encoding for other types (DataView, TypedArrays, etc.) | ||
| { | ||
| const typeEncoder = typeEncoders[typ] | ||
| if (!typeEncoder) { | ||
| throw new Error(`${encodeErrPrefix} unsupported type: ${typ}`) | ||
| } | ||
| const tokens = typeEncoder(data, typ, options, refStack) | ||
| tokensToEncoded(writer, tokens, cborEncoders, options) | ||
| } | ||
| } | ||
| } | ||
| /** | ||
| * @param {any} data | ||
| * @param {TokenTypeEncoder[]} encoders | ||
@@ -524,2 +657,10 @@ * @param {EncodeOptions} options | ||
| options = Object.assign({}, defaultEncodeOptions, options) | ||
| // Use direct encode path when possible | ||
| if (canDirectEncode(options)) { | ||
| defaultWriter.reset() | ||
| directEncode(defaultWriter, data, options, undefined) | ||
| return defaultWriter.toBytes(true) | ||
| } | ||
| return encodeCustom(data, cborEncoders, options) | ||
@@ -536,2 +677,10 @@ } | ||
| options = Object.assign({}, defaultEncodeOptions, options) | ||
| // Use direct encode path when possible | ||
| if (canDirectEncode(options)) { | ||
| const writer = new U8Bl(destination) | ||
| directEncode(writer, data, options, undefined) | ||
| return { written: writer.toBytes().length } | ||
| } | ||
| const result = encodeCustom(data, cborEncoders, options, destination) | ||
@@ -538,0 +687,0 @@ return { written: result.length } |
+1
-1
| { | ||
| "name": "cborg", | ||
| "version": "4.5.3", | ||
| "version": "4.5.4", | ||
| "description": "Fast CBOR with a focus on strictness", | ||
@@ -5,0 +5,0 @@ "main": "cborg.js", |
@@ -56,2 +56,11 @@ /** | ||
| } | ||
| /** | ||
| * @typedef {import('../interface').ByteWriter} ByteWriter | ||
| * @typedef {import('../interface').DecodeOptions} DecodeOptions | ||
| * @typedef {import('../interface').EncodeOptions} EncodeOptions | ||
| */ | ||
| export const MINOR_FALSE: 20; | ||
| export const MINOR_TRUE: 21; | ||
| export const MINOR_NULL: 22; | ||
| export const MINOR_UNDEFINED: 23; | ||
| export type ByteWriter = import("../interface").ByteWriter; | ||
@@ -58,0 +67,0 @@ export type DecodeOptions = import("../interface").DecodeOptions; |
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
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
434385
1.23%9640
1.45%15
7.14%