Confirm Fast Setup choices from the scheduled fetch flag

This commit is contained in:
vorotamoroz committed 2026-10-29 14:45:15 +00:00
1 parent efa3e356b4
commit 9632f2ae5a
12 files changed
+1440 -150

No files matched your search

+109
View File
@@ -0,0 +1,109 @@
import type { NecessaryServices } from "@vrtmrz/livesync-commonlib/compat/interfaces/ServiceModule";
import type { ObsidianLiveSyncSettings } from "@vrtmrz/livesync-commonlib/settings";
import {
REMOTE_COUCHDB,
REMOTE_MINIO,
REMOTE_P2P,
} from "@vrtmrz/livesync-commonlib/compat/common/models/setting.const";
import {
FlagFilesHumanReadable,
FlagFilesOriginal,
} from "@vrtmrz/livesync-commonlib/compat/common/models/redflag.const";
import { readFetchFlagState, writeFetchFlagState, type FetchFlagState } from "./redFlag.fetchStateMarkdown";
type FetchStateHost = NecessaryServices<never, "storageAccess">;
function endpointDescription(value: string): string {
try {
const url = new URL(value);
url.username = "";
url.password = "";
url.search = "";
url.hash = "";
return url.toString().replace(/\/+$/, "");
} catch {
return "";
}
}
/** Describe the current destination for confirmation, without connection credentials. */
export function describeFetchRemote(settings: ObsidianLiveSyncSettings): string {
switch (settings.remoteType) {
case REMOTE_COUCHDB:
return ["CouchDB", endpointDescription(settings.couchDB_URI), settings.couchDB_DBNAME].join(" / ");
case REMOTE_MINIO:
return [
"Object Storage",
endpointDescription(settings.endpoint),
settings.region,
settings.bucket,
settings.bucketPrefix,
]
.filter(Boolean)
.join(" / ");
case REMOTE_P2P:
return [
"P2P",
settings.P2P_AppID,
settings.P2P_roomID,
...settings.P2P_relays.split(",").map((relay) => endpointDescription(relay.trim())),
]
.filter(Boolean)
.join(" / ");
default:
throw new Error("The selected remote type cannot use Fast Setup.");
}
}
async function readFetchFlag(host: FetchStateHost) {
const storage = host.serviceModules.storageAccess;
// A newly scheduled fetch writes the human-readable flag, even if an older alias remains.
for (const name of [FlagFilesHumanReadable.FETCH_ALL, FlagFilesOriginal.FETCH_ALL]) {
const path = storage.normalisePath(name);
if (await storage.isExists(path)) {
return { path, markdown: await storage.readFileText(path) };
}
}
throw new Error("The scheduled fetch flag is missing.");
}
async function writeVerified(host: FetchStateHost, path: string, markdown: string) {
const storage = host.serviceModules.storageAccess;
if (!(await storage.writeFileAuto(path, markdown)) || (await storage.readFileText(path)) !== markdown) {
throw new Error("The Fast Setup choices could not be saved in the fetch flag.");
}
}
export async function readFetchSelection(host: FetchStateHost): Promise<FetchFlagState | "empty" | "unreadable"> {
const { markdown } = await readFetchFlag(host);
if (!markdown.trim()) return "empty";
return readFetchFlagState(markdown) ?? "unreadable";
}
export async function saveFetchSelection(host: FetchStateHost, stage1: string, stage2: string): Promise<void> {
const { path, markdown } = await readFetchFlag(host);
const state: FetchFlagState = {
type: "livesync-fast-setup",
version: 1,
stage1,
stage2,
};
const updated = writeFetchFlagState(markdown, state);
if (updated !== markdown) await writeVerified(host, path, updated);
}
export async function clearFetchSelection(host: FetchStateHost): Promise<void> {
const { path, markdown } = await readFetchFlag(host);
const cleared = writeFetchFlagState(markdown, undefined);
if (cleared !== markdown) await writeVerified(host, path, cleared);
}
/** Remove both aliases, retaining the authoritative flag until the other alias is gone. */
export async function deleteFetchFlags(host: NecessaryServices<never, "storageAccess">): Promise<void> {
const storage = host.serviceModules.storageAccess;
for (const name of [FlagFilesOriginal.FETCH_ALL, FlagFilesHumanReadable.FETCH_ALL]) {
const path = storage.normalisePath(name);
if (await storage.isExists(path)) await storage.delete(path, true);
if (await storage.isExists(path)) throw new Error(`Could not remove ${name}.`);
}
}