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.ts73
1 files changed, 63 insertions, 10 deletions
diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts
index 656101c95..7273c3fe4 100644
--- a/src/client/util/SerializationHelper.ts
+++ b/src/client/util/SerializationHelper.ts
@@ -1,9 +1,13 @@
-import { PropSchema, serialize, deserialize, custom } from "serializr";
+import { PropSchema, serialize, deserialize, custom, setDefaultModelSchema, getDefaultModelSchema, primitive, SKIP } from "serializr";
import { Field } from "../../fields/NewDoc";
-export class SerializationHelper {
+export namespace SerializationHelper {
+ let serializing: number = 0;
+ export function IsSerializing() {
+ return serializing > 0;
+ }
- public static Serialize(obj: Field): any {
+ export function Serialize(obj: Field): any {
if (!obj) {
return null;
}
@@ -12,16 +16,18 @@ export class SerializationHelper {
return obj;
}
+ serializing += 1;
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];
+ serializing -= 1;
return json;
}
- public static Deserialize(obj: any): any {
+ export function Deserialize(obj: any): any {
if (!obj) {
return null;
}
@@ -30,6 +36,7 @@ export class SerializationHelper {
return obj;
}
+ serializing += 1;
if (!obj.__type) {
throw Error("No property 'type' found in JSON.");
}
@@ -38,32 +45,78 @@ export class SerializationHelper {
throw Error(`type '${obj.__type}' not registered. Make sure you register it using a @Deserializable decorator`);
}
- return deserialize(serializationTypes[obj.__type], obj);
+ const value = deserialize(serializationTypes[obj.__type], obj);
+ serializing -= 1;
+ return value;
}
}
let serializationTypes: { [name: string]: any } = {};
let reverseMap: { [ctor: string]: string } = {};
-export function Deserializable(name: string): Function;
+export interface DeserializableOpts {
+ (constructor: Function): void;
+ withFields(fields: string[]): Function;
+}
+
+export function Deserializable(name: string): DeserializableOpts;
export function Deserializable(constructor: Function): void;
-export function Deserializable(constructor: Function | string): Function | void {
+export function Deserializable(constructor: Function | string): DeserializableOpts | void {
function addToMap(name: string, ctor: Function) {
if (!(name in serializationTypes)) {
- serializationTypes[name] = constructor;
+ serializationTypes[name] = ctor;
reverseMap[ctor.name] = name;
} else {
throw new Error(`Name ${name} has already been registered as deserializable`);
}
}
if (typeof constructor === "string") {
- return (ctor: Function) => {
+ return Object.assign((ctor: Function) => {
addToMap(constructor, ctor);
- };
+ }, { withFields: Deserializable.withFields });
}
addToMap(constructor.name, constructor);
}
+export namespace Deserializable {
+ export function withFields(fields: string[]) {
+ return function (constructor: { new(...fields: any[]): any }) {
+ Deserializable(constructor);
+ let schema = getDefaultModelSchema(constructor);
+ if (schema) {
+ schema.factory = context => {
+ const args = fields.map(key => context.json[key]);
+ return new constructor(...args);
+ };
+ // TODO A modified version of this would let us not reassign fields that we're passing into the constructor later on in deserializing
+ // fields.forEach(field => {
+ // if (field in schema.props) {
+ // let propSchema = schema.props[field];
+ // if (propSchema === false) {
+ // return;
+ // } else if (propSchema === true) {
+ // propSchema = primitive();
+ // }
+ // schema.props[field] = custom(propSchema.serializer,
+ // () => {
+ // return SKIP;
+ // });
+ // }
+ // });
+ } else {
+ schema = {
+ props: {},
+ factory: context => {
+ const args = fields.map(key => context.json[key]);
+ return new constructor(...args);
+ }
+ };
+ setDefaultModelSchema(constructor, schema);
+ }
+ };
+ }
+}
+
export function autoObject(): PropSchema {
return custom(
(s) => SerializationHelper.Serialize(s),