mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-10-29 04:23:20 +00:00
Make strict startup content checks optional
This commit is contained in:
1 parent
e83aa892b4
commit
e46c05ddc2
13 files changed
+1029
-23
No files matched your search
@@ -23,6 +23,7 @@ export function createAdvancedSettingSpecGroups({
|
||||
control: { type: "dropdown", options: () => ChunkAlgorithmNames },
|
||||
},
|
||||
{ key: "customChunkSize", control: { type: "number", min: 0, allowZero: true } },
|
||||
{ key: "strictContentCheckOnStartup", control: { type: "toggle" } },
|
||||
{
|
||||
key: "pathNormalizationVersion",
|
||||
holdValue: true,
|
||||
|
||||
@@ -43,7 +43,7 @@ describe("paneAdvanced", () => {
|
||||
};
|
||||
|
||||
paneAdvanced.call(host as never, {} as HTMLElement, { addPanel } as never);
|
||||
await vi.waitFor(() => expect(settingHarness.rendered).toHaveLength(10));
|
||||
await vi.waitFor(() => expect(settingHarness.rendered).toHaveLength(11));
|
||||
|
||||
expect(addPanel.mock.calls.map(([, heading]) => heading)).toEqual([
|
||||
"Memory cache",
|
||||
@@ -56,6 +56,7 @@ describe("paneAdvanced", () => {
|
||||
panelElements.get("Local Database Tweak"),
|
||||
panelElements.get("Local Database Tweak"),
|
||||
panelElements.get("Local Database Tweak"),
|
||||
panelElements.get("Local Database Tweak"),
|
||||
panelElements.get("Transfer Tweak"),
|
||||
panelElements.get("Transfer Tweak"),
|
||||
panelElements.get("Transfer Tweak"),
|
||||
@@ -67,6 +68,7 @@ describe("paneAdvanced", () => {
|
||||
"hashCacheMaxCount",
|
||||
"chunkSplitterVersion",
|
||||
"customChunkSize",
|
||||
"strictContentCheckOnStartup",
|
||||
"pathNormalizationVersion",
|
||||
"readChunksOnline",
|
||||
"useOnlyLocalChunk",
|
||||
|
||||
@@ -17,7 +17,7 @@ const rangeMessages = {
|
||||
};
|
||||
|
||||
describe("Advanced setting specifications", () => {
|
||||
it("lists only the ten controls currently exposed by the Advanced page", () => {
|
||||
it("lists only the eleven controls currently exposed by the Advanced page", () => {
|
||||
const groups = createAdvancedSettingSpecGroups({ isCouchDB: () => true });
|
||||
|
||||
expect(groups.map(({ heading }) => heading)).toEqual([
|
||||
@@ -30,6 +30,7 @@ describe("Advanced setting specifications", () => {
|
||||
"hashCacheMaxCount",
|
||||
"chunkSplitterVersion",
|
||||
"customChunkSize",
|
||||
"strictContentCheckOnStartup",
|
||||
"pathNormalizationVersion",
|
||||
"readChunksOnline",
|
||||
"useOnlyLocalChunk",
|
||||
@@ -40,6 +41,17 @@ describe("Advanced setting specifications", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("exposes strict content checking as an ungated Advanced toggle", () => {
|
||||
const spec = createAdvancedSettingSpecGroups({ isCouchDB: () => false })
|
||||
.find(({ heading }) => heading === "Local Database Tweak")
|
||||
?.items.find(({ key }) => key === "strictContentCheckOnStartup");
|
||||
if (!spec) throw new Error("Strict content checking is not exposed on the Advanced page");
|
||||
|
||||
expect(spec.control).toEqual({ type: "toggle" });
|
||||
expect(spec.visible).toBeUndefined();
|
||||
expect(spec.disabled).toBeUndefined();
|
||||
});
|
||||
|
||||
it("keeps path identity and the four remote chunk controls CouchDB-only", () => {
|
||||
let couchDB = false;
|
||||
const groups = createAdvancedSettingSpecGroups({ isCouchDB: () => couchDB });
|
||||
|
||||
@@ -86,6 +86,7 @@ describe("settings page catalogue", () => {
|
||||
"hashCacheMaxCount",
|
||||
"chunkSplitterVersion",
|
||||
"customChunkSize",
|
||||
"strictContentCheckOnStartup",
|
||||
"pathNormalizationVersion",
|
||||
"readChunksOnline",
|
||||
"useOnlyLocalChunk",
|
||||
|
||||
@@ -19,6 +19,22 @@ import { initialiseWorkerModule } from "@vrtmrz/livesync-commonlib/compat/worker
|
||||
import { manifestVersion, packageVersion } from "@vrtmrz/livesync-commonlib/compat/common/coreEnvVars";
|
||||
import { VaultScanResults } from "@vrtmrz/livesync-commonlib/compat/serviceFeatures/offlineScanner";
|
||||
|
||||
const OBSIDIAN_PLATFORMS = new Set([
|
||||
"android-app",
|
||||
"ios",
|
||||
"macos",
|
||||
"mobile-app",
|
||||
"mobile",
|
||||
"safari",
|
||||
"desktop",
|
||||
"desktop-app",
|
||||
"unknown-obsidian",
|
||||
]);
|
||||
|
||||
function isObsidianPlatform(platform: string): boolean {
|
||||
return OBSIDIAN_PLATFORMS.has(platform);
|
||||
}
|
||||
|
||||
export class ModuleLiveSyncMain extends AbstractModule {
|
||||
async _onLiveSyncReady() {
|
||||
if (!(await this.core.services.appLifecycle.onLayoutReady())) return false;
|
||||
@@ -44,13 +60,20 @@ export class ModuleLiveSyncMain extends AbstractModule {
|
||||
}
|
||||
}
|
||||
// Ordinary start-up may continue when individual files could not be
|
||||
// processed. Explicit Fetch and Rebuild flows retain the strict default.
|
||||
// processed. Explicit Fetch and Rebuild flows remain strict.
|
||||
const { ignoreSuspending = false, continueOnFileFailure = true } = this.core.startupDatabaseOptions;
|
||||
// Only ordinary Obsidian start-up honours the opt-out. Keep other hosts
|
||||
// and explicit operation modes strict.
|
||||
const strictContentCheck =
|
||||
!isObsidianPlatform(this.services.API.getPlatform()) ||
|
||||
this.settings.strictContentCheckOnStartup === true ||
|
||||
this.core.startupDatabaseOptions.continueOnFileFailure === false;
|
||||
const initialisationResult = await this.services.databaseEvents.initialiseDatabase(
|
||||
false,
|
||||
false,
|
||||
ignoreSuspending,
|
||||
continueOnFileFailure
|
||||
continueOnFileFailure,
|
||||
{ strictContentCheck }
|
||||
);
|
||||
if (initialisationResult === VaultScanResults.FAILED) {
|
||||
this._log($msg("Ui.Common.LocalDatabaseInitialisationFailed"), LOG_LEVEL_NOTICE);
|
||||
|
||||
@@ -90,9 +90,11 @@ describe("ModuleLiveSyncMain", () => {
|
||||
},
|
||||
},
|
||||
services: {
|
||||
API: { getPlatform: () => "desktop" },
|
||||
databaseEvents: { initialiseDatabase },
|
||||
},
|
||||
settings: {
|
||||
strictContentCheckOnStartup: false,
|
||||
suspendFileWatching: false,
|
||||
suspendParseReplicationResult: false,
|
||||
},
|
||||
@@ -102,7 +104,7 @@ describe("ModuleLiveSyncMain", () => {
|
||||
const result = await ModuleLiveSyncMain.prototype._onLiveSyncReady.call(host as never);
|
||||
|
||||
expect(result).toBe(false);
|
||||
expect(initialiseDatabase).toHaveBeenCalledWith(false, false, false, true);
|
||||
expect(initialiseDatabase).toHaveBeenCalledWith(false, false, false, true, { strictContentCheck: false });
|
||||
expect(log).toHaveBeenCalledWith("Ui.Common.LocalDatabaseInitialisationFailed", LOG_LEVEL_NOTICE);
|
||||
});
|
||||
|
||||
@@ -120,6 +122,7 @@ describe("ModuleLiveSyncMain", () => {
|
||||
services: { appLifecycle },
|
||||
},
|
||||
services: {
|
||||
API: { getPlatform: () => "desktop" },
|
||||
appLifecycle,
|
||||
control: { applySettings: vi.fn(async () => undefined) },
|
||||
databaseEvents: { initialiseDatabase },
|
||||
@@ -152,6 +155,7 @@ describe("ModuleLiveSyncMain", () => {
|
||||
},
|
||||
},
|
||||
services: {
|
||||
API: { getPlatform: () => "desktop" },
|
||||
databaseEvents: { initialiseDatabase },
|
||||
},
|
||||
settings: {
|
||||
@@ -163,6 +167,96 @@ describe("ModuleLiveSyncMain", () => {
|
||||
|
||||
await ModuleLiveSyncMain.prototype._onLiveSyncReady.call(host as never);
|
||||
|
||||
expect(initialiseDatabase).toHaveBeenCalledWith(false, false, true, false);
|
||||
expect(initialiseDatabase).toHaveBeenCalledWith(false, false, true, false, { strictContentCheck: true });
|
||||
});
|
||||
|
||||
it("passes the strict content check setting for ordinary Obsidian start-up", async () => {
|
||||
const initialiseDatabase = vi.fn(async () => false);
|
||||
const host = {
|
||||
core: {
|
||||
startupDatabaseOptions: {},
|
||||
services: {
|
||||
appLifecycle: {
|
||||
onLayoutReady: vi.fn(async () => true),
|
||||
},
|
||||
},
|
||||
},
|
||||
services: {
|
||||
API: { getPlatform: () => "desktop" },
|
||||
databaseEvents: { initialiseDatabase },
|
||||
},
|
||||
settings: {
|
||||
strictContentCheckOnStartup: true,
|
||||
suspendFileWatching: false,
|
||||
suspendParseReplicationResult: false,
|
||||
},
|
||||
_log: vi.fn(),
|
||||
};
|
||||
|
||||
await ModuleLiveSyncMain.prototype._onLiveSyncReady.call(host as never);
|
||||
|
||||
expect(initialiseDatabase).toHaveBeenCalledWith(false, false, false, true, { strictContentCheck: true });
|
||||
});
|
||||
|
||||
it.each(["server", "browser"])(
|
||||
"keeps the strict content check on non-Obsidian host start-up (%s)",
|
||||
async (platform) => {
|
||||
const initialiseDatabase = vi.fn(async () => false);
|
||||
const host = {
|
||||
core: {
|
||||
startupDatabaseOptions: { ignoreSuspending: false, continueOnFileFailure: true },
|
||||
services: {
|
||||
appLifecycle: {
|
||||
onLayoutReady: vi.fn(async () => true),
|
||||
},
|
||||
},
|
||||
},
|
||||
services: {
|
||||
API: { getPlatform: () => platform },
|
||||
databaseEvents: { initialiseDatabase },
|
||||
},
|
||||
settings: {
|
||||
strictContentCheckOnStartup: false,
|
||||
suspendFileWatching: false,
|
||||
suspendParseReplicationResult: false,
|
||||
},
|
||||
_log: vi.fn(),
|
||||
};
|
||||
|
||||
await ModuleLiveSyncMain.prototype._onLiveSyncReady.call(host as never);
|
||||
|
||||
expect(initialiseDatabase).toHaveBeenCalledWith(false, false, false, true, { strictContentCheck: true });
|
||||
}
|
||||
);
|
||||
|
||||
it("keeps explicit recovery startup options strict when the setting is off", async () => {
|
||||
const initialiseDatabase = vi.fn(async () => false);
|
||||
const host = {
|
||||
core: {
|
||||
startupDatabaseOptions: {
|
||||
ignoreSuspending: false,
|
||||
continueOnFileFailure: false,
|
||||
},
|
||||
services: {
|
||||
appLifecycle: {
|
||||
onLayoutReady: vi.fn(async () => true),
|
||||
},
|
||||
},
|
||||
},
|
||||
services: {
|
||||
API: { getPlatform: () => "desktop" },
|
||||
databaseEvents: { initialiseDatabase },
|
||||
},
|
||||
settings: {
|
||||
strictContentCheckOnStartup: false,
|
||||
suspendFileWatching: false,
|
||||
suspendParseReplicationResult: false,
|
||||
},
|
||||
_log: vi.fn(),
|
||||
};
|
||||
|
||||
await ModuleLiveSyncMain.prototype._onLiveSyncReady.call(host as never);
|
||||
|
||||
expect(initialiseDatabase).toHaveBeenCalledWith(false, false, false, false, { strictContentCheck: true });
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user