Add storage search foundation
This commit is contained in:
+17
-31
@@ -1,4 +1,5 @@
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { buildVerseSearchIndex } from './searchIndex'
|
||||
import type {
|
||||
CommentaryEntry,
|
||||
DictionaryEntry,
|
||||
@@ -110,7 +111,6 @@ type BrowserLexiconEntry = {
|
||||
|
||||
type BrowserStrongData = {
|
||||
linksByVerse: Map<string, StrongLink[]>
|
||||
verseIdsByStrong: Map<string, Set<string>>
|
||||
}
|
||||
|
||||
let browserCatalogCache: Promise<ImportedCatalog> | null = null
|
||||
@@ -120,6 +120,7 @@ const browserFootnotesCache = new Map<string, Promise<Map<string, Footnote[]>>>(
|
||||
const browserStudyNotesCache = new Map<string, Promise<Map<string, Footnote[]>>>()
|
||||
const browserChapterFootnotesCache = new Map<string, Promise<Map<string, Footnote[]>>>()
|
||||
const browserChapterStudyNotesCache = new Map<string, Promise<Map<string, Footnote[]>>>()
|
||||
const browserSearchIndexCache = new Map<string, Promise<ReturnType<typeof buildVerseSearchIndex>>>()
|
||||
let browserCommentaryCache: Promise<Map<string, CommentaryEntry[]>> | null = null
|
||||
let browserDictionaryCache: Promise<Map<string, DictionaryEntry>> | null = null
|
||||
const browserVerseSourceIds = new Map<number, string>()
|
||||
@@ -359,30 +360,8 @@ export async function searchVerses(query: string, translationId = defaultTransla
|
||||
return invoke<Verse[]>('search_verses', { query })
|
||||
}
|
||||
|
||||
const trimmed = query.trim().toLowerCase()
|
||||
const verses = await loadBrowserVersesForTranslation(translationId)
|
||||
if (!trimmed) return verses
|
||||
|
||||
if (trimmed.startsWith('tag:')) {
|
||||
const label = trimmed.slice(4)
|
||||
return verses.filter((verse) =>
|
||||
verse.tags.some((tag) => tag.label.toLowerCase() === label),
|
||||
)
|
||||
}
|
||||
|
||||
if (/^[gh]\d+$/.test(trimmed)) {
|
||||
const strongData = await loadBrowserStrongData(translationId)
|
||||
const matchingVerseIds = strongData.verseIdsByStrong.get(trimmed.toUpperCase()) ?? new Set()
|
||||
return verses.filter((verse) =>
|
||||
matchingVerseIds.has(browserVerseKey(verse)),
|
||||
)
|
||||
}
|
||||
|
||||
return verses.filter((verse) =>
|
||||
`${verse.book} ${verse.chapter}:${verse.verse} ${verse.text}`
|
||||
.toLowerCase()
|
||||
.includes(trimmed),
|
||||
)
|
||||
const searchIndex = await loadBrowserSearchIndex(translationId)
|
||||
return searchIndex.search(query)
|
||||
}
|
||||
|
||||
export async function addTagToVerse(
|
||||
@@ -401,6 +380,7 @@ export async function addTagToVerse(
|
||||
const tag = existing ?? { id: Date.now(), label, color }
|
||||
tagsByVerse[verseId] = existing ? current : [...current, tag]
|
||||
writeBrowserTags(tagsByVerse)
|
||||
browserSearchIndexCache.delete(translationId)
|
||||
|
||||
const verse = (await loadBrowserVersesForTranslation(translationId)).find((item) => item.id === verseId)
|
||||
if (!verse) throw new Error(`Verse ${verseId} was not found.`)
|
||||
@@ -441,6 +421,17 @@ async function loadBrowserCatalog(): Promise<ImportedCatalog> {
|
||||
return browserCatalogCache
|
||||
}
|
||||
|
||||
async function loadBrowserSearchIndex(translationId = defaultTranslationId) {
|
||||
if (!browserSearchIndexCache.has(translationId)) {
|
||||
browserSearchIndexCache.set(
|
||||
translationId,
|
||||
loadBrowserVersesForTranslation(translationId).then((verses) => buildVerseSearchIndex(verses)),
|
||||
)
|
||||
}
|
||||
|
||||
return browserSearchIndexCache.get(translationId)!
|
||||
}
|
||||
|
||||
async function loadLibreBibleDevVerses(translationId = defaultTranslationId): Promise<Verse[]> {
|
||||
const importedVerses = await fetchJsonl<ImportedVerse>(
|
||||
`${libreBibleDevRoot}/${translationId}/verses.jsonl`,
|
||||
@@ -652,7 +643,6 @@ async function loadLibreBibleDevStrongData(translationId = defaultTranslationId)
|
||||
]),
|
||||
)
|
||||
const linksByVerse = new Map<string, StrongLink[]>()
|
||||
const verseIdsByStrong = new Map<string, Set<string>>()
|
||||
|
||||
for (const link of importedLinks) {
|
||||
const entry = lexicon.get(link.strong)
|
||||
@@ -668,17 +658,13 @@ async function loadLibreBibleDevStrongData(translationId = defaultTranslationId)
|
||||
const current = linksByVerse.get(link.verse_id) ?? []
|
||||
current.push(strongLink)
|
||||
linksByVerse.set(link.verse_id, current)
|
||||
|
||||
const strongMatches = verseIdsByStrong.get(link.strong) ?? new Set<string>()
|
||||
strongMatches.add(link.verse_id)
|
||||
verseIdsByStrong.set(link.strong, strongMatches)
|
||||
}
|
||||
|
||||
for (const links of linksByVerse.values()) {
|
||||
links.sort((a, b) => a.position - b.position)
|
||||
}
|
||||
|
||||
return { linksByVerse, verseIdsByStrong }
|
||||
return { linksByVerse }
|
||||
}
|
||||
|
||||
function strongLanguage(strong: string): 'Hebrew' | 'Greek' {
|
||||
|
||||
Reference in New Issue
Block a user