From 983fa2120b5b91a05227373b7da9a88fd4be991f Mon Sep 17 00:00:00 2001 From: Simon Cambier Date: Fri, 27 Sep 2024 13:53:30 +0200 Subject: [PATCH] fix(#245): correctly update embeds on fs events --- src/cache-manager.ts | 2 +- src/database.ts | 4 +- src/main.ts | 9 ++-- src/repositories/embeds-repository.ts | 69 +++++++++++++++++++-------- 4 files changed, 58 insertions(+), 26 deletions(-) diff --git a/src/cache-manager.ts b/src/cache-manager.ts index 60afdfd..8f90528 100644 --- a/src/cache-manager.ts +++ b/src/cache-manager.ts @@ -44,7 +44,7 @@ export class CacheManager { return } this.documents.set(path, doc) - this.plugin.embedsRepository.refreshEmbeds(path) + this.plugin.embedsRepository.refreshEmbedsForNote(path) } catch (e) { console.warn(`Omnisearch: Error while adding "${path}" to live cache`, e) // Shouldn't be needed, but... diff --git a/src/database.ts b/src/database.ts index 834a844..4fe1c5b 100644 --- a/src/database.ts +++ b/src/database.ts @@ -5,7 +5,7 @@ import { Notice } from 'obsidian' import type OmnisearchPlugin from './main' export class Database extends Dexie { - public static readonly dbVersion = 9 + public static readonly dbVersion = 10 searchHistory!: Dexie.Table<{ id?: number; query: string }, number> minisearch!: Dexie.Table< { @@ -15,7 +15,7 @@ export class Database extends Dexie { }, string > - embeds!: Dexie.Table<{ embedded: string; references: string[] }, string> + embeds!: Dexie.Table<{ embedded: string; referencedBy: string[] }, string> constructor(private plugin: OmnisearchPlugin) { super(Database.getDbName(plugin.app.appId)) diff --git a/src/main.ts b/src/main.ts index 59ef232..f2586d9 100644 --- a/src/main.ts +++ b/src/main.ts @@ -112,7 +112,7 @@ export default class OmnisearchPlugin extends Plugin { if (this.notesIndexer.isFileIndexable(file.path)) { logDebug('Indexing new file', file.path) searchEngine.addFromPaths([file.path]) - this.embedsRepository.refreshEmbeds(file.path) + this.embedsRepository.refreshEmbedsForNote(file.path) } }) ) @@ -121,7 +121,7 @@ export default class OmnisearchPlugin extends Plugin { logDebug('Removing file', file.path) this.cacheManager.removeFromLiveCache(file.path) searchEngine.removeFromPaths([file.path]) - this.embedsRepository.refreshEmbeds(file.path) + this.embedsRepository.removeFile(file.path) }) ) this.registerEvent( @@ -129,7 +129,7 @@ export default class OmnisearchPlugin extends Plugin { if (this.notesIndexer.isFileIndexable(file.path)) { this.notesIndexer.flagNoteForReindex(file) } - this.embedsRepository.refreshEmbeds(file.path) + this.embedsRepository.refreshEmbedsForNote(file.path) }) ) this.registerEvent( @@ -138,8 +138,11 @@ export default class OmnisearchPlugin extends Plugin { logDebug('Renaming file', file.path) this.cacheManager.removeFromLiveCache(oldPath) await this.cacheManager.addToLiveCache(file.path) + searchEngine.removeFromPaths([oldPath]) await searchEngine.addFromPaths([file.path]) + + this.embedsRepository.renameFile(oldPath, file.path) } }) ) diff --git a/src/repositories/embeds-repository.ts b/src/repositories/embeds-repository.ts index 4547b92..7a08fdc 100644 --- a/src/repositories/embeds-repository.ts +++ b/src/repositories/embeds-repository.ts @@ -1,9 +1,9 @@ -import { getLinkpath } from 'obsidian' +import { getLinkpath, Notice } from 'obsidian' import type OmnisearchPlugin from '../main' import { logDebug } from '../tools/utils' export class EmbedsRepository { - /** Map */ + /** Map */ private embeds: Map> = new Map() constructor(private plugin: OmnisearchPlugin) {} @@ -15,13 +15,36 @@ export class EmbedsRepository { this.embeds.get(embed)!.add(notePath) } - public refreshEmbeds(notePath: string): void { - this.embeds.forEach((value, key) => { - if (value.has(notePath)) { - value.delete(notePath) + public removeFile(filePath: string): void { + // If the file is embedded + this.embeds.delete(filePath) + // If the file is a note referencing other files + this.refreshEmbedsForNote(filePath) + } + + public renameFile(oldPath: string, newPath: string): void { + // If the file is embedded + if (this.embeds.has(oldPath)) { + this.embeds.set(newPath, this.embeds.get(oldPath)!) + this.embeds.delete(oldPath) + } + // If the file is a note referencing other files + this.embeds.forEach((referencedBy, key) => { + if (referencedBy.has(oldPath)) { + referencedBy.delete(oldPath) + referencedBy.add(newPath) } }) - this.addEmbeds(notePath) + } + + public refreshEmbedsForNote(filePath: string): void { + this.embeds.forEach((referencedBy, key) => { + if (referencedBy.has(filePath)) { + referencedBy.delete(filePath) + } + }) + + this.addEmbedsForNote(filePath) } public getEmbeds(pathEmbedded: string): string[] { @@ -34,30 +57,36 @@ export class EmbedsRepository { public async writeToCache(): Promise { logDebug('Writing embeds to cache') const database = this.plugin.database - const data: { embedded: string; references: string[] }[] = [] + const data: { embedded: string; referencedBy: string[] }[] = [] for (const [path, embedsList] of this.embeds) { - data.push({ embedded: path, references: [...embedsList] }) + data.push({ embedded: path, referencedBy: [...embedsList] }) } await database.embeds.clear() await database.embeds.bulkAdd(data) } public async loadFromCache(): Promise { - const database = this.plugin.database - if (!database.embeds) { - logDebug('No embeds in cache') - return - } - logDebug('Loading embeds from cache') - const embedsArr = await database.embeds.toArray() - for (const { embedded: path, references: embeds } of embedsArr) { - for (const embed of embeds) { - this.addEmbed(path, embed) + try { + const database = this.plugin.database + if (!database.embeds) { + logDebug('No embeds in cache') + return } + logDebug('Loading embeds from cache') + const embedsArr = await database.embeds.toArray() + for (const { embedded: path, referencedBy: embeds } of embedsArr) { + for (const embed of embeds) { + this.addEmbed(path, embed) + } + } + } catch (e) { + this.plugin.database.clearCache() + console.error('Omnisearch - Error while loading embeds cache') + new Notice('Omnisearch - There was an error while loading the cache. Please restart Obsidian.') } } - private addEmbeds(notePath: string): void { + private addEmbedsForNote(notePath: string): void { // Get all embeds from the note // and map them to TFiles to get the real path const embeds = (