* 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
77 lines
1.8 KiB
TypeScript
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);
|
|
}
|