CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/project/sync/open-synctables.ts
Views: 687
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
/*
7
All SyncTables that are currently open and being managed in this project.
8
9
*/
10
11
import { callback } from "awaiting";
12
import { SyncTable } from "@cocalc/sync/table";
13
import { is_array } from "@cocalc/util/misc";
14
15
const open_synctables: { [key: string]: SyncTable } = {};
16
const wait_for: { [key: string]: Function[] } = {};
17
18
export function key(query): string {
19
const table: string = Object.keys(query)[0];
20
if (!table) {
21
throw Error("no table in query");
22
}
23
let c = query[table];
24
if (c == null) {
25
throw Error("invalid query format");
26
}
27
if (is_array(c)) {
28
c = c[0];
29
}
30
const string_id = c.string_id;
31
if (string_id == null) {
32
throw Error(
33
"open-syncstring-tables is only for queries with a specified string_id field" +
34
"(patches, cursors, eval_inputs, eval_outputs, etc.): query=" +
35
JSON.stringify(query)
36
);
37
}
38
return `${table}.${string_id}`;
39
}
40
41
export function register_synctable(query: any, synctable: SyncTable): void {
42
const k = key(query);
43
open_synctables[k] = synctable;
44
synctable.on("closed", function () {
45
delete open_synctables[k];
46
});
47
if (wait_for[k] != null) {
48
handle_wait_for(k, synctable);
49
}
50
}
51
52
export async function get_synctable(query, client): Promise<SyncTable> {
53
const k = key(query);
54
const log = client.dbg(`get_synctable(key=${k})`);
55
log("open_synctables = ", Object.keys(open_synctables));
56
log("key=", k, "query=", query);
57
const s = open_synctables[k];
58
if (s != null) {
59
// easy - already have it.
60
log("done");
61
return s;
62
}
63
function f(cb: Function) {
64
log("f got called");
65
add_to_wait_for(k, cb);
66
}
67
log("waiting...");
68
const synctable = await callback(f);
69
log(`got the synctable! ${JSON.stringify((synctable as any).query)}`);
70
return synctable;
71
}
72
73
function add_to_wait_for(k: string, cb: Function): void {
74
if (wait_for[k] == null) {
75
wait_for[k] = [cb];
76
} else {
77
wait_for[k].push(cb);
78
}
79
}
80
81
function handle_wait_for(k: string, synctable: SyncTable): void {
82
if (wait_for[k] == null) {
83
return;
84
}
85
const v: Function[] = wait_for[k];
86
delete wait_for[k];
87
for (const cb of v) {
88
cb(undefined, synctable);
89
}
90
}
91
92