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

161 lines (155 loc) 5.9 kB
'use strict'; var R = require('ramda'); var Zousan = require('zousan'); var configUtils = require('../../../src/utils/configUtils.js'); var rand = require('../../../src/utils/rand.js'); var poiSearch = require('./poiSearch.js'); var searchTypeahead = require('./searchTypeahead.js'); function _interopNamespaceDefault(e) { var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var R__namespace = /*#__PURE__*/_interopNamespaceDefault(R); function create(app, config) { const state = { poiSearch: null, typeahead: null, indexesCreated: new Zousan(), // re-initialize this when changing venues defaultSearchTerms: null, specialQueryTerms: {} }; const init = async () => { const pois = await app.bus.get("poi/getAll"); state.poiSearch = poiSearch(pois, app.i18n().language); state.typeahead = searchTypeahead(pois, state.poiSearch.search, app.i18n().language); state.defaultSearchTerms = configUtils.getLocalized(config, "defaultSearchTerms", app.i18n().language); state.indexesCreated.resolve(); }; app.bus.on("search/queryNearby", async () => { const pois = await searchNearby(); app.bus.send("search/showNearby", { pois, term: "Nearby" }); return pois; }); app.bus.on("search/queryNearbyAsync", searchNearby); async function searchNearby() { const startLocation = await app.bus.getFirst("user/getPhysicalLocation"); if (!startLocation?.floorId) { return []; } const poisSameFloor = await app.bus.get("poi/getByFloorId", { floorId: startLocation?.floorId }); const isNotPortal = (poi) => poi.category.indexOf("portal") === -1 && poi.category !== "element.door"; const noPortalPois = Object.values(R__namespace.pickBy(isNotPortal, poisSameFloor)); const poisWithDistance = await app.bus.get("wayfinder/addPathTimeMultiple", { pois: noPortalPois, startLocation }); return R__namespace.sortBy(R__namespace.prop("distance"), Object.values(poisWithDistance)).slice(0, 50); } app.bus.on("search/queryCategory", async ({ category, categoryName, searchTerm }) => { const pois = await state.indexesCreated.then(() => state.poiSearch.search({ query: searchTerm || category })); app.bus.send("search/showCategory", { pois, category, categoryName }); return pois; }); app.bus.on("search/query", ({ term }) => { return state.indexesCreated.then(() => { const pois = state.poiSearch.search({ query: term }); app.bus.send("search/showSearchResults", { results: pois, term }); return pois; }); }); app.bus.on( "search/queryAsync", ({ term }) => state.indexesCreated.then(() => state.poiSearch.search({ query: term })) ); app.bus.on("search/queryWithSpecial", ({ term }) => { if (state.specialQueryTerms[term]) { const { event, params } = state.specialQueryTerms[term]; return app.bus.send(event, params); } else { return app.bus.get("search/query", { term }); } }); app.bus.on("search/getDefaultSearchTerms", async ({ limit = 5 } = {}) => { const defaultSearchTerms = state.defaultSearchTerms; const hasDefaultSearchTerms = defaultSearchTerms && defaultSearchTerms.length; const keywords = hasDefaultSearchTerms ? defaultSearchTerms : await getUniqueRandomCategories(limit); app.bus.send("search/showDefaultSearchKeywords", { keywords }); return keywords; }); async function getUniqueRandomCategories(limit) { const allCategories = (await app.bus.send("poi/getAllCategories"))[0]; const uniqueCategories = Array.from(new Set(allCategories)); const shuffledUniqueCategories = rand.randomizeArray(uniqueCategories); return shuffledUniqueCategories.slice(0, limit); } app.bus.on("search/getDefaultSearchPois", async ({ limit = 5 } = {}) => { const allPois = await app.bus.get("poi/getAll"); const navigablePred = (val) => val.isNavigable; const navigablePois = R__namespace.pickBy(navigablePred, allPois); return rand.arrayPick(Object.values(navigablePois), limit); }); app.bus.on("search/registerSpecialQuery", ({ term, event, params, addKeyword = true }) => { state.indexesCreated.then(() => { if (addKeyword) { state.typeahead.addKeyword(term); } state.specialQueryTerms[term] = { event, params }; }); }); app.bus.on( "search/addKeywords", ({ keywords }) => state.indexesCreated.then(() => keywords.forEach((keyword) => state.typeahead.addKeyword(keyword))) ); app.bus.on( "search/typeahead", ({ term, limit }) => state.indexesCreated.then(() => { const { keywords, pois } = state.typeahead.query(term, limit); return { keywords, pois, term }; }) ); app.bus.on("venueData/loadNewVenue", () => { state.indexesCreated = new Zousan(); init(); }); app.bus.on("poi/setDynamicData", async ({ plugin, idValuesMap }) => { if (plugin !== "grab") { return; } const dynamicPoisPromises = Object.keys(idValuesMap).map((id) => app.bus.get("poi/getById", { id })); return Promise.all(dynamicPoisPromises).then( (pois) => state.indexesCreated.then(() => state.poiSearch.updateMultiple(pois)) ); }); app.bus.on("poi/updated", async ({ pois }) => { if (!pois || pois.length === 0) { return; } await state.indexesCreated; state.poiSearch.updateMultiple(pois); state.typeahead.updatePOIs(pois); }); const runTest = async (initialState, testRoutine) => { await testRoutine(); return state; }; return { init, runTest }; } exports.create = create;