json-bible 1.1.6 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/search.ts +51 -28
- package/package.json +1 -1
package/lib/search.ts
CHANGED
|
@@ -111,52 +111,75 @@ export function _bookSearch(bible: Bible, searchValue: string) {
|
|
|
111
111
|
|
|
112
112
|
// TEXT SEARCH //
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
const formattedTextCache = new Map<string, string>()
|
|
115
|
+
function getFormattedVerse(text: string) {
|
|
116
|
+
const cached = formattedTextCache.get(text)
|
|
117
|
+
if (cached !== undefined) return cached
|
|
118
|
+
|
|
119
|
+
const formatted = formatText(text)
|
|
120
|
+
formattedTextCache.set(text, formatted)
|
|
121
|
+
|
|
122
|
+
return formatted
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const textSearchCache = new Map<string, VerseReference[]>()
|
|
115
126
|
export function _textSearch(bible: Bible, searchValue: string, limit: number, bookNumber?: number) {
|
|
116
127
|
searchValue = formatText(searchValue).trim()
|
|
117
|
-
if (!searchValue
|
|
128
|
+
if (!searchValue) return []
|
|
118
129
|
|
|
119
|
-
|
|
120
|
-
|
|
130
|
+
// cache results for identical searches
|
|
131
|
+
const cacheId = `${bible.name}|${searchValue}|${limit}|${bookNumber ?? ""}`
|
|
132
|
+
const cached = textSearchCache.get(cacheId)
|
|
133
|
+
if (cached) return cached
|
|
121
134
|
|
|
122
|
-
|
|
135
|
+
// split into individual words so we can match verses containing all words even if the exact phrase is absent
|
|
136
|
+
const searchWords = searchValue.split(/\s+/)
|
|
123
137
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
/////
|
|
138
|
+
// search in a specific book or all books
|
|
139
|
+
const books = bookNumber === undefined ? bible.books : [bible.books[getBookIndex(bible, bookNumber)]]
|
|
128
140
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const
|
|
141
|
+
const matches: VerseReference[] = []
|
|
142
|
+
for (const book of books) {
|
|
143
|
+
for (const chapter of book.chapters) {
|
|
144
|
+
const verses: number[] = []
|
|
132
145
|
|
|
133
|
-
|
|
146
|
+
for (const verse of chapter.verses) {
|
|
147
|
+
const verseValue = getFormattedVerse(verse.text ?? "")
|
|
134
148
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
let verses: number[] = []
|
|
149
|
+
// check if the full phrase exists in the verse
|
|
150
|
+
let isMatch = verseValue.includes(searchValue)
|
|
138
151
|
|
|
139
|
-
|
|
140
|
-
|
|
152
|
+
// or check whether every search word exists somewhere in the verse
|
|
153
|
+
if (!isMatch) {
|
|
154
|
+
isMatch = true
|
|
141
155
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
156
|
+
for (const word of searchWords) {
|
|
157
|
+
if (!verseValue.includes(word)) {
|
|
158
|
+
isMatch = false
|
|
159
|
+
break
|
|
160
|
+
}
|
|
145
161
|
}
|
|
146
162
|
}
|
|
147
163
|
|
|
148
|
-
if (verses.
|
|
149
|
-
|
|
150
|
-
|
|
164
|
+
if (isMatch) verses.push(verse.number)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (verses.length) {
|
|
168
|
+
const reference = getVerseReferences(bible, { book: book.number, chapter: chapter.number, verses })
|
|
169
|
+
matches.push(...reference)
|
|
151
170
|
|
|
152
|
-
|
|
153
|
-
|
|
171
|
+
// return early once we have enough results
|
|
172
|
+
if (matches.length >= limit) {
|
|
173
|
+
const result = matches.slice(0, limit)
|
|
174
|
+
textSearchCache.set(cacheId, result)
|
|
175
|
+
return result
|
|
154
176
|
}
|
|
155
177
|
}
|
|
156
178
|
}
|
|
157
|
-
|
|
158
|
-
return matches
|
|
159
179
|
}
|
|
180
|
+
|
|
181
|
+
textSearchCache.set(cacheId, matches)
|
|
182
|
+
return matches
|
|
160
183
|
}
|
|
161
184
|
|
|
162
185
|
// HELPERS //
|