Solve serialization
This commit is contained in:
parent
ba8b1a29fd
commit
8e44dd3733
45 changed files with 242 additions and 201 deletions
13
shared/src/transport/serializable/deserialize.ts
Normal file
13
shared/src/transport/serializable/deserialize.ts
Normal 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;
|
||||
});
|
||||
};
|
||||
58
shared/src/transport/serializable/serializable.ts
Normal file
58
shared/src/transport/serializable/serializable.ts
Normal 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;
|
||||
};
|
||||
};
|
||||
10
shared/src/transport/serializable/serialize.ts
Normal file
10
shared/src/transport/serializable/serialize.ts
Normal 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;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue