Skip to content

Commit

Permalink
feat(serialization): Update the serialization helpers to use singleto…
Browse files Browse the repository at this point in the history
…n class
  • Loading branch information
sullivanpj committed Jan 4, 2024
1 parent b033b02 commit 326970f
Show file tree
Hide file tree
Showing 9 changed files with 253 additions and 100 deletions.
6 changes: 6 additions & 0 deletions docs/api-reports/packages/utilities/api-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,12 @@ type IsEqual<A, B> = (<G>() => G extends A ? 1 : 2) extends <G>() => G extends B
export { IsEqual };
export { IsEqual as IsEqual_alias_1 };

// @public (undocumented)
function isEqual(a: any, b: any): boolean;
export { isEqual };
export { isEqual as isEqual_alias_1 };
export { isEqual as isEqual_alias_2 };

// @public (undocumented)
interface ISequenced {
sequence: number;
Expand Down
61 changes: 61 additions & 0 deletions docs/api-reports/packages/utilities/documents-model.api.json
Original file line number Diff line number Diff line change
Expand Up @@ -1849,6 +1849,67 @@
"endIndex": 4
}
},
{
"kind": "Function",
"canonicalReference": "@storm-stack/utilities!isEqual:function(1)",
"docComment": "",
"excerptTokens": [
{
"kind": "Content",
"text": "export declare function isEqual(a: "
},
{
"kind": "Content",
"text": "any"
},
{
"kind": "Content",
"text": ", b: "
},
{
"kind": "Content",
"text": "any"
},
{
"kind": "Content",
"text": "): "
},
{
"kind": "Content",
"text": "boolean"
},
{
"kind": "Content",
"text": ";"
}
],
"fileUrlPath": "packages/utilities/src/helper-fns/is-deep-equal.ts",
"returnTypeTokenRange": {
"startIndex": 5,
"endIndex": 6
},
"releaseTag": "Public",
"overloadIndex": 1,
"parameters": [
{
"parameterName": "a",
"parameterTypeTokenRange": {
"startIndex": 1,
"endIndex": 2
},
"isOptional": false
},
{
"parameterName": "b",
"parameterTypeTokenRange": {
"startIndex": 3,
"endIndex": 4
},
"isOptional": false
}
],
"name": "isEqual"
},
{
"kind": "TypeAlias",
"canonicalReference": "@storm-stack/utilities!IsEqual:type",
Expand Down
5 changes: 1 addition & 4 deletions packages/date-time/src/storm-date-time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,7 @@ export function deserializeStormDateTime(utcString: JsonValue): StormDateTime {
*
* @decorator `@Serializable()`
*/
@Serializable({
serialize: serializeStormDateTime,
deserialize: deserializeStormDateTime
})
@Serializable()
export class StormDateTime extends Date {
/**
* Type-check to determine if `obj` is a `DateTime` object
Expand Down
5 changes: 1 addition & 4 deletions packages/date-time/src/storm-date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@ export function deserializeStormDate(utcString: JsonValue): StormDate {
*
* @decorator `@Serializable()`
*/
@Serializable({
serialize: serializeStormDate,
deserialize: deserializeStormDate
})
@Serializable()
export class StormDate extends StormDateTime {
/**
* The current function returns a new DateTime object with the current date and time
Expand Down
5 changes: 1 addition & 4 deletions packages/date-time/src/storm-time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@ export function deserializeStormTime(utcString: JsonValue): StormTime {
*
* @decorator `@Serializable()`
*/
@Serializable({
serialize: serializeStormTime,
deserialize: deserializeStormTime
})
@Serializable()
export class StormTime extends StormDateTime {
/**
* The current function returns a new DateTime object with the current date and time
Expand Down
9 changes: 1 addition & 8 deletions packages/errors/src/storm-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ import { Serializable } from "@storm-stack/serialization";
import { EMPTY_STRING, NEWLINE_STRING } from "@storm-stack/utilities";
import StackTracey from "stacktracey";
import { getCauseFromUnknown, isStormError } from "./utilities";
import {
deserializeStormError,
serializeStormError
} from "./utilities/serialization";

export interface StormErrorOptions {
name?: string;
Expand All @@ -21,10 +17,7 @@ export interface StormErrorOptions {
*
* @decorator `@Serializable()`
*/
@Serializable({
serialize: serializeStormError,
deserialize: deserializeStormError
})
@Serializable()
export class StormError<TCode extends string = string> extends Error {
__proto__ = Error;

Expand Down
165 changes: 118 additions & 47 deletions packages/serialization/src/json-parser.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,16 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
// import { Decimal } from "decimal.js";
import {
registerCustom,
deserialize as superDeserialize,
parse as superParse,
serialize as superSerialize,
stringify as superStringify
} from "superjson";
import { JsonParserResult, JsonValue } from "./types";
import { isObject, isString } from "@storm-stack/utilities";
import SuperJSON from "superjson";
import { Class, JsonParserResult, JsonValue } from "./types";

/**
* Stringify the given value with superjson
*/
export function stringify(json: any): string {
return superStringify(json);
}

/**
* Parse the given value with superjson using the given metadata
*/
export function parse<TData = unknown>(strData: string): TData {
return superParse<TData>(strData);
}

/**
* Serialize the given value with superjson
*/
export function serialize(object: JsonValue): JsonParserResult {
return superSerialize(object);
}

/**
* Deserialize the given value with superjson using the given metadata
*/
export function deserialize<TData = unknown>(payload: JsonParserResult): TData {
return superDeserialize(payload);
}

export function register<
TData = any,
TJsonObject extends JsonValue = JsonValue
>(
function _register<TData = any, TJsonObject extends JsonValue = JsonValue>(
name: string,
serialize: (data: TData) => TJsonObject,
deserialize: (json: TJsonObject) => TData,
isApplicable: (data: any) => data is TData
) {
return registerCustom<TData, TJsonObject>(
return SuperJSON.registerCustom<TData, TJsonObject>(
{ isApplicable, serialize, deserialize },
name
);
Expand All @@ -63,9 +27,116 @@ export function register<

// register("StormError", StormError.stringify, StormError.parse, isStormError);

register<Buffer, string>(
"Bytes",
v => v.toString("base64"),
v => Buffer.from(v, "base64"),
(v): v is Buffer => Buffer.isBuffer(v)
);
/**
* A static JSON parser class used by Storm Software to serialize and deserialize JSON
*
* @remarks
* This class uses the {@link https://github.com/blitz-js/superjson | SuperJSON} library
*/
export class StormParser extends SuperJSON {
static #instance: StormParser;

public static get instance(): StormParser {
if (!this.#instance) {
this.#instance = new StormParser();
}

return this.#instance;
}

/**
* Deserialize the given value with superjson using the given metadata
*/
public static override deserialize<TData = unknown>(
payload: JsonParserResult
): TData {
return StormParser.instance.deserialize(payload);
}

/**
* Serialize the given value with superjson
*/
public static override serialize(object: JsonValue): JsonParserResult {
return StormParser.instance.serialize(object);
}

/**
* Parse the given value with superjson using the given metadata
*/
public static override parse<TData = unknown>(strData: string): TData {
return StormParser.instance.parse(strData);
}

/**
* Stringify the given value with superjson
*/
public static override stringify(json: any): string {
return StormParser.instance.stringify(json);
}

/**
* Register a custom schema with superjson
*
* @param name - The name of the schema
* @param serialize - The function to serialize the schema
* @param deserialize - The function to deserialize the schema
* @param isApplicable - The function to check if the schema is applicable
*/
public static register<
TData = any,
TJsonObject extends JsonValue = JsonValue
>(
name: string,
serialize: (data: TData) => TJsonObject,
deserialize: (json: TJsonObject) => TData,
isApplicable: (data: any) => data is TData
) {
StormParser.instance.registerCustom<TData, TJsonObject>(
{ isApplicable, serialize, deserialize },
name
);
}

/**
* Register a class with superjson
*
* @param classConstructor - The class constructor to register
*/
public static override registerClass(
classConstructor: Class,
options?: { identifier?: string; allowProps?: string[] } | string
) {
StormParser.instance.registerClass(classConstructor, {
identifier: isString(options)
? options
: options?.identifier
? options?.identifier
: classConstructor.name,
allowProps:
options &&
isObject(options) &&
options?.allowProps &&
Array.isArray(options.allowProps)
? options.allowProps
: ["__typename"]
});
}

private constructor() {
super({ dedupe: true });

_register<Buffer, string>(
"Bytes",
v => v.toString("base64"),
v => Buffer.from(v, "base64"),
(v): v is Buffer => Buffer.isBuffer(v)
);
}
}

export const registerClass = StormParser.registerClass;
export const register = StormParser.register;
export const deserialize = StormParser.deserialize;
export const serialize = StormParser.serialize;
export const parse = StormParser.parse;
export const stringify = StormParser.stringify;

0 comments on commit 326970f

Please sign in to comment.