aboutsummaryrefslogtreecommitdiff
path: root/src/server/websocket.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/websocket.ts')
-rw-r--r--src/server/websocket.ts84
1 files changed, 58 insertions, 26 deletions
diff --git a/src/server/websocket.ts b/src/server/websocket.ts
index e5692a7dd..7d111f359 100644
--- a/src/server/websocket.ts
+++ b/src/server/websocket.ts
@@ -207,9 +207,12 @@ export namespace WebSocket {
}
}
+ function GetRefFieldLocal([id, callback]: [string, (result?: Transferable) => void]) {
+ return Database.Instance.getDocument(id, callback);
+ }
function GetRefField([id, callback]: [string, (result?: Transferable) => void]) {
process.stdout.write(`.`);
- Database.Instance.getDocument(id, callback);
+ GetRefFieldLocal([id, callback]);
}
function GetRefFields([ids, callback]: [string[], (result?: Transferable[]) => void]) {
@@ -275,18 +278,20 @@ export namespace WebSocket {
diff.diff.$set = diff.diff.$addToSet; delete diff.diff.$addToSet;// convert add to set to a query of the current fields, and then a set of the composition of the new fields with the old ones
const updatefield = Array.from(Object.keys(diff.diff.$set))[0];
const newListItems = diff.diff.$set[updatefield].fields;
- const curList = (curListItems as any)?.fields?.[updatefield.replace("fields.", "")]?.fields || [];
- diff.diff.$set[updatefield].fields = [...curList, ...newListItems.filter((newItem: any) => !curList.some((curItem: any) => curItem.fieldId ? curItem.fieldId === newItem.fieldId : curItem.heading ? curItem.heading === newItem.heading : curItem === newItem))];
+ const curList = (curListItems as any)?.fields?.[updatefield.replace("fields.", "")]?.fields.filter((item: any) => item !== undefined) || [];
+ diff.diff.$set[updatefield].fields = [...curList, ...newListItems.filter((newItem: any) => newItem && !curList.some((curItem: any) => curItem.fieldId ? curItem.fieldId === newItem.fieldId : curItem.heading ? curItem.heading === newItem.heading : curItem === newItem))];
const sendBack = diff.diff.length !== diff.diff.$set[updatefield].fields.length;
delete diff.diff.length;
Database.Instance.update(diff.id, diff.diff,
() => {
if (sendBack) {
+ console.log("RET BACK");
const id = socket.id;
socket.id = "";
socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
socket.id = id;
} else socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
+ dispatchNextOp(diff.id);
}, false);
}
@@ -301,47 +306,74 @@ export namespace WebSocket {
Database.Instance.update(diff.id, diff.diff,
() => {
if (sendBack) {
+ console.log("SEND BACK");
const id = socket.id;
socket.id = "";
socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
socket.id = id;
} else socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
+ dispatchNextOp(diff.id);
}, false);
}
+ const pendingOps = new Map<string, { diff: Diff, socket: Socket }[]>();
+
+ function dispatchNextOp(id: string) {
+ const next = pendingOps.get(id)!.shift();
+ if (next) {
+ const { diff, socket } = next;
+ if (diff.diff.$addToSet) {
+ return GetRefFieldLocal([diff.id, (result?: Transferable) => addToListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
+ }
+ if (diff.diff.$remFromSet) {
+ return GetRefFieldLocal([diff.id, (result?: Transferable) => remFromListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
+ }
+ return GetRefFieldLocal([diff.id, (result?: Transferable) => SetField(socket, diff, result)]);
+ }
+ if (!pendingOps.get(id)!.length) pendingOps.delete(id);
+ }
function UpdateField(socket: Socket, diff: Diff) {
- if (diff.diff.$addToSet) return GetRefField([diff.id, (result?: Transferable) => addToListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
- if (diff.diff.$remFromSet) return GetRefField([diff.id, (result?: Transferable) => remFromListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
- return GetRefField([diff.id, (result?: Transferable) => SetField(socket, diff, result)]);
+ if (pendingOps.has(diff.id)) {
+ pendingOps.get(diff.id)!.push({ diff, socket });
+ return true;
+ }
+ pendingOps.set(diff.id, [{ diff, socket }]);
+ if (diff.diff.$addToSet) {
+ return GetRefFieldLocal([diff.id, (result?: Transferable) => addToListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
+ }
+ if (diff.diff.$remFromSet) {
+ return GetRefFieldLocal([diff.id, (result?: Transferable) => remFromListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
+ }
+ return GetRefFieldLocal([diff.id, (result?: Transferable) => SetField(socket, diff, result)]);
}
function SetField(socket: Socket, diff: Diff, curListItems?: Transferable) {
Database.Instance.update(diff.id, diff.diff,
() => socket.broadcast.emit(MessageStore.UpdateField.Message, diff), false);
const docfield = diff.diff.$set || diff.diff.$unset;
- if (!docfield) {
- return;
- }
- const update: any = { id: diff.id };
- let dynfield = false;
- for (let key in docfield) {
- if (!key.startsWith("fields.")) continue;
- dynfield = true;
- const val = docfield[key];
- key = key.substring(7);
- Object.values(suffixMap).forEach(suf => { update[key + getSuffix(suf)] = { set: null }; });
- const term = ToSearchTerm(val);
- if (term !== undefined) {
- const { suffix, value } = term;
- update[key + suffix] = { set: value };
- if (key.endsWith('lastModified')) {
- update["lastModified" + suffix] = value;
+ if (docfield) {
+ const update: any = { id: diff.id };
+ let dynfield = false;
+ for (let key in docfield) {
+ if (!key.startsWith("fields.")) continue;
+ dynfield = true;
+ const val = docfield[key];
+ key = key.substring(7);
+ Object.values(suffixMap).forEach(suf => { update[key + getSuffix(suf)] = { set: null }; });
+ const term = ToSearchTerm(val);
+ if (term !== undefined) {
+ const { suffix, value } = term;
+ update[key + suffix] = { set: value };
+ if (key.endsWith('lastModified')) {
+ update["lastModified" + suffix] = value;
+ }
}
}
+ if (dynfield) {
+ Search.updateDocument(update);
+ }
}
- if (dynfield) {
- Search.updateDocument(update);
- }
+ dispatchNextOp(diff.id);
}
function DeleteField(socket: Socket, id: string) {