Re-added the live cache, lazily populated

This commit is contained in:
Simon Cambier
2022-11-26 22:20:48 +01:00
parent d4519b57c2
commit 911ef193ae
6 changed files with 45 additions and 39 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "scambier.obsidian-search", "name": "scambier.obsidian-search",
"version": "1.9.0-beta.1", "version": "1.9.0-beta.2",
"description": "A search engine for Obsidian", "description": "A search engine for Obsidian",
"main": "dist/main.js", "main": "dist/main.js",
"scripts": { "scripts": {

View File

@@ -1,4 +1,4 @@
import { Notice, TFile } from 'obsidian' import { Notice } from 'obsidian'
import type { DocumentRef, IndexedDocument } from './globals' import type { DocumentRef, IndexedDocument } from './globals'
import { database } from './database' import { database } from './database'
import type { AsPlainObject } from 'minisearch' import type { AsPlainObject } from 'minisearch'
@@ -11,13 +11,11 @@ import {
isFilePDF, isFilePDF,
isFilePlaintext, isFilePlaintext,
makeMD5, makeMD5,
removeDiacritics removeDiacritics,
} from './tools/utils' } from './tools/utils'
import { getImageText, getPdfText } from "obsidian-text-extract"; import { getImageText, getPdfText } from 'obsidian-text-extract'
async function getIndexedDocument( async function getIndexedDocument(path: string): Promise<IndexedDocument> {
path: string
): Promise<IndexedDocument> {
const file = app.vault.getFiles().find(f => f.path === path) const file = app.vault.getFiles().find(f => f.path === path)
if (!file) throw new Error(`Invalid file path: "${path}"`) if (!file) throw new Error(`Invalid file path: "${path}"`)
let content: string let content: string
@@ -76,12 +74,20 @@ class CacheManager {
*/ */
private nextQueryIsEmpty = false private nextQueryIsEmpty = false
/**
* The "live cache", containing all indexed vault files
* in the form of IndexedDocuments
*/
private documents: Map<string, IndexedDocument> = new Map() private documents: Map<string, IndexedDocument> = new Map()
public async addToLiveCache(path: string): Promise<void> { public async addToLiveCache(path: string): Promise<void> {
const doc = await getIndexedDocument(path) const doc = await getIndexedDocument(path)
this.documents.set(path, doc) this.documents.set(path, doc)
console.log(path) // console.log(path)
}
public removeFromLiveCache(path: string): void {
this.documents.delete(path)
} }
public async getDocument(path: string): Promise<IndexedDocument> { public async getDocument(path: string): Promise<IndexedDocument> {

View File

@@ -32,7 +32,7 @@
// the next time we open the modal, the search field will be empty // the next time we open the modal, the search field will be empty
cacheManager.addToSearchHistory('') cacheManager.addToSearchHistory('')
dispatch('input', value) dispatch('input', value)
}, 200) }, 500)
</script> </script>
<div class="omnisearch-input-container"> <div class="omnisearch-input-container">

View File

@@ -3,13 +3,10 @@
import { onDestroy, onMount, tick } from 'svelte' import { onDestroy, onMount, tick } from 'svelte'
import InputSearch from './InputSearch.svelte' import InputSearch from './InputSearch.svelte'
import ModalContainer from './ModalContainer.svelte' import ModalContainer from './ModalContainer.svelte'
import { eventBus, indexingStep, IndexingStepType, type ResultNote } from 'src/globals' import { eventBus, indexingStep, IndexingStepType, type ResultNote, } from 'src/globals'
import { createNote, openNote } from 'src/tools/notes' import { createNote, openNote } from 'src/tools/notes'
import { getCtrlKeyLabel, getExtension, isFilePDF, loopIndex } from 'src/tools/utils' import { getCtrlKeyLabel, getExtension, isFilePDF, loopIndex, } from 'src/tools/utils'
import { import { OmnisearchInFileModal, type OmnisearchVaultModal, } from 'src/components/modals'
OmnisearchInFileModal,
type OmnisearchVaultModal,
} from 'src/components/modals'
import ResultItemVault from './ResultItemVault.svelte' import ResultItemVault from './ResultItemVault.svelte'
import { Query } from 'src/search/query' import { Query } from 'src/search/query'
import { settings } from '../settings' import { settings } from '../settings'
@@ -25,12 +22,18 @@
let resultNotes: ResultNote[] = [] let resultNotes: ResultNote[] = []
let query: Query let query: Query
let indexingStepDesc = '' let indexingStepDesc = ''
let searching = true
$: selectedNote = resultNotes[selectedIndex] $: selectedNote = resultNotes[selectedIndex]
$: searchQuery = searchQuery ?? previousQuery $: searchQuery = searchQuery ?? previousQuery
$: if (searchQuery) { $: if (searchQuery) {
updateResults() resultNotes = []
searching = true
updateResults().then(() => {
searching = false
})
} else { } else {
searching = false
resultNotes = [] resultNotes = []
} }
$: { $: {
@@ -246,11 +249,13 @@
on:mousemove="{_ => (selectedIndex = i)}" on:mousemove="{_ => (selectedIndex = i)}"
on:click="{onClick}" /> on:click="{onClick}" />
{/each} {/each}
{#if !resultNotes.length && searchQuery} <div style="text-align: center;">
<div style="text-align: center;"> {#if !resultNotes.length && searchQuery && !searching}
We found 0 result for your search here. We found 0 result for your search here.
</div> {:else if searching}
{/if} Searching...
{/if}
</div>
</ModalContainer> </ModalContainer>
<div class="prompt-instructions"> <div class="prompt-instructions">

View File

@@ -6,13 +6,7 @@ import {
import { loadSettings, settings, SettingsTab, showExcerpt } from './settings' import { loadSettings, settings, SettingsTab, showExcerpt } from './settings'
import { eventBus, EventNames, indexingStep, IndexingStepType } from './globals' import { eventBus, EventNames, indexingStep, IndexingStepType } from './globals'
import api from './tools/api' import api from './tools/api'
import { import { isFileIndexable, isFilePlaintext } from './tools/utils'
isFileImage,
isFileIndexable,
isFilePDF,
isFilePlaintext,
wait,
} from './tools/utils'
import { OmnisearchCache } from './database' import { OmnisearchCache } from './database'
import * as NotesIndex from './notes-index' import * as NotesIndex from './notes-index'
import { searchEngine } from './search/omnisearch' import { searchEngine } from './search/omnisearch'
@@ -59,23 +53,28 @@ export default class OmnisearchPlugin extends Plugin {
app.workspace.onLayoutReady(async () => { app.workspace.onLayoutReady(async () => {
// Listeners to keep the search index up-to-date // Listeners to keep the search index up-to-date
this.registerEvent( this.registerEvent(
this.app.vault.on('create', file => { this.app.vault.on('create', async file => {
cacheManager.addToLiveCache(file.path)
searchEngine.addFromPaths([file.path], false) searchEngine.addFromPaths([file.path], false)
}) })
) )
this.registerEvent( this.registerEvent(
this.app.vault.on('delete', file => { this.app.vault.on('delete', file => {
cacheManager.removeFromLiveCache(file.path)
searchEngine.removeFromPaths([file.path]) searchEngine.removeFromPaths([file.path])
}) })
) )
this.registerEvent( this.registerEvent(
this.app.vault.on('modify', async file => { this.app.vault.on('modify', async file => {
cacheManager.addToLiveCache(file.path)
NotesIndex.markNoteForReindex(file) NotesIndex.markNoteForReindex(file)
}) })
) )
this.registerEvent( this.registerEvent(
this.app.vault.on('rename', async (file, oldPath) => { this.app.vault.on('rename', async (file, oldPath) => {
if (file instanceof TFile && isFilePlaintext(file.path)) { if (file instanceof TFile && isFilePlaintext(file.path)) {
cacheManager.removeFromLiveCache(oldPath)
cacheManager.addToLiveCache(file.path)
searchEngine.removeFromPaths([oldPath]) searchEngine.removeFromPaths([oldPath])
await searchEngine.addFromPaths([file.path], false) await searchEngine.addFromPaths([file.path], false)
} }
@@ -115,7 +114,7 @@ async function populateIndex(): Promise<void> {
const files = app.vault.getFiles().filter(f => isFileIndexable(f.path)) const files = app.vault.getFiles().filter(f => isFileIndexable(f.path))
// Map documents in the background // Map documents in the background
files.forEach(f => cacheManager.addToLiveCache(f.path)) // Promise.all(files.map(f => cacheManager.addToLiveCache(f.path)))
if (!Platform.isIosApp) { if (!Platform.isIosApp) {
console.time('Omnisearch - Loading index from cache') console.time('Omnisearch - Loading index from cache')

View File

@@ -1,8 +1,4 @@
import MiniSearch, { import MiniSearch, { type Options, type SearchResult } from 'minisearch'
type AsPlainObject,
type Options,
type SearchResult,
} from 'minisearch'
import type { import type {
DocumentRef, DocumentRef,
IndexedDocument, IndexedDocument,
@@ -183,6 +179,8 @@ export class Omnisearch {
}) })
} }
results = results.slice(0, 50)
const documents = await Promise.all( const documents = await Promise.all(
results.map(async result => await cacheManager.getDocument(result.id)) results.map(async result => await cacheManager.getDocument(result.id))
) )
@@ -212,11 +210,9 @@ export class Omnisearch {
} }
// FIXME: // FIXME:
// Dedupe results - clutch for https://github.com/scambier/obsidian-omnisearch/issues/129 // Dedupe results - clutch for https://github.com/scambier/obsidian-omnisearch/issues/129
results = results results = results.filter(
.filter( (result, index, arr) => arr.findIndex(t => t.id === result.id) === index
(result, index, arr) => arr.findIndex(t => t.id === result.id) === index )
)
.slice(0, 50)
this.previousResults = results this.previousResults = results