Refactor serialization

This commit is contained in:
schmelczerandras 2020-10-07 10:04:05 +02:00
parent 8e44dd3733
commit b3da27e73b
35 changed files with 142 additions and 133 deletions

View file

@ -0,0 +1 @@
export type DeserializableClass = { new(...args: Array<any>): {}; name: string };

View file

@ -0,0 +1,13 @@
import { serializableMapping } from './serializable-mapping';
export const deserialize = (json: string): any => {
return JSON.parse(json, (k, v) => {
const possibleType = v[0];
const overridableConstructor = serializableMapping.get(possibleType);
if (overridableConstructor) {
v.shift();
return new overridableConstructor.constructor(...v);
}
return v;
});
};

View file

@ -0,0 +1,13 @@
import { DeserializableClass } from './deserializable-class';
import { SerializableClass } from './serializable-class';
import { serializableMapping } from './serializable-mapping';
export const overrideDeserialization = (
source: SerializableClass,
target: DeserializableClass
) => {
serializableMapping.set(source.name, {
constructor: target,
overriden: true,
});
};

View file

@ -0,0 +1,4 @@
export type SerializableClass = {
new(...args: Array<any>): { toArray(): Array<any> };
name: string;
};

View file

@ -0,0 +1,12 @@
import { DeserializableClass } from './deserializable-class';
/**
* @internal
*/
export const serializableMapping = new Map<
string,
{
constructor: DeserializableClass;
overriden: boolean;
}
>();

View file

@ -0,0 +1,16 @@
import { SerializableClass } from './serializable-class';
import { serializableMapping } from './serializable-mapping';
export const serializable = (type: SerializableClass): any => {
if (!serializableMapping.get(type.name)) {
serializableMapping.set(type.name, {
constructor: type,
overriden: false,
});
}
Object.defineProperty(type, '__serializable_type', { value: type.name });
Object.defineProperty(type.prototype, '__serializable_type', { value: type.name });
return type;
};

View file

@ -0,0 +1,8 @@
export const serialize = (object): string => {
return JSON.stringify(object, (_, value) => {
if (value?.__serializable_type) {
return [value.__serializable_type, ...value.toArray()];
}
return value?.toFixed ? Number(value.toFixed(3)) : value;
});
};

View file

@ -0,0 +1,20 @@
import { SerializableClass } from './serializable-class';
import { serializableMapping } from './serializable-mapping';
export const serializesTo = (target: SerializableClass) => {
return (actual: SerializableClass): any => {
if (!serializableMapping.get(target.name)) {
serializableMapping.set(target.name, {
constructor: target,
overriden: false,
});
}
Object.defineProperty(actual, '__serializable_type', { value: target.name });
Object.defineProperty(actual.prototype, '__serializable_type', {
value: target.name,
});
return actual;
};
};