aboutsummaryrefslogtreecommitdiff
path: root/src/fields
diff options
context:
space:
mode:
Diffstat (limited to 'src/fields')
-rw-r--r--src/fields/Doc.ts1
-rw-r--r--src/fields/List.ts7
-rw-r--r--src/fields/util.ts54
3 files changed, 45 insertions, 17 deletions
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index a8a5ba9bd..54d85ba86 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -104,6 +104,7 @@ const AclMap = new Map<string, symbol>([
]);
export function fetchProto(doc: Doc) {
+ if (!doc) return;
const permissions: { [key: string]: symbol } = {};
Object.keys(doc).filter(key => key.startsWith("acl") && (permissions[key] = AclMap.get(StrCast(doc[key]))!));
diff --git a/src/fields/List.ts b/src/fields/List.ts
index c9e4bd3c1..ceb538b2d 100644
--- a/src/fields/List.ts
+++ b/src/fields/List.ts
@@ -43,7 +43,7 @@ const listHandlers: any = {
}
}
const res = list.__fields.push(...items);
- this[Update]();
+ this[Update]({ op: "$addToSet", items });
return res;
}),
reverse() {
@@ -66,6 +66,7 @@ const listHandlers: any = {
this[Self].__realFields(); // coerce retrieving entire array
items = items.map(toObjectField);
const list = this[Self];
+ const removed = list.__fields.filter((item: any, i: number) => i >= start && i < start + deleteCount);
for (let i = 0; i < items.length; i++) {
const item = items[i];
//TODO Error checking to make sure parent doesn't already exist
@@ -76,7 +77,7 @@ const listHandlers: any = {
}
}
const res = list.__fields.splice(start, deleteCount, ...items);
- this[Update]();
+ this[Update](items.length === 0 && deleteCount ? { op: "$remFromSet", items: removed } : undefined);
return res.map(toRealField);
}),
unshift(...items: any[]) {
@@ -314,7 +315,7 @@ class ListImpl<T extends Field> extends ObjectField {
// console.log(diff);
const update = this[OnUpdate];
// update && update(diff);
- update?.();
+ update?.(diff);
}
private [Self] = this;
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 4da9fce74..8a694de83 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -11,7 +11,7 @@ import { ComputedField } from "./ScriptField";
import { ScriptCast, StrCast } from "./Types";
import { returnZero } from "../Utils";
import CursorField from "./CursorField";
-
+import { List } from "./List";
function _readOnlySetter(): never {
throw new Error("Documents can't be modified in read-only mode");
@@ -93,7 +93,7 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number
} else {
DocServer.registerDocWithCachedUpdate(receiver, prop as string, curValue);
}
- UndoManager.AddEvent({
+ !receiver[UpdatingFromServer] && UndoManager.AddEvent({
redo: () => receiver[prop] = value,
undo: () => receiver[prop] = curValue
});
@@ -371,18 +371,44 @@ export function deleteProperty(target: any, prop: string | number | symbol) {
export function updateFunction(target: any, prop: any, value: any, receiver: any) {
let current = ObjectField.MakeCopy(value);
return (diff?: any) => {
- if (true || !diff) {
- diff = { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } };
- const oldValue = current;
- const newValue = ObjectField.MakeCopy(value);
- current = newValue;
- if (!(value instanceof CursorField) && !(value?.some?.((v: any) => v instanceof CursorField))) {
- UndoManager.AddEvent({
- redo() { receiver[prop] = newValue; },
- undo() { receiver[prop] = oldValue; }
- });
- }
+ const op = diff?.op === "$addToSet" ? { '$addToSet': { ["fields." + prop]: SerializationHelper.Serialize(new List<Doc>(diff.items)) } } :
+ diff?.op === "$remFromSet" ? { '$remFromSet': { ["fields." + prop]: SerializationHelper.Serialize(new List<Doc>(diff.items)) } }
+ : { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } };
+ const oldValue = current;
+ const newValue = ObjectField.MakeCopy(value);
+ current = newValue;
+ if (!(value instanceof CursorField) && !(value?.some?.((v: any) => v instanceof CursorField))) {
+ !receiver[UpdatingFromServer] && UndoManager.AddEvent(
+ diff?.op === "$addToSet" ?
+ {
+ redo: () => {
+ receiver[prop].push(...diff.items);
+ },
+ undo: action(() => {
+ let curList = receiver[prop];
+ //while (curList[ForwardUpates]) curList = curList[ForwardUpates];
+ diff.items.forEach((doc: any) => {
+ const ind = curList.indexOf(doc.value());
+ ind !== -1 && curList.splice(ind, 1);
+ });
+ })
+ } :
+ diff?.op === "$remFromSet" ?
+ {
+ redo: action(() => {
+ let curList = receiver[prop];
+ diff.items.forEach((doc: any) => {
+ const ind = curList.indexOf(doc.value());
+ ind !== -1 && curList.splice(ind, 1);
+ });
+ }),
+ undo: () => receiver[prop].push(...diff.items)
+ }
+ : {
+ redo: () => receiver[prop] = newValue,
+ undo: () => receiver[prop] = oldValue
+ });
}
- target[Update](diff);
+ target[Update](op);
};
} \ No newline at end of file