aboutsummaryrefslogtreecommitdiff
path: root/src/client/DocServer.ts
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2022-07-08 00:17:26 -0400
committerbobzel <zzzman@gmail.com>2022-07-08 00:17:26 -0400
commit146f8622d5bac2edc6b09f57c173bd057dfbcfad (patch)
treef871089c438a476543ca96bac163c0532b9557c7 /src/client/DocServer.ts
parentb7e66da6b23cdb41c127000dfe13843d35f7d0cc (diff)
restructured currentUserUtils to avoid having import cycles.
Diffstat (limited to 'src/client/DocServer.ts')
-rw-r--r--src/client/DocServer.ts91
1 files changed, 42 insertions, 49 deletions
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index c9a30b8e3..1b0ba6bc3 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -1,27 +1,27 @@
-import * as io from 'socket.io-client';
-import { MessageStore, YoutubeQueryTypes, GestureContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent, MobileDocumentUploadContent } from "./../server/Message";
-import { Opt, Doc, UpdatingFromServer, updateCachedAcls } from '../fields/Doc';
-import { Utils, emptyFunction } from '../Utils';
-import { SerializationHelper } from './util/SerializationHelper';
-import { RefField } from '../fields/RefField';
-import { Id, HandleUpdate, Parent } from '../fields/FieldSymbols';
-import { GestureOverlay } from './views/GestureOverlay';
-import MobileInkOverlay from '../mobile/MobileInkOverlay';
import { runInAction } from 'mobx';
+import * as rp from 'request-promise';
+import * as io from 'socket.io-client';
+import { Doc, Opt, UpdatingFromServer } from '../fields/Doc';
+import { HandleUpdate, Id, Parent } from '../fields/FieldSymbols';
import { ObjectField } from '../fields/ObjectField';
+import { RefField } from '../fields/RefField';
import { StrCast } from '../fields/Types';
-import * as rp from 'request-promise';
+import MobileInkOverlay from '../mobile/MobileInkOverlay';
+import { emptyFunction, Utils } from '../Utils';
+import { GestureContent, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent, YoutubeQueryTypes } from './../server/Message';
+import { SerializationHelper } from './util/SerializationHelper';
+import { GestureOverlay } from './views/GestureOverlay';
/**
* This class encapsulates the transfer and cross-client synchronization of
* data stored only in documents (RefFields). In the process, it also
* creates and maintains a cache of documents so that they can be accessed
* more efficiently. Currently, there is no cache eviction scheme in place.
- *
+ *
* NOTE: while this class is technically abstracted to work with any [RefField], because
* [Doc] instances are the only [RefField] we need / have implemented at the moment, the documentation
* will treat all data used here as [Doc]s
- *
+ *
* Any time we want to write a new field to the database (via the server)
* or update ourselves based on the server's update message, that occurs here
*/
@@ -32,12 +32,12 @@ export namespace DocServer {
const strings: string[] = [];
Array.from(Object.keys(_cache)).forEach(key => {
const doc = _cache[key];
- if (doc instanceof Doc) strings.push(StrCast(doc.author) + " " + StrCast(doc.title) + " " + StrCast(Doc.GetT(doc, "title", "string", true)));
+ if (doc instanceof Doc) strings.push(StrCast(doc.author) + ' ' + StrCast(doc.title) + ' ' + StrCast(Doc.GetT(doc, 'title', 'string', true)));
});
- print && strings.sort().forEach((str, i) => console.log(i.toString() + " " + str));
- rp.post(Utils.prepend("/setCacheDocumentIds"), {
+ print && strings.sort().forEach((str, i) => console.log(i.toString() + ' ' + str));
+ rp.post(Utils.prepend('/setCacheDocumentIds'), {
body: {
- cacheDocumentIds: Array.from(Object.keys(_cache)).join(";"),
+ cacheDocumentIds: Array.from(Object.keys(_cache)).join(';'),
},
json: true,
});
@@ -50,8 +50,8 @@ export namespace DocServer {
export enum WriteMode {
Default = 0, //Anything goes
Playground = 1, //Playground (write own/no read other updates)
- LiveReadonly = 2,//Live Readonly (no write/read others)
- LivePlayground = 3,//Live Playground (write own/read others)
+ LiveReadonly = 2, //Live Readonly (no write/read others)
+ LivePlayground = 3, //Live Playground (write own/read others)
}
const fieldWriteModes: { [field: string]: WriteMode } = {};
const docsWithUpdates: { [field: string]: Set<Doc> } = {};
@@ -62,7 +62,7 @@ export namespace DocServer {
livePlaygroundFields.forEach(f => DocServer.setFieldWriteMode(f, DocServer.WriteMode.Playground));
}
export function IsPlaygroundField(field: string) {
- return DocServer.PlaygroundFields?.includes(field.replace(/^_/, ""));
+ return DocServer.PlaygroundFields?.includes(field.replace(/^_/, ''));
}
export function setFieldWriteMode(field: string, writeMode: WriteMode) {
@@ -83,7 +83,7 @@ export namespace DocServer {
export function registerDocWithCachedUpdate(doc: Doc, field: string, oldValue: any) {
let list = docsWithUpdates[field];
if (!list) {
- list = docsWithUpdates[field] = new Set;
+ list = docsWithUpdates[field] = new Set();
}
if (!list.has(doc)) {
Doc.AddCachedUpdate(doc, field, oldValue);
@@ -92,7 +92,6 @@ export namespace DocServer {
}
export namespace Mobile {
-
export function dispatchGesturePoints(content: GestureContent) {
Utils.Emit(_socket, MessageStore.GesturePoints, content);
}
@@ -111,17 +110,17 @@ export namespace DocServer {
}
}
- const instructions = "This page will automatically refresh after this alert is closed. Expect to reconnect after about 30 seconds.";
+ const instructions = 'This page will automatically refresh after this alert is closed. Expect to reconnect after about 30 seconds.';
function alertUser(connectionTerminationReason: string) {
switch (connectionTerminationReason) {
- case "crash":
+ case 'crash':
alert(`Dash has temporarily crashed. Administrators have been notified and the server is restarting itself. ${instructions}`);
break;
- case "temporary":
+ case 'temporary':
alert(`An administrator has chosen to restart the server. ${instructions}`);
break;
- case "exit":
- alert("An administrator has chosen to kill the server. Do not expect to reconnect until administrators start the server.");
+ case 'exit':
+ alert('An administrator has chosen to kill the server. Do not expect to reconnect until administrators start the server.');
break;
default:
console.log(`Received an unknown ConnectionTerminated message: ${connectionTerminationReason}`);
@@ -132,7 +131,7 @@ export namespace DocServer {
export function init(protocol: string, hostname: string, port: number, identifier: string) {
_cache = {};
GUID = identifier;
- protocol = protocol.startsWith("https") ? "wss" : "ws";
+ protocol = protocol.startsWith('https') ? 'wss' : 'ws';
_socket = io.connect(`${protocol}://${hostname}:${port}`);
// io.connect(`https://7f079dda.ngrok.io`);// if using ngrok, create a special address for the websocket
@@ -153,17 +152,17 @@ export namespace DocServer {
Utils.AddServerHandler(_socket, MessageStore.ConnectionTerminated, alertUser);
// mobile ink overlay socket events to communicate between mobile view and desktop view
- _socket.addEventListener("receiveGesturePoints", (content: GestureContent) => {
+ _socket.addEventListener('receiveGesturePoints', (content: GestureContent) => {
MobileInkOverlay.Instance.drawStroke(content);
});
- _socket.addEventListener("receiveOverlayTrigger", (content: MobileInkOverlayContent) => {
+ _socket.addEventListener('receiveOverlayTrigger', (content: MobileInkOverlayContent) => {
GestureOverlay.Instance.enableMobileInkOverlay(content);
MobileInkOverlay.Instance.initMobileInkOverlay(content);
});
- _socket.addEventListener("receiveUpdateOverlayPosition", (content: UpdateMobileInkOverlayPositionContent) => {
+ _socket.addEventListener('receiveUpdateOverlayPosition', (content: UpdateMobileInkOverlayPositionContent) => {
MobileInkOverlay.Instance.updatePosition(content);
});
- _socket.addEventListener("receiveMobileDocumentUpload", (content: MobileDocumentUploadContent) => {
+ _socket.addEventListener('receiveMobileDocumentUpload', (content: MobileDocumentUploadContent) => {
MobileInkOverlay.Instance.uploadDocument(content);
});
}
@@ -173,12 +172,11 @@ export namespace DocServer {
}
export namespace Control {
-
let _isReadOnly = false;
export function makeReadOnly() {
if (!_isReadOnly) {
_isReadOnly = true;
- _CreateField = field => _cache[field[Id]] = field;
+ _CreateField = field => (_cache[field[Id]] = field);
_UpdateField = emptyFunction;
_RespondToUpdate = emptyFunction; // bcz: option: don't clear RespondToUpdate to continue to receive updates as others change the DB
}
@@ -195,8 +193,9 @@ export namespace DocServer {
}
}
- export function isReadOnly() { return _isReadOnly; }
-
+ export function isReadOnly() {
+ return _isReadOnly;
+ }
}
/**
@@ -209,7 +208,6 @@ export namespace DocServer {
}
export namespace Util {
-
/**
* Emits a message to the server that wipes
* all documents in the database.
@@ -217,7 +215,6 @@ export namespace DocServer {
export function deleteDatabase() {
Utils.Emit(_socket, MessageStore.DeleteAll, {});
}
-
}
// RETRIEVE DOCS FROM SERVER
@@ -258,8 +255,7 @@ export namespace DocServer {
});
cached[UpdatingFromServer] = false;
return cached;
- }
- else if (field !== undefined) {
+ } else if (field !== undefined) {
_cache[id] = field;
} else {
delete _cache[id];
@@ -272,7 +268,7 @@ export namespace DocServer {
// here, indicate that the document associated with this id is currently
// being retrieved and cached
!force && (_cache[id] = deserializeField);
- return force ? cached as any : deserializeField;
+ return force ? (cached as any) : deserializeField;
} else if (cached instanceof Promise) {
// BEING RETRIEVED AND CACHED => some other caller previously (likely recently) called GetRefField(s),
// and requested the document I'm looking for. Shouldn't fetch again, just
@@ -316,7 +312,6 @@ export namespace DocServer {
Utils.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.VideoDetails, videoIds: videoIds }, callBack);
}
-
/**
* Given a list of Doc GUIDs, this utility function will asynchronously attempt to each id's associated
* field, first looking in the RefField cache and then communicating with
@@ -381,7 +376,7 @@ export namespace DocServer {
return deserialized;
});
// 4) here, for each of the documents we've requested *ourselves* (i.e. weren't promises or found in the cache)
- // we set the value at the field's id to a promise that will resolve to the field.
+ // we set the value at the field's id to a promise that will resolve to the field.
// When we find that promises exist at keys in the cache, THIS is where they were set, just by some other caller (method).
// The mapping in the .then call ensures that when other callers await these promises, they'll
// get the resolved field
@@ -391,7 +386,7 @@ export namespace DocServer {
proms.push(prom);
} else if (cached instanceof Promise) {
proms.push(cached as any);
- cached.then((f: any) => fieldMap[field.id] = f);
+ cached.then((f: any) => (fieldMap[field.id] = f));
} else if (field) {
proms.push(cached as any);
fieldMap[field.id] = DocServer.GetCachedRefField(field.id) || field;
@@ -413,20 +408,19 @@ export namespace DocServer {
const field = fields[id];
map[id] = field;
});
-
}
// 7) those promises we encountered in the else if of 1), which represent
// other callers having already submitted a request to the server for (a) document(s)
// in which we're interested, must still be awaited so that we can return the proper
- // values for those as well.
+ // values for those as well.
//
// fortunately, those other callers will also hit their own version of 6) and clean up
// the shared cache when these promises resolve, so all we have to do is...
const otherCallersFetching = await Promise.all(promises);
// ...extract the RefFields returned from the resolution of those promises and add them to our
// own map.
- waitingIds.forEach((id, index) => map[id] = otherCallersFetching[index]);
+ waitingIds.forEach((id, index) => (map[id] = otherCallersFetching[index]));
// now, we return our completed mapping from all of the ids that were passed into the method
// to their actual RefField | undefined values. This return value either becomes the input
@@ -476,7 +470,7 @@ export namespace DocServer {
}
function _UpdateFieldImpl(id: string, diff: any) {
- (!DocServer.Control.isReadOnly()) && Utils.Emit(_socket, MessageStore.UpdateField, { id, diff });
+ !DocServer.Control.isReadOnly() && Utils.Emit(_socket, MessageStore.UpdateField, { id, diff });
}
let _UpdateField: (id: string, diff: any) => void = errorFunc;
@@ -520,12 +514,11 @@ export namespace DocServer {
Utils.Emit(_socket, MessageStore.DeleteFields, ids);
}
-
function _respondToDeleteImpl(ids: string | string[]) {
function deleteId(id: string) {
delete _cache[id];
}
- if (typeof ids === "string") {
+ if (typeof ids === 'string') {
deleteId(ids);
} else if (Array.isArray(ids)) {
ids.map(deleteId);