atriusmaps-node-sdk
Version:
This project provides an API to Atrius Personal Wayfinder maps within a Node environment. See the README.md for more information
76 lines (72 loc) • 3.08 kB
JavaScript
;
var R = require('ramda');
var utils = require('./utils.js');
function createSearchTypeahead(pois, poiSearch, lang) {
const suggestedKeywordsSearch = createSuggestedKeywordsSearch(pois, lang);
function queryPois(query2, limit) {
const matches = poiSearch({ query: query2, limit });
const withSuggestions = poiSearch({ query: query2, suggest: true, limit });
const matchedIds = matches.map((poi) => poi.poiId);
const filteredSuggestions = withSuggestions.filter((poi) => matchedIds.indexOf(poi.poiId) === -1);
return matches.concat(filteredSuggestions);
}
const query = (query2, limit) => {
const suggestedKeywords = suggestedKeywordsSearch.search({ query: query2, limit });
const queryLengthUnderLimit = query2.length < 3;
const shouldQueryPois = !queryLengthUnderLimit && suggestedKeywords.length;
const poisLimit = limit - suggestedKeywords.length;
const pois2 = shouldQueryPois ? queryPois(query2, poisLimit) : [];
return { keywords: suggestedKeywords, pois: pois2 };
};
const addKeyword = (keyword) => {
suggestedKeywordsSearch.add(keyword);
};
const updatePOIs = (updatedPois) => {
const allPois = suggestedKeywordsSearch.getAllPois();
const mergedPois = { ...allPois };
for (const poi of updatedPois) {
mergedPois[poi.poiId] = poi;
}
suggestedKeywordsSearch.update(mergedPois);
};
return { query, addKeyword, updatePOIs };
}
function buildKeywordsAndIndex(pois, lang) {
const categories = extractParentCategories(pois);
const poisKeywords = R.pipe(R.values, R.chain(R.prop("keywords")), R.filter(R.prop("isUserSearchable")), R.pluck("name"))(pois);
const poiNames = R.pipe(R.values, R.pluck("name"))(pois);
const poiStaticNames = R.pipe(
R.values,
R.filter((poi) => poi.staticName && poi.staticName !== poi.name),
R.pluck("staticName")
)(pois);
const allPotentialKeywords = [...categories, ...poisKeywords, ...poiNames, ...poiStaticNames];
const keywords = Array.from(/* @__PURE__ */ new Set([...allPotentialKeywords]));
const index = utils.getFlexSearchInstance({ lang});
keywords.forEach((keyword, i) => index.add(i, keyword));
return { keywords, index };
}
function createSuggestedKeywordsSearch(pois, lang) {
let allPois = pois;
let { keywords, index } = buildKeywordsAndIndex(pois, lang);
const search = (queryParams) => {
const ids = index.search(queryParams);
return ids.map((index2) => keywords[index2]);
};
const add = (newKeyword) => {
keywords.push(newKeyword);
index.add(keywords.length - 1, newKeyword);
};
const update = (newPois) => {
allPois = newPois;
const built = buildKeywordsAndIndex(newPois, lang);
keywords = built.keywords;
index = built.index;
};
const getAllPois = () => allPois;
return { search, add, update, getAllPois };
}
function extractParentCategories(pois) {
return Object.values(pois).map((poi) => poi.category).map((fullCategory) => fullCategory.split(".")).map((subcategories) => subcategories[0]);
}
module.exports = createSearchTypeahead;