CoolFace
Apppublic

opusdev/vector-similarity-api

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes
objectid.ts390 linesDownload Raw Back to src
1import { BSONValue } from './bson_value';2import { BSONError } from './error';3import { type InspectFn, defaultInspect } from './parser/utils';4import { ByteUtils } from './utils/byte_utils';5import { NumberUtils } from './utils/number_utils';6 7// Unique sequence for the current process (initialized on first use)8let PROCESS_UNIQUE: Uint8Array | null = null;9 10/** ObjectId hexString cache @internal */11const __idCache = new WeakMap(); // TODO(NODE-6549): convert this to #__id private field when target updated to ES202212 13/** @public */14export interface ObjectIdLike {15  id: string | Uint8Array;16  __id?: string;17  toHexString(): string;18}19 20/** @public */21export interface ObjectIdExtended {22  $oid: string;23}24 25/**26 * A class representation of the BSON ObjectId type.27 * @public28 * @category BSONType29 */30export class ObjectId extends BSONValue {31  get _bsontype(): 'ObjectId' {32    return 'ObjectId';33  }34 35  /** @internal */36  private static index = Math.floor(Math.random() * 0xffffff);37 38  static cacheHexString: boolean;39 40  /** ObjectId Bytes @internal */41  private buffer!: Uint8Array;42 43  /**44   * Create ObjectId from a number.45   *46   * @param inputId - A number.47   * @deprecated Instead, use `static createFromTime()` to set a numeric value for the new ObjectId.48   */49  constructor(inputId: number);50  /**51   * Create ObjectId from a 24 character hex string.52   *53   * @param inputId - A 24 character hex string.54   */55  constructor(inputId: string);56  /**57   * Create ObjectId from the BSON ObjectId type.58   *59   * @param inputId - The BSON ObjectId type.60   */61  constructor(inputId: ObjectId);62  /**63   * Create ObjectId from the object type that has the toHexString method.64   *65   * @param inputId - The ObjectIdLike type.66   */67  constructor(inputId: ObjectIdLike);68  /**69   * Create ObjectId from a 12 byte binary Buffer.70   *71   * @param inputId - A 12 byte binary Buffer.72   */73  constructor(inputId: Uint8Array);74  /** To generate a new ObjectId, use ObjectId() with no argument. */75  constructor();76  /**77   * Implementation overload.78   *79   * @param inputId - All input types that are used in the constructor implementation.80   */81  constructor(inputId?: string | number | ObjectId | ObjectIdLike | Uint8Array);82  /**83   * Create a new ObjectId.84   *85   * @param inputId - An input value to create a new ObjectId from.86   */87  constructor(inputId?: string | number | ObjectId | ObjectIdLike | Uint8Array) {88    super();89    // workingId is set based on type of input and whether valid id exists for the input90    let workingId;91    if (typeof inputId === 'object' && inputId && 'id' in inputId) {92      if (typeof inputId.id !== 'string' && !ArrayBuffer.isView(inputId.id)) {93        throw new BSONError('Argument passed in must have an id that is of type string or Buffer');94      }95      if ('toHexString' in inputId && typeof inputId.toHexString === 'function') {96        workingId = ByteUtils.fromHex(inputId.toHexString());97      } else {98        workingId = inputId.id;99      }100    } else {101      workingId = inputId;102    }103 104    // The following cases use workingId to construct an ObjectId105    if (workingId == null || typeof workingId === 'number') {106      // The most common use case (blank id, new objectId instance)107      // Generate a new id108      this.buffer = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);109    } else if (ArrayBuffer.isView(workingId) && workingId.byteLength === 12) {110      // If intstanceof matches we can escape calling ensure buffer in Node.js environments111      this.buffer = ByteUtils.toLocalBufferType(workingId);112    } else if (typeof workingId === 'string') {113      if (ObjectId.validateHexString(workingId)) {114        this.buffer = ByteUtils.fromHex(workingId);115        // If we are caching the hex string116        if (ObjectId.cacheHexString) {117          __idCache.set(this, workingId);118        }119      } else {120        throw new BSONError(121          'input must be a 24 character hex string, 12 byte Uint8Array, or an integer'122        );123      }124    } else {125      throw new BSONError('Argument passed in does not match the accepted types');126    }127  }128 129  /**130   * The ObjectId bytes131   * @readonly132   */133  get id(): Uint8Array {134    return this.buffer;135  }136 137  set id(value: Uint8Array) {138    this.buffer = value;139    if (ObjectId.cacheHexString) {140      __idCache.set(this, ByteUtils.toHex(value));141    }142  }143 144  /**145   * @internal146   * Validates the input string is a valid hex representation of an ObjectId.147   */148  private static validateHexString(string: string): boolean {149    if (string?.length !== 24) return false;150    for (let i = 0; i < 24; i++) {151      const char = string.charCodeAt(i);152      if (153        // Check for ASCII 0-9154        (char >= 48 && char <= 57) ||155        // Check for ASCII a-f156        (char >= 97 && char <= 102) ||157        // Check for ASCII A-F158        (char >= 65 && char <= 70)159      ) {160        continue;161      }162      return false;163    }164    return true;165  }166 167  /** Returns the ObjectId id as a 24 lowercase character hex string representation */168  toHexString(): string {169    if (ObjectId.cacheHexString) {170      const __id = __idCache.get(this);171      if (__id) return __id;172    }173 174    const hexString = ByteUtils.toHex(this.id);175 176    if (ObjectId.cacheHexString) {177      __idCache.set(this, hexString);178    }179 180    return hexString;181  }182 183  /**184   * Update the ObjectId index185   * @internal186   */187  private static getInc(): number {188    return (ObjectId.index = (ObjectId.index + 1) % 0xffffff);189  }190 191  /**192   * Generate a 12 byte id buffer used in ObjectId's193   *194   * @param time - pass in a second based timestamp.195   */196  static generate(time?: number): Uint8Array {197    if ('number' !== typeof time) {198      time = Math.floor(Date.now() / 1000);199    }200 201    const inc = ObjectId.getInc();202    const buffer = ByteUtils.allocateUnsafe(12);203 204    // 4-byte timestamp205    NumberUtils.setInt32BE(buffer, 0, time);206 207    // set PROCESS_UNIQUE if yet not initialized208    if (PROCESS_UNIQUE === null) {209      PROCESS_UNIQUE = ByteUtils.randomBytes(5);210    }211 212    // 5-byte process unique213    buffer[4] = PROCESS_UNIQUE[0];214    buffer[5] = PROCESS_UNIQUE[1];215    buffer[6] = PROCESS_UNIQUE[2];216    buffer[7] = PROCESS_UNIQUE[3];217    buffer[8] = PROCESS_UNIQUE[4];218 219    // 3-byte counter220    buffer[11] = inc & 0xff;221    buffer[10] = (inc >> 8) & 0xff;222    buffer[9] = (inc >> 16) & 0xff;223 224    return buffer;225  }226 227  /**228   * Converts the id into a 24 character hex string for printing, unless encoding is provided.229   * @param encoding - hex or base64230   */231  toString(encoding?: 'hex' | 'base64'): string {232    // Is the id a buffer then use the buffer toString method to return the format233    if (encoding === 'base64') return ByteUtils.toBase64(this.id);234    if (encoding === 'hex') return this.toHexString();235    return this.toHexString();236  }237 238  /** Converts to its JSON the 24 character hex string representation. */239  toJSON(): string {240    return this.toHexString();241  }242 243  /** @internal */244  private static is(variable: unknown): variable is ObjectId {245    return (246      variable != null &&247      typeof variable === 'object' &&248      '_bsontype' in variable &&249      variable._bsontype === 'ObjectId'250    );251  }252 253  /**254   * Compares the equality of this ObjectId with `otherID`.255   *256   * @param otherId - ObjectId instance to compare against.257   */258  equals(otherId: string | ObjectId | ObjectIdLike | undefined | null): boolean {259    if (otherId === undefined || otherId === null) {260      return false;261    }262 263    if (ObjectId.is(otherId)) {264      return (265        this.buffer[11] === otherId.buffer[11] && ByteUtils.equals(this.buffer, otherId.buffer)266      );267    }268 269    if (typeof otherId === 'string') {270      return otherId.toLowerCase() === this.toHexString();271    }272 273    if (typeof otherId === 'object' && typeof otherId.toHexString === 'function') {274      const otherIdString = otherId.toHexString();275      const thisIdString = this.toHexString();276      return typeof otherIdString === 'string' && otherIdString.toLowerCase() === thisIdString;277    }278 279    return false;280  }281 282  /** Returns the generation date (accurate up to the second) that this ID was generated. */283  getTimestamp(): Date {284    const timestamp = new Date();285    const time = NumberUtils.getUint32BE(this.buffer, 0);286    timestamp.setTime(Math.floor(time) * 1000);287    return timestamp;288  }289 290  /** @internal */291  static createPk(): ObjectId {292    return new ObjectId();293  }294 295  /** @internal */296  serializeInto(uint8array: Uint8Array, index: number): 12 {297    uint8array[index] = this.buffer[0];298    uint8array[index + 1] = this.buffer[1];299    uint8array[index + 2] = this.buffer[2];300    uint8array[index + 3] = this.buffer[3];301    uint8array[index + 4] = this.buffer[4];302    uint8array[index + 5] = this.buffer[5];303    uint8array[index + 6] = this.buffer[6];304    uint8array[index + 7] = this.buffer[7];305    uint8array[index + 8] = this.buffer[8];306    uint8array[index + 9] = this.buffer[9];307    uint8array[index + 10] = this.buffer[10];308    uint8array[index + 11] = this.buffer[11];309    return 12;310  }311 312  /**313   * Creates an ObjectId from a second based number, with the rest of the ObjectId zeroed out. Used for comparisons or sorting the ObjectId.314   *315   * @param time - an integer number representing a number of seconds.316   */317  static createFromTime(time: number): ObjectId {318    const buffer = ByteUtils.allocate(12);319    for (let i = 11; i >= 4; i--) buffer[i] = 0;320    // Encode time into first 4 bytes321    NumberUtils.setInt32BE(buffer, 0, time);322    // Return the new objectId323    return new ObjectId(buffer);324  }325 326  /**327   * Creates an ObjectId from a hex string representation of an ObjectId.328   *329   * @param hexString - create a ObjectId from a passed in 24 character hexstring.330   */331  static createFromHexString(hexString: string): ObjectId {332    if (hexString?.length !== 24) {333      throw new BSONError('hex string must be 24 characters');334    }335 336    return new ObjectId(ByteUtils.fromHex(hexString));337  }338 339  /** Creates an ObjectId instance from a base64 string */340  static createFromBase64(base64: string): ObjectId {341    if (base64?.length !== 16) {342      throw new BSONError('base64 string must be 16 characters');343    }344 345    return new ObjectId(ByteUtils.fromBase64(base64));346  }347 348  /**349   * Checks if a value can be used to create a valid bson ObjectId350   * @param id - any JS value351   */352  static isValid(id: string | number | ObjectId | ObjectIdLike | Uint8Array): boolean {353    if (id == null) return false;354    if (typeof id === 'string') return ObjectId.validateHexString(id);355 356    try {357      new ObjectId(id);358      return true;359    } catch {360      return false;361    }362  }363 364  /** @internal */365  toExtendedJSON(): ObjectIdExtended {366    if (this.toHexString) return { $oid: this.toHexString() };367    return { $oid: this.toString('hex') };368  }369 370  /** @internal */371  static fromExtendedJSON(doc: ObjectIdExtended): ObjectId {372    return new ObjectId(doc.$oid);373  }374 375  /** @internal */376  private isCached(): boolean {377    return ObjectId.cacheHexString && __idCache.has(this);378  }379 380  /**381   * Converts to a string representation of this Id.382   *383   * @returns return the 24 character hex string representation.384   */385  inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {386    inspect ??= defaultInspect;387    return `new ObjectId(${inspect(this.toHexString(), options)})`;388  }389}390