1
0
silverbullet/plugs/sync/sync.ts

143 lines
3.4 KiB
TypeScript
Raw Normal View History

2023-01-13 14:41:29 +00:00
import { store } from "$sb/plugos-syscall/mod.ts";
import {
editor,
index,
space,
sync,
system,
} from "$sb/silverbullet-syscall/mod.ts";
2023-01-13 14:41:29 +00:00
import type { SyncEndpoint } from "$sb/silverbullet-syscall/sync.ts";
export async function configureCommand() {
const url = await editor.prompt(
"Enter the URL of the remote space to sync with",
"https://",
);
if (!url) {
return;
}
const user = await editor.prompt("Username (if any):");
let password = undefined;
if (user) {
password = await editor.prompt("Password:");
}
const syncConfig: SyncEndpoint = {
url,
user,
password,
};
try {
await system.invokeFunction("server", "check", syncConfig);
} catch (e: any) {
await editor.flashNotification(
`Sync configuration failed: ${e.message}`,
"error",
);
return;
}
await store.batchSet([
{ key: "sync.config", value: syncConfig },
// Empty initial snapshot
{ key: "sync.snapshot", value: {} },
]);
await editor.flashNotification("Sync configuration saved.");
return syncConfig;
}
export async function syncCommand() {
let config: SyncEndpoint | undefined = await store.get("sync.config");
if (!config) {
config = await configureCommand();
if (!config) {
return;
}
}
await editor.flashNotification("Starting sync...");
try {
2023-01-14 17:51:00 +00:00
await system.invokeFunction("server", "check", config);
2023-01-13 14:41:29 +00:00
const operations = await system.invokeFunction("server", "performSync");
await editor.flashNotification(
`Sync complete. Performed ${operations} operations.`,
);
} catch (e: any) {
await editor.flashNotification(
`Sync failed: ${e.message}`,
"error",
);
}
}
export async function localWipeAndSyncCommand() {
let config: SyncEndpoint | undefined = await store.get("sync.config");
if (!config) {
config = await configureCommand();
if (!config) {
return;
}
}
if (
!(await editor.confirm(
"Are you sure you want to wipe your local space and sync with the remote?",
))
) {
return;
}
if (
!(await editor.confirm(
"To be clear: this means all local content will be deleted with no way to recover it. Are you sure?",
))
) {
return;
}
console.log("Wiping local pages");
await editor.flashNotification("Now wiping all pages");
for (const page of await space.listPages()) {
console.log("Deleting page", page.name);
await space.deletePage(page.name);
}
console.log("Wiping local attachments");
await editor.flashNotification("Now wiping all attachments");
for (const attachment of await space.listAttachments()) {
console.log("Deleting attachment", attachment.name);
await space.deleteAttachment(attachment.name);
}
console.log("Wiping local sync state");
await store.set("sync.snapshot", {});
// Starting actual sync
await syncCommand();
}
2023-01-13 14:41:29 +00:00
// Run on server
export function check(config: SyncEndpoint) {
return sync.check(config);
}
// Run on server
export async function performSync() {
const config: SyncEndpoint = await store.get("sync.config");
const snapshot = await store.get("sync.snapshot");
const { snapshot: newSnapshot, operations, error } = await sync.sync(
config,
snapshot,
);
await store.set("sync.snapshot", newSnapshot);
if (error) {
console.error("Sync error", error);
throw new Error(error);
}
return operations;
}