Skip to content

Commit 221d97c

Browse files
committed
starting work on general file editing sync service (not running in a project)
1 parent f161cc8 commit 221d97c

File tree

1 file changed

+64
-17
lines changed

1 file changed

+64
-17
lines changed

src/packages/conat/files/sync.ts

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ OUTPUT: starts (or keeps running) the filesystem aware side of an editing sessio
2020
2121
*/
2222

23-
// import { type Client } from "@cocalc/conat/core/client";
23+
import type { Client, Message, Subscription } from "@cocalc/conat/core/client";
24+
import { STICKY_QUEUE_GROUP } from "@cocalc/conat/core/client";
25+
import { isValidUUID } from "@cocalc/util/misc";
2426

2527
interface SyncDoc {
2628
close: () => void;
@@ -32,7 +34,6 @@ export type SyncDocCreator = (opts: {
3234
doctype?: any;
3335
}) => SyncDoc;
3436

35-
/*
3637
interface Options {
3738
client: Client;
3839

@@ -43,28 +44,74 @@ interface Options {
4344
createSyncDoc: SyncDocCreator;
4445
}
4546

46-
export function init(opts: Options) {
47-
return new SyncServer(opts.client, opts.projects, opts.createSyncDocs);
47+
export async function init(opts: Options) {
48+
const syncServer = new SyncServer(
49+
opts.client,
50+
opts.projects,
51+
opts.createSyncDoc,
52+
);
53+
await syncServer.init();
54+
return syncServer;
4855
}
4956

5057
interface Api {
5158
open: (opts: { path: string; doctype?: any }) => Promise<void>;
5259
}
5360

5461
class SyncServer {
55-
constructor(client: Client, projects: string, createSyncDoc: SyncDocCreator) {
56-
this.client.service = await client1.service<Api>("arith.*", {
57-
add: async (a, b) => a + b,
58-
mul: async (a, b) => a * b,
59-
// Here we do NOT use an arrow => function and this is
60-
// bound to the calling mesg, which lets us get the subject.
61-
// Because user identity and permissions are done via wildcard
62-
// subjects, having access to the calling message is critical
63-
async open({ path, doctype }) {
64-
const mesg: Message = this as any;
65-
console.log(mesg.subject);
62+
private service?: Subscription;
63+
private syncDocs: { [key: string]: SyncDoc } = {};
64+
private interest: { [key: string]: number } = {};
65+
66+
constructor(
67+
private client: Client,
68+
private projects: string,
69+
private createSyncDoc: SyncDocCreator,
70+
) {}
71+
72+
init = async () => {
73+
const self = this;
74+
this.service = await this.client.service<Api>(
75+
"sync.*.open",
76+
{
77+
async open({ path, doctype }) {
78+
const mesg: Message = this as any;
79+
self.open(mesg.subject, path, doctype);
80+
},
6681
},
82+
{ queue: STICKY_QUEUE_GROUP },
83+
);
84+
};
85+
86+
private key = (project_id, path) => {
87+
return `${project_id}/${path}`;
88+
};
89+
90+
private open = (subject: string, path: string, doctype) => {
91+
const project_id = subject.split(".")[1]?.slice("project-".length);
92+
console.log("open", {
93+
subject,
94+
path,
95+
doctype,
96+
project_id,
97+
projects: this.projects,
6798
});
68-
}
99+
if (!isValidUUID(project_id)) {
100+
throw Error("invalid subject");
101+
}
102+
const key = this.key(project_id, path);
103+
if (this.syncDocs[key] === undefined) {
104+
this.syncDocs[key] = this.createSyncDoc({ project_id, path, doctype });
105+
}
106+
this.interest[key] = Date.now();
107+
};
108+
109+
close = () => {
110+
this.service?.close();
111+
delete this.service;
112+
for (const key in this.syncDocs) {
113+
this.syncDocs[key].close();
114+
delete this.syncDocs[key];
115+
}
116+
};
69117
}
70-
*/

0 commit comments

Comments
 (0)