diff options
author | Tyler Schicke <tyler_schicke@brown.edu> | 2019-04-17 19:45:59 -0400 |
---|---|---|
committer | Tyler Schicke <tyler_schicke@brown.edu> | 2019-04-17 19:45:59 -0400 |
commit | 9712a046868ee51a565a425d3216a2bb297c4eee (patch) | |
tree | d2adc9a47fb41ab9386dcdc0dc7e6404ad51df23 /src/client/util/SerializationHelper.ts | |
parent | 6afdd5e5136394c9dc739b5de390aa1b55c6360f (diff) |
Got saving to database working
Diffstat (limited to 'src/client/util/SerializationHelper.ts')
-rw-r--r-- | src/client/util/SerializationHelper.ts | 73 |
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), |