aboutsummaryrefslogtreecommitdiff
path: root/src/client/DocServer.ts
diff options
context:
space:
mode:
authoryunahi <60233430+yunahi@users.noreply.github.com>2020-07-28 01:53:21 +0900
committeryunahi <60233430+yunahi@users.noreply.github.com>2020-07-28 01:53:21 +0900
commite8caa12dc736ef66741b5652425b0cb8b0a5eb16 (patch)
treeafd47f6b46d1d9c1d814650b2590b738cd36c495 /src/client/DocServer.ts
parentf3a331573be09115f9a92b8e927081f8f743c478 (diff)
parentf869c7a75eb6a2f6e6301aa76c57e383b41d3fea (diff)
merge fix
Diffstat (limited to 'src/client/DocServer.ts')
-rw-r--r--src/client/DocServer.ts88
1 files changed, 52 insertions, 36 deletions
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index 2a7a7c59a..8ded43468 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -1,13 +1,14 @@
import * as io from 'socket.io-client';
import { MessageStore, YoutubeQueryTypes, GestureContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent, MobileDocumentUploadContent } from "./../server/Message";
-import { Opt, Doc, fetchProto } from '../fields/Doc';
+import { Opt, Doc, fetchProto, FieldsSym } from '../fields/Doc';
import { Utils, emptyFunction } from '../Utils';
import { SerializationHelper } from './util/SerializationHelper';
import { RefField } from '../fields/RefField';
-import { Id, HandleUpdate } from '../fields/FieldSymbols';
+import { Id, HandleUpdate, Parent } from '../fields/FieldSymbols';
import GestureOverlay from './views/GestureOverlay';
import MobileInkOverlay from '../mobile/MobileInkOverlay';
import { runInAction } from 'mobx';
+import { ObjectField } from '../fields/ObjectField';
/**
* This class encapsulates the transfer and cross-client synchronization of
@@ -31,7 +32,7 @@ export namespace DocServer {
export enum WriteMode {
Default = 0, //Anything goes
- Playground = 1, //Playground (write own/no read)
+ 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)
}
@@ -39,9 +40,9 @@ export namespace DocServer {
const docsWithUpdates: { [field: string]: Set<Doc> } = {};
export var PlaygroundFields: string[];
- export function setPlaygroundFields(livePlayougroundFields: string[]) {
- DocServer.PlaygroundFields = livePlayougroundFields;
- livePlayougroundFields.forEach(f => DocServer.setFieldWriteMode(f, DocServer.WriteMode.LivePlayground));
+ export function setPlaygroundFields(livePlaygroundFields: string[]) {
+ DocServer.PlaygroundFields = livePlaygroundFields;
+ livePlaygroundFields.forEach(f => DocServer.setFieldWriteMode(f, DocServer.WriteMode.LivePlayground));
}
export function setFieldWriteMode(field: string, writeMode: WriteMode) {
@@ -207,12 +208,12 @@ export namespace DocServer {
* the server if the document has not been cached.
* @param id the id of the requested document
*/
- const _GetRefFieldImpl = (id: string): Promise<Opt<RefField>> => {
+ const _GetRefFieldImpl = (id: string, force: boolean = false): Promise<Opt<RefField>> => {
// an initial pass through the cache to determine whether the document needs to be fetched,
// is already in the process of being fetched or already exists in the
// cache
const cached = _cache[id];
- if (cached === undefined) {
+ if (cached === undefined || force) {
// NOT CACHED => we'll have to send a request to the server
// synchronously, we emit a single callback to the server requesting the serialized (i.e. represented by a string)
@@ -226,7 +227,16 @@ export namespace DocServer {
const deserializeField = getSerializedField.then(async fieldJson => {
// deserialize
const field = await SerializationHelper.Deserialize(fieldJson);
- if (field !== undefined) {
+ if (force && field instanceof Doc && cached instanceof Doc) {
+ Array.from(Object.keys(field)).forEach(key => {
+ const fieldval = field[key];
+ if (fieldval instanceof ObjectField) {
+ fieldval[Parent] = undefined;
+ }
+ cached[key] = field[key];
+ });
+ }
+ else if (field !== undefined) {
_cache[id] = field;
} else {
delete _cache[id];
@@ -238,8 +248,8 @@ export namespace DocServer {
});
// here, indicate that the document associated with this id is currently
// being retrieved and cached
- _cache[id] = deserializeField;
- return deserializeField;
+ !force && (_cache[id] = 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
@@ -260,11 +270,11 @@ export namespace DocServer {
}
};
- let _GetRefField: (id: string) => Promise<Opt<RefField>> = errorFunc;
+ let _GetRefField: (id: string, force: boolean) => Promise<Opt<RefField>> = errorFunc;
let _GetCachedRefField: (id: string) => Opt<RefField> = errorFunc;
- export function GetRefField(id: string): Promise<Opt<RefField>> {
- return _GetRefField(id);
+ export function GetRefField(id: string, force = false): Promise<Opt<RefField>> {
+ return _GetRefField(id, force);
}
export function GetCachedRefField(id: string): Opt<RefField> {
return _GetCachedRefField(id);
@@ -330,29 +340,35 @@ export namespace DocServer {
const proms: Promise<void>[] = [];
runInAction(() => {
for (const field of fields) {
- if (field !== undefined && field !== null) {
+ if (field !== undefined && field !== null && !_cache[field.id]) {
// deserialize
- const prom = SerializationHelper.Deserialize(field).then(deserialized => {
- fieldMap[field.id] = deserialized;
-
- //overwrite or delete any promises (that we inserted as flags
- // to indicate that the field was in the process of being fetched). Now everything
- // should be an actual value within or entirely absent from the cache.
- if (deserialized !== undefined) {
- _cache[field.id] = deserialized;
- } else {
- delete _cache[field.id];
- }
- 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.
- // 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
- _cache[field.id] = prom;
- // adds to a list of promises that will be awaited asynchronously
- proms.push(prom);
+ const cached = _cache[field.id];
+ if (!cached) {
+ const prom = SerializationHelper.Deserialize(field).then(deserialized => {
+ fieldMap[field.id] = deserialized;
+
+ //overwrite or delete any promises (that we inserted as flags
+ // to indicate that the field was in the process of being fetched). Now everything
+ // should be an actual value within or entirely absent from the cache.
+ if (deserialized !== undefined) {
+ _cache[field.id] = deserialized;
+ } else {
+ delete _cache[field.id];
+ }
+ 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.
+ // 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
+ _cache[field.id] = prom;
+
+ // adds to a list of promises that will be awaited asynchronously
+ proms.push(prom);
+ } else if (cached instanceof Promise) {
+ proms.push(cached as any);
+ }
}
}
});