obj-codec
Version:
Encode objects into binary and decode binary back into objects, supporting nested references, custom object encoding/decoding, unique pointers...
184 lines (179 loc) • 5.76 kB
TypeScript
//#region src/types.d.ts
/** 二进制数据类型 */
type BinaryType = ArrayBuffer | Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | globalThis.Float16Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array | DataView;
/** 基本数据类型 */
type BaseType = BinaryType | number | bigint | string | false | true | null | undefined;
/** 内置数据类型 */
type InternalType = {
[x: string | number | symbol]: BasicType;
} | BasicType[] | Set<BasicType> | Map<BasicType, BasicType> | Date | RegExp | Symbol;
/** 基础数据类型 */
type BasicType = BaseType | InternalType;
/** 构造方法 */
type IClass = new (...args: any[]) => any;
/**
* 编解码器
* @template Type 数据类型
* @template EncodeResult 编码类型
* @template DecodeMiddle 解码中间类型
*/
interface ICodec<Type extends object, EncodeResult, DecodeMiddle extends Type = Type> {
/**
* 编解码器名称
* @description
* 通过编解码器名称确定编解码器,
* 请确保编解码器名称唯一
*/
name: string;
/** 编解码目标类 */
class: new (...args: any[]) => Type;
/**
* 编解码目标类父类
* @description
* 用于确定匹配顺序
* @example
* [ParentClass, GrandClass, GrandGrandClass]
*/
parentClasses?: IClass[];
/**
* 编码
* @param data 数据
*/
encode(data: Type): EncodeResult;
/**
* 解码
* @param encoded 已编码数据
*/
decode(encoded: EncodeResult): DecodeMiddle;
/**
* 解引用
* @param data 解码中间数据
*/
deref?(data: DecodeMiddle): void;
}
/** 任意编解码器 */
type AnyCodec = ICodec<any, any, any>;
/** 编解码器图 */
type CodecMap = Map<string, AnyCodec>;
/**
* 内置编解码器
* @template Type 数据类型
* @template DecodeMiddle 解码中间类型
* @template EncodeResult 编码类型
*/
interface InternalCodec<Type, DecodeMiddle extends Type = Type, EncodeResult extends Uint8Array = Uint8Array> {
/** 编码后长度 */
bufferLength?: number;
/**
* 编码
* @param data 数据
* @param serialize 序列化
*/
encode(data: Type, serialize: (data: any) => Uint8Array): EncodeResult;
/**
* 解码
* @param encoded 已编码数据
* @param deserialize 反序列化
*/
decode(encoded: EncodeResult, deserialize: (buffer: Uint8Array) => any[]): DecodeMiddle;
/**
* 解引用
* @param data 解码中间数据
*/
deref?(data: DecodeMiddle): void;
}
type InternalTypeName = 'POINTER' | 'BINARY' | 'NUMBER' | 'BIGINT' | 'STRING' | 'FALSE' | 'TRUE' | 'NULL' | 'UNDEFINED' | 'OBJECT' | 'ARRAY' | 'SET' | 'MAP' | 'DATE' | 'REGEXP' | 'SYMBOL' | 'UNIQUE_POINTER';
interface ObjEncoderOptions {
/**
* 唯一值
* @description
* 唯一指针指向该数组中指定下标的值,
* 需确保编解码时该数组内容和顺序不变
*/
uniqueValues?: any[];
/** 忽略不支持的类型 */
ignoreUnsupportedTypes?: boolean;
}
interface ObjDecoderOptions {
/**
* 唯一值
* @description
* 唯一指针指向该数组中指定下标的值,
* 需确保编解码时该数组内容和顺序不变
*/
uniqueValues?: any[];
/** 忽略缺少的编解码器 */
ignoreMissedCodec?: boolean;
/** 忽略缺少的唯一值 */
ignoreMissedUniqueValue?: boolean;
/** 允许不完全解码 */
allowIncompleteDecoding?: boolean;
}
//#endregion
//#region src/decoder.d.ts
interface DecodeOptions {
codec: CodecMap;
uniqueValues?: any[];
ignoreMissedCodec?: boolean;
ignoreMissedUniqueValue?: boolean;
allowIncompleteDecoding?: boolean;
}
//#endregion
//#region src/encoder.d.ts
interface EncodeOptions {
codec: CodecMap;
root: any;
uniqueValues?: any[];
ignoreUnsupportedTypes?: boolean;
}
//#endregion
//#region src/global.d.ts
/** 内置编解码器 */
declare const INTERNAL_CODEC_MAP: Readonly<Record<InternalTypeName, InternalCodec<BasicType>>>;
declare const INTERNAL_CODEC: readonly InternalCodec<BasicType>[];
/** 内置类型 ID */
declare const INTERNAL_TYPE_ID: Readonly<Record<InternalTypeName, number>>;
/** 自定义类型起始 ID */
declare const CUSTOM_TYPE_ID_BEGIN = 17;
/** 数据结构版本号 */
declare const VERSION = 1;
declare abstract class IObjCodec {
protected _codecs: CodecMap;
/**
* 唯一值
* @description
* 该唯一值数组在该 `ObjCodec` 实例中生效,
* 调用 `encode`/`decode` 方法时可覆盖该值。
*
* 唯一指针指向该数组中指定下标的值,
* 需确保编解码时该数组内容和顺序不变。
*/
uniqueValues?: any[];
constructor(uniqueValues?: any[]);
/** 注册全局编解码器 */
static register(codec: AnyCodec): void;
/** 注册编解码器 */
register(codec: AnyCodec): void;
/**
* 编码
* @param root 编码根对象
*/
abstract encode(root: any, options?: ObjEncoderOptions): any;
/** 解码 */
abstract decode(options?: ObjDecoderOptions): any;
}
//#endregion
//#region src/utils.d.ts
/** 合并缓冲区 */
declare function concatBuffers(...buffers: (Uint8Array | number[])[]): Uint8Array;
/** 转 Uint8Array */
declare function bufferToUint8Array(buffer: BinaryType): Uint8Array<ArrayBufferLike>;
declare function isBinary(data: any): boolean;
declare class Pointer {
#private;
constructor(id: number, pointers: any[]);
/** 解引用 */
deref(): any;
}
//#endregion
export { BaseType, BasicType, BinaryType, CUSTOM_TYPE_ID_BEGIN, DecodeOptions, EncodeOptions, IClass, ICodec, INTERNAL_CODEC, INTERNAL_CODEC_MAP, INTERNAL_TYPE_ID, IObjCodec, InternalCodec, InternalType, InternalTypeName, ObjDecoderOptions, ObjEncoderOptions, Pointer, VERSION, bufferToUint8Array, concatBuffers, isBinary };