diff options
author | Sam Wilkins <abdullah_ahmed@brown.edu> | 2019-05-09 20:59:10 -0400 |
---|---|---|
committer | Sam Wilkins <abdullah_ahmed@brown.edu> | 2019-05-09 20:59:10 -0400 |
commit | 47ecf8d30f4aa5e25a659fc7f3c0c1487420150e (patch) | |
tree | cbae92b4aca6cc8427410cc2ec51b0afff1d8ea2 /src/client/DocServer.ts | |
parent | ff5e275d4d9bb17866a432459884274cd870a640 (diff) |
merge with master, but haven't reconciled internal and external linking
Diffstat (limited to 'src/client/DocServer.ts')
-rw-r--r-- | src/client/DocServer.ts | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts new file mode 100644 index 000000000..a288d394a --- /dev/null +++ b/src/client/DocServer.ts @@ -0,0 +1,130 @@ +import * as OpenSocket from 'socket.io-client'; +import { MessageStore } from "./../server/Message"; +import { Opt } from '../new_fields/Doc'; +import { Utils } from '../Utils'; +import { SerializationHelper } from './util/SerializationHelper'; +import { RefField, HandleUpdate, Id } from '../new_fields/RefField'; + +export namespace DocServer { + const _cache: { [id: string]: RefField | Promise<Opt<RefField>> } = {}; + const _socket = OpenSocket(`${window.location.protocol}//${window.location.hostname}:4321`); + const GUID: string = Utils.GenerateGuid(); + + export function prepend(extension: string): string { + return window.location.origin + extension; + } + + export function DeleteDatabase() { + Utils.Emit(_socket, MessageStore.DeleteAll, {}); + } + + export async function GetRefField(id: string): Promise<Opt<RefField>> { + let cached = _cache[id]; + if (cached === undefined) { + const prom = Utils.EmitCallback(_socket, MessageStore.GetRefField, id).then(fieldJson => { + const field = SerializationHelper.Deserialize(fieldJson); + if (_cache[id] !== undefined && !(_cache[id] instanceof Promise)) { + id; + } + if (field !== undefined) { + _cache[id] = field; + } else { + delete _cache[id]; + } + return field; + }); + _cache[id] = prom; + return prom; + } else if (cached instanceof Promise) { + return cached; + } else { + return cached; + } + } + + export async function GetRefFields(ids: string[]): Promise<{ [id: string]: Opt<RefField> }> { + const requestedIds: string[] = []; + const waitingIds: string[] = []; + const promises: Promise<Opt<RefField>>[] = []; + const map: { [id: string]: Opt<RefField> } = {}; + for (const id of ids) { + const cached = _cache[id]; + if (cached === undefined) { + requestedIds.push(id); + } else if (cached instanceof Promise) { + promises.push(cached); + waitingIds.push(id); + } else { + map[id] = cached; + } + } + const prom = Utils.EmitCallback(_socket, MessageStore.GetRefFields, requestedIds).then(fields => { + const fieldMap: { [id: string]: RefField } = {}; + for (const field of fields) { + if (field !== undefined) { + fieldMap[field.id] = SerializationHelper.Deserialize(field); + } + } + return fieldMap; + }); + requestedIds.forEach(id => _cache[id] = prom.then(fields => fields[id])); + const fields = await prom; + requestedIds.forEach(id => { + const field = fields[id]; + if (field !== undefined) { + _cache[id] = field; + } else { + delete _cache[id]; + } + map[id] = field; + }); + const otherFields = await Promise.all(promises); + waitingIds.forEach((id, index) => map[id] = otherFields[index]); + return map; + } + + export function UpdateField(id: string, diff: any) { + if (id === updatingId) { + return; + } + Utils.Emit(_socket, MessageStore.UpdateField, { id, diff }); + } + + export function CreateField(field: RefField) { + _cache[field[Id]] = field; + const initialState = SerializationHelper.Serialize(field); + Utils.Emit(_socket, MessageStore.CreateField, initialState); + } + + let updatingId: string | undefined; + function respondToUpdate(diff: any) { + const id = diff.id; + if (id === undefined) { + return; + } + const field = _cache[id]; + const update = (f: Opt<RefField>) => { + if (f === undefined) { + return; + } + const handler = f[HandleUpdate]; + if (handler) { + updatingId = id; + handler.call(f, diff.diff); + updatingId = undefined; + } + }; + if (field instanceof Promise) { + field.then(update); + } else { + update(field); + } + } + + function connected() { + _socket.emit(MessageStore.Bar.Message, GUID); + } + + Utils.AddServerHandler(_socket, MessageStore.Foo, connected); + Utils.AddServerHandler(_socket, MessageStore.UpdateField, respondToUpdate); +}
\ No newline at end of file |