### Fixed

- Fixed wrong event type bindings (which caused some events not to be handled correctly).
- Fixed detected a timing issue in StorageEventManager
    - When multiple events for the same file are fired in quick succession, metadata has been kept older information. This induces unexpected wrong notifications and write prevention.
This commit is contained in:
vorotamoroz
2025-10-08 05:00:42 +01:00
parent 67c9b4cf06
commit 7c4f2bf78a
4 changed files with 10 additions and 3 deletions

Submodule src/lib updated: 6972cf45b3...6c2a72d9cc

View File

@@ -94,10 +94,14 @@ export class ModuleFileHandler extends AbstractModule {
let readFile: UXFileInfo | undefined = undefined; let readFile: UXFileInfo | undefined = undefined;
if (!shouldApplied) { if (!shouldApplied) {
readFile = await this.readFileFromStub(file); readFile = await this.readFileFromStub(file);
if (!readFile) {
this._log(`File ${file.path} is not exist on the storage`, LOG_LEVEL_NOTICE);
return false;
}
if (await isDocContentSame(getDocDataAsArray(entry.data), readFile.body)) { if (await isDocContentSame(getDocDataAsArray(entry.data), readFile.body)) {
// Timestamp is different but the content is same. therefore, two timestamps should be handled as same. // Timestamp is different but the content is same. therefore, two timestamps should be handled as same.
// So, mark the changes are same. // So, mark the changes are same.
markChangesAreSame(file, file.stat.mtime, entry.mtime); markChangesAreSame(readFile, readFile.stat.mtime, entry.mtime);
} else { } else {
shouldApplied = true; shouldApplied = true;
} }

View File

@@ -222,6 +222,7 @@ export class ModuleFileAccessObsidian extends AbstractObsidianModule implements
return null; return null;
} }
} }
async readStubContent(stub: UXFileInfoStub): Promise<UXFileInfo | false> { async readStubContent(stub: UXFileInfoStub): Promise<UXFileInfo | false> {
const file = this.vaultAccess.getAbstractFileByPath(stub.path); const file = this.vaultAccess.getAbstractFileByPath(stub.path);
if (!(file instanceof TFile)) { if (!(file instanceof TFile)) {
@@ -231,6 +232,7 @@ export class ModuleFileAccessObsidian extends AbstractObsidianModule implements
const data = await this.vaultAccess.vaultReadAuto(file); const data = await this.vaultAccess.vaultReadAuto(file);
return { return {
...stub, ...stub,
...TFileToUXFileInfoStub(file),
body: createBlob(data), body: createBlob(data),
}; };
} }

View File

@@ -295,7 +295,7 @@ export class StorageEventManagerObsidian extends StorageEventManager {
concurrentProcessing = Semaphore(5); concurrentProcessing = Semaphore(5);
waitedSince = new Map<FilePath | FilePathWithPrefix, number>(); waitedSince = new Map<FilePath | FilePathWithPrefix, number>();
async startStandingBy(filename: FilePath) { async startStandingBy(filename: FilePath) {
// If waited, cancel previous waiting. // If waited, no need to start again (looping inside the function)
await skipIfDuplicated(`storage-event-manager-${filename}`, async () => { await skipIfDuplicated(`storage-event-manager-${filename}`, async () => {
Logger(`Processing ${filename}: Starting`, LOG_LEVEL_DEBUG); Logger(`Processing ${filename}: Starting`, LOG_LEVEL_DEBUG);
const release = await this.concurrentProcessing.acquire(); const release = await this.concurrentProcessing.acquire();
@@ -315,6 +315,7 @@ export class StorageEventManagerObsidian extends StorageEventManager {
// continue; // continue;
// } // }
const type = target.type; const type = target.type;
// If already cancelled by other operation, skip this.
if (target.cancelled) { if (target.cancelled) {
Logger(`Processing ${filename}: Cancelled (scheduled): ${operationType}`, LOG_LEVEL_DEBUG); Logger(`Processing ${filename}: Cancelled (scheduled): ${operationType}`, LOG_LEVEL_DEBUG);
this.cancelStandingBy(target); this.cancelStandingBy(target);