Files
plainleaf/cmd/sync.ts
T
Zef HemelandGitHub dc2987a3f9 Sync engine rearchitecture (#1516)
* Don't require auth for .ping
* Finally introducing loggers
* Remove file list caching from disk_space_primitives
I don't think this is required anymore with the sync model
* Simplification of space primitives and more tests
* More reliable online status
* Add .zed settings
* Remove selfUpdate argument from `writeFile` no longer used
- Add `sync` config schema and document sync options
- Move sync config handling to client boot logic
- Move BootConfig type to ui_types.ts
- Remove sync env vars from server
- Update documentation for sync and architecture
* Improve sync logic and proxy routing for full sync state
* Add BoxProxy for late-bound client and improve Lua boot
- Add isMobile syscall for editor
* Add concurrency to sync process and log indexing duration
* Better service worker lifecycle management
2025-09-12 14:43:57 +02:00

77 lines
1.8 KiB
TypeScript

import { SpaceSync, SyncSnapshot } from "../lib/spaces/sync.ts";
import { determineStorageBackend } from "../server/storage_backend.ts";
export async function syncCommand(
options: {
snapshot?: string;
wipeSecondary?: boolean;
},
primary: string,
secondary: string,
) {
console.log("Going to synchronize", primary, "and", secondary);
const primarySpacePrimitives = determineStorageBackend(
primary,
);
const secondarySpacePrimitives = determineStorageBackend(
secondary,
);
if (options.wipeSecondary) {
if (
!confirm(
`About to wipe the secondary storage at ${secondary}, are you sure?`,
)
) {
return;
}
const allFiles = await secondarySpacePrimitives.fetchFileList();
for (const file of allFiles) {
try {
console.log("Deleting", file.name);
await secondarySpacePrimitives.deleteFile(file.name);
} catch (e: any) {
console.warn("Failed to delete file", file.name, e.message);
}
}
console.log("Done wiping secondary storage.");
}
let snapshot = new SyncSnapshot();
if (options.snapshot) {
try {
snapshot = SyncSnapshot.fromJSON(
JSON.parse(await Deno.readTextFile(options.snapshot)),
);
} catch (e: any) {
console.warn(
"Failed to read snapshot file",
e.message,
"using empty snapshot",
);
}
}
const sync = new SpaceSync(
primarySpacePrimitives,
secondarySpacePrimitives,
{
conflictResolver: SpaceSync.primaryConflictResolver,
isSyncCandidate: () => true,
},
);
if (options.snapshot) {
sync.on({
snapshotUpdated: async (snapshot) => {
await Deno.writeTextFile(
options.snapshot!,
JSON.stringify(snapshot.toJSON()),
);
},
});
}
await sync.syncFiles(snapshot);
}