diff options
Diffstat (limited to 'src/client/DocServer.ts')
-rw-r--r-- | src/client/DocServer.ts | 103 |
1 files changed, 77 insertions, 26 deletions
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index cb460799f..bf5168c22 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -1,6 +1,6 @@ import * as OpenSocket from 'socket.io-client'; -import { MessageStore, Diff } from "./../server/Message"; -import { Opt } from '../new_fields/Doc'; +import { MessageStore, Diff, YoutubeQueryTypes } from "./../server/Message"; +import { Opt, Doc } from '../new_fields/Doc'; import { Utils, emptyFunction } from '../Utils'; import { SerializationHelper } from './util/SerializationHelper'; import { RefField } from '../new_fields/RefField'; @@ -26,6 +26,42 @@ export namespace DocServer { let GUID: string; // indicates whether or not a document is currently being udpated, and, if so, its id + export enum WriteMode { + Default = 0, //Anything goes + Playground = 1, + LiveReadonly = 2, + LivePlayground = 3, + } + + const fieldWriteModes: { [field: string]: WriteMode } = {}; + const docsWithUpdates: { [field: string]: Set<Doc> } = {}; + + export function setFieldWriteMode(field: string, writeMode: WriteMode) { + fieldWriteModes[field] = writeMode; + if (writeMode !== WriteMode.Playground) { + const docs = docsWithUpdates[field]; + if (docs) { + docs.forEach(doc => Doc.RunCachedUpdate(doc, field)); + delete docsWithUpdates[field]; + } + } + } + + export function getFieldWriteMode(field: string) { + return fieldWriteModes[field] || WriteMode.Default; + } + + export function registerDocWithCachedUpdate(doc: Doc, field: string, oldValue: any) { + let list = docsWithUpdates[field]; + if (!list) { + list = docsWithUpdates[field] = new Set; + } + if (!list.has(doc)) { + Doc.AddCachedUpdate(doc, field, oldValue); + list.add(doc); + } + } + export function init(protocol: string, hostname: string, port: number, identifier: string) { _cache = {}; GUID = identifier; @@ -125,15 +161,15 @@ export namespace DocServer { const deserializeField = getSerializedField.then(async fieldJson => { // deserialize const field = await SerializationHelper.Deserialize(fieldJson); - // either way, overwrite or delete any promises cached at this id (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 (field !== undefined) { _cache[id] = field; } else { delete _cache[id]; } return field; + // either way, overwrite or delete any promises cached at this id (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. }); // here, indicate that the document associated with this id is currently // being retrieved and cached @@ -156,6 +192,20 @@ export namespace DocServer { return _GetRefField(id); } + export async function getYoutubeChannels() { + let apiKey = await Utils.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.Channels }); + return apiKey; + } + + export function getYoutubeVideos(videoTitle: string, callBack: (videos: any[]) => void) { + Utils.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.SearchVideo, userInput: videoTitle }, callBack); + } + + export function getYoutubeVideoDetails(videoIds: string, callBack: (videoDetails: any[]) => void) { + 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 @@ -199,28 +249,37 @@ export namespace DocServer { // future .proto calls on the Doc won't have to go farther than the cache to get their actual value. const deserializeFields = getSerializedFields.then(async fields => { const fieldMap: { [id: string]: RefField } = {}; - // const protosToLoad: any = []; + const proms: Promise<void>[] = []; for (const field of fields) { if (field !== undefined) { // deserialize - let deserialized = await SerializationHelper.Deserialize(field); - fieldMap[field.id] = deserialized; + let 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 - // protosToLoad.push(deserialized.proto); + proms.push(prom); } } - // this actually handles the loading of prototypes - // await Promise.all(protosToLoad); + await Promise.all(proms); return fieldMap; }); - // 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 - requestedIds.forEach(id => _cache[id] = deserializeFields.then(fields => fields[id])); - // 5) at this point, all fields have a) been returned from the server and b) been deserialized into actual Field objects whose // prototype documents, if any, have also been fetched and cached. const fields = await deserializeFields; @@ -230,14 +289,6 @@ export namespace DocServer { // id to the soon-to-be-returned field mapping. requestedIds.forEach(id => { const field = fields[id]; - // either way, 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 (field !== undefined) { - _cache[id] = field; - } else { - delete _cache[id]; - } map[id] = field; }); |