Solve serialization

This commit is contained in:
schmelczerandras 2020-10-06 21:33:04 +02:00
parent ba8b1a29fd
commit 8e44dd3733
45 changed files with 242 additions and 201 deletions

View file

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

View file

@ -0,0 +1,58 @@
export const serializableClasses = new Map<
string,
{
constructor: any;
overriden: boolean;
}
>();
export const serializable = (serializableType?) => {
return (type): any => {
const actualType = serializableType
? Object.getPrototypeOf((serializableType as any).prototype).constructor
: type;
const typeName = actualType.name;
const overridableConstructor = serializableClasses.get(typeName);
if (!overridableConstructor) {
serializableClasses.set(typeName, {
constructor: actualType,
overriden: false,
});
}
if (!Object.prototype.hasOwnProperty.call(actualType.prototype, 'toArray')) {
throw new Error(
`Class ${typeName} must define a toArray returning an array containing the arguments for its constructor.`
);
}
return class extends type {
public get type(): string {
return typeName;
}
public static get type(): string {
return typeName;
}
};
};
};
export const deserializable = (fromType) => {
return (type): any => {
const overridableConstructor = serializableClasses.get(fromType.name);
if (!overridableConstructor || !overridableConstructor.overriden) {
serializableClasses.set(fromType.name, {
constructor: type,
overriden: true,
});
} else {
throw new Error(
`Constructor ${fromType} already overriden, cannot override again with ${type}`
);
}
return type;
};
};

View file

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