From 4af7afa4aab88ac6c476aed6e81ccd46653bcbae Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Sat, 5 Aug 2023 21:09:41 +0200 Subject: [PATCH] Instantly sync updated pages when ticking off a task in a directive --- plug-api/silverbullet-syscall/sync.ts | 4 ++++ plugs/tasks/task.ts | 2 ++ web/sync_service.ts | 29 +++++++++++++++++++-------- web/syscalls/sync.ts | 3 +++ 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/plug-api/silverbullet-syscall/sync.ts b/plug-api/silverbullet-syscall/sync.ts index 16377fb..5acf8cc 100644 --- a/plug-api/silverbullet-syscall/sync.ts +++ b/plug-api/silverbullet-syscall/sync.ts @@ -7,3 +7,7 @@ export function isSyncing(): Promise { export function hasInitialSyncCompleted(): Promise { return syscall("sync.hasInitialSyncCompleted"); } + +export function scheduleFileSync(path: string): Promise { + return syscall("sync.scheduleFileSync", path); +} diff --git a/plugs/tasks/task.ts b/plugs/tasks/task.ts index 40a942f..772017c 100644 --- a/plugs/tasks/task.ts +++ b/plugs/tasks/task.ts @@ -9,6 +9,7 @@ import { index, markdown, space, + sync, } from "$sb/silverbullet-syscall/mod.ts"; import { @@ -164,6 +165,7 @@ async function toggleTaskMarker( taskMarkerNode.children![0].text = changeTo; text = renderToText(referenceMdTree); await space.writePage(page, text); + sync.scheduleFileSync(`${page}.md`); } } } diff --git a/web/sync_service.ts b/web/sync_service.ts index 1dea4be..cc61155 100644 --- a/web/sync_service.ts +++ b/web/sync_service.ts @@ -54,16 +54,16 @@ export class SyncService { eventHook.addLocalListener( "editor:pageLoaded", - async (name, _prevPage, isSynced) => { + (name, _prevPage, isSynced) => { if (!isSynced) { - await this.syncFile(`${name}.md`); + this.scheduleFileSync(`${name}.md`).catch(console.error); } }, ); - eventHook.addLocalListener("editor:pageSaved", async (name) => { + eventHook.addLocalListener("editor:pageSaved", (name) => { const path = `${name}.md`; - await this.syncFile(path); + this.scheduleFileSync(path).catch(console.error); }); } @@ -126,10 +126,23 @@ export class SyncService { async noOngoingSync(): Promise { // Not completely safe, could have race condition on setting the syncStartTimeKey while (await this.isSyncing()) { - await sleep(100); + await sleep(250); } } + filesScheduledForSync = new Set(); + async scheduleFileSync(path: string): Promise { + if (this.filesScheduledForSync.has(path)) { + // Already scheduled, no need to duplicate + console.info(`File ${path} already scheduled for sync`); + return; + } + this.filesScheduledForSync.add(path); + await this.noOngoingSync(); + await this.syncFile(path); + this.filesScheduledForSync.delete(path); + } + start() { this.syncSpace().catch( console.error, @@ -177,11 +190,11 @@ export class SyncService { // Syncs a single file async syncFile(name: string) { - if (await this.isSyncing()) { - console.log("Already syncing, aborting individual file sync for", name); + if (!this.isSyncCandidate(name)) { return; } - if (!this.isSyncCandidate(name)) { + if (await this.isSyncing()) { + console.log("Already syncing, aborting individual file sync for", name); return; } await this.registerSyncStart(); diff --git a/web/syscalls/sync.ts b/web/syscalls/sync.ts index c08857a..c1c2680 100644 --- a/web/syscalls/sync.ts +++ b/web/syscalls/sync.ts @@ -9,5 +9,8 @@ export function syncSyscalls(editor: Client): SysCallMapping { "sync.hasInitialSyncCompleted": (): Promise => { return editor.syncService.hasInitialSyncCompleted(); }, + "sync.scheduleFileSync": (_ctx, path: string): Promise => { + return editor.syncService.scheduleFileSync(path); + }, }; }