From 43f64032c2dae6d019a3c6e52e06431d7ed9423c Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Thu, 21 Nov 2024 17:42:03 -0500 Subject: [PATCH 1/7] Revert "perf(NODE-6356): Improve serialization performance (#709)" This reverts commit 61537f54b8e3816e943ca1b7a164327e5d812f57. --- src/bson_value.ts | 3 +- src/constants.ts | 3 - src/decimal128.ts | 2 +- src/extended_json.ts | 5 +- src/parser/calculate_size.ts | 2 +- src/parser/serializer.ts | 384 +++++++++++++++++------------------ src/parser/utils.ts | 52 +---- 7 files changed, 202 insertions(+), 249 deletions(-) diff --git a/src/bson_value.ts b/src/bson_value.ts index 10d501412..069764d8c 100644 --- a/src/bson_value.ts +++ b/src/bson_value.ts @@ -1,6 +1,5 @@ import { BSON_MAJOR_VERSION } from './constants'; import { type InspectFn } from './parser/utils'; -import { BSON_VERSION_SYMBOL } from './constants'; /** @public */ export abstract class BSONValue { @@ -8,7 +7,7 @@ export abstract class BSONValue { public abstract get _bsontype(): string; /** @internal */ - get [BSON_VERSION_SYMBOL](): typeof BSON_MAJOR_VERSION { + get [Symbol.for('@@mdb.bson.version')](): typeof BSON_MAJOR_VERSION { return BSON_MAJOR_VERSION; } diff --git a/src/constants.ts b/src/constants.ts index c399fda39..7f273948b 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,9 +1,6 @@ /** @internal */ export const BSON_MAJOR_VERSION = 6; -/** @internal */ -export const BSON_VERSION_SYMBOL = Symbol.for('@@mdb.bson.version'); - /** @internal */ export const BSON_INT32_MAX = 0x7fffffff; /** @internal */ diff --git a/src/decimal128.ts b/src/decimal128.ts index 8f491b3ce..806938e30 100644 --- a/src/decimal128.ts +++ b/src/decimal128.ts @@ -142,7 +142,7 @@ export class Decimal128 extends BSONValue { super(); if (typeof bytes === 'string') { this.bytes = Decimal128.fromString(bytes).bytes; - } else if (bytes instanceof Uint8Array || isUint8Array(bytes)) { + } else if (isUint8Array(bytes)) { if (bytes.byteLength !== 16) { throw new BSONError('Decimal128 must take a Buffer of 16 bytes'); } diff --git a/src/extended_json.ts b/src/extended_json.ts index 7727ce93c..eb08b3c1f 100644 --- a/src/extended_json.ts +++ b/src/extended_json.ts @@ -6,8 +6,7 @@ import { BSON_INT32_MIN, BSON_INT64_MAX, BSON_INT64_MIN, - BSON_MAJOR_VERSION, - BSON_VERSION_SYMBOL + BSON_MAJOR_VERSION } from './constants'; import { DBRef, isDBRefLike } from './db_ref'; import { Decimal128 } from './decimal128'; @@ -359,7 +358,7 @@ function serializeDocument(doc: any, options: EJSONSerializeOptions) { doc != null && typeof doc === 'object' && typeof doc._bsontype === 'string' && - doc[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION + doc[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION ) { throw new BSONVersionError(); } else if (isBSONType(doc)) { diff --git a/src/parser/calculate_size.ts b/src/parser/calculate_size.ts index 923beeb0b..fd1e4a029 100644 --- a/src/parser/calculate_size.ts +++ b/src/parser/calculate_size.ts @@ -81,7 +81,7 @@ function calculateElement( if ( value != null && typeof value._bsontype === 'string' && - value[constants.BSON_VERSION_SYMBOL] !== constants.BSON_MAJOR_VERSION + value[Symbol.for('@@mdb.bson.version')] !== constants.BSON_MAJOR_VERSION ) { throw new BSONVersionError(); } else if (value == null || value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { diff --git a/src/parser/serializer.ts b/src/parser/serializer.ts index 787bfa8af..11762df18 100644 --- a/src/parser/serializer.ts +++ b/src/parser/serializer.ts @@ -637,81 +637,77 @@ export function serializeInto( value = value.toBSON(); } - // Check the type of the value - const type = typeof value; - - if (value === undefined) { - index = serializeNull(buffer, key, value, index); - } else if (value === null) { - index = serializeNull(buffer, key, value, index); - } else if (type === 'string') { + if (typeof value === 'string') { index = serializeString(buffer, key, value, index); - } else if (type === 'number') { + } else if (typeof value === 'number') { index = serializeNumber(buffer, key, value, index); - } else if (type === 'bigint') { + } else if (typeof value === 'bigint') { index = serializeBigInt(buffer, key, value, index); - } else if (type === 'boolean') { + } else if (typeof value === 'boolean') { index = serializeBoolean(buffer, key, value, index); - } else if (type === 'object' && value._bsontype == null) { - if (value instanceof Date || isDate(value)) { - index = serializeDate(buffer, key, value, index); - } else if (value instanceof Uint8Array || isUint8Array(value)) { - index = serializeBuffer(buffer, key, value, index); - } else if (value instanceof RegExp || isRegExp(value)) { - index = serializeRegExp(buffer, key, value, index); - } else { - index = serializeObject( - buffer, - key, - value, - index, - checkKeys, - depth, - serializeFunctions, - ignoreUndefined, - path - ); - } - } else if (type === 'object') { - if (value[constants.BSON_VERSION_SYMBOL] !== constants.BSON_MAJOR_VERSION) { - throw new BSONVersionError(); - } else if (value._bsontype === 'ObjectId') { - index = serializeObjectId(buffer, key, value, index); - } else if (value._bsontype === 'Decimal128') { - index = serializeDecimal128(buffer, key, value, index); - } else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') { - index = serializeLong(buffer, key, value, index); - } else if (value._bsontype === 'Double') { - index = serializeDouble(buffer, key, value, index); - } else if (value._bsontype === 'Code') { - index = serializeCode( - buffer, - key, - value, - index, - checkKeys, - depth, - serializeFunctions, - ignoreUndefined, - path - ); - } else if (value._bsontype === 'Binary') { - index = serializeBinary(buffer, key, value, index); - } else if (value._bsontype === 'BSONSymbol') { - index = serializeSymbol(buffer, key, value, index); - } else if (value._bsontype === 'DBRef') { - index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path); - } else if (value._bsontype === 'BSONRegExp') { - index = serializeBSONRegExp(buffer, key, value, index); - } else if (value._bsontype === 'Int32') { - index = serializeInt32(buffer, key, value, index); - } else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { - index = serializeMinMax(buffer, key, value, index); - } else if (typeof value._bsontype !== 'undefined') { - throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); - } - } else if (type === 'function' && serializeFunctions) { + } else if (value instanceof Date || isDate(value)) { + index = serializeDate(buffer, key, value, index); + } else if (value === undefined) { + index = serializeNull(buffer, key, value, index); + } else if (value === null) { + index = serializeNull(buffer, key, value, index); + } else if (isUint8Array(value)) { + index = serializeBuffer(buffer, key, value, index); + } else if (value instanceof RegExp || isRegExp(value)) { + index = serializeRegExp(buffer, key, value, index); + } else if (typeof value === 'object' && value._bsontype == null) { + index = serializeObject( + buffer, + key, + value, + index, + checkKeys, + depth, + serializeFunctions, + ignoreUndefined, + path + ); + } else if ( + typeof value === 'object' && + value[Symbol.for('@@mdb.bson.version')] !== constants.BSON_MAJOR_VERSION + ) { + throw new BSONVersionError(); + } else if (value._bsontype === 'ObjectId') { + index = serializeObjectId(buffer, key, value, index); + } else if (value._bsontype === 'Decimal128') { + index = serializeDecimal128(buffer, key, value, index); + } else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') { + index = serializeLong(buffer, key, value, index); + } else if (value._bsontype === 'Double') { + index = serializeDouble(buffer, key, value, index); + } else if (typeof value === 'function' && serializeFunctions) { index = serializeFunction(buffer, key, value, index); + } else if (value._bsontype === 'Code') { + index = serializeCode( + buffer, + key, + value, + index, + checkKeys, + depth, + serializeFunctions, + ignoreUndefined, + path + ); + } else if (value._bsontype === 'Binary') { + index = serializeBinary(buffer, key, value, index); + } else if (value._bsontype === 'BSONSymbol') { + index = serializeSymbol(buffer, key, value, index); + } else if (value._bsontype === 'DBRef') { + index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path); + } else if (value._bsontype === 'BSONRegExp') { + index = serializeBSONRegExp(buffer, key, value, index); + } else if (value._bsontype === 'Int32') { + index = serializeInt32(buffer, key, value, index); + } else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { + index = serializeMinMax(buffer, key, value, index); + } else if (typeof value._bsontype !== 'undefined') { + throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); } } } else if (object instanceof Map || isMap(object)) { @@ -753,11 +749,7 @@ export function serializeInto( } } - if (value === undefined) { - if (ignoreUndefined === false) index = serializeNull(buffer, key, value, index); - } else if (value === null) { - index = serializeNull(buffer, key, value, index); - } else if (type === 'string') { + if (type === 'string') { index = serializeString(buffer, key, value, index); } else if (type === 'number') { index = serializeNumber(buffer, key, value, index); @@ -765,66 +757,67 @@ export function serializeInto( index = serializeBigInt(buffer, key, value, index); } else if (type === 'boolean') { index = serializeBoolean(buffer, key, value, index); + } else if (value instanceof Date || isDate(value)) { + index = serializeDate(buffer, key, value, index); + } else if (value === null || (value === undefined && ignoreUndefined === false)) { + index = serializeNull(buffer, key, value, index); + } else if (isUint8Array(value)) { + index = serializeBuffer(buffer, key, value, index); + } else if (value instanceof RegExp || isRegExp(value)) { + index = serializeRegExp(buffer, key, value, index); } else if (type === 'object' && value._bsontype == null) { - if (value instanceof Date || isDate(value)) { - index = serializeDate(buffer, key, value, index); - } else if (value instanceof Uint8Array || isUint8Array(value)) { - index = serializeBuffer(buffer, key, value, index); - } else if (value instanceof RegExp || isRegExp(value)) { - index = serializeRegExp(buffer, key, value, index); - } else { - index = serializeObject( - buffer, - key, - value, - index, - checkKeys, - depth, - serializeFunctions, - ignoreUndefined, - path - ); - } - } else if (type === 'object') { - if (value[constants.BSON_VERSION_SYMBOL] !== constants.BSON_MAJOR_VERSION) { - throw new BSONVersionError(); - } else if (value._bsontype === 'ObjectId') { - index = serializeObjectId(buffer, key, value, index); - } else if (value._bsontype === 'Decimal128') { - index = serializeDecimal128(buffer, key, value, index); - } else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') { - index = serializeLong(buffer, key, value, index); - } else if (value._bsontype === 'Double') { - index = serializeDouble(buffer, key, value, index); - } else if (value._bsontype === 'Code') { - index = serializeCode( - buffer, - key, - value, - index, - checkKeys, - depth, - serializeFunctions, - ignoreUndefined, - path - ); - } else if (value._bsontype === 'Binary') { - index = serializeBinary(buffer, key, value, index); - } else if (value._bsontype === 'BSONSymbol') { - index = serializeSymbol(buffer, key, value, index); - } else if (value._bsontype === 'DBRef') { - index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path); - } else if (value._bsontype === 'BSONRegExp') { - index = serializeBSONRegExp(buffer, key, value, index); - } else if (value._bsontype === 'Int32') { - index = serializeInt32(buffer, key, value, index); - } else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { - index = serializeMinMax(buffer, key, value, index); - } else if (typeof value._bsontype !== 'undefined') { - throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); - } - } else if (type === 'function' && serializeFunctions) { + index = serializeObject( + buffer, + key, + value, + index, + checkKeys, + depth, + serializeFunctions, + ignoreUndefined, + path + ); + } else if ( + typeof value === 'object' && + value[Symbol.for('@@mdb.bson.version')] !== constants.BSON_MAJOR_VERSION + ) { + throw new BSONVersionError(); + } else if (value._bsontype === 'ObjectId') { + index = serializeObjectId(buffer, key, value, index); + } else if (type === 'object' && value._bsontype === 'Decimal128') { + index = serializeDecimal128(buffer, key, value, index); + } else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') { + index = serializeLong(buffer, key, value, index); + } else if (value._bsontype === 'Double') { + index = serializeDouble(buffer, key, value, index); + } else if (value._bsontype === 'Code') { + index = serializeCode( + buffer, + key, + value, + index, + checkKeys, + depth, + serializeFunctions, + ignoreUndefined, + path + ); + } else if (typeof value === 'function' && serializeFunctions) { index = serializeFunction(buffer, key, value, index); + } else if (value._bsontype === 'Binary') { + index = serializeBinary(buffer, key, value, index); + } else if (value._bsontype === 'BSONSymbol') { + index = serializeSymbol(buffer, key, value, index); + } else if (value._bsontype === 'DBRef') { + index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path); + } else if (value._bsontype === 'BSONRegExp') { + index = serializeBSONRegExp(buffer, key, value, index); + } else if (value._bsontype === 'Int32') { + index = serializeInt32(buffer, key, value, index); + } else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { + index = serializeMinMax(buffer, key, value, index); + } else if (typeof value._bsontype !== 'undefined') { + throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); } } } else { @@ -864,11 +857,7 @@ export function serializeInto( } } - if (value === undefined) { - if (ignoreUndefined === false) index = serializeNull(buffer, key, value, index); - } else if (value === null) { - index = serializeNull(buffer, key, value, index); - } else if (type === 'string') { + if (type === 'string') { index = serializeString(buffer, key, value, index); } else if (type === 'number') { index = serializeNumber(buffer, key, value, index); @@ -876,66 +865,69 @@ export function serializeInto( index = serializeBigInt(buffer, key, value, index); } else if (type === 'boolean') { index = serializeBoolean(buffer, key, value, index); + } else if (value instanceof Date || isDate(value)) { + index = serializeDate(buffer, key, value, index); + } else if (value === undefined) { + if (ignoreUndefined === false) index = serializeNull(buffer, key, value, index); + } else if (value === null) { + index = serializeNull(buffer, key, value, index); + } else if (isUint8Array(value)) { + index = serializeBuffer(buffer, key, value, index); + } else if (value instanceof RegExp || isRegExp(value)) { + index = serializeRegExp(buffer, key, value, index); } else if (type === 'object' && value._bsontype == null) { - if (value instanceof Date || isDate(value)) { - index = serializeDate(buffer, key, value, index); - } else if (value instanceof Uint8Array || isUint8Array(value)) { - index = serializeBuffer(buffer, key, value, index); - } else if (value instanceof RegExp || isRegExp(value)) { - index = serializeRegExp(buffer, key, value, index); - } else { - index = serializeObject( - buffer, - key, - value, - index, - checkKeys, - depth, - serializeFunctions, - ignoreUndefined, - path - ); - } - } else if (type === 'object') { - if (value[constants.BSON_VERSION_SYMBOL] !== constants.BSON_MAJOR_VERSION) { - throw new BSONVersionError(); - } else if (value._bsontype === 'ObjectId') { - index = serializeObjectId(buffer, key, value, index); - } else if (value._bsontype === 'Decimal128') { - index = serializeDecimal128(buffer, key, value, index); - } else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') { - index = serializeLong(buffer, key, value, index); - } else if (value._bsontype === 'Double') { - index = serializeDouble(buffer, key, value, index); - } else if (value._bsontype === 'Code') { - index = serializeCode( - buffer, - key, - value, - index, - checkKeys, - depth, - serializeFunctions, - ignoreUndefined, - path - ); - } else if (value._bsontype === 'Binary') { - index = serializeBinary(buffer, key, value, index); - } else if (value._bsontype === 'BSONSymbol') { - index = serializeSymbol(buffer, key, value, index); - } else if (value._bsontype === 'DBRef') { - index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path); - } else if (value._bsontype === 'BSONRegExp') { - index = serializeBSONRegExp(buffer, key, value, index); - } else if (value._bsontype === 'Int32') { - index = serializeInt32(buffer, key, value, index); - } else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { - index = serializeMinMax(buffer, key, value, index); - } else if (typeof value._bsontype !== 'undefined') { - throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); - } - } else if (type === 'function' && serializeFunctions) { + index = serializeObject( + buffer, + key, + value, + index, + checkKeys, + depth, + serializeFunctions, + ignoreUndefined, + path + ); + } else if ( + typeof value === 'object' && + value[Symbol.for('@@mdb.bson.version')] !== constants.BSON_MAJOR_VERSION + ) { + throw new BSONVersionError(); + } else if (value._bsontype === 'ObjectId') { + index = serializeObjectId(buffer, key, value, index); + } else if (type === 'object' && value._bsontype === 'Decimal128') { + index = serializeDecimal128(buffer, key, value, index); + } else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') { + index = serializeLong(buffer, key, value, index); + } else if (value._bsontype === 'Double') { + index = serializeDouble(buffer, key, value, index); + } else if (value._bsontype === 'Code') { + index = serializeCode( + buffer, + key, + value, + index, + checkKeys, + depth, + serializeFunctions, + ignoreUndefined, + path + ); + } else if (typeof value === 'function' && serializeFunctions) { index = serializeFunction(buffer, key, value, index); + } else if (value._bsontype === 'Binary') { + index = serializeBinary(buffer, key, value, index); + } else if (value._bsontype === 'BSONSymbol') { + index = serializeSymbol(buffer, key, value, index); + } else if (value._bsontype === 'DBRef') { + index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path); + } else if (value._bsontype === 'BSONRegExp') { + index = serializeBSONRegExp(buffer, key, value, index); + } else if (value._bsontype === 'Int32') { + index = serializeInt32(buffer, key, value, index); + } else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { + index = serializeMinMax(buffer, key, value, index); + } else if (typeof value._bsontype !== 'undefined') { + throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); } } } diff --git a/src/parser/utils.ts b/src/parser/utils.ts index a404eb4b7..0b27249ee 100644 --- a/src/parser/utils.ts +++ b/src/parser/utils.ts @@ -1,65 +1,31 @@ -const map = new WeakMap(); - -const TYPES = { - ArrayBuffer: '[object ArrayBuffer]', - SharedArrayBuffer: '[object SharedArrayBuffer]', - Uint8Array: '[object Uint8Array]', - BigInt64Array: '[object BigInt64Array]', - BigUint64Array: '[object BigUint64Array]', - RegExp: '[object RegExp]', - Map: '[object Map]', - Date: '[object Date]' -}; - -/** - * Retrieves the prototype.toString() of a value. - * If the value is an object, it will cache the result in a WeakMap for future use. - */ -function getPrototypeString(value: unknown): string { - let str = map.get(value as object); - - if (!str) { - str = Object.prototype.toString.call(value); - if (value !== null && typeof value === 'object') { - map.set(value, str); - } - } - return str; -} - export function isAnyArrayBuffer(value: unknown): value is ArrayBuffer { - const type = getPrototypeString(value); - return type === TYPES.ArrayBuffer || type === TYPES.SharedArrayBuffer; + return ['[object ArrayBuffer]', '[object SharedArrayBuffer]'].includes( + Object.prototype.toString.call(value) + ); } export function isUint8Array(value: unknown): value is Uint8Array { - const type = getPrototypeString(value); - return type === TYPES.Uint8Array; + return Object.prototype.toString.call(value) === '[object Uint8Array]'; } export function isBigInt64Array(value: unknown): value is BigInt64Array { - const type = getPrototypeString(value); - return type === TYPES.BigInt64Array; + return Object.prototype.toString.call(value) === '[object BigInt64Array]'; } export function isBigUInt64Array(value: unknown): value is BigUint64Array { - const type = getPrototypeString(value); - return type === TYPES.BigUint64Array; + return Object.prototype.toString.call(value) === '[object BigUint64Array]'; } export function isRegExp(d: unknown): d is RegExp { - const type = getPrototypeString(d); - return type === TYPES.RegExp; + return Object.prototype.toString.call(d) === '[object RegExp]'; } export function isMap(d: unknown): d is Map { - const type = getPrototypeString(d); - return type === TYPES.Map; + return Object.prototype.toString.call(d) === '[object Map]'; } export function isDate(d: unknown): d is Date { - const type = getPrototypeString(d); - return type === TYPES.Date; + return Object.prototype.toString.call(d) === '[object Date]'; } export type InspectFn = (x: unknown, options?: unknown) => string; From e251a8a96550b31ae879afb3a78c73c839a85c85 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Fri, 22 Nov 2024 12:22:15 -0500 Subject: [PATCH 2/7] chore: keep condition improvement --- src/bson_value.ts | 3 +- src/constants.ts | 3 + src/decimal128.ts | 2 +- src/extended_json.ts | 5 +- src/parser/calculate_size.ts | 2 +- src/parser/serializer.ts | 384 ++++++++++++++++++----------------- 6 files changed, 206 insertions(+), 193 deletions(-) diff --git a/src/bson_value.ts b/src/bson_value.ts index 069764d8c..10d501412 100644 --- a/src/bson_value.ts +++ b/src/bson_value.ts @@ -1,5 +1,6 @@ import { BSON_MAJOR_VERSION } from './constants'; import { type InspectFn } from './parser/utils'; +import { BSON_VERSION_SYMBOL } from './constants'; /** @public */ export abstract class BSONValue { @@ -7,7 +8,7 @@ export abstract class BSONValue { public abstract get _bsontype(): string; /** @internal */ - get [Symbol.for('@@mdb.bson.version')](): typeof BSON_MAJOR_VERSION { + get [BSON_VERSION_SYMBOL](): typeof BSON_MAJOR_VERSION { return BSON_MAJOR_VERSION; } diff --git a/src/constants.ts b/src/constants.ts index 7f273948b..c399fda39 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,6 +1,9 @@ /** @internal */ export const BSON_MAJOR_VERSION = 6; +/** @internal */ +export const BSON_VERSION_SYMBOL = Symbol.for('@@mdb.bson.version'); + /** @internal */ export const BSON_INT32_MAX = 0x7fffffff; /** @internal */ diff --git a/src/decimal128.ts b/src/decimal128.ts index 806938e30..8f491b3ce 100644 --- a/src/decimal128.ts +++ b/src/decimal128.ts @@ -142,7 +142,7 @@ export class Decimal128 extends BSONValue { super(); if (typeof bytes === 'string') { this.bytes = Decimal128.fromString(bytes).bytes; - } else if (isUint8Array(bytes)) { + } else if (bytes instanceof Uint8Array || isUint8Array(bytes)) { if (bytes.byteLength !== 16) { throw new BSONError('Decimal128 must take a Buffer of 16 bytes'); } diff --git a/src/extended_json.ts b/src/extended_json.ts index eb08b3c1f..7727ce93c 100644 --- a/src/extended_json.ts +++ b/src/extended_json.ts @@ -6,7 +6,8 @@ import { BSON_INT32_MIN, BSON_INT64_MAX, BSON_INT64_MIN, - BSON_MAJOR_VERSION + BSON_MAJOR_VERSION, + BSON_VERSION_SYMBOL } from './constants'; import { DBRef, isDBRefLike } from './db_ref'; import { Decimal128 } from './decimal128'; @@ -358,7 +359,7 @@ function serializeDocument(doc: any, options: EJSONSerializeOptions) { doc != null && typeof doc === 'object' && typeof doc._bsontype === 'string' && - doc[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION + doc[BSON_VERSION_SYMBOL] !== BSON_MAJOR_VERSION ) { throw new BSONVersionError(); } else if (isBSONType(doc)) { diff --git a/src/parser/calculate_size.ts b/src/parser/calculate_size.ts index fd1e4a029..923beeb0b 100644 --- a/src/parser/calculate_size.ts +++ b/src/parser/calculate_size.ts @@ -81,7 +81,7 @@ function calculateElement( if ( value != null && typeof value._bsontype === 'string' && - value[Symbol.for('@@mdb.bson.version')] !== constants.BSON_MAJOR_VERSION + value[constants.BSON_VERSION_SYMBOL] !== constants.BSON_MAJOR_VERSION ) { throw new BSONVersionError(); } else if (value == null || value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { diff --git a/src/parser/serializer.ts b/src/parser/serializer.ts index 11762df18..787bfa8af 100644 --- a/src/parser/serializer.ts +++ b/src/parser/serializer.ts @@ -637,77 +637,81 @@ export function serializeInto( value = value.toBSON(); } - if (typeof value === 'string') { + // Check the type of the value + const type = typeof value; + + if (value === undefined) { + index = serializeNull(buffer, key, value, index); + } else if (value === null) { + index = serializeNull(buffer, key, value, index); + } else if (type === 'string') { index = serializeString(buffer, key, value, index); - } else if (typeof value === 'number') { + } else if (type === 'number') { index = serializeNumber(buffer, key, value, index); - } else if (typeof value === 'bigint') { + } else if (type === 'bigint') { index = serializeBigInt(buffer, key, value, index); - } else if (typeof value === 'boolean') { + } else if (type === 'boolean') { index = serializeBoolean(buffer, key, value, index); - } else if (value instanceof Date || isDate(value)) { - index = serializeDate(buffer, key, value, index); - } else if (value === undefined) { - index = serializeNull(buffer, key, value, index); - } else if (value === null) { - index = serializeNull(buffer, key, value, index); - } else if (isUint8Array(value)) { - index = serializeBuffer(buffer, key, value, index); - } else if (value instanceof RegExp || isRegExp(value)) { - index = serializeRegExp(buffer, key, value, index); - } else if (typeof value === 'object' && value._bsontype == null) { - index = serializeObject( - buffer, - key, - value, - index, - checkKeys, - depth, - serializeFunctions, - ignoreUndefined, - path - ); - } else if ( - typeof value === 'object' && - value[Symbol.for('@@mdb.bson.version')] !== constants.BSON_MAJOR_VERSION - ) { - throw new BSONVersionError(); - } else if (value._bsontype === 'ObjectId') { - index = serializeObjectId(buffer, key, value, index); - } else if (value._bsontype === 'Decimal128') { - index = serializeDecimal128(buffer, key, value, index); - } else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') { - index = serializeLong(buffer, key, value, index); - } else if (value._bsontype === 'Double') { - index = serializeDouble(buffer, key, value, index); - } else if (typeof value === 'function' && serializeFunctions) { + } else if (type === 'object' && value._bsontype == null) { + if (value instanceof Date || isDate(value)) { + index = serializeDate(buffer, key, value, index); + } else if (value instanceof Uint8Array || isUint8Array(value)) { + index = serializeBuffer(buffer, key, value, index); + } else if (value instanceof RegExp || isRegExp(value)) { + index = serializeRegExp(buffer, key, value, index); + } else { + index = serializeObject( + buffer, + key, + value, + index, + checkKeys, + depth, + serializeFunctions, + ignoreUndefined, + path + ); + } + } else if (type === 'object') { + if (value[constants.BSON_VERSION_SYMBOL] !== constants.BSON_MAJOR_VERSION) { + throw new BSONVersionError(); + } else if (value._bsontype === 'ObjectId') { + index = serializeObjectId(buffer, key, value, index); + } else if (value._bsontype === 'Decimal128') { + index = serializeDecimal128(buffer, key, value, index); + } else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') { + index = serializeLong(buffer, key, value, index); + } else if (value._bsontype === 'Double') { + index = serializeDouble(buffer, key, value, index); + } else if (value._bsontype === 'Code') { + index = serializeCode( + buffer, + key, + value, + index, + checkKeys, + depth, + serializeFunctions, + ignoreUndefined, + path + ); + } else if (value._bsontype === 'Binary') { + index = serializeBinary(buffer, key, value, index); + } else if (value._bsontype === 'BSONSymbol') { + index = serializeSymbol(buffer, key, value, index); + } else if (value._bsontype === 'DBRef') { + index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path); + } else if (value._bsontype === 'BSONRegExp') { + index = serializeBSONRegExp(buffer, key, value, index); + } else if (value._bsontype === 'Int32') { + index = serializeInt32(buffer, key, value, index); + } else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { + index = serializeMinMax(buffer, key, value, index); + } else if (typeof value._bsontype !== 'undefined') { + throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); + } + } else if (type === 'function' && serializeFunctions) { index = serializeFunction(buffer, key, value, index); - } else if (value._bsontype === 'Code') { - index = serializeCode( - buffer, - key, - value, - index, - checkKeys, - depth, - serializeFunctions, - ignoreUndefined, - path - ); - } else if (value._bsontype === 'Binary') { - index = serializeBinary(buffer, key, value, index); - } else if (value._bsontype === 'BSONSymbol') { - index = serializeSymbol(buffer, key, value, index); - } else if (value._bsontype === 'DBRef') { - index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path); - } else if (value._bsontype === 'BSONRegExp') { - index = serializeBSONRegExp(buffer, key, value, index); - } else if (value._bsontype === 'Int32') { - index = serializeInt32(buffer, key, value, index); - } else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { - index = serializeMinMax(buffer, key, value, index); - } else if (typeof value._bsontype !== 'undefined') { - throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); } } } else if (object instanceof Map || isMap(object)) { @@ -749,7 +753,11 @@ export function serializeInto( } } - if (type === 'string') { + if (value === undefined) { + if (ignoreUndefined === false) index = serializeNull(buffer, key, value, index); + } else if (value === null) { + index = serializeNull(buffer, key, value, index); + } else if (type === 'string') { index = serializeString(buffer, key, value, index); } else if (type === 'number') { index = serializeNumber(buffer, key, value, index); @@ -757,67 +765,66 @@ export function serializeInto( index = serializeBigInt(buffer, key, value, index); } else if (type === 'boolean') { index = serializeBoolean(buffer, key, value, index); - } else if (value instanceof Date || isDate(value)) { - index = serializeDate(buffer, key, value, index); - } else if (value === null || (value === undefined && ignoreUndefined === false)) { - index = serializeNull(buffer, key, value, index); - } else if (isUint8Array(value)) { - index = serializeBuffer(buffer, key, value, index); - } else if (value instanceof RegExp || isRegExp(value)) { - index = serializeRegExp(buffer, key, value, index); } else if (type === 'object' && value._bsontype == null) { - index = serializeObject( - buffer, - key, - value, - index, - checkKeys, - depth, - serializeFunctions, - ignoreUndefined, - path - ); - } else if ( - typeof value === 'object' && - value[Symbol.for('@@mdb.bson.version')] !== constants.BSON_MAJOR_VERSION - ) { - throw new BSONVersionError(); - } else if (value._bsontype === 'ObjectId') { - index = serializeObjectId(buffer, key, value, index); - } else if (type === 'object' && value._bsontype === 'Decimal128') { - index = serializeDecimal128(buffer, key, value, index); - } else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') { - index = serializeLong(buffer, key, value, index); - } else if (value._bsontype === 'Double') { - index = serializeDouble(buffer, key, value, index); - } else if (value._bsontype === 'Code') { - index = serializeCode( - buffer, - key, - value, - index, - checkKeys, - depth, - serializeFunctions, - ignoreUndefined, - path - ); - } else if (typeof value === 'function' && serializeFunctions) { + if (value instanceof Date || isDate(value)) { + index = serializeDate(buffer, key, value, index); + } else if (value instanceof Uint8Array || isUint8Array(value)) { + index = serializeBuffer(buffer, key, value, index); + } else if (value instanceof RegExp || isRegExp(value)) { + index = serializeRegExp(buffer, key, value, index); + } else { + index = serializeObject( + buffer, + key, + value, + index, + checkKeys, + depth, + serializeFunctions, + ignoreUndefined, + path + ); + } + } else if (type === 'object') { + if (value[constants.BSON_VERSION_SYMBOL] !== constants.BSON_MAJOR_VERSION) { + throw new BSONVersionError(); + } else if (value._bsontype === 'ObjectId') { + index = serializeObjectId(buffer, key, value, index); + } else if (value._bsontype === 'Decimal128') { + index = serializeDecimal128(buffer, key, value, index); + } else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') { + index = serializeLong(buffer, key, value, index); + } else if (value._bsontype === 'Double') { + index = serializeDouble(buffer, key, value, index); + } else if (value._bsontype === 'Code') { + index = serializeCode( + buffer, + key, + value, + index, + checkKeys, + depth, + serializeFunctions, + ignoreUndefined, + path + ); + } else if (value._bsontype === 'Binary') { + index = serializeBinary(buffer, key, value, index); + } else if (value._bsontype === 'BSONSymbol') { + index = serializeSymbol(buffer, key, value, index); + } else if (value._bsontype === 'DBRef') { + index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path); + } else if (value._bsontype === 'BSONRegExp') { + index = serializeBSONRegExp(buffer, key, value, index); + } else if (value._bsontype === 'Int32') { + index = serializeInt32(buffer, key, value, index); + } else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { + index = serializeMinMax(buffer, key, value, index); + } else if (typeof value._bsontype !== 'undefined') { + throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); + } + } else if (type === 'function' && serializeFunctions) { index = serializeFunction(buffer, key, value, index); - } else if (value._bsontype === 'Binary') { - index = serializeBinary(buffer, key, value, index); - } else if (value._bsontype === 'BSONSymbol') { - index = serializeSymbol(buffer, key, value, index); - } else if (value._bsontype === 'DBRef') { - index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path); - } else if (value._bsontype === 'BSONRegExp') { - index = serializeBSONRegExp(buffer, key, value, index); - } else if (value._bsontype === 'Int32') { - index = serializeInt32(buffer, key, value, index); - } else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { - index = serializeMinMax(buffer, key, value, index); - } else if (typeof value._bsontype !== 'undefined') { - throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); } } } else { @@ -857,7 +864,11 @@ export function serializeInto( } } - if (type === 'string') { + if (value === undefined) { + if (ignoreUndefined === false) index = serializeNull(buffer, key, value, index); + } else if (value === null) { + index = serializeNull(buffer, key, value, index); + } else if (type === 'string') { index = serializeString(buffer, key, value, index); } else if (type === 'number') { index = serializeNumber(buffer, key, value, index); @@ -865,69 +876,66 @@ export function serializeInto( index = serializeBigInt(buffer, key, value, index); } else if (type === 'boolean') { index = serializeBoolean(buffer, key, value, index); - } else if (value instanceof Date || isDate(value)) { - index = serializeDate(buffer, key, value, index); - } else if (value === undefined) { - if (ignoreUndefined === false) index = serializeNull(buffer, key, value, index); - } else if (value === null) { - index = serializeNull(buffer, key, value, index); - } else if (isUint8Array(value)) { - index = serializeBuffer(buffer, key, value, index); - } else if (value instanceof RegExp || isRegExp(value)) { - index = serializeRegExp(buffer, key, value, index); } else if (type === 'object' && value._bsontype == null) { - index = serializeObject( - buffer, - key, - value, - index, - checkKeys, - depth, - serializeFunctions, - ignoreUndefined, - path - ); - } else if ( - typeof value === 'object' && - value[Symbol.for('@@mdb.bson.version')] !== constants.BSON_MAJOR_VERSION - ) { - throw new BSONVersionError(); - } else if (value._bsontype === 'ObjectId') { - index = serializeObjectId(buffer, key, value, index); - } else if (type === 'object' && value._bsontype === 'Decimal128') { - index = serializeDecimal128(buffer, key, value, index); - } else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') { - index = serializeLong(buffer, key, value, index); - } else if (value._bsontype === 'Double') { - index = serializeDouble(buffer, key, value, index); - } else if (value._bsontype === 'Code') { - index = serializeCode( - buffer, - key, - value, - index, - checkKeys, - depth, - serializeFunctions, - ignoreUndefined, - path - ); - } else if (typeof value === 'function' && serializeFunctions) { + if (value instanceof Date || isDate(value)) { + index = serializeDate(buffer, key, value, index); + } else if (value instanceof Uint8Array || isUint8Array(value)) { + index = serializeBuffer(buffer, key, value, index); + } else if (value instanceof RegExp || isRegExp(value)) { + index = serializeRegExp(buffer, key, value, index); + } else { + index = serializeObject( + buffer, + key, + value, + index, + checkKeys, + depth, + serializeFunctions, + ignoreUndefined, + path + ); + } + } else if (type === 'object') { + if (value[constants.BSON_VERSION_SYMBOL] !== constants.BSON_MAJOR_VERSION) { + throw new BSONVersionError(); + } else if (value._bsontype === 'ObjectId') { + index = serializeObjectId(buffer, key, value, index); + } else if (value._bsontype === 'Decimal128') { + index = serializeDecimal128(buffer, key, value, index); + } else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') { + index = serializeLong(buffer, key, value, index); + } else if (value._bsontype === 'Double') { + index = serializeDouble(buffer, key, value, index); + } else if (value._bsontype === 'Code') { + index = serializeCode( + buffer, + key, + value, + index, + checkKeys, + depth, + serializeFunctions, + ignoreUndefined, + path + ); + } else if (value._bsontype === 'Binary') { + index = serializeBinary(buffer, key, value, index); + } else if (value._bsontype === 'BSONSymbol') { + index = serializeSymbol(buffer, key, value, index); + } else if (value._bsontype === 'DBRef') { + index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path); + } else if (value._bsontype === 'BSONRegExp') { + index = serializeBSONRegExp(buffer, key, value, index); + } else if (value._bsontype === 'Int32') { + index = serializeInt32(buffer, key, value, index); + } else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { + index = serializeMinMax(buffer, key, value, index); + } else if (typeof value._bsontype !== 'undefined') { + throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); + } + } else if (type === 'function' && serializeFunctions) { index = serializeFunction(buffer, key, value, index); - } else if (value._bsontype === 'Binary') { - index = serializeBinary(buffer, key, value, index); - } else if (value._bsontype === 'BSONSymbol') { - index = serializeSymbol(buffer, key, value, index); - } else if (value._bsontype === 'DBRef') { - index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path); - } else if (value._bsontype === 'BSONRegExp') { - index = serializeBSONRegExp(buffer, key, value, index); - } else if (value._bsontype === 'Int32') { - index = serializeInt32(buffer, key, value, index); - } else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { - index = serializeMinMax(buffer, key, value, index); - } else if (typeof value._bsontype !== 'undefined') { - throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); } } } From ced10d73bd2ff2bd0e4a78d0ff1b1ddec32bf0d8 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Fri, 22 Nov 2024 12:41:30 -0500 Subject: [PATCH 3/7] chore: remove WeakMap cache of types and use toStringTag getter --- src/parser/utils.ts | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/parser/utils.ts b/src/parser/utils.ts index 0b27249ee..c8347dd3f 100644 --- a/src/parser/utils.ts +++ b/src/parser/utils.ts @@ -1,27 +1,51 @@ export function isAnyArrayBuffer(value: unknown): value is ArrayBuffer { - return ['[object ArrayBuffer]', '[object SharedArrayBuffer]'].includes( - Object.prototype.toString.call(value) + return ( + typeof value === 'object' && + value != null && + Symbol.toStringTag in value && + (value[Symbol.toStringTag] === 'ArrayBuffer' || + value[Symbol.toStringTag] === 'SharedArrayBuffer') ); } export function isUint8Array(value: unknown): value is Uint8Array { - return Object.prototype.toString.call(value) === '[object Uint8Array]'; + return ( + typeof value === 'object' && + value != null && + Symbol.toStringTag in value && + value[Symbol.toStringTag] === 'Uint8Array' + ); } export function isBigInt64Array(value: unknown): value is BigInt64Array { - return Object.prototype.toString.call(value) === '[object BigInt64Array]'; + return ( + typeof value === 'object' && + value != null && + Symbol.toStringTag in value && + value[Symbol.toStringTag] === 'BigInt64Array' + ); } export function isBigUInt64Array(value: unknown): value is BigUint64Array { - return Object.prototype.toString.call(value) === '[object BigUint64Array]'; + return ( + typeof value === 'object' && + value != null && + Symbol.toStringTag in value && + value[Symbol.toStringTag] === 'BigUint64Array' + ); } export function isRegExp(d: unknown): d is RegExp { return Object.prototype.toString.call(d) === '[object RegExp]'; } -export function isMap(d: unknown): d is Map { - return Object.prototype.toString.call(d) === '[object Map]'; +export function isMap(value: unknown): d is Map { + return ( + typeof value === 'object' && + value != null && + Symbol.toStringTag in value && + value[Symbol.toStringTag] === 'Map' + ); } export function isDate(d: unknown): d is Date { From 8d2c0f3e08db1644e6ef6249ad146efaa116f917 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Fri, 22 Nov 2024 12:44:22 -0500 Subject: [PATCH 4/7] fix: param name --- src/parser/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser/utils.ts b/src/parser/utils.ts index c8347dd3f..986ac9ebe 100644 --- a/src/parser/utils.ts +++ b/src/parser/utils.ts @@ -39,7 +39,7 @@ export function isRegExp(d: unknown): d is RegExp { return Object.prototype.toString.call(d) === '[object RegExp]'; } -export function isMap(value: unknown): d is Map { +export function isMap(value: unknown): value is Map { return ( typeof value === 'object' && value != null && From dd11dcb0372f42f310451193d0c379f955fe4532 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Tue, 26 Nov 2024 12:13:43 -0500 Subject: [PATCH 5/7] perf: add instanceof checks --- src/parser/utils.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parser/utils.ts b/src/parser/utils.ts index 986ac9ebe..19e069f4b 100644 --- a/src/parser/utils.ts +++ b/src/parser/utils.ts @@ -35,8 +35,8 @@ export function isBigUInt64Array(value: unknown): value is BigUint64Array { ); } -export function isRegExp(d: unknown): d is RegExp { - return Object.prototype.toString.call(d) === '[object RegExp]'; +export function isRegExp(regexp: unknown): regexp is RegExp { + return regexp instanceof RegExp || Object.prototype.toString.call(regexp) === '[object RegExp]'; } export function isMap(value: unknown): value is Map { @@ -48,8 +48,8 @@ export function isMap(value: unknown): value is Map { ); } -export function isDate(d: unknown): d is Date { - return Object.prototype.toString.call(d) === '[object Date]'; +export function isDate(date: unknown): date is Date { + return date instanceof Date || Object.prototype.toString.call(date) === '[object Date]'; } export type InspectFn = (x: unknown, options?: unknown) => string; From fd2e7dd1ed569ddd13b389908fa266fba3e29b45 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Tue, 26 Nov 2024 15:25:39 -0500 Subject: [PATCH 6/7] chore: use toStringTag getter --- src/parser/utils.ts | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/src/parser/utils.ts b/src/parser/utils.ts index 19e069f4b..415988460 100644 --- a/src/parser/utils.ts +++ b/src/parser/utils.ts @@ -1,37 +1,24 @@ -export function isAnyArrayBuffer(value: unknown): value is ArrayBuffer { - return ( - typeof value === 'object' && - value != null && - Symbol.toStringTag in value && - (value[Symbol.toStringTag] === 'ArrayBuffer' || - value[Symbol.toStringTag] === 'SharedArrayBuffer') - ); -} +const TypedArrayPrototypeGetSymbolToStringTag = (() => { + // eslint-disable-next-line @typescript-eslint/unbound-method -- the intention is to call this method with a bound value + const g = Object.getOwnPropertyDescriptor( + Object.getPrototypeOf(Uint8Array.prototype), + Symbol.toStringTag + )!.get!; -export function isUint8Array(value: unknown): value is Uint8Array { - return ( - typeof value === 'object' && - value != null && - Symbol.toStringTag in value && - value[Symbol.toStringTag] === 'Uint8Array' - ); -} + return (value: unknown) => g.call(value); +})(); -export function isBigInt64Array(value: unknown): value is BigInt64Array { - return ( - typeof value === 'object' && - value != null && - Symbol.toStringTag in value && - value[Symbol.toStringTag] === 'BigInt64Array' - ); +export function isUint8Array(value: unknown): value is Uint8Array { + return TypedArrayPrototypeGetSymbolToStringTag(value) === 'Uint8Array'; } -export function isBigUInt64Array(value: unknown): value is BigUint64Array { +export function isAnyArrayBuffer(value: unknown): value is ArrayBuffer { return ( typeof value === 'object' && value != null && Symbol.toStringTag in value && - value[Symbol.toStringTag] === 'BigUint64Array' + (value[Symbol.toStringTag] === 'ArrayBuffer' || + value[Symbol.toStringTag] === 'SharedArrayBuffer') ); } From fac472e10bf6d70a8c147219aae0749c16d0337c Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Tue, 26 Nov 2024 15:41:01 -0500 Subject: [PATCH 7/7] chore: comment for reference --- src/parser/utils.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/parser/utils.ts b/src/parser/utils.ts index 415988460..2e3839910 100644 --- a/src/parser/utils.ts +++ b/src/parser/utils.ts @@ -1,4 +1,6 @@ const TypedArrayPrototypeGetSymbolToStringTag = (() => { + // Type check system lovingly referenced from: + // https://github.com/nodejs/node/blob/7450332339ed40481f470df2a3014e2ec355d8d8/lib/internal/util/types.js#L13-L15 // eslint-disable-next-line @typescript-eslint/unbound-method -- the intention is to call this method with a bound value const g = Object.getOwnPropertyDescriptor( Object.getPrototypeOf(Uint8Array.prototype),