aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/SerializationHelper.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util/SerializationHelper.ts')
-rw-r--r--src/client/util/SerializationHelper.ts72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts
new file mode 100644
index 000000000..656101c95
--- /dev/null
+++ b/src/client/util/SerializationHelper.ts
@@ -0,0 +1,72 @@
+import { PropSchema, serialize, deserialize, custom } from "serializr";
+import { Field } from "../../fields/NewDoc";
+
+export class SerializationHelper {
+
+ public static Serialize(obj: Field): any {
+ if (!obj) {
+ return null;
+ }
+
+ if (typeof obj !== 'object') {
+ return obj;
+ }
+
+ if (!(obj.constructor.name in reverseMap)) {
+ throw Error(`type '${obj.constructor.name}' not registered. Make sure you register it using a @Deserializable decorator`);
+ }
+
+ const json = serialize(obj);
+ json.__type = reverseMap[obj.constructor.name];
+ return json;
+ }
+
+ public static Deserialize(obj: any): any {
+ if (!obj) {
+ return null;
+ }
+
+ if (typeof obj !== 'object') {
+ return obj;
+ }
+
+ if (!obj.__type) {
+ throw Error("No property 'type' found in JSON.");
+ }
+
+ if (!(obj.__type in serializationTypes)) {
+ throw Error(`type '${obj.__type}' not registered. Make sure you register it using a @Deserializable decorator`);
+ }
+
+ return deserialize(serializationTypes[obj.__type], obj);
+ }
+}
+
+let serializationTypes: { [name: string]: any } = {};
+let reverseMap: { [ctor: string]: string } = {};
+
+export function Deserializable(name: string): Function;
+export function Deserializable(constructor: Function): void;
+export function Deserializable(constructor: Function | string): Function | void {
+ function addToMap(name: string, ctor: Function) {
+ if (!(name in serializationTypes)) {
+ serializationTypes[name] = constructor;
+ reverseMap[ctor.name] = name;
+ } else {
+ throw new Error(`Name ${name} has already been registered as deserializable`);
+ }
+ }
+ if (typeof constructor === "string") {
+ return (ctor: Function) => {
+ addToMap(constructor, ctor);
+ };
+ }
+ addToMap(constructor.name, constructor);
+}
+
+export function autoObject(): PropSchema {
+ return custom(
+ (s) => SerializationHelper.Serialize(s),
+ (s) => SerializationHelper.Deserialize(s)
+ );
+} \ No newline at end of file