### Fixed

- Unexpected errors no longer occurred when the plug-in was unloaded.
- Hidden File Sync now respects selectors.
- Registering protocol-handlers now works safely without causing unexpected errors.

### Refactored
- LiveSyncManagers has now explicit dependencies.
- LiveSyncLocalDB is now responsible for LiveSyncManagers, not accepting the managers as dependencies.
    - This is to avoid circular dependencies and clarify the ownership of the managers.
- ChangeManager has been refactored. This had a potential issue, so something had been fixed, possibly.
- Some tests have been ported from Deno's test runner to Vitest to accumulate coverage.
This commit is contained in:
vorotamoroz
2026-02-26 11:30:57 +00:00
parent 392f76fd36
commit 646f8af680
5 changed files with 39 additions and 27 deletions

View File

@@ -92,7 +92,7 @@ export class HiddenFileSync extends LiveSyncCommands {
return this.plugin.kvDB;
}
getConflictedDoc(path: FilePathWithPrefix, rev: string) {
return this.plugin.managers.conflictManager.getConflictedDoc(path, rev);
return this.localDatabase.managers.conflictManager.getConflictedDoc(path, rev);
}
onunload() {
this.periodicInternalFileScanProcessor?.disable();
@@ -244,13 +244,23 @@ export class HiddenFileSync extends LiveSyncCommands {
if (this.isThisModuleEnabled()) {
//system file
const filename = this.getPath(doc);
if (await this.services.vault.isTargetFile(filename)) {
// this.procInternalFile(filename);
await this.processReplicationResult(doc);
const unprefixedPath = stripAllPrefixes(filename);
// No need to check via vaultService
// if (!await this.services.vault.isTargetFile(unprefixedPath)) {
// this._log(`Skipped processing sync file:${unprefixedPath} (Not target)`, LOG_LEVEL_VERBOSE);
// return true;
// }
if (!(await this.isTargetFile(stripAllPrefixes(unprefixedPath)))) {
this._log(
`Skipped processing sync file:${unprefixedPath} (Not Hidden File Sync target)`,
LOG_LEVEL_VERBOSE
);
// We should return true, we made sure that document is a internalMetadata.
return true;
} else {
this._log(`Skipped (Not target:${filename})`, LOG_LEVEL_VERBOSE);
return false;
}
if (!(await this.processReplicationResult(doc))) {
this._log(`Failed to process sync file:${unprefixedPath}`, LOG_LEVEL_NOTICE);
// Do not yield false, this file had been processed.
}
}
return true;
@@ -700,7 +710,7 @@ Offline Changed files: ${processFiles.length}`;
revFrom._revs_info
?.filter((e) => e.status == "available" && Number(e.rev.split("-")[0]) < conflictedRevNo)
.first()?.rev ?? "";
const result = await this.plugin.managers.conflictManager.mergeObject(
const result = await this.localDatabase.managers.conflictManager.mergeObject(
doc.path,
commonBase,
doc._rev,

Submodule src/lib updated: 1335a01744...29f2a6aa4f

View File

@@ -239,13 +239,6 @@ export default class ObsidianLiveSyncPlugin
return this.services.database.localDatabase;
}
/**
* @obsolete Use services.database.managers instead. The database managers, including entry manager, revision manager, etc.
*/
get managers() {
return this.services.database.managers;
}
/**
* @obsolete Use services.database.localDatabase instead. Get the PouchDB database instance. Note that this is not the same as the local database instance, which is a wrapper around the PouchDB database.
* @returns The PouchDB database instance.

View File

@@ -1,4 +1,4 @@
import { type ObsidianLiveSyncSettings, LOG_LEVEL_NOTICE } from "../../lib/src/common/types.ts";
import { type ObsidianLiveSyncSettings, LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE } from "../../lib/src/common/types.ts";
import { configURIBase } from "../../common/types.ts";
// import { PouchDB } from "../../lib/src/pouchdb/pouchdb-browser.js";
import { fireAndForget } from "../../lib/src/common/utils.ts";
@@ -25,16 +25,24 @@ export class ModuleSetupObsidian extends AbstractModule {
private _setupManager!: SetupManager;
private _everyOnload(): Promise<boolean> {
this._setupManager = this.core.getModule(SetupManager);
this.registerObsidianProtocolHandler("setuplivesync", async (conf: any) => {
if (conf.settings) {
await this._setupManager.onUseSetupURI(
UserMode.Unknown,
`${configURIBase}${encodeURIComponent(conf.settings)}`
);
} else if (conf.settingsQR) {
await this._setupManager.decodeQR(conf.settingsQR);
}
});
try {
this.registerObsidianProtocolHandler("setuplivesync", async (conf: any) => {
if (conf.settings) {
await this._setupManager.onUseSetupURI(
UserMode.Unknown,
`${configURIBase}${encodeURIComponent(conf.settings)}`
);
} else if (conf.settingsQR) {
await this._setupManager.decodeQR(conf.settingsQR);
}
});
} catch (e) {
this._log(
"Failed to register protocol handler. This feature may not work in some environments.",
LOG_LEVEL_NOTICE
);
this._log(e, LOG_LEVEL_VERBOSE);
}
this.addCommand({
id: "livesync-setting-qr",
name: "Show settings as a QR code",

View File

@@ -59,6 +59,7 @@ export class ObsidianServiceHub extends InjectableServiceHub<ObsidianServiceCont
path: path,
vault: vault,
setting: setting,
API: API,
});
const keyValueDB = new ObsidianKeyValueDBService(context, {
appLifecycle: appLifecycle,