/** * A byte buffer for efficient reading and writing of primitive values and bit sequences. * * The DataPack class provides methods for serializing and deserializing various data types * including numbers, strings, bit sequences, and other primitive values to/from byte buffers. * It supports both reading and writing operations with automatic buffer management. */ export default class DataPack { private buffer; private dataView?; readPos: number; writePos: number; static EOD: symbol; /** * Backward compatibility: Access to the internal buffer */ get _buffer(): Uint8Array; /** * Create a new DataPack instance. * @param data Optional initial data as Uint8Array or buffer size as number. */ constructor(data?: Uint8Array | number); /** * Helper function to write a multi-byte integer with length prefix * @param value The value to write * @param headerType The type bits (0-7) for the header * @param invertBytes Whether to invert bytes (for negative numbers) * @param invertByteCount Whether to invert the byte count (for type 0) */ private writeMultiByteNumber; /** * Helper function to read a multi-byte integer with length prefix * @param byteCount Number of bytes to read * @param invertBytes Whether to invert bytes (for negative numbers) * @returns The read value */ private readMultiByteNumber; private notEnoughData; /** * Each data item starts with a single byte. The high 3 bits indicate the type. * The low 5 bits indicate a size or a subtype, depending on the type. * * 0: negative integer (byte count encoded as bitwise NOT in lower bits) * 1: small integer 0..31 (encoded in lower bits) * 2: small integer 32...63 (encoded in lower bits) * 3: integer (byte count encoded in lower bits) * 4: * 0: float64 (8 bytes follow) * 1: undefined * 2: null * 3: true * 4: false * 5: array start (followed by a items until EOD) * 6: object start (followed by key+value pairs until EOD) * 7: map start (followed by key+value pairs until EOD) * 8: set start (followed by items until EOD) * 9: EOD * 10: identifier (6 byte positive int follows, represented as a base64 string of length 8) * 11: null-terminated string * 12: Date/Time (varint with whole seconds since epoch follows) * 13: custom type, followed by name string and data value * 5: short string (length in lower bits, 0-31) * 6: string (byte count of length in lower bits) * 7: blob (byte count of length in lower bits) */ write(data: any): DataPack; read(customConverters?: { [name: string]: ((data: any) => any); } | undefined): any; /** * Ensure the buffer has capacity for additional bytes. * @param bytesNeeded Number of additional bytes needed. */ private ensureCapacity; readNumber(): number; readDate(): Date; readPositiveInt(limit?: number): number; readBoolean(): boolean; readUint8Array(): Uint8Array; readString(): string; writeIdentifier(id: string | number): DataPack; readIdentifier(): string; readIdentifierNumber(): number; /** * Like writeString but writes without a length prefix and with a null terminator, for ordered storage. * Can be read with {@link read} or {@link readString} just like any other string. * @param str The string to write. May not contain null characters. */ writeOrderedString(str: string): DataPack; toUint8Array(copyBuffer?: boolean, startPos?: number, endPos?: number): Uint8Array; toBuffer(): ArrayBuffer; clone(copyBuffer: boolean, readPos?: number, writePos?: number): DataPack; writeCustom(name: string, data: any): void; writeAsObject(obj: Record): this; /** * Write a collection (array, set, object, or map) using a callback to add items/fields. * @param type 'array' | 'set' | 'object' | 'map' * @param bodyFunc Callback function to add items/fields. It accepts a function to add values or key-value pairs (depending on the collection type). * @returns The DataPack instance for chaining. * @example * // Writing an array * pack.writeCollection('array', add => { * add(1); * add(2); * add(3); * }); * * // Writing an object * pack.writeCollection('object', (add) => { * add('key1', 'value1'); * add('key2', 42); * }); */ writeCollection(type: 'array' | 'set', bodyFunc: (addField: (value: any) => void) => void): DataPack; writeCollection(type: 'object', bodyFunc: (addField: (field: number | string, value: any) => void) => void): DataPack; writeCollection(type: 'map', bodyFunc: (addField: (field: any, value: any) => void) => void): DataPack; /** * Write a collection boundary marker (start or end) for arrays, sets, objects, or maps. * This is a low-level method for advanced use cases. Use `writeCollection` (or just `write`) * if possible. */ writeCollectionBoundary(marker: 'array' | 'set' | 'object' | 'map' | 'end'): DataPack; /** * Writes either a string or a number, converting strings to numbers if they represent javascript-safe integers. * This is useful for writing object keys, which are always strings but may be more compactly represented as numbers. */ writeObjectKey(key: number | string): void; /** * Read and consume a collection boundary marker, validating it matches the expected type. */ readCollectionBoundary(expected: 'array' | 'set' | 'object' | 'map' | 'end'): void; /** * Increment the last byte of the buffer. If it was already 255 set it to 0 and * increment the previous byte, and so on. If all bytes were 255, return undefined. * This is useful for creating an exclusive end key for range scans. * This may result in a DataPack instance that cannot be parsed (or represented by * {@link toString}). */ increment(): DataPack | undefined; toString(extended?: boolean | undefined, startPos?: number, endPos?: number): string; readAvailable(): boolean; static generateIdentifier(): string; static createBuffer(...args: any): ArrayBuffer; static createUint8Array(...args: any): Uint8Array; } declare class CustomData { name: string; data: any; constructor(name: string, data: any); } export default interface DataPack { CustomData: typeof CustomData; } export {};