Refactoring

deno-express
Zef Hemel 2023-06-02 13:43:49 +02:00
parent 610fe9de6d
commit eebf920a9d
4 changed files with 51 additions and 42 deletions

View File

@ -1,4 +1,5 @@
import { Extension, HocuspocusProvider, Y, yCollab } from "../deps.ts";
import { SyncService } from "../sync_service.ts";
const userColors = [
{ color: "#30bced", light: "#30bced33" },
@ -17,15 +18,31 @@ export class CollabState {
private yundoManager: Y.UndoManager;
constructor(
serverUrl: string,
name: string,
username: string,
onStateless: (data: any) => any,
private serverUrl: string,
private pageName: string,
private token: string,
private username: string,
private syncService: SyncService,
) {
this.collabProvider = new HocuspocusProvider({
url: serverUrl,
name: name,
onStateless,
name: token,
// Receive broadcasted messages from the server (right now only "page has been persisted" notifications)
onStateless: (
{ payload },
) => {
const message = JSON.parse(payload);
switch (message.type) {
case "persisted": {
// Received remote persist notification, updating snapshot
syncService.updateRemoteLastModified(
message.path,
message.lastModified,
).catch(console.error);
}
}
},
});
this.collabProvider.on("status", (e: any) => {
@ -46,12 +63,18 @@ export class CollabState {
}
stop() {
// this.collabProvider.disconnect();
console.log("[COLLAB] Destroying collab provider");
this.collabProvider.destroy();
// For whatever reason, destroy() doesn't properly clean up everything so we need to help a bit
this.collabProvider.configuration.websocketProvider.webSocket = null;
this.collabProvider.configuration.websocketProvider.destroy();
// When stopping collaboration, we're going back to sync mode. Make sure we got the latest and greatest remote timestamp to avoid
// conflicts
this.syncService.fetchAndPersistRemoteLastModified(`${this.pageName}.md`)
.catch(
console.error,
);
}
collabExtension(): Extension {

View File

@ -1155,7 +1155,7 @@ export class Editor {
await this.save(true);
// And stop the collab session
if (this.collabState) {
this.stopCollab(previousPage);
this.stopCollab();
}
}
}
@ -1525,49 +1525,25 @@ export class Editor {
this.collabState.stop();
}
const initialText = this.editorView!.state.sliceDoc();
this.collabState = new CollabState(serverUrl, token, username, (
{ payload },
) => {
const message = JSON.parse(payload);
switch (message.type) {
case "persisted": {
// console.log(
// "Received remote persist notification, updating snapshot",
// message,
// );
this.syncService.updateRemoteLastModified(
message.path,
message.lastModified,
).catch(console.error);
}
}
});
this.collabState = new CollabState(
serverUrl,
this.currentPage!,
token,
username,
this.syncService,
);
// this.collabState.collabProvider.on("synced", () => {
// if (this.collabState?.ytext.toString() === "") {
// console.error("Synced value is empty, putting back original text");
// this.collabState?.ytext.insert(0, initialText);
// }
// });
this.rebuildEditorState();
// Don't watch for local changes in this mode
this.space.unwatch();
}
stopCollab(pageName: string) {
stopCollab() {
if (this.collabState) {
this.collabState.stop();
this.collabState = undefined;
this.rebuildEditorState();
// Switching off collab mode
this.syncService.remoteSpace.getFileMeta(`${pageName}.md`).then(
(meta) => {
return this.syncService.updateRemoteLastModified(
meta.name,
meta.lastModified,
);
},
).catch(console.error);
}
// Start file watching again
this.space.watch();

View File

@ -165,6 +165,16 @@ export class SyncService {
await this.registerSyncStop();
}
// Reach out out to remote space, fetch the latest lastModified time and update the local snapshot
// This is used when exiting collab mode
async fetchAndPersistRemoteLastModified(path: string) {
const meta = await this.remoteSpace.getFileMeta(path);
await this.updateRemoteLastModified(
meta.name,
meta.lastModified,
);
}
// When in collab mode, we delegate the sync to the CDRT engine, to avoid conflicts, we try to keep the lastModified time in sync when local changes happen
async updateLocalLastModified(path: string, lastModified: number) {
await this.noOngoingSync();

View File

@ -14,7 +14,7 @@ export function collabSyscalls(editor: Editor): SysCallMapping {
"collab.stop": (
_ctx,
) => {
editor.stopCollab(editor.currentPage!);
editor.stopCollab();
},
"collab.ping": async (
_ctx,