aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/DocServer.ts21
-rw-r--r--src/client/views/GestureOverlay.tsx5
-rw-r--r--src/fields/Doc.ts3
-rw-r--r--src/fields/ObjectField.ts15
-rw-r--r--src/fields/util.ts20
-rw-r--r--src/server/IDatabase.ts8
-rw-r--r--src/server/MemoryDatabase.ts6
-rw-r--r--src/server/Message.ts66
-rw-r--r--src/server/apis/google/GoogleApiServerUtils.ts1
-rw-r--r--src/server/database.ts12
-rw-r--r--src/server/server_Initialization.ts7
11 files changed, 44 insertions, 120 deletions
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index 2bf3a6f9f..33fa928f2 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -8,7 +8,7 @@ import { UpdatingFromServer } from '../fields/DocSymbols';
import { FieldLoader } from '../fields/FieldLoader';
import { HandleUpdate, Id, Parent } from '../fields/FieldSymbols';
import { ObjectField, serverOpType } from '../fields/ObjectField';
-import { GestureContent, Message, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent } from '../server/Message';
+import { Message, MessageStore } from '../server/Message';
import { SerializationHelper } from './util/SerializationHelper';
/**
@@ -109,25 +109,6 @@ export namespace DocServer {
}
}
- export namespace Mobile {
- export function dispatchGesturePoints(content: GestureContent) {
- DocServer.Emit(_socket, MessageStore.GesturePoints, content);
- }
-
- export function dispatchOverlayTrigger(content: MobileInkOverlayContent) {
- // _socket.emit("dispatchBoxTrigger");
- DocServer.Emit(_socket, MessageStore.MobileInkOverlayTrigger, content);
- }
-
- export function dispatchOverlayPositionUpdate(content: UpdateMobileInkOverlayPositionContent) {
- DocServer.Emit(_socket, MessageStore.UpdateMobileInkOverlayPosition, content);
- }
-
- export function dispatchMobileDocumentUpload(content: MobileDocumentUploadContent) {
- DocServer.Emit(_socket, MessageStore.MobileDocumentUpload, content);
- }
- }
-
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) {
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index bcd4d1ee5..3a2738c3b 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -21,10 +21,8 @@ import {
SetActiveInkColor,
SetActiveInkWidth,
} from './nodes/DocumentView';
-// import MobileInkOverlay from '../../mobile/MobileInkOverlay';
import { Gestures } from '../../pen-gestures/GestureTypes';
import { GestureUtils } from '../../pen-gestures/GestureUtils';
-// import { MobileInkOverlayContent } from '../../server/Message';
import { InteractionUtils } from '../util/InteractionUtils';
import { ScriptingGlobals } from '../util/ScriptingGlobals';
import { Transform } from '../util/Transform';
@@ -71,8 +69,6 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
return this.Tool !== ToolglassTools.None;
}
- // @observable private showMobileInkOverlay: boolean = false;
-
private _overlayRef = React.createRef<HTMLDivElement>();
private _d1: Doc | undefined;
private _inkToTextDoc: Doc | undefined;
@@ -485,7 +481,6 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
render() {
return (
<div className="gestureOverlay-cont" style={{ pointerEvents: this._props.isActive ? 'all' : 'none' }} ref={this._overlayRef} onPointerDown={this.onPointerDown}>
- {/* {this.showMobileInkOverlay ? <MobileInkOverlay /> : null} */}
{this.elements}
<div
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 7e7c319bf..ad7609895 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -191,7 +191,6 @@ export class Doc extends RefField {
@observable public static RecordingEvent = 0;
@observable public static GuestDashboard: Doc | undefined = undefined;
@observable public static GuestTarget: Doc | undefined = undefined;
- @observable public static GuestMobile: Doc | undefined = undefined;
@observable.shallow public static CurrentlyLoading: Doc[] = observable([]);
// DocServer api
public static FindDocByTitle(title: string) {
@@ -379,7 +378,7 @@ export class Doc extends RefField {
private [CachedUpdates]: { [key: string]: () => void | Promise<void> } = {};
public [Initializing]: boolean = false;
- public [FieldChanged] = (diff: { op: '$addToSet' | '$remFromSet' | '$set'; items: FieldType[] | undefined; length: number | undefined; hint?: unknown } | undefined, serverOp: serverOpType) => {
+ public [FieldChanged] = (diff: { op: '$addToSet' | '$remFromSet' | '$set'; items: FieldType[] | undefined; length: number | undefined; hint?: { start: number; deleteCount: number } } | undefined, serverOp: serverOpType) => {
if (!this[UpdatingFromServer] || this[ForceServerWrite]) {
DocServer.UpdateField(this[Id], serverOp);
}
diff --git a/src/fields/ObjectField.ts b/src/fields/ObjectField.ts
index 21c4af608..5f31208eb 100644
--- a/src/fields/ObjectField.ts
+++ b/src/fields/ObjectField.ts
@@ -2,11 +2,18 @@ import { ScriptingGlobals } from '../client/util/ScriptingGlobals';
import { Copy, FieldChanged, Parent, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols';
import { RefField } from './RefField';
+export type serializedFieldType = { fieldId: string; heading?: string; __type: string };
+export type serializedFieldsType = { [key: string]: { fields: serializedFieldType[] } };
+export interface serializedDoctype {
+ readonly id: string;
+ readonly fields?: serializedFieldsType;
+}
+
export type serverOpType = {
- $set?: { [key: string]: unknown }; //
+ $set?: serializedFieldsType; //
$unset?: { [key: string]: unknown };
- $remFromSet?: { [key: string]: unknown };
- $addToSet?: { [key: string]: unknown };
+ $remFromSet?: { [key: string]: { fields: serializedFieldType[] } | { deleteCount: number; start: number } | undefined; hint?: { deleteCount: number; start: number } };
+ $addToSet?: serializedFieldsType;
length?: number;
};
export abstract class ObjectField {
@@ -15,7 +22,7 @@ export abstract class ObjectField {
// eslint-disable-next-line no-use-before-define
items: FieldType[] | undefined;
length: number | undefined;
- hint?: unknown },
+ hint?: { deleteCount: number, start: number} },
serverOp?: serverOpType) => void;
// eslint-disable-next-line no-use-before-define
public [Parent]?: RefField | ObjectField;
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 69ece82a2..a5c56607c 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -8,7 +8,7 @@ import { Doc, DocListCast, FieldType, FieldResult, HierarchyMapping, ReverseHier
import { AclAdmin, AclAugment, AclEdit, AclPrivate, DirectLinks, DocAcl, DocData, DocLayout, FieldKeys, ForceServerWrite, Height, Initializing, SelfProxy, UpdatingFromServer, Width } from './DocSymbols';
import { FieldChanged, Id, Parent, ToValue } from './FieldSymbols';
import { List, ListImpl } from './List';
-import { ObjectField } from './ObjectField';
+import { ObjectField, serializedFieldType, serverOpType } from './ObjectField';
import { PrefetchProxy, ProxyField } from './Proxy';
import { RefField } from './RefField';
import { RichTextField } from './RichTextField';
@@ -112,9 +112,9 @@ const _setterImpl = action((target: Doc | ListImpl<FieldType>, prop: string | sy
if (writeToServer) {
// prettier-ignore
- if (value === undefined)
+ if (value === undefined || value === null)
(target as Doc|ObjectField)[FieldChanged]?.(undefined, { $unset: { ['fields.' + prop]: '' } });
- else (target as Doc|ObjectField)[FieldChanged]?.(undefined, { $set: { ['fields.' + prop]: value instanceof ObjectField ? SerializationHelper.Serialize(value) :value}});
+ else (target as Doc|ObjectField)[FieldChanged]?.(undefined, { $set: { ['fields.' + prop]: (value instanceof ObjectField ? SerializationHelper.Serialize(value) :value) as { fields: serializedFieldType[]}}});
if (prop === 'author' || prop.toString().startsWith('acl_')) updateCachedAcls(target);
} else if (receiver instanceof Doc) {
DocServer.registerDocWithCachedUpdate(receiver, prop as string, curValue);
@@ -393,15 +393,15 @@ export function deleteProperty(target: Doc | ListImpl<FieldType>, prop: string |
// able to undo and redo the partial change.
//
export function containedFieldChangedHandler(container: ListImpl<FieldType> | Doc, prop: string | number, liveContainedField: ObjectField) {
- let lastValue: FieldResult = liveContainedField instanceof ObjectField ? ObjectField.MakeCopy(liveContainedField) : liveContainedField;
- return (diff?: { op: '$addToSet' | '$remFromSet' | '$set'; items: (FieldType & { value?: FieldType })[] | undefined; length: number | undefined; hint?: unknown } /* , dummyServerOp?: any */) => {
- const serializeItems = () => ({ __type: 'list', fields: diff?.items?.map((item: FieldType) => SerializationHelper.Serialize(item)) });
+ let lastValue = ObjectField.MakeCopy(liveContainedField);
+ return (diff?: { op: '$addToSet' | '$remFromSet' | '$set'; items: (FieldType & { value?: FieldType })[] | undefined; length: number | undefined; hint?: { start: number; deleteCount: number } } /* , dummyServerOp?: any */) => {
+ const serializeItems = () => ({ __type: 'list', fields: diff?.items?.map((item: FieldType) => SerializationHelper.Serialize(item) as serializedFieldType) ?? [] });
// prettier-ignore
- const serverOp = diff?.op === '$addToSet'
+ const serverOp: serverOpType = diff?.op === '$addToSet'
? { $addToSet: { ['fields.' + prop]: serializeItems() }, length: diff.length }
: diff?.op === '$remFromSet'
? { $remFromSet: { ['fields.' + prop]: serializeItems(), hint: diff.hint}, length: diff.length }
- : { $set: { ['fields.' + prop]: liveContainedField ? SerializationHelper.Serialize(liveContainedField) as FieldType : undefined } };
+ : { $set: { ['fields.' + prop]: SerializationHelper.Serialize(liveContainedField) as {fields: serializedFieldType[]}} };
if (!(container instanceof Doc) || !container[UpdatingFromServer]) {
const cont = container as { [key: string | number]: FieldType };
@@ -477,13 +477,13 @@ export function containedFieldChangedHandler(container: ListImpl<FieldType> | Do
// console.log('redo list: ' + prop, fieldVal()); // bcz: uncomment to log undo
setFieldVal(ObjectField.MakeCopy(newValue));
const containerProp = cont[prop];
- lastValue = containerProp instanceof ObjectField && ObjectField.MakeCopy(containerProp);
+ if (containerProp instanceof ObjectField) lastValue = ObjectField.MakeCopy(containerProp);
},
undo: () => {
// console.log('undo list: ' + prop, fieldVal()); // bcz: uncomment to log undo
setFieldVal(ObjectField.MakeCopy(prevValue));
const containerProp = cont[prop];
- lastValue = containerProp instanceof ObjectField && ObjectField.MakeCopy(containerProp);
+ if (containerProp instanceof ObjectField) lastValue = ObjectField.MakeCopy(containerProp);
},
prop: 'set list field',
},
diff --git a/src/server/IDatabase.ts b/src/server/IDatabase.ts
index 2274792b3..481b64d4a 100644
--- a/src/server/IDatabase.ts
+++ b/src/server/IDatabase.ts
@@ -1,5 +1,5 @@
import * as mongodb from 'mongodb';
-import { Transferable } from './Message';
+import { serializedDoctype } from '../fields/ObjectField';
export const DocumentsCollection = 'documents';
export interface IDatabase {
@@ -13,10 +13,10 @@ export interface IDatabase {
dropSchema(...schemaNames: string[]): Promise<any>;
- insert(value: any, collectionName?: string): Promise<void>;
+ insert(value: { _id: string }, collectionName?: string): Promise<void>;
- getDocument(id: string, fn: (result?: Transferable) => void, collectionName?: string): void;
- getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName?: string): void;
+ getDocument(id: string, fn: (result?: serializedDoctype) => void, collectionName?: string): void;
+ getDocuments(ids: string[], fn: (result: serializedDoctype[]) => void, collectionName?: string): void;
getCollectionNames(): Promise<string[]>;
visit(ids: string[], fn: (result: any) => string[] | Promise<string[]>, collectionName?: string): Promise<void>;
diff --git a/src/server/MemoryDatabase.ts b/src/server/MemoryDatabase.ts
index 1432d91c4..b838cb61b 100644
--- a/src/server/MemoryDatabase.ts
+++ b/src/server/MemoryDatabase.ts
@@ -1,6 +1,6 @@
import * as mongodb from 'mongodb';
+import { serializedDoctype } from '../fields/ObjectField';
import { DocumentsCollection, IDatabase } from './IDatabase';
-import { Transferable } from './Message';
export class MemoryDatabase implements IDatabase {
private db: { [collectionName: string]: { [id: string]: any } } = {};
@@ -81,10 +81,10 @@ export class MemoryDatabase implements IDatabase {
return Promise.resolve();
}
- public getDocument(id: string, fn: (result?: Transferable) => void, collectionName = DocumentsCollection): void {
+ public getDocument(id: string, fn: (result?: serializedDoctype) => void, collectionName = DocumentsCollection): void {
fn(this.getCollection(collectionName)[id]);
}
- public getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName = DocumentsCollection): void {
+ public getDocuments(ids: string[], fn: (result: serializedDoctype[]) => void, collectionName = DocumentsCollection): void {
fn(ids.map(id => this.getCollection(collectionName)[id]));
}
diff --git a/src/server/Message.ts b/src/server/Message.ts
index 03150c841..26b41539b 100644
--- a/src/server/Message.ts
+++ b/src/server/Message.ts
@@ -1,5 +1,6 @@
import * as uuid from 'uuid';
import { Point } from '../pen-gestures/ndollar';
+import { serverOpType } from '../fields/ObjectField';
function GenerateDeterministicGuid(seed: string): string {
return uuid.v5(seed, uuid.v5.URL);
@@ -22,52 +23,12 @@ export class Message<T> {
}
}
-export enum Types {
- Number,
- List,
- Key,
- Image,
- Web,
- Document,
- Text,
- Icon,
- RichText,
- DocumentReference,
- Html,
- Video,
- Audio,
- Ink,
- PDF,
- Tuple,
- Boolean,
- Script,
- Templates,
-}
-
-export interface Transferable {
- readonly id: string;
- readonly type: Types;
- readonly data?: any;
-}
-
-export enum YoutubeQueryTypes {
- Channels,
- SearchVideo,
- VideoDetails,
-}
-
-export interface YoutubeQueryInput {
- readonly type: YoutubeQueryTypes;
- readonly userInput?: string;
- readonly videoIds?: string;
-}
-
export interface Reference {
readonly id: string;
}
export interface Diff extends Reference {
- readonly diff: any;
+ readonly diff: serverOpType;
}
export interface GestureContent {
@@ -77,23 +38,6 @@ export interface GestureContent {
readonly color?: string;
}
-export interface MobileInkOverlayContent {
- readonly enableOverlay: boolean;
- readonly width?: number;
- readonly height?: number;
- readonly text?: string;
-}
-
-export interface UpdateMobileInkOverlayPositionContent {
- readonly dx?: number;
- readonly dy?: number;
- readonly dsize?: number;
-}
-
-export interface MobileDocumentUploadContent {
- readonly docId: string;
-}
-
export interface RoomMessage {
readonly message: string;
readonly room: string;
@@ -102,17 +46,11 @@ export interface RoomMessage {
export namespace MessageStore {
export const Foo = new Message<string>('Foo');
export const Bar = new Message<string>('Bar');
- export const SetField = new Message<Transferable>('Set Field'); // send Transferable (no reply)
- export const GetField = new Message<string>('Get Field'); // send string 'id' get Transferable back
- export const GetFields = new Message<string[]>('Get Fields'); // send string[] of 'id' get Transferable[] back
export const GetDocument = new Message<string>('Get Document');
export const DeleteAll = new Message<any>('Delete All');
export const ConnectionTerminated = new Message<string>('Connection Terminated');
export const GesturePoints = new Message<GestureContent>('Gesture Points');
- export const MobileInkOverlayTrigger = new Message<MobileInkOverlayContent>('Trigger Mobile Ink Overlay');
- export const UpdateMobileInkOverlayPosition = new Message<UpdateMobileInkOverlayPositionContent>('Update Mobile Ink Overlay Position');
- export const MobileDocumentUpload = new Message<MobileDocumentUploadContent>('Upload Document From Mobile');
export const GetRefField = new Message<string>('Get Ref Field');
export const GetRefFields = new Message<string[]>('Get Ref Fields');
diff --git a/src/server/apis/google/GoogleApiServerUtils.ts b/src/server/apis/google/GoogleApiServerUtils.ts
index d3acc968b..47206f415 100644
--- a/src/server/apis/google/GoogleApiServerUtils.ts
+++ b/src/server/apis/google/GoogleApiServerUtils.ts
@@ -21,6 +21,7 @@ const scope = ['documents.readonly', 'documents', 'presentations', 'presentation
* This namespace manages server side authentication for Google API queries, either
* from the standard v1 APIs or the Google Photos REST API.
*/
+// eslint-disable-next-line @typescript-eslint/no-namespace
export namespace GoogleApiServerUtils {
/**
* As we expand out to more Google APIs that are accessible from
diff --git a/src/server/database.ts b/src/server/database.ts
index ff8584cd7..a93117349 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-namespace */
import * as mongodb from 'mongodb';
import * as mongoose from 'mongoose';
import { Opt } from '../fields/Doc';
@@ -5,11 +6,11 @@ import { emptyFunction, Utils } from '../Utils';
import { GoogleApiServerUtils } from './apis/google/GoogleApiServerUtils';
import { DocumentsCollection, IDatabase } from './IDatabase';
import { MemoryDatabase } from './MemoryDatabase';
-import { Transferable } from './Message';
import { Upload } from './SharedMediaTypes';
+import { serializedDoctype } from '../fields/ObjectField';
export namespace Database {
- export let disconnect: Function;
+ export let disconnect: () => void;
class DocSchema implements mongodb.BSON.Document {
_id!: string;
@@ -84,6 +85,7 @@ export namespace Database {
if (this.db) {
const collection = this.db.collection<DocSchema>(collectionName);
const prom = this.currentWrites[id];
+ // eslint-disable-next-line prefer-const
let newProm: Promise<void>;
const run = (): Promise<void> =>
new Promise<void>(resolve => {
@@ -112,6 +114,7 @@ export namespace Database {
if (this.db) {
const collection = this.db.collection<DocSchema>(collectionName);
const prom = this.currentWrites[id];
+ // eslint-disable-next-line prefer-const
let newProm: Promise<void>;
const run = (): Promise<void> =>
new Promise<void>(resolve => {
@@ -196,6 +199,7 @@ export namespace Database {
const id = value._id;
const collection = this.db.collection<DocSchema>(collectionName);
const prom = this.currentWrites[id];
+ // eslint-disable-next-line prefer-const
let newProm: Promise<void>;
const run = (): Promise<void> =>
new Promise<void>(resolve => {
@@ -219,7 +223,7 @@ export namespace Database {
return undefined;
}
- public getDocument(id: string, fn: (result?: Transferable) => void, collectionName = DocumentsCollection) {
+ public getDocument(id: string, fn: (result?: serializedDoctype) => void, collectionName = DocumentsCollection) {
if (this.db) {
const collection = this.db.collection<DocSchema>(collectionName);
collection.findOne({ _id: id }).then(resultIn => {
@@ -237,7 +241,7 @@ export namespace Database {
}
}
- public async getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName = DocumentsCollection) {
+ public async getDocuments(ids: string[], fn: (result: serializedDoctype[]) => void, collectionName = DocumentsCollection) {
if (this.db) {
const found = await this.db
.collection<DocSchema>(collectionName)
diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts
index 9183688c6..2190e27c7 100644
--- a/src/server/server_Initialization.ts
+++ b/src/server/server_Initialization.ts
@@ -29,7 +29,6 @@ import { WebSocket } from './websocket';
export type RouteSetter = (server: RouteManager) => void;
// export let disconnect: Function;
-// eslint-disable-next-line import/no-mutable-exports
export let resolvedServerUrl: string;
const week = 7 * 24 * 60 * 60 * 1000;
@@ -115,12 +114,12 @@ function registerEmbeddedBrowseRelativePathHandler(server: express.Express) {
}
function proxyServe(req: any, requrl: string, response: any) {
- // eslint-disable-next-line global-require
+ // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
const htmlBodyMemoryStream = new (require('memorystream'))();
let wasinBrFormat = false;
const sendModifiedBody = () => {
const header = response.headers['content-encoding'];
- const refToCors = (match: any, tag: string, sym: string, href: string) => `${tag}=${sym + resolvedServerUrl}/corsProxy/${href + sym}`;
+ const refToCors = (match: string, tag: string, sym: string, href: string) => `${tag}=${sym + resolvedServerUrl}/corsProxy/${href + sym}`;
// const relpathToCors = (match: any, href: string, offset: any, string: any) => `="${resolvedServerUrl + '/corsProxy/' + decodeURIComponent(req.originalUrl.split('/corsProxy/')[1].match(/https?:\/\/[^\/]*/)?.[0] ?? '') + '/' + href}"`;
if (header) {
try {
@@ -238,7 +237,7 @@ function registerAuthenticationRoutes(server: express.Express) {
export default async function InitializeServer(routeSetter: RouteSetter) {
const isRelease = determineEnvironment();
const app = buildWithMiddleware(express());
- const compiler = webpack(config as any);
+ const compiler = webpack(config as webpack.Configuration);
// route table managed by express. routes are tested sequentially against each of these map rules. when a match is found, the handler is called to process the request
app.use(wdm(compiler, { publicPath: config.output.publicPath }));