1 | import lunr from 'lunr'; |
2 | |
3 | |
4 | function joinPath(...path){ |
5 | return path.filter(Boolean).join("/").replace(/\/+/g, "/"); |
6 | } |
7 | |
8 | export default function initializeLunr({lunrDir}){ |
9 | let idxMap = new Map(); |
10 | async function getIndex(index = ""){ |
11 | if(!idxMap.has(index)){ |
12 | let response = await fetch(joinPath(lunrDir, index, "idx.json")); |
13 | if(response.status !== 200){ |
14 | throw new Error(`Astro-lunr: idx.json not found for index=${index}`); |
15 | } |
16 | let idxJson = await response.text(); |
17 | idxMap.set(index, lunr.Index.load(JSON.parse(idxJson))); |
18 | } |
19 | return idxMap.get(index); |
20 | } |
21 | |
22 | let docMap = new Map(); |
23 | async function getDocs(index = ""){ |
24 | if(!docMap.has(index)){ |
25 | let response = await fetch(joinPath(lunrDir, index, "docs.json")); |
26 | if(response.status !== 200){ |
27 | throw new Error(`Astro-lunr: docs.json not found for index=${index}`); |
28 | } |
29 | let docsJson = await response.text(); |
30 | docMap.set(index, JSON.parse(docsJson).reduce((map, doc) => map.set(doc.id, doc), new Map())); |
31 | } |
32 | return docMap.get(index); |
33 | } |
34 | |
35 | async function search(query, index) { |
36 | if(!query) { |
37 | return []; |
38 | } |
39 | let idx = await getIndex(index); |
40 | return idx.search(query); |
41 | } |
42 | |
43 | async function enrich(hits, index){ |
44 | const docs = await getDocs(index) |
45 | return hits.map(hit => { |
46 | return { |
47 | doc: docs.get(hit.ref), |
48 | hit |
49 | } |
50 | }) |
51 | } |
52 | |
53 | return { |
54 | getIndex, |
55 | getDocs, |
56 | search, |
57 | enrich, |
58 | } |
59 | } |