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/sync/table/synctable-no-changefeed.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
Make a SyncTable which does not use a changefeed at all.
8
9
It does the initial database read as usual, and also
10
writes changes as usual, but does not use a changefeed
11
at all. Instead changes are injected by calling
12
a function.
13
14
This is used, e.g., by a backend project for implementing a version
15
of SyncTable, where the project itself handles all changes,
16
not the database or hubs. However, data is still persisted
17
to the central database.
18
19
Returned object is not cached in any way.
20
*/
21
22
import { EventEmitter } from "events";
23
import { SyncTable, Client } from "./synctable";
24
import { bind_methods } from "@cocalc/util/misc";
25
26
export function synctable_no_changefeed(
27
query,
28
options,
29
client: Client,
30
throttle_changes?: undefined | number,
31
): SyncTable {
32
if (options == null) {
33
options = [];
34
}
35
const client2 = new ClientNoChangefeed(client);
36
return new SyncTable(query, options, client2, throttle_changes, true, false);
37
}
38
39
class ClientNoChangefeed extends EventEmitter {
40
private client: Client;
41
42
constructor(client) {
43
super();
44
45
bind_methods(this, [
46
"query",
47
"dbg",
48
"query_cancel",
49
"emit_connected",
50
"emit_signed_in",
51
]);
52
this.client = client;
53
54
// These MUST be after the binds above, obviously.
55
client.on("connected", this.emit_connected);
56
client.on("signed_in", this.emit_signed_in);
57
}
58
59
private emit_connected(): void {
60
this.emit("connected");
61
}
62
63
private emit_signed_in(): void {
64
this.emit("signed_in");
65
}
66
67
public is_project(): boolean {
68
return this.client.is_project();
69
}
70
71
public is_browser(): boolean {
72
return this.client.is_browser();
73
}
74
75
public is_compute_server(): boolean {
76
return this.client.is_compute_server();
77
}
78
79
public async touch_project(project_id: string): Promise<void> {
80
await this.client.touch_project(project_id);
81
}
82
83
public is_connected(): boolean {
84
return this.client.is_connected();
85
}
86
87
public is_signed_in(): boolean {
88
return this.client.is_signed_in();
89
}
90
91
public server_time(): Date {
92
return this.client.server_time();
93
}
94
95
public dbg(s: string): Function {
96
return this.client.dbg(s);
97
}
98
99
public query(opts): void {
100
if (opts.changes) {
101
this.changefeed_query(opts);
102
} else {
103
this.client.query(opts);
104
}
105
}
106
107
private changefeed_query(opts): void {
108
opts.changes = false;
109
this.client.query(opts);
110
}
111
112
public query_cancel(_): void {
113
// no op since no changefeed.
114
this.client.removeListener("connected", this.emit_connected);
115
this.client.removeListener("signed_in", this.emit_signed_in);
116
}
117
118
public alert_message(opts): void {
119
if (this.client.alert_message != null) {
120
this.client.alert_message(opts);
121
}
122
}
123
124
is_deleted = (_path: string, _project_id: string) => {
125
// not implemented yet in general
126
return undefined;
127
};
128
}
129
130