diff options
Diffstat (limited to 'src/new_fields')
| -rw-r--r-- | src/new_fields/Doc.ts | 9 | ||||
| -rw-r--r-- | src/new_fields/Proxy.ts | 2 | ||||
| -rw-r--r-- | src/new_fields/Types.ts | 22 |
3 files changed, 21 insertions, 12 deletions
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 8cbd8cf38..10e8fe7ec 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -32,9 +32,8 @@ export class ObjectField { export type Field = number | string | boolean | ObjectField | RefField; export type Opt<T> = T | undefined; -export type FieldWaiting = null; -export const FieldWaiting: FieldWaiting = null; -export type FieldValue<T extends Field = Field> = Opt<T> | FieldWaiting; +export type FieldWaiting<T extends Field = Field> = Promise<T | undefined>; +export type FieldValue<T extends Field = Field> = Opt<T> | FieldWaiting<T>; export const Self = Symbol("Self"); @@ -58,7 +57,7 @@ export class Doc extends RefField { @serializable(alias("fields", map(autoObject()))) @observable - private __fields: { [key: string]: Field | null | undefined } = {}; + private __fields: { [key: string]: Field | FieldWaiting | undefined } = {}; private [Update] = (diff: any) => { DocServer.UpdateField(this[Id], diff); @@ -78,7 +77,7 @@ export namespace Doc { return Cast(field, ctor); }); } - export function Get(doc: Doc, key: string, ignoreProto: boolean = false): Field | null | undefined { + export function Get(doc: Doc, key: string, ignoreProto: boolean = false): FieldValue { const self = doc[Self]; return getField(self, key, ignoreProto); } diff --git a/src/new_fields/Proxy.ts b/src/new_fields/Proxy.ts index 6a78388c1..2aa78731e 100644 --- a/src/new_fields/Proxy.ts +++ b/src/new_fields/Proxy.ts @@ -50,6 +50,6 @@ export class ProxyField<T extends RefField> extends ObjectField { })); } callback && this.promise.then(callback); - return null; + return this.promise; } } diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts index 0fbd8984c..0392dc2fb 100644 --- a/src/new_fields/Types.ts +++ b/src/new_fields/Types.ts @@ -1,4 +1,4 @@ -import { Field, Opt } from "./Doc"; +import { Field, Opt, FieldWaiting, FieldValue } from "./Doc"; import { List } from "./List"; export type ToType<T> = @@ -6,7 +6,7 @@ export type ToType<T> = T extends "number" ? number : T extends "boolean" ? boolean : T extends ListSpec<infer U> ? List<U> : - T extends { new(...args: any[]): infer R } ? R : never; + T extends { new(...args: any[]): infer R } ? (R | Promise<R>) : never; export type ToConstructor<T> = T extends string ? "string" : @@ -35,10 +35,13 @@ export interface Interface { export type FieldCtor<T extends Field> = T extends List<infer R> ? ListSpec<R> : ToConstructor<T>; -export function Cast<T extends FieldCtor<Field>>(field: Field | null | undefined, ctor: T): ToType<T> | null | undefined; -export function Cast<T extends FieldCtor<Field>>(field: Field | null | undefined, ctor: T, defaultVal: ToType<T>): ToType<T>; -export function Cast<T extends FieldCtor<Field>>(field: Field | null | undefined, ctor: T, defaultVal?: ToType<T>): ToType<T> | null | undefined { - if (field !== undefined && field !== null) { +export function Cast<T extends FieldCtor<Field>>(field: Field | FieldWaiting | undefined, ctor: T): FieldValue<ToType<T>>; +export function Cast<T extends FieldCtor<Field>>(field: Field | FieldWaiting | undefined, ctor: T, defaultVal: ToType<T>): ToType<T>; +export function Cast<T extends FieldCtor<Field>>(field: Field | FieldWaiting | undefined, ctor: T, defaultVal?: ToType<T>): FieldValue<ToType<T>> | undefined { + if (field instanceof Promise) { + return defaultVal === undefined ? field.then(f => Cast(f, ctor) as any) : defaultVal; + } + if (field !== undefined && !(field instanceof Promise)) { if (typeof ctor === "string") { if (typeof field === ctor) { return field as ToType<T>; @@ -59,3 +62,10 @@ export function FieldValue<T extends Field>(field: Opt<T> | Promise<Opt<T>>): Op export function FieldValue<T extends Field>(field: Opt<T> | Promise<Opt<T>>, defaultValue?: T): Opt<T> { return field instanceof Promise ? defaultValue : field; } + +export interface PromiseLike<T> { + then(callback: (field: Opt<T> | PromiseLike<T>) => void): void; +} +export function PromiseValue<T extends Field>(field: FieldValue<T>): PromiseLike<Opt<T>> { + return field instanceof Promise ? field : { then(cb: ((field: Opt<T>) => void)) { return cb(field); } }; +}
\ No newline at end of file |
