Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/sync/table/synctable-no-changefeed.ts
1447 views
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(
80
project_id: string,
81
compute_server_id?: number,
82
): Promise<void> {
83
await this.client.touch_project(project_id, compute_server_id);
84
}
85
86
public is_connected(): boolean {
87
return this.client.is_connected();
88
}
89
90
public is_signed_in(): boolean {
91
return this.client.is_signed_in();
92
}
93
94
public server_time(): Date {
95
return this.client.server_time();
96
}
97
98
public dbg(s: string): Function {
99
return this.client.dbg(s);
100
}
101
102
public query(opts): void {
103
if (opts.changes) {
104
this.changefeed_query(opts);
105
} else {
106
this.client.query(opts);
107
}
108
}
109
110
private changefeed_query(opts): void {
111
opts.changes = false;
112
this.client.query(opts);
113
}
114
115
public query_cancel(_): void {
116
// no op since no changefeed.
117
this.client.removeListener("connected", this.emit_connected);
118
this.client.removeListener("signed_in", this.emit_signed_in);
119
}
120
121
public alert_message(opts): void {
122
if (this.client.alert_message != null) {
123
this.client.alert_message(opts);
124
}
125
}
126
127
is_deleted = (_path: string, _project_id: string) => {
128
// not implemented yet in general
129
return undefined;
130
};
131
}
132
133