Re-added the live cache, lazily populated
This commit is contained in:
@@ -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": {
|
||||||
|
|||||||
@@ -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> {
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
17
src/main.ts
17
src/main.ts
@@ -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')
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user