From 93c81b9fcc93dd05d723f7f103bc38fff9e21786 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Tue, 23 Jul 2019 15:19:34 -0400 Subject: Added async deserialization and got captures for script fields working again --- src/client/util/SerializationHelper.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src/client/util/SerializationHelper.ts') diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts index dca539f3b..692d07c74 100644 --- a/src/client/util/SerializationHelper.ts +++ b/src/client/util/SerializationHelper.ts @@ -28,7 +28,7 @@ export namespace SerializationHelper { return json; } - export function Deserialize(obj: any): any { + export async function Deserialize(obj: any): Promise { if (obj === undefined || obj === null) { return undefined; } @@ -52,16 +52,19 @@ export namespace SerializationHelper { } const type = serializationTypes[obj.__type]; - const value = deserialize(type.ctor, obj); + const value = await new Promise(res => deserialize(type.ctor, obj, (err, result) => res(result))); if (type.afterDeserialize) { - type.afterDeserialize(value); + const currentSerialization = serializing; + serializing = 0; + await type.afterDeserialize(value); + serializing = currentSerialization; } serializing -= 1; return value; } } -let serializationTypes: { [name: string]: { ctor: { new(): any }, afterDeserialize?: (obj: any) => void } } = {}; +let serializationTypes: { [name: string]: { ctor: { new(): any }, afterDeserialize?: (obj: any) => void | Promise } } = {}; let reverseMap: { [ctor: string]: string } = {}; export interface DeserializableOpts { @@ -69,7 +72,7 @@ export interface DeserializableOpts { withFields(fields: string[]): Function; } -export function Deserializable(name: string, afterDeserialize?: (obj: any) => void): DeserializableOpts; +export function Deserializable(name: string, afterDeserialize?: (obj: any) => void | Promise): DeserializableOpts; export function Deserializable(constructor: { new(...args: any[]): any }): void; export function Deserializable(constructor: { new(...args: any[]): any } | string, afterDeserialize?: (obj: any) => void): DeserializableOpts | void { function addToMap(name: string, ctor: { new(...args: any[]): any }) { @@ -135,6 +138,6 @@ export namespace Deserializable { export function autoObject(): PropSchema { return custom( (s) => SerializationHelper.Serialize(s), - (s) => SerializationHelper.Deserialize(s) + (json: any, context: any, oldValue: any, cb: (err: any, result: any) => void) => SerializationHelper.Deserialize(json).then(res => cb(null, res)) ); } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 35b1450709c751ae9782f60140d31718fed8146d Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Tue, 23 Jul 2019 18:22:19 -0400 Subject: Fixed async deserialization --- src/client/util/SerializationHelper.ts | 18 +++++++++--------- src/new_fields/Doc.ts | 8 ++++---- src/new_fields/List.ts | 4 ++-- src/new_fields/RefField.ts | 3 ++- 4 files changed, 17 insertions(+), 16 deletions(-) (limited to 'src/client/util/SerializationHelper.ts') diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts index 692d07c74..94b640afa 100644 --- a/src/client/util/SerializationHelper.ts +++ b/src/client/util/SerializationHelper.ts @@ -1,9 +1,14 @@ import { PropSchema, serialize, deserialize, custom, setDefaultModelSchema, getDefaultModelSchema, primitive, SKIP } from "serializr"; -import { Field } from "../../new_fields/Doc"; +import { Field, Doc } from "../../new_fields/Doc"; import { ClientUtils } from "./ClientUtils"; +let serializing = 0; +export function afterDocDeserialize(cb: (err: any, val: any) => void, err: any, newValue: any) { + serializing++; + cb(err, newValue); + serializing--; +} export namespace SerializationHelper { - let serializing: number = 0; export function IsSerializing() { return serializing > 0; } @@ -17,14 +22,14 @@ export namespace SerializationHelper { return obj; } - serializing += 1; + serializing++; 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; + serializing--; return json; } @@ -37,7 +42,6 @@ export namespace SerializationHelper { return obj; } - serializing += 1; if (!obj.__type) { if (ClientUtils.RELEASE) { console.warn("No property 'type' found in JSON."); @@ -54,12 +58,8 @@ export namespace SerializationHelper { const type = serializationTypes[obj.__type]; const value = await new Promise(res => deserialize(type.ctor, obj, (err, result) => res(result))); if (type.afterDeserialize) { - const currentSerialization = serializing; - serializing = 0; await type.afterDeserialize(value); - serializing = currentSerialization; } - serializing -= 1; return value; } } diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 45eb2e514..f0a2f7e07 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -1,6 +1,6 @@ import { observable, action } from "mobx"; -import { serializable, primitive, map, alias, list } from "serializr"; -import { autoObject, SerializationHelper, Deserializable } from "../client/util/SerializationHelper"; +import { serializable, primitive, map, alias, list, PropSchema, custom } from "serializr"; +import { autoObject, SerializationHelper, Deserializable, afterDocDeserialize } from "../client/util/SerializationHelper"; import { DocServer } from "../client/DocServer"; import { setter, getter, getField, updateFunction, deleteProperty, makeEditable, makeReadOnly } from "./util"; import { Cast, ToConstructor, PromiseValue, FieldValue, NumCast, BoolCast, StrCast } from "./Types"; @@ -61,7 +61,7 @@ export function DocListCastAsync(field: FieldResult, defaultValue?: Doc[]) { } export function DocListCast(field: FieldResult): Doc[] { - return Cast(field, listSpec(Doc), []).filter(d => d instanceof Doc) as Doc[]; + return Cast(field, listSpec(Doc), []).filter(d => d instanceof Doc) as Doc[]; j } export const WidthSym = Symbol("Width"); @@ -108,7 +108,7 @@ export class Doc extends RefField { proto: Opt; [key: string]: FieldResult; - @serializable(alias("fields", map(autoObject()))) + @serializable(alias("fields", map(autoObject(), { afterDeserialize: afterDocDeserialize }))) private get __fields() { return this.___fields; } diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts index a2133a990..0c7b77fa5 100644 --- a/src/new_fields/List.ts +++ b/src/new_fields/List.ts @@ -1,4 +1,4 @@ -import { Deserializable, autoObject } from "../client/util/SerializationHelper"; +import { Deserializable, autoObject, afterDocDeserialize } from "../client/util/SerializationHelper"; import { Field } from "./Doc"; import { setter, getter, deleteProperty, updateFunction } from "./util"; import { serializable, alias, list } from "serializr"; @@ -254,7 +254,7 @@ class ListImpl extends ObjectField { [key: number]: T | (T extends RefField ? Promise : never); - @serializable(alias("fields", list(autoObject()))) + @serializable(alias("fields", list(autoObject(), { afterDeserialize: afterDocDeserialize }))) private get __fields() { return this.___fields; } diff --git a/src/new_fields/RefField.ts b/src/new_fields/RefField.ts index 75ce4287f..5414df2b9 100644 --- a/src/new_fields/RefField.ts +++ b/src/new_fields/RefField.ts @@ -1,10 +1,11 @@ import { serializable, primitive, alias } from "serializr"; import { Utils } from "../Utils"; import { Id, HandleUpdate, ToScriptString } from "./FieldSymbols"; +import { afterDocDeserialize } from "../client/util/SerializationHelper"; export type FieldId = string; export abstract class RefField { - @serializable(alias("id", primitive())) + @serializable(alias("id", primitive({ afterDeserialize: afterDocDeserialize }))) private __id: FieldId; readonly [Id]: FieldId; -- cgit v1.2.3-70-g09d2