aboutsummaryrefslogtreecommitdiff
path: root/src/new_fields
diff options
context:
space:
mode:
Diffstat (limited to 'src/new_fields')
-rw-r--r--src/new_fields/Doc.ts11
-rw-r--r--src/new_fields/Proxy.ts4
-rw-r--r--src/new_fields/util.ts36
3 files changed, 40 insertions, 11 deletions
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 9bacf49ba..cce4fff5d 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -2,7 +2,7 @@ import { observable, action } from "mobx";
import { serializable, primitive, map, alias, list } from "serializr";
import { autoObject, SerializationHelper, Deserializable } from "../client/util/SerializationHelper";
import { DocServer } from "../client/DocServer";
-import { setter, getter, getField, updateFunction, deleteProperty } from "./util";
+import { setter, getter, getField, updateFunction, deleteProperty, makeEditable, makeReadOnly } from "./util";
import { Cast, ToConstructor, PromiseValue, FieldValue, NumCast } from "./Types";
import { listSpec } from "./Schema";
import { ObjectField } from "./ObjectField";
@@ -156,6 +156,15 @@ export namespace Doc {
// return Cast(field, ctor);
// });
// }
+ export function MakeReadOnly(): { end(): void } {
+ makeReadOnly();
+ return {
+ end() {
+ makeEditable();
+ }
+ };
+ }
+
export function Get(doc: Doc, key: string, ignoreProto: boolean = false): FieldResult {
const self = doc[Self];
return getField(self, key, ignoreProto);
diff --git a/src/new_fields/Proxy.ts b/src/new_fields/Proxy.ts
index 130ec066e..38d874a68 100644
--- a/src/new_fields/Proxy.ts
+++ b/src/new_fields/Proxy.ts
@@ -48,9 +48,8 @@ export class ProxyField<T extends RefField> extends ObjectField {
private failed = false;
private promise?: Promise<any>;
- value(callback?: ((field: T | undefined) => void)): T | undefined | FieldWaiting {
+ value(): T | undefined | FieldWaiting {
if (this.cache) {
- callback && callback(this.cache);
return this.cache;
}
if (this.failed) {
@@ -64,7 +63,6 @@ export class ProxyField<T extends RefField> extends ObjectField {
return field;
}));
}
- callback && this.promise.then(callback);
return this.promise;
}
}
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index 8cb1db953..cc937c567 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -6,10 +6,13 @@ import { FieldValue } from "./Types";
import { RefField } from "./RefField";
import { ObjectField } from "./ObjectField";
import { action } from "mobx";
-import { Parent, OnUpdate, Update, Id, SelfProxy } from "./FieldSymbols";
+import { Parent, OnUpdate, Update, Id, SelfProxy, Self } from "./FieldSymbols";
import { ComputedField } from "../fields/ScriptField";
-export const setter = action(function (target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
+function _readOnlySetter(): never {
+ throw new Error("Documents can't be modified in read-only mode");
+}
+const _setterImpl = action(function (target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
if (SerializationHelper.IsSerializing()) {
target[prop] = value;
return true;
@@ -53,6 +56,20 @@ export const setter = action(function (target: any, prop: string | symbol | numb
return true;
});
+let _setter: (target: any, prop: string | symbol | number, value: any, receiver: any) => boolean = _setterImpl;
+
+export function makeReadOnly() {
+ _setter = _readOnlySetter;
+}
+
+export function makeEditable() {
+ _setter = _setterImpl;
+}
+
+export function setter(target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
+ return _setter(target, prop, value, receiver);
+}
+
export function getter(target: any, prop: string | symbol | number, receiver: any): any {
if (typeof prop === "symbol") {
return target.__fields[prop] || target[prop];
@@ -60,25 +77,30 @@ export function getter(target: any, prop: string | symbol | number, receiver: an
if (SerializationHelper.IsSerializing()) {
return target[prop];
}
- return getField(target, prop);
+ return getFieldImpl(target, prop, receiver);
}
-export function getField(target: any, prop: string | number, ignoreProto: boolean = false): any {
+function getFieldImpl(target: any, prop: string | number, receiver: any, ignoreProto: boolean = false): any {
+ receiver = receiver || target[SelfProxy];
const field = target.__fields[prop];
if (field instanceof ProxyField) {
return field.value();
}
if (field instanceof ComputedField) {
- return field.value;
+ return field.value(receiver);
}
if (field === undefined && !ignoreProto && prop !== "proto") {
- const proto = getField(target, "proto", true);
+ const proto = getFieldImpl(target, "proto", receiver, true);//TODO tfs: instead of receiver we could use target[SelfProxy]... I don't which semantics we want or if it really matters
if (proto instanceof Doc) {
- return proto[prop];
+ return getFieldImpl(proto[Self], prop, receiver, ignoreProto);
}
return undefined;
}
return field;
+
+}
+export function getField(target: any, prop: string | number, ignoreProto: boolean = false): any {
+ return getFieldImpl(target, prop, undefined, ignoreProto);
}
export function deleteProperty(target: any, prop: string | number | symbol) {