fix(#245): correctly update embeds on fs events

This commit is contained in:
Simon Cambier
2024-09-27 13:53:30 +02:00
parent 10721601b1
commit 983fa2120b
4 changed files with 58 additions and 26 deletions

View File

@@ -44,7 +44,7 @@ export class CacheManager {
return return
} }
this.documents.set(path, doc) this.documents.set(path, doc)
this.plugin.embedsRepository.refreshEmbeds(path) this.plugin.embedsRepository.refreshEmbedsForNote(path)
} catch (e) { } catch (e) {
console.warn(`Omnisearch: Error while adding "${path}" to live cache`, e) console.warn(`Omnisearch: Error while adding "${path}" to live cache`, e)
// Shouldn't be needed, but... // Shouldn't be needed, but...

View File

@@ -5,7 +5,7 @@ import { Notice } from 'obsidian'
import type OmnisearchPlugin from './main' import type OmnisearchPlugin from './main'
export class Database extends Dexie { export class Database extends Dexie {
public static readonly dbVersion = 9 public static readonly dbVersion = 10
searchHistory!: Dexie.Table<{ id?: number; query: string }, number> searchHistory!: Dexie.Table<{ id?: number; query: string }, number>
minisearch!: Dexie.Table< minisearch!: Dexie.Table<
{ {
@@ -15,7 +15,7 @@ export class Database extends Dexie {
}, },
string string
> >
embeds!: Dexie.Table<{ embedded: string; references: string[] }, string> embeds!: Dexie.Table<{ embedded: string; referencedBy: string[] }, string>
constructor(private plugin: OmnisearchPlugin) { constructor(private plugin: OmnisearchPlugin) {
super(Database.getDbName(plugin.app.appId)) super(Database.getDbName(plugin.app.appId))

View File

@@ -112,7 +112,7 @@ export default class OmnisearchPlugin extends Plugin {
if (this.notesIndexer.isFileIndexable(file.path)) { if (this.notesIndexer.isFileIndexable(file.path)) {
logDebug('Indexing new file', file.path) logDebug('Indexing new file', file.path)
searchEngine.addFromPaths([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) logDebug('Removing file', file.path)
this.cacheManager.removeFromLiveCache(file.path) this.cacheManager.removeFromLiveCache(file.path)
searchEngine.removeFromPaths([file.path]) searchEngine.removeFromPaths([file.path])
this.embedsRepository.refreshEmbeds(file.path) this.embedsRepository.removeFile(file.path)
}) })
) )
this.registerEvent( this.registerEvent(
@@ -129,7 +129,7 @@ export default class OmnisearchPlugin extends Plugin {
if (this.notesIndexer.isFileIndexable(file.path)) { if (this.notesIndexer.isFileIndexable(file.path)) {
this.notesIndexer.flagNoteForReindex(file) this.notesIndexer.flagNoteForReindex(file)
} }
this.embedsRepository.refreshEmbeds(file.path) this.embedsRepository.refreshEmbedsForNote(file.path)
}) })
) )
this.registerEvent( this.registerEvent(
@@ -138,8 +138,11 @@ export default class OmnisearchPlugin extends Plugin {
logDebug('Renaming file', file.path) logDebug('Renaming file', file.path)
this.cacheManager.removeFromLiveCache(oldPath) this.cacheManager.removeFromLiveCache(oldPath)
await this.cacheManager.addToLiveCache(file.path) await this.cacheManager.addToLiveCache(file.path)
searchEngine.removeFromPaths([oldPath]) searchEngine.removeFromPaths([oldPath])
await searchEngine.addFromPaths([file.path]) await searchEngine.addFromPaths([file.path])
this.embedsRepository.renameFile(oldPath, file.path)
} }
}) })
) )

View File

@@ -1,9 +1,9 @@
import { getLinkpath } from 'obsidian' import { getLinkpath, Notice } from 'obsidian'
import type OmnisearchPlugin from '../main' import type OmnisearchPlugin from '../main'
import { logDebug } from '../tools/utils' import { logDebug } from '../tools/utils'
export class EmbedsRepository { export class EmbedsRepository {
/** Map<image or pdf, notes where embedded> */ /** Map<embedded file, notes where the embed is referenced> */
private embeds: Map<string, Set<string>> = new Map() private embeds: Map<string, Set<string>> = new Map()
constructor(private plugin: OmnisearchPlugin) {} constructor(private plugin: OmnisearchPlugin) {}
@@ -15,13 +15,36 @@ export class EmbedsRepository {
this.embeds.get(embed)!.add(notePath) this.embeds.get(embed)!.add(notePath)
} }
public refreshEmbeds(notePath: string): void { public removeFile(filePath: string): void {
this.embeds.forEach((value, key) => { // If the file is embedded
if (value.has(notePath)) { this.embeds.delete(filePath)
value.delete(notePath) // 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[] { public getEmbeds(pathEmbedded: string): string[] {
@@ -34,15 +57,16 @@ export class EmbedsRepository {
public async writeToCache(): Promise<void> { public async writeToCache(): Promise<void> {
logDebug('Writing embeds to cache') logDebug('Writing embeds to cache')
const database = this.plugin.database const database = this.plugin.database
const data: { embedded: string; references: string[] }[] = [] const data: { embedded: string; referencedBy: string[] }[] = []
for (const [path, embedsList] of this.embeds) { 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.clear()
await database.embeds.bulkAdd(data) await database.embeds.bulkAdd(data)
} }
public async loadFromCache(): Promise<void> { public async loadFromCache(): Promise<void> {
try {
const database = this.plugin.database const database = this.plugin.database
if (!database.embeds) { if (!database.embeds) {
logDebug('No embeds in cache') logDebug('No embeds in cache')
@@ -50,14 +74,19 @@ export class EmbedsRepository {
} }
logDebug('Loading embeds from cache') logDebug('Loading embeds from cache')
const embedsArr = await database.embeds.toArray() const embedsArr = await database.embeds.toArray()
for (const { embedded: path, references: embeds } of embedsArr) { for (const { embedded: path, referencedBy: embeds } of embedsArr) {
for (const embed of embeds) { for (const embed of embeds) {
this.addEmbed(path, embed) 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 // Get all embeds from the note
// and map them to TFiles to get the real path // and map them to TFiles to get the real path
const embeds = ( const embeds = (