UNPKG

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
'use strict'; 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;