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
JavaScript
;
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;