1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
import * as OpenSocket from 'socket.io-client';
import { MessageStore, Types } from "./../server/Message";
import { Opt, FieldWaiting, RefField, HandleUpdate } from '../new_fields/Doc';
import { Utils } from '../Utils';
import { SerializationHelper } from './util/SerializationHelper';
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 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 = fieldJson === undefined ? fieldJson : SerializationHelper.Deserialize(fieldJson);
if (field) {
_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.GetFields, requestedIds);
requestedIds.map((id, index) => _cache[id] = prom.then((fields: RefField[]) => fields[index]));
const fields = await prom;
requestedIds.map((id, index) => map[id] = fields[index]);
const otherFields = await Promise.all(promises);
waitingIds.map((id, index) => map[id] = otherFields[index]);
return map;
}
export function UpdateField(id: string, diff: any) {
Utils.Emit(_socket, MessageStore.UpdateField, { id, diff });
}
export function CreateField(initialState: any) {
if (!("id" in initialState)) {
throw new Error("Can't create a field on the server without an id");
}
Utils.Emit(_socket, MessageStore.CreateField, initialState);
}
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) {
handler(diff);
}
};
if (field instanceof Promise) {
field.then(update);
} else {
update(field);
}
}
function connected(message: string) {
_socket.emit(MessageStore.Bar.Message, GUID);
}
Utils.AddServerHandler(_socket, MessageStore.Foo, connected);
Utils.AddServerHandler(_socket, MessageStore.UpdateField, respondToUpdate);
}
|