diff options
Diffstat (limited to 'src/fields')
| -rw-r--r-- | src/fields/Proxy.ts | 66 | 
1 files changed, 56 insertions, 10 deletions
| diff --git a/src/fields/Proxy.ts b/src/fields/Proxy.ts index 07553f17c..62734d3d2 100644 --- a/src/fields/Proxy.ts +++ b/src/fields/Proxy.ts @@ -9,33 +9,72 @@ import { Id, Copy, ToScriptString, ToString } from "./FieldSymbols";  import { scriptingGlobal } from "../client/util/Scripting";  import { Plugins } from "./util"; -@Deserializable("proxy") +function deserializeProxy(field: any) { +    if (!field.cache) { +        field.cache = DocServer.GetCachedRefField(field.fieldId) as any; +    } +} +@Deserializable("proxy", deserializeProxy)  export class ProxyField<T extends RefField> extends ObjectField {      constructor();      constructor(value: T);      constructor(fieldId: string);      constructor(value?: T | string) {          super(); -        this.fieldId = typeof value === "string" ? value : (value?.[Id] ?? ""); +        if (typeof value === "string") { +            this.cache = DocServer.GetCachedRefField(value) as any; +            this.fieldId = value; +        } else if (value) { +            this.cache = value; +            this.fieldId = value[Id]; +        } +    } + +    [Copy]() { +        if (this.cache) return new ProxyField<T>(this.cache); +        return new ProxyField<T>(this.fieldId);      } -    [Copy]() { return new ProxyField<T>((this.cache ?? this.fieldId) as T); } -    [ToScriptString]() { return "invalid"; } -    [ToString]() { return "ProxyField"; } +    [ToScriptString]() { +        return "invalid"; +    } +    [ToString]() { +        return "ProxyField"; +    }      @serializable(primitive())      readonly fieldId: string = ""; + +    // This getter/setter and nested object thing is  +    // because mobx doesn't play well with observable proxies +    @observable.ref +    private _cache: { readonly field: T | undefined } = { field: undefined }; +    private get cache(): T | undefined { +        return this._cache.field; +    } +    private set cache(field: T | undefined) { +        this._cache = { field }; +    } +      private failed = false;      private promise?: Promise<any>; -    private get cache(): T | undefined { return DocServer.GetCachedRefField(this.fieldId) as T } -      value(): T | undefined | FieldWaiting<T> { -        if (this.cache) return this.cache; -        if (this.failed) return undefined; +        if (this.cache) { +            return this.cache; +        } +        if (this.failed) { +            return undefined; +        }          if (!this.promise) { +            const cached = DocServer.GetCachedRefField(this.fieldId); +            if (cached !== undefined) { +                runInAction(() => this.cache = cached as any); +                return cached as any; +            }              this.promise = DocServer.GetRefField(this.fieldId).then(action((field: any) => {                  this.promise = undefined; +                this.cache = field;                  if (field === undefined) this.failed = true;                  return field;              })); @@ -44,7 +83,14 @@ export class ProxyField<T extends RefField> extends ObjectField {      }      promisedValue(): string { return !this.cache && !this.failed && !this.promise ? this.fieldId : ""; }      setPromise(promise: any) { -        if (this.cache === undefined) this.promise = promise; +        this.promise = promise; +    } +    @action +    setValue(field: any) { +        this.promise = undefined; +        this.cache = field; +        if (field === undefined) this.failed = true; +        return field;      }  } | 
