tupleson
Version:
A hackable JSON serializer/deserializer
95 lines (93 loc) • 3.34 kB
TypeScript
declare const brand: unique symbol;
type TsonBranded<TType, TBrand> = TType & {
[brand]: TBrand;
};
type TsonNonce = TsonBranded<string, "TsonNonce">;
type TsonTypeHandlerKey = TsonBranded<string, "TsonTypeHandlerKey">;
type TsonSerializedValue = unknown;
type TsonTuple = [TsonTypeHandlerKey, TsonSerializedValue, TsonNonce];
type TsonAllTypes = "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined";
type SerializedType = Record<string, unknown> | boolean | number | string | unknown[];
interface TsonTransformerNone {
async?: false;
deserialize?: never;
/**
* The key to use when serialized
*/
key?: never;
serialize?: never;
serializeIterator?: never;
}
interface TsonTransformerSerializeDeserialize<TValue, TSerializedType extends SerializedType> {
async?: false;
/**
* From JSON-serializable value
*/
deserialize: (v: TSerializedType) => TValue;
/**
* The key to use when serialized
*/
key: string;
/**
* JSON-serializable value
*/
serialize: (v: TValue) => TSerializedType;
serializeIterator?: never;
}
type TsonTransformer<TValue, TSerializedType extends SerializedType> = TsonTransformerNone | TsonTransformerSerializeDeserialize<TValue, TSerializedType>;
interface TsonTypeTesterPrimitive {
/**
* The type of the primitive
*/
primitive: TsonAllTypes;
/**
* Test if the value is of this type
*/
test?: (v: unknown) => boolean;
}
interface TsonTypeTesterCustom {
/**
* The type of the primitive
*/
primitive?: never;
/**
* Test if the value is of this type
*/
test: (v: unknown) => boolean;
}
type TsonTypeTester = TsonTypeTesterCustom | TsonTypeTesterPrimitive;
type TsonType<
/**
* The type of the value
*/
TValue,
/**
* JSON-serializable value how it's stored after it's serialized
*/
TSerializedType extends SerializedType> = TsonTypeTester & TsonTransformer<TValue, TSerializedType>;
interface TsonOptions {
/**
* The nonce function every time we start serializing a new object
* Should return a unique value every time it's called
* @default `${crypto.randomUUID} if available, otherwise a random string generated by Math.random`
*/
nonce?: () => number | string;
/**
* The list of types to use
*/
types: (TsonType<any, any> | TsonType<any, never>)[];
}
declare const serialized: unique symbol;
interface TsonSerialized<TValue = unknown> {
json: TsonSerializedValue;
nonce: TsonNonce;
[serialized]: TValue;
}
type TsonSerializeFn = <TValue>(obj: TValue) => TsonSerialized<TValue>;
type TsonDeserializeFn = <TValue>(data: TsonSerialized<TValue>) => TValue;
type TsonStringified<TValue> = string & {
[serialized]: TValue;
};
type TsonStringifyFn = <TValue>(obj: TValue, space?: number | string) => TsonStringified<TValue>;
type TsonParseFn = <TValue>(string: TsonStringified<TValue>) => TValue;
export { TsonAllTypes, TsonBranded, TsonDeserializeFn, TsonNonce, TsonOptions, TsonParseFn, TsonSerializeFn, TsonSerialized, TsonSerializedValue, TsonStringified, TsonStringifyFn, TsonTransformer, TsonTransformerNone, TsonTransformerSerializeDeserialize, TsonTuple, TsonType, TsonTypeHandlerKey, TsonTypeTesterCustom, TsonTypeTesterPrimitive, serialized };