@barnabask/astro-minisearch
Version:
Utilities to add a static full text index to an Astro project
68 lines • 2.28 kB
JavaScript
import MiniSearch from "minisearch";
const optionDefaults = {
idField: "url",
fields: ["title", "heading", "text"],
storeFields: ["title", "heading"],
};
/**
* Unravels all possible search inputs and resolve them to a simple array of search documents.
* Also removes documents with duplicate or missing URLs and outputs a warning.
*/
export async function getDocuments(input) {
let documents = [];
if (Array.isArray(input)) {
documents = (await Promise.all(input)).flat(2);
}
else {
// single promise: Promise<SearchDocument[]>
documents = (await input);
}
const docsMap = new Map();
let [missing, duplicate] = [0, 0];
documents.forEach((doc) => {
if (typeof doc.url !== "string") {
missing++;
}
else if (docsMap.has(doc.url)) {
duplicate++;
}
else {
docsMap.set(doc.url, doc);
}
});
if (docsMap.size < documents.length) {
console.warn(`WARNING: ${duplicate} duplicate URLs and ${missing} missing URLs in search index.`);
}
return Array.from(docsMap.values());
}
/**
* Generate the MiniSearch object from a list of prepared search documents.
*
* @param documentsInput search documents or promises from other functions
* @param options search index options
* @returns a populated MiniSearch object
*/
export async function generateIndex(documentsInput, options) {
const docs = await getDocuments(documentsInput);
const opts = { ...optionDefaults, ...options };
const miniSearch = new MiniSearch(opts);
miniSearch.addAll(docs);
return miniSearch;
}
/** Load a MiniSearch object from a string or JSON object. */
export function loadIndex(json, options) {
const opts = { ...optionDefaults, ...options };
if (typeof json === "string") {
return MiniSearch.loadJSON(json, opts);
}
return MiniSearch.loadJS(json, opts);
}
/**
* Helper function to both generate an index and output a static endpoint.
* @see [Astro docs on static endpoints]()
*/
export async function getSearchIndex(documentsInput, options) {
const index = await generateIndex(documentsInput, options);
return { body: JSON.stringify(index) };
}
//# sourceMappingURL=search-index.js.map