bebop
Version:
The TypeScript runtime for Bebop, a schema-based binary serialization format.
547 lines (544 loc) • 19.1 kB
TypeScript
declare enum WireMethodType {
Unary = 0,
ServerStreaming = 1,
ClientStreaming = 2,
DuplexStream = 3
}
declare enum WireTypeKind {
Struct = 1,
Message = 2,
Union = 3,
Enum = 4
}
type Decorators = Decorator[];
interface Decorator {
identifier: string;
arguments?: {
[identifier: string]: DecoratorArgument;
};
}
interface DecoratorArgument {
typeId: number;
value: string | number | bigint | Guid | null;
}
interface Definition {
index: number;
name: string;
kind: WireTypeKind;
minimalEncodeSize: number;
decorators: Decorators;
}
interface Service {
name: string;
decorators: Decorators;
methods: {
[methodName: string]: ServiceMethod;
};
}
interface ServiceMethod {
name: string;
decorators: Decorators;
requestTypeId: number;
responseTypeId: number;
methodType: WireMethodType;
id: number;
}
interface SchemaAst {
bebopVersion: number;
definitions: {
[typeName: string]: Definition;
};
services?: {
[serviceName: string]: Service;
};
}
/**
* A class that can read a buffer containing a Bebop encoded record by utilizing a binary schema.
*/
declare class RecordReader {
private readonly schema;
/**
* @param schema - BinarySchema object containing metadata about Bebop schemas.
* @private
*/
private constructor();
/**
* Reads a Bebop encoded record from a buffer.
*
* @param definitionName - Name of the definition in the schema for the record to read.
* @param data - The buffer to read the record from.
* @returns - The read record as a Record object.
* @throws - Throws an error if the record cannot be decoded directly.
* @public
*/
read(definitionName: string, data: Uint8Array): Record<string, unknown>;
private readDefinition;
private readStructDefinition;
private readMessageDefinition;
private readField;
private readScalar;
private readArray;
private readMap;
private readEnumDefinition;
private readUnionDefinition;
}
/**
* A class responsible for writing a dynamic record into a Bebop buffer.
* The class uses a binary schema provided during instantiation to encode the data.
*
* @example
* const writer = binarySchema.writer;
* const buffer = writer.write('DefinitionName', record);
*/
declare class RecordWriter {
private schema;
/**
* @param schema Binary schema used for encoding the data.
* @private
*/
private constructor();
/**
* Encodes a given record according to a provided definition name and returns it as a Uint8Array.
*
* @param definitionName Name of the definition to be used for encoding.
* @param record The record to be encoded.
* @returns Encoded record as a Uint8Array.
*/
write(definitionName: string, record: Record<string, unknown>): Uint8Array;
private writeDefinition;
private writeStructDefinition;
private writeMessageDefinition;
private writeEnumDefinition;
private writeUnionDefinition;
private writeField;
private writeArray;
private writeMap;
private writeScalar;
private isRecord;
}
/**
* `BinarySchema` represents a class that allows parsing of a Bebop schema in binary form.
*
* This class holds the DataView representation of the binary data, its parsing position,
* and contains methods to get each specific type of Bebop schema structure.
*/
declare class BinarySchema {
private readonly data;
private readonly view;
private readonly dataProxy;
private pos;
private readonly ArrayType;
private readonly MapType;
private parsedSchema?;
private indexToDefinition;
private nameToDefinition;
reader: RecordReader;
writer: RecordWriter;
/**
* Create a new BinarySchema instance.
* @param data - The binary data array.
*/
constructor(data: Uint8Array);
/**
* Get the schema.
* This method should only be called once per instance.
*/
get(): void;
/**
* Returns the getd schema.
*/
get ast(): Readonly<SchemaAst>;
/**
* Returns the raw binary data of the schema wrapped in an immutable Uint8Array.
*/
get raw(): Uint8Array;
/**
* Get a Definition by its index or name.
* @param index - The index or name of the Definition.
* @returns - The requested Definition.
* @throws - Will throw an error if no Definition is found at the provided index.
*/
getDefinition(index: number | string): Definition;
private getDefinedType;
private getDecorators;
private getDecorator;
private getEnumDefinition;
private getEnumMember;
private getUnionDefinition;
private getUnionBranch;
private getStructDefinition;
private getMessageDefinition;
private getFields;
private getField;
private getNestedType;
private getConstantValue;
private getServiceDefinition;
private getString;
private getUint8;
private getUint16;
private getInt16;
private getUint32;
private getInt32;
private getUint64;
private getInt64;
private getFloat32;
private getFloat64;
private getBool;
private getTypeId;
private getGuid;
}
declare class BebopRuntimeError extends Error {
constructor(message: string);
}
/**
* Represents a globally unique identifier (GUID).
*/
declare class Guid {
private readonly value;
static readonly empty: Guid;
/**
* Constructs a new Guid object with the specified value.
* @param value The value of the GUID.
*/
private constructor();
/**
* Gets the string value of the Guid.
* @returns The string representation of the Guid.
*/
toString(): string;
/**
* Checks if the Guid is empty.
* @returns true if the Guid is empty, false otherwise.
*/
isEmpty(): boolean;
/**
* Checks if a value is a Guid.
* @param value The value to be checked.
* @returns true if the value is a Guid, false otherwise.
*/
static isGuid(value: any): value is Guid;
/**
* Parses a string into a Guid.
* @param value The string to be parsed.
* @returns A new Guid that represents the parsed value.
* @throws {BebopRuntimeError} If the input string is not a valid Guid.
*/
static parseGuid(value: string): Guid;
/**
* Creates a an insecure new Guid using Math.random.
* @returns A new Guid.
*/
static newGuid(): Guid;
/**
* Creates a new cryptographically secure Guid using Crypto.getRandomValues.
* @returns A new secure Guid.
* @throws {BebopRuntimeError} If Crypto.getRandomValues is not available.
*/
static newSecureGuid(): Guid;
/**
* Checks if the Guid is equal to another Guid.
* @param other The other Guid to be compared with.
* @returns true if the Guids are equal, false otherwise.
*/
equals(other: Guid): boolean;
/**
* Writes the Guid to a DataView.
* @param view The DataView to write to.
* @param length The position to start writing at.
*/
writeToView(view: DataView, length: number): void;
/**
* Creates a Guid from a byte array.
* @param buffer The byte array to create the Guid from.
* @param index The position in the array to start reading from.
* @returns A new Guid that represents the byte array.
*/
static fromBytes(buffer: Uint8Array, index: number): Guid;
/**
* Converts the Guid to a string when it's used as a primitive.
* @returns The string representation of the Guid.
*/
[Symbol.toPrimitive](hint: string): string;
}
/**
* Represents a wrapper around the `Map` class with support for using `Guid` instances as keys.
*
* This class is designed to provide a 1:1 mapping between `Guid` instances and values, allowing `Guid` instances to be used as keys in the map.
* The class handles converting `Guid` instances to their string representation for key storage and retrieval.
* @remarks this is required because Javascript lacks true reference equality. Thus two `Guid` instances with the same value are not equal.
*/
declare class GuidMap<TValue> {
private readonly map;
/**
* Creates a new GuidMap instance.
* @param entries - An optional array or iterable containing key-value pairs to initialize the map.
*/
constructor(entries?: readonly (readonly [Guid, TValue])[] | null | Iterable<readonly [Guid, TValue]>);
/**
* Sets the value associated with the specified `Guid` key in the map.
* @param key The `Guid` key.
* @param value The value to be set.
* @returns The updated `GuidMap` instance.
*/
set(key: Guid, value: TValue): this;
/**
* Retrieves the value associated with the specified `Guid` key from the map.
* @param key The `Guid` key.
* @returns The associated value, or `undefined` if the key is not found.
*/
get(key: Guid): TValue | undefined;
/**
* Deletes the value associated with the specified `Guid` key from the map.
* @param key The `Guid` key.
* @returns `true` if the key was found and deleted, or `false` otherwise.
*/
delete(key: Guid): boolean;
/**
* Checks if the map contains the specified `Guid` key.
* @param key The `Guid` key.
* @returns `true` if the key is found, or `false` otherwise.
*/
has(key: Guid): boolean;
/**
* Removes all entries from the map.
*/
clear(): void;
/**
* Returns the number of entries in the map.
* @returns The number of entries in the map.
*/
get size(): number;
/**
* Executes the provided callback function once for each key-value pair in the map.
* @param callbackFn The callback function to execute.
*/
forEach(callbackFn: (value: TValue, key: Guid, map: GuidMap<TValue>) => void): void;
/**
* Returns an iterator that yields key-value pairs in the map.
* @returns An iterator for key-value pairs in the map.
*/
entries(): Generator<[Guid, TValue]>;
/**
* Returns an iterator that yields the keys of the map.
* @returns An iterator for the keys of the map.
*/
keys(): Generator<Guid>;
/**
* Returns an iterator that yields the values in the map.
* @returns An iterator for the values in the map.
*/
values(): Generator<TValue>;
/**
* Returns an iterator that yields key-value pairs in the map.
* This method is invoked when using the spread operator or destructuring the map.
* @returns An iterator for key-value pairs in the map.
*/
[Symbol.iterator](): Generator<[Guid, TValue]>;
/**
* The constructor function used to create derived objects.
*/
get [Symbol.species](): typeof GuidMap;
}
/**
* An interface which all generated Bebop interfaces implement.
* @note this interface is not currently used by the runtime; it is reserved for future use.
*/
interface BebopRecord {
}
declare class BebopView {
private static textDecoder;
private static writeBuffer;
private static writeBufferView;
private static instance;
static getInstance(): BebopView;
minimumTextDecoderLength: number;
private buffer;
private view;
index: number;
length: number;
private constructor();
startReading(buffer: Uint8Array): void;
startWriting(): void;
private guaranteeBufferLength;
private growBy;
skip(amount: number): void;
toArray(): Uint8Array;
readByte(): number;
readUint16(): number;
readInt16(): number;
readUint32(): number;
readInt32(): number;
readUint64(): bigint;
readInt64(): bigint;
readFloat32(): number;
readFloat64(): number;
writeByte(value: number): void;
writeUint16(value: number): void;
writeInt16(value: number): void;
writeUint32(value: number): void;
writeInt32(value: number): void;
writeUint64(value: bigint): void;
writeInt64(value: bigint): void;
writeFloat32(value: number): void;
writeFloat64(value: number): void;
readBytes(): Uint8Array;
writeBytes(value: Uint8Array): void;
/**
* Reads a length-prefixed UTF-8-encoded string.
*/
readString(): string;
/**
* Writes a length-prefixed UTF-8-encoded string.
*/
writeString(value: string): void;
readGuid(): Guid;
writeGuid(value: Guid): void;
readDate(): Date;
writeDate(date: Date): void;
/**
* Reserve some space to write a message's length prefix, and return its index.
* The length is stored as a little-endian fixed-width unsigned 32-bit integer, so 4 bytes are reserved.
*/
reserveMessageLength(): number;
/**
* Fill in a message's length prefix.
*/
fillMessageLength(position: number, messageLength: number): void;
/**
* Read out a message's length prefix.
*/
readMessageLength(): number;
}
/**
* A collection of functions for working with Bebop-encoded JSON.
*/
declare const BebopJson: {
/**
* A custom replacer function for JSON.stringify that supports BigInt, Map,
* Date, Uint8Array, including BigInt values inside Map and Array.
* @param _key - The key of the property being stringified.
* @param value - The value of the property being stringified.
* @returns The modified value for the property, or the original value if not a BigInt or Map.
*/
replacer: (_key: string | number, value: any) => any;
/**
* A custom reviver function for JSON.parse that supports BigInt, Map, Date,
* Uint8Array, including nested values
* @param _key - The key of the property being parsed.
* @param value - The value of the property being parsed.
* @returns The modified value for the property, or the original value if not a marked type.
*/
reviver: (_key: string | number, value: any) => any;
};
/**
* This object contains functions for ensuring that values conform to specific types.
*/
declare const BebopTypeGuard: {
/**
* Ensures that the given value is a valid boolean.
* @param value - The value to check.
* @throws {BebopRuntimeError} - If the value is not a valid boolean.
*/
ensureBoolean: (value: any) => void;
/**
* Ensures that the given value is a valid Uint8 number (0 to 255).
* @param value - The value to check.
* @throws {BebopRuntimeError} - If the value is not a valid Uint8 number.
*/
ensureUint8: (value: any) => void;
/**
* Ensures that the given value is a valid Int16 number (-32768 to 32767).
* @param value - The value to check.
* @throws {BebopRuntimeError} - If the value is not a valid Int16 number.
*/
ensureInt16: (value: any) => void;
/**
* Ensures that the given value is a valid Uint16 number (0 to 65535).
* @param value - The value to check.
* @throws {BebopRuntimeError} - If the value is not a valid Uint16 number.
*/
ensureUint16: (value: any) => void;
/**
* Ensures that the given value is a valid Int32 number (-2147483648 to 2147483647).
* @param value - The value to check.
* @throws {BebopRuntimeError} - If the value is not a valid Int32 number.
*/
ensureInt32: (value: any) => void;
/**
* Ensures that the given value is a valid Uint32 number (0 to 4294967295).
* @param value - The value to check.
* @throws {BebopRuntimeError} - If the value is not a valid Uint32 number.
*/
ensureUint32: (value: any) => void;
/**
* Ensures that the given value is a valid Int64 number (-9223372036854775808 to 9223372036854775807).
* @param value - The value to check.
* @throws {BebopRuntimeError} - If the value is not a valid Int64 number.
*/
ensureInt64: (value: bigint | number) => void;
/**
* Ensures that the given value is a valid Uint64 number (0 to 18446744073709551615).
* @param value - The value to check.
* @throws {BebopRuntimeError} - If the value is not a valid Uint64 number.
*/
ensureUint64: (value: bigint | number) => void;
/**
* Ensures that the given value is a valid BigInt number.
* @param value - The value to check.
* @throws {BebopRuntimeError} - If the value is not a valid BigInt number.
*/
ensureBigInt: (value: any) => void;
/**
* Ensures that the given value is a valid float number.
* @param value - The value to check.
* @throws {BebopRuntimeError} - If the value is not a valid float number.
*/
ensureFloat: (value: any) => void;
/**
* Ensures that the given value is a valid Map object, with keys and values that pass the specified validators.
* @param value - The value to check.
* @param keyTypeValidator - A function that validates the type of each key in the Map.
* @param valueTypeValidator - A function that validates the type of each value in the Map.
* @throws {BebopRuntimeError} - If the value is not a valid Map object, or if any key or value fails validation.
*/
ensureMap: (value: any, keyTypeValidator: (key: any) => void, valueTypeValidator: (value: any) => void) => void;
/**
* Ensures that the given value is a valid Array object, with elements that pass the specified validator.
* @param value - The value to check.
* @param elementTypeValidator - A function that validates the type of each element in the Array.
* @throws {BebopRuntimeError} - If the value is not a valid Array object, or if any element fails validation.
*/
ensureArray: (value: any, elementTypeValidator: (element: any) => void) => void;
/**
* Ensures that the given value is a valid Date object.
* @param value - The value to check.
* @throws {BebopRuntimeError} - If the value is not a valid Date object.
*/
ensureDate: (value: any) => void;
/**
* Ensures that the given value is a valid Uint8Array object.
* @param value - The value to check.
* @throws {BebopRuntimeError} - If the value is not a valid Uint8Array object.
*/
ensureUint8Array: (value: any) => void;
/**
* Ensures that the given value is a valid string.
* @param value - The value to check.
* @throws {BebopRuntimeError} - If the value is not a valid string.
*/
ensureString: (value: any) => void;
/**
* Ensures that the given value is a valid enum value.
* @param value - The value to check.
* @param enumValues - An array of valid enum values.
* @throws {BebopRuntimeError} - If the value is not a valid enum value.
*/
ensureEnum: (value: any, enumValue: object) => void;
/**
* Ensures that the given value is a valid GUID string.
* @param value - The value to check.
* @throws {BebopRuntimeError} - If the value is not a valid GUID string.
*/
ensureGuid: (value: any) => void;
};
export { BebopJson, BebopRecord, BebopRuntimeError, BebopTypeGuard, BebopView, BinarySchema, Guid, GuidMap };