atriusmaps-node-sdk 3.3.898 → 3.3.899
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/nodesdk/nodeEntry.js +36 -58
- package/dist/cjs/package.json.js +8 -4
- package/dist/cjs/plugins/clientAPI/src/clientAPI.js +8 -6
- package/dist/cjs/plugins/dynamicPois/src/dynamicPois.js +50 -142
- package/dist/cjs/plugins/dynamicPois/src/processors.js +31 -53
- package/dist/cjs/plugins/flightStatus/src/flightDetailsMapper.js +47 -116
- package/dist/cjs/plugins/flightStatus/src/flightStatus.js +48 -82
- package/dist/cjs/plugins/flightStatus/src/utils.js +4 -14
- package/dist/cjs/plugins/poiDataManager/src/poiDataManager.js +77 -154
- package/dist/cjs/plugins/sdkServer/src/prepareSDKConfig.js +45 -76
- package/dist/cjs/plugins/sdkServer/src/sdkHeadless.js +70 -79
- package/dist/cjs/plugins/sdkServer/src/sdkServer.js +97 -147
- package/dist/cjs/plugins/searchService/src/flexsearchExports/lang.js +16 -190
- package/dist/cjs/plugins/searchService/src/flexsearchExports/simple.js +28 -35
- package/dist/cjs/plugins/searchService/src/poiSearch.js +10 -21
- package/dist/cjs/plugins/searchService/src/searchService.js +45 -147
- package/dist/cjs/plugins/searchService/src/searchTypeahead.js +17 -28
- package/dist/cjs/plugins/searchService/src/utils.js +9 -13
- package/dist/cjs/plugins/venueDataLoader/src/venueDataLoader.js +148 -304
- package/dist/cjs/plugins/venueDataLoader/src/venueLoadingUtils.js +47 -126
- package/dist/cjs/plugins/wayfinder/src/findRoute.js +6 -73
- package/dist/cjs/plugins/wayfinder/src/minPriorityQueue.js +7 -27
- package/dist/cjs/plugins/wayfinder/src/navGraph.js +78 -259
- package/dist/cjs/plugins/wayfinder/src/navGraphDebug.js +26 -57
- package/dist/cjs/plugins/wayfinder/src/segmentBadges.js +25 -25
- package/dist/cjs/plugins/wayfinder/src/segmentBuilder.js +50 -133
- package/dist/cjs/plugins/wayfinder/src/segmentCategories.js +29 -29
- package/dist/cjs/plugins/wayfinder/src/stepBuilder.js +53 -145
- package/dist/cjs/plugins/wayfinder/src/wayfinder.js +105 -349
- package/dist/cjs/src/app.js +53 -91
- package/dist/cjs/src/configs/postproc-mol-url-parms.js +34 -43
- package/dist/cjs/src/configs/postproc-stateTracking.js +1 -19
- package/dist/cjs/src/controller.js +4 -26
- package/dist/cjs/src/debugTools.js +55 -94
- package/dist/cjs/src/env.js +8 -19
- package/dist/cjs/src/extModules/bustle.js +15 -71
- package/dist/cjs/src/extModules/flexapi/src/help.js +7 -22
- package/dist/cjs/src/extModules/flexapi/src/index.js +15 -29
- package/dist/cjs/src/extModules/flexapi/src/validate.js +45 -93
- package/dist/cjs/src/extModules/geohasher.js +13 -31
- package/dist/cjs/src/extModules/log.js +18 -29
- package/dist/cjs/src/historyManager.js +4 -6
- package/dist/cjs/src/utils/bounds.js +2 -4
- package/dist/cjs/src/utils/buildStructureLookup.js +7 -7
- package/dist/cjs/src/utils/configUtils.js +7 -43
- package/dist/cjs/src/utils/date.js +5 -17
- package/dist/cjs/src/utils/distance.js +2 -2
- package/dist/cjs/src/utils/dom.js +9 -24
- package/dist/cjs/src/utils/funcs.js +15 -30
- package/dist/cjs/src/utils/geodesy.js +24 -39
- package/dist/cjs/src/utils/geom.js +32 -148
- package/dist/cjs/src/utils/i18n.js +39 -70
- package/dist/cjs/src/utils/isInitialState.js +7 -13
- package/dist/cjs/src/utils/location.js +10 -29
- package/dist/cjs/src/utils/observable.js +4 -29
- package/dist/cjs/src/utils/rand.js +9 -80
- package/dist/cjs/utils/constants.js +1 -1
- package/dist/package.json.js +1 -1
- package/dist/plugins/sdkServer/src/prepareSDKConfig.js +1 -1
- package/dist/src/utils/buildStructureLookup.js +1 -1
- package/dist/src/utils/date.js +1 -1
- package/package.json +1 -1
|
@@ -10,50 +10,36 @@ var controller = require('../src/controller.js');
|
|
|
10
10
|
var observable = require('../src/utils/observable.js');
|
|
11
11
|
|
|
12
12
|
const version = _package.default.version;
|
|
13
|
-
const LIB_NAME =
|
|
14
|
-
|
|
13
|
+
const LIB_NAME = "Atrius Maps JS SDK Client";
|
|
15
14
|
function setupFetch(config) {
|
|
16
15
|
const httpAgent = new http.Agent({ keepAlive: true });
|
|
17
16
|
const httpsAgent = new https.Agent({ keepAlive: true });
|
|
18
|
-
|
|
19
|
-
// provide easy proxy handling via config.proxy in form of { host, port }
|
|
20
17
|
const proxyAgent = config.proxy ? new httpsProxyAgent.HttpsProxyAgent(`http://${config.proxy.host}:${config.proxy.port}`) : null;
|
|
21
|
-
|
|
22
|
-
// Support a user defined agent - or a proxy agent - else we specify our own, forcing keepAlive to true (which is default in Node >= 19)
|
|
23
|
-
const agent = config.agent || proxyAgent || (url => (url.protocol === 'http:' ? httpAgent : httpsAgent));
|
|
24
|
-
|
|
18
|
+
const agent = config.agent || proxyAgent || ((url) => url.protocol === "http:" ? httpAgent : httpsAgent);
|
|
25
19
|
global.fetch = async (url, options) => fetch(url, { ...options, agent });
|
|
26
20
|
}
|
|
27
|
-
|
|
28
|
-
// logging setup
|
|
29
21
|
let sdkLogging = false;
|
|
30
|
-
const pad2 = x =>
|
|
22
|
+
const pad2 = (x) => x.toString().length < 2 ? "0" + x : x;
|
|
31
23
|
const ts = () => {
|
|
32
|
-
const d = new Date();
|
|
24
|
+
const d = /* @__PURE__ */ new Date();
|
|
33
25
|
return `${d.getHours()}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}.${d.getMilliseconds()}`;
|
|
34
26
|
};
|
|
35
27
|
const logPre = () => `AtriusMaps Node SDK (${ts()}): `;
|
|
36
|
-
const log = function
|
|
28
|
+
const log = function(...logArgs) {
|
|
37
29
|
if (sdkLogging) {
|
|
38
|
-
let msg =
|
|
39
|
-
|
|
40
|
-
Array.from(logArgs)
|
|
41
|
-
.map(arg => (typeof arg === 'object' ? JSON.stringify(arg) : arg))
|
|
42
|
-
.join(' ');
|
|
43
|
-
const lines = msg.split('\n');
|
|
30
|
+
let msg = logPre() + Array.from(logArgs).map((arg) => typeof arg === "object" ? JSON.stringify(arg) : arg).join(" ");
|
|
31
|
+
const lines = msg.split("\n");
|
|
44
32
|
if (lines.length > 1) {
|
|
45
|
-
msg = lines[0] +
|
|
33
|
+
msg = lines[0] + `\u2026 (+ ${lines.length - 1} lines)`;
|
|
46
34
|
} else if (msg.length > 256) {
|
|
47
|
-
msg = msg.substring(0, 255) +
|
|
35
|
+
msg = msg.substring(0, 255) + `\u2026 (length: ${msg.length} chars)`;
|
|
48
36
|
}
|
|
49
37
|
console.log(msg);
|
|
50
38
|
}
|
|
51
39
|
};
|
|
52
|
-
|
|
53
|
-
// this iterates through available commands and makes them member functions of map
|
|
54
40
|
function addCommands(map, commands) {
|
|
55
|
-
commands.forEach(sig => {
|
|
56
|
-
map[sig.command] = function
|
|
41
|
+
commands.forEach((sig) => {
|
|
42
|
+
map[sig.command] = function(...args) {
|
|
57
43
|
const cob = { command: sig.command };
|
|
58
44
|
for (let i = 0; i < args.length; i++) {
|
|
59
45
|
cob[sig.args[i].name] = args[i];
|
|
@@ -62,59 +48,51 @@ function addCommands(map, commands) {
|
|
|
62
48
|
};
|
|
63
49
|
});
|
|
64
50
|
}
|
|
65
|
-
|
|
66
51
|
async function newMap(sdkConfig) {
|
|
67
|
-
return new Promise(resolve => {
|
|
52
|
+
return new Promise((resolve) => {
|
|
68
53
|
sdkConfig.headless = true;
|
|
69
|
-
|
|
70
|
-
setupFetch(sdkConfig); // This installs the fetch function globally (overriding native if exists)
|
|
71
|
-
|
|
54
|
+
setupFetch(sdkConfig);
|
|
72
55
|
const config = prepareSDKConfig(sdkConfig);
|
|
73
|
-
config.plugins.monitoring = null;
|
|
74
|
-
|
|
75
|
-
controller.create(config).then(app => {
|
|
56
|
+
config.plugins.monitoring = null;
|
|
57
|
+
controller.create(config).then((app) => {
|
|
76
58
|
const map = (payload, arg2) => {
|
|
77
|
-
if (typeof payload ===
|
|
59
|
+
if (typeof payload === "string") {
|
|
78
60
|
payload = { ...arg2, command: payload };
|
|
79
61
|
}
|
|
80
|
-
log(
|
|
81
|
-
return app.bus
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
log('Error: ', e.message); // doesn't seem to ever get called?? WTF?
|
|
89
|
-
throw e;
|
|
90
|
-
});
|
|
62
|
+
log("Sending command object: ", payload);
|
|
63
|
+
return app.bus.get("clientAPI/execute", payload).then((result) => {
|
|
64
|
+
log("Received Message: ", result);
|
|
65
|
+
return result;
|
|
66
|
+
}).catch((e) => {
|
|
67
|
+
log("Error: ", e.message);
|
|
68
|
+
throw e;
|
|
69
|
+
});
|
|
91
70
|
};
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
observable(map); // make map handle events pub/sub
|
|
95
|
-
app.eventListener.observe(function (...args) {
|
|
71
|
+
observable(map);
|
|
72
|
+
app.eventListener.observe(function(...args) {
|
|
96
73
|
map.fire(...args);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
74
|
+
});
|
|
75
|
+
map.on("ready", (eName, data) => {
|
|
76
|
+
const {
|
|
77
|
+
commands
|
|
78
|
+
/*, customTypes */
|
|
79
|
+
} = data.commandJSON;
|
|
101
80
|
addCommands(map, commands);
|
|
102
81
|
resolve(map);
|
|
103
|
-
log(
|
|
82
|
+
log("map ready");
|
|
104
83
|
});
|
|
105
84
|
});
|
|
106
85
|
});
|
|
107
86
|
}
|
|
108
|
-
|
|
109
87
|
const Init = {
|
|
110
88
|
getVersion: () => version,
|
|
111
|
-
newMap: config => newMap(config),
|
|
112
|
-
setLogging: flag => {
|
|
89
|
+
newMap: (config) => newMap(config),
|
|
90
|
+
setLogging: (flag) => {
|
|
113
91
|
sdkLogging = flag;
|
|
114
92
|
if (flag) {
|
|
115
93
|
log(`${LIB_NAME} v${version} Logging enabled.`);
|
|
116
94
|
}
|
|
117
|
-
}
|
|
95
|
+
}
|
|
118
96
|
};
|
|
119
97
|
|
|
120
98
|
module.exports = Init;
|
package/dist/cjs/package.json.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var name = "web-engine";
|
|
6
|
-
var version = "3.3.
|
|
6
|
+
var version = "3.3.899";
|
|
7
7
|
var license = "UNLICENSED";
|
|
8
8
|
var type = "module";
|
|
9
9
|
var main = "src/main.ts";
|
|
@@ -17,7 +17,7 @@ var workspaces = [
|
|
|
17
17
|
];
|
|
18
18
|
var scripts = {
|
|
19
19
|
"build-storybook": "storybook build",
|
|
20
|
-
colors: "cat utils/colors1.txt && node
|
|
20
|
+
colors: "cat utils/colors1.txt && node utils/processColors.ts | pbcopy && cat utils/colors2.txt",
|
|
21
21
|
demo: "cd demo/ && yarn start",
|
|
22
22
|
dev: "yarn mol e2e",
|
|
23
23
|
"format:check": "yarn prettier . --check",
|
|
@@ -43,7 +43,8 @@ var scripts = {
|
|
|
43
43
|
"test:comp:ui": "VITE_COMP_UI=1 vitest --project browser --ui --browser.headless=false",
|
|
44
44
|
"test:all": "yarn lint && yarn format:check && yarn test && yarn playwright:ci",
|
|
45
45
|
"test:mod": "playwright test --config=playwright.mod.config.ts",
|
|
46
|
-
typecheck: "tsc -p tsconfig.checkjs.json"
|
|
46
|
+
typecheck: "tsc -p tsconfig.checkjs.json",
|
|
47
|
+
"typecheck:strict": "tsc -p tsconfig.strict.json"
|
|
47
48
|
};
|
|
48
49
|
var browserslist = [
|
|
49
50
|
"defaults"
|
|
@@ -113,6 +114,7 @@ var devDependencies = {
|
|
|
113
114
|
"@azure/identity": "^4.13.0",
|
|
114
115
|
"@azure/playwright": "^1.0.0",
|
|
115
116
|
"@playwright/test": "~1.59.1",
|
|
117
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
116
118
|
"@storybook/addon-essentials": "^8.6.15",
|
|
117
119
|
"@storybook/blocks": "^8.6.15",
|
|
118
120
|
"@storybook/react": "^8.6.15",
|
|
@@ -121,6 +123,7 @@ var devDependencies = {
|
|
|
121
123
|
"@testing-library/jest-dom": "^6.6.3",
|
|
122
124
|
"@testing-library/react": "^16.3.0",
|
|
123
125
|
"@testing-library/user-event": "^14.5.2",
|
|
126
|
+
"@types/luxon": "^3.7.2",
|
|
124
127
|
"@types/react": "^19.0.10",
|
|
125
128
|
"@types/react-dom": "^19.0.4",
|
|
126
129
|
"@typescript-eslint/eslint-plugin": "^8.26.1",
|
|
@@ -144,6 +147,7 @@ var devDependencies = {
|
|
|
144
147
|
"nx-remotecache-azure": "^19.0.0",
|
|
145
148
|
"os-browserify": "^0.3.0",
|
|
146
149
|
prettier: "^3.8.3",
|
|
150
|
+
"rollup-plugin-esbuild": "^6.2.1",
|
|
147
151
|
"start-server-and-test": "^2.0.11",
|
|
148
152
|
storybook: "^8.6.15",
|
|
149
153
|
typescript: "^5.8.2",
|
|
@@ -175,7 +179,7 @@ var pkg = {
|
|
|
175
179
|
"prettier --check"
|
|
176
180
|
],
|
|
177
181
|
"src/i18n/**/*.json": [
|
|
178
|
-
"node
|
|
182
|
+
"node utils/sort-json.ts",
|
|
179
183
|
"prettier --write"
|
|
180
184
|
]
|
|
181
185
|
},
|
|
@@ -4,14 +4,16 @@ var index = require('../../../src/extModules/flexapi/src/index.js');
|
|
|
4
4
|
|
|
5
5
|
function create(app) {
|
|
6
6
|
const api = index();
|
|
7
|
-
app.bus.on(
|
|
8
|
-
|
|
7
|
+
app.bus.on(
|
|
8
|
+
"clientAPI/registerCommand",
|
|
9
|
+
(ob) => api.registerCommand(ob, (cob) => app.bus.get(`clientAPI/${cob.command}`, cob))
|
|
9
10
|
);
|
|
10
|
-
app.bus.on(
|
|
11
|
-
app.bus.on(
|
|
12
|
-
|
|
11
|
+
app.bus.on("clientAPI/registerCustomType", ({ name, spec }) => api.registerCustomType(name, spec));
|
|
12
|
+
app.bus.on("clientAPI/execute", (cob) => api.execute(cob));
|
|
13
13
|
return {
|
|
14
|
-
init: () => {
|
|
14
|
+
init: () => {
|
|
15
|
+
}
|
|
16
|
+
// nothing more to do
|
|
15
17
|
};
|
|
16
18
|
}
|
|
17
19
|
|
|
@@ -3,129 +3,65 @@
|
|
|
3
3
|
var Zousan = require('zousan');
|
|
4
4
|
var processors = require('./processors.js');
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
urlBase : to override the REST url base. i.e. for alpha use 'https://rest-alpha.locuslabs.com/v1'. You can also reference
|
|
12
|
-
a local file, such as './testDynamicPois.json'
|
|
13
|
-
|
|
14
|
-
Values defined by 'parking':
|
|
15
|
-
lotName: Name of the lot for this POI, such as 'East'
|
|
16
|
-
lotStatus: returns either 'Closed' or 'Open'
|
|
17
|
-
timeIsReal: If true, the time here is live and valid, else its a default fallback
|
|
18
|
-
rateDay: Daily Rate expressed in English: '$17 per day'
|
|
19
|
-
rateHour: Hourly Rate expressed in English: '$5 per hour'
|
|
20
|
-
timeToTerminal1: Time in walking or by shuttle to Terminal 1 : 'Shuttle 5-7'
|
|
21
|
-
timeToTerminal2: Time in nwalking or by shuttle to Terminal 2 : 'Walking 5-10'
|
|
22
|
-
lastUpdated: timestamp of last update (as sent by server)
|
|
23
|
-
|
|
24
|
-
Values defined by 'security'
|
|
25
|
-
queueTime: Estimated Time in queue (in minutes) : i.e. 45
|
|
26
|
-
isTemporarilyClosed: If true, this line is closed - else it is open
|
|
27
|
-
timeIsReal: If true, the time here is live and valid, else its a default fallback
|
|
28
|
-
lastUpdated: timestamp of last update (as sent by server)
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
let REFRESH_FREQUENCY = 1000 * 30; // every 30 seconds
|
|
33
|
-
const MARKETPLACE_URL_BASE = 'https://marketplace.locuslabs.com';
|
|
34
|
-
|
|
35
|
-
const MAX_FETCH_FAILS = 3; // 3 strikes and you're out!
|
|
36
|
-
|
|
37
|
-
const ACCOUNT_ID_HEADER = 'x-account-id';
|
|
38
|
-
const isObject = value => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
39
|
-
|
|
6
|
+
let REFRESH_FREQUENCY = 1e3 * 30;
|
|
7
|
+
const MARKETPLACE_URL_BASE = "https://marketplace.locuslabs.com";
|
|
8
|
+
const MAX_FETCH_FAILS = 3;
|
|
9
|
+
const ACCOUNT_ID_HEADER = "x-account-id";
|
|
10
|
+
const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
40
11
|
function create(app, config = {}) {
|
|
41
12
|
const state = {
|
|
42
|
-
dynamicDataNotPending: new Zousan()
|
|
13
|
+
dynamicDataNotPending: new Zousan()
|
|
43
14
|
};
|
|
44
15
|
const T = app.gt();
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Returns security checkpoint POIs that have dynamic security data.
|
|
48
|
-
*
|
|
49
|
-
* @param {{ isOpen?: boolean }} [options] Optional open-state filter. Omit to return all checkpoints,
|
|
50
|
-
* set to true for open checkpoints, or false for temporarily closed checkpoints.
|
|
51
|
-
* @returns {Promise<Array<{id: number, name: string, queueTime?: number, isTemporarilyClosed?: boolean, timeIsReal?: boolean, lastUpdated?: string}>>}
|
|
52
|
-
*/
|
|
53
16
|
const getSecurityWaitTimes = async ({ isOpen } = {}) => {
|
|
54
|
-
const pois = await app.bus.get(
|
|
55
|
-
return Object.values(pois)
|
|
56
|
-
.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
)
|
|
63
|
-
.map(poi => ({
|
|
64
|
-
id: poi.poiId,
|
|
65
|
-
name: poi.name,
|
|
66
|
-
...poi.dynamicData.security,
|
|
67
|
-
}));
|
|
17
|
+
const pois = await app.bus.get("poi/getAll");
|
|
18
|
+
return Object.values(pois).filter(
|
|
19
|
+
(poi) => poi.category === "security.checkpoint" && poi?.dynamicData?.security && isObject(poi?.dynamicData?.security) && (isOpen === void 0 ? true : poi?.dynamicData?.security?.isTemporarilyClosed !== isOpen)
|
|
20
|
+
).map((poi) => ({
|
|
21
|
+
id: poi.poiId,
|
|
22
|
+
name: poi.name,
|
|
23
|
+
...poi.dynamicData.security
|
|
24
|
+
}));
|
|
68
25
|
};
|
|
69
|
-
|
|
70
|
-
// used in testing
|
|
71
26
|
if (config._overrideRefreshFrequency) {
|
|
72
27
|
REFRESH_FREQUENCY = config._overrideRefreshFrequency;
|
|
73
28
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const previousNameOverrides = new Map();
|
|
78
|
-
|
|
79
|
-
// by returning this dynamicDataLoaded promise, we hold sdkReady event until this is resolved
|
|
80
|
-
app.bus.on('system/readywhenyouare', () => state.dynamicDataNotPending);
|
|
81
|
-
app.bus.on('dynamicPois/getSecurityWaitTimes', getSecurityWaitTimes);
|
|
82
|
-
|
|
29
|
+
const previousNameOverrides = /* @__PURE__ */ new Map();
|
|
30
|
+
app.bus.on("system/readywhenyouare", () => state.dynamicDataNotPending);
|
|
31
|
+
app.bus.on("dynamicPois/getSecurityWaitTimes", getSecurityWaitTimes);
|
|
83
32
|
const init = async () => {
|
|
84
33
|
const [accountId, venueId] = await Promise.all([
|
|
85
|
-
app.bus.get(
|
|
86
|
-
app.bus.get(
|
|
34
|
+
app.bus.get("venueData/getAccountId"),
|
|
35
|
+
app.bus.get("venueData/getVenueId")
|
|
87
36
|
]);
|
|
88
|
-
|
|
89
37
|
const dynamicPoisUrl = `${MARKETPLACE_URL_BASE}/venueId/${venueId}/dynamic-poi`;
|
|
90
|
-
|
|
91
38
|
let fetchFailuresCount = 0;
|
|
92
39
|
let fetchSuccessCount = 0;
|
|
93
40
|
let fetchIntervalHandle;
|
|
94
41
|
const updateFromAPI = async () => {
|
|
95
42
|
const response = await fetch(dynamicPoisUrl, {
|
|
96
|
-
headers: { [ACCOUNT_ID_HEADER]: accountId }
|
|
43
|
+
headers: { [ACCOUNT_ID_HEADER]: accountId }
|
|
97
44
|
});
|
|
98
|
-
if (response.ok)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
.then(({ data }) => processDynamicPois(data))
|
|
103
|
-
.then(() => {
|
|
104
|
-
fetchSuccessCount++;
|
|
105
|
-
})
|
|
106
|
-
.catch(console.error);
|
|
45
|
+
if (response.ok) {
|
|
46
|
+
return response.json().then(({ data }) => processDynamicPois(data)).then(() => {
|
|
47
|
+
fetchSuccessCount++;
|
|
48
|
+
}).catch(console.error);
|
|
107
49
|
} else {
|
|
108
|
-
console.warn(
|
|
50
|
+
console.warn("dynamicPois: fetch response status not ok", response);
|
|
109
51
|
fetchFailuresCount++;
|
|
110
|
-
// Don't keep trying after multiple fails unless past success is at least 50%
|
|
111
52
|
if (fetchFailuresCount >= MAX_FETCH_FAILS && fetchFailuresCount > fetchSuccessCount) {
|
|
112
53
|
clearInterval(fetchIntervalHandle);
|
|
113
54
|
}
|
|
114
55
|
}
|
|
115
56
|
};
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
.
|
|
119
|
-
fetchIntervalHandle
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
} // Node only - do not keep-alive Lambda or other short-term environments
|
|
123
|
-
})
|
|
124
|
-
.finally(() => state.dynamicDataNotPending.resolve(true)); // even in case of failure, we don't want to hold up the UI
|
|
125
|
-
|
|
57
|
+
await updateFromAPI().then(() => {
|
|
58
|
+
fetchIntervalHandle = setInterval(updateFromAPI, REFRESH_FREQUENCY);
|
|
59
|
+
if (typeof fetchIntervalHandle.unref === "function") {
|
|
60
|
+
fetchIntervalHandle.unref();
|
|
61
|
+
}
|
|
62
|
+
}).finally(() => state.dynamicDataNotPending.resolve(true));
|
|
126
63
|
return () => clearInterval(fetchIntervalHandle);
|
|
127
64
|
};
|
|
128
|
-
|
|
129
65
|
async function processDynamicPois(pois) {
|
|
130
66
|
processParkingPOIS(pois);
|
|
131
67
|
processOpenClosedPois(pois);
|
|
@@ -133,108 +69,80 @@ function create(app, config = {}) {
|
|
|
133
69
|
processDynamicRouting(pois);
|
|
134
70
|
processDynamicAttributes(pois);
|
|
135
71
|
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Extracts `dynamicData.poiAttributes.name` overrides from each POI in the API response and emits
|
|
139
|
-
* `poi/setCoreAttributes` and `map/mutateFeature` for any changes. A `null` name signals a revert to the original value.
|
|
140
|
-
* Only emits when a value actually changes to avoid unnecessary downstream updates.
|
|
141
|
-
*
|
|
142
|
-
* @param {Object} poiDataMap - The `data` map from the /dynamic-poi API response
|
|
143
|
-
*/
|
|
144
72
|
async function processDynamicAttributes(poiDataMap) {
|
|
145
73
|
const updates = {};
|
|
146
|
-
|
|
147
74
|
for (const [poiId, poiData] of Object.entries(poiDataMap)) {
|
|
148
75
|
const name = poiData?.dynamicData?.poiAttributes?.name ?? null;
|
|
149
|
-
const previous = previousNameOverrides.get(poiId);
|
|
150
|
-
|
|
151
|
-
if (previous === undefined) {
|
|
152
|
-
// First time seeing this POI: only track and emit if there's an actual name override
|
|
76
|
+
const previous = previousNameOverrides.get(poiId);
|
|
77
|
+
if (previous === void 0) {
|
|
153
78
|
if (name !== null) {
|
|
154
79
|
updates[poiId] = { name };
|
|
155
80
|
previousNameOverrides.set(poiId, name);
|
|
156
81
|
}
|
|
157
82
|
} else if (previous !== name) {
|
|
158
|
-
// Value changed (including override → null revert)
|
|
159
83
|
updates[poiId] = { name };
|
|
160
84
|
previousNameOverrides.set(poiId, name);
|
|
161
85
|
}
|
|
162
86
|
}
|
|
163
|
-
|
|
164
|
-
// Emit null for any POIs that were previously overridden but are no longer in the response
|
|
165
87
|
for (const [poiId, prevName] of previousNameOverrides.entries()) {
|
|
166
88
|
if (!(poiId in poiDataMap) && prevName !== null) {
|
|
167
89
|
updates[poiId] = { name: null };
|
|
168
90
|
previousNameOverrides.set(poiId, null);
|
|
169
91
|
}
|
|
170
92
|
}
|
|
171
|
-
|
|
172
93
|
if (Object.keys(updates).length > 0) {
|
|
173
|
-
app.bus.send(
|
|
94
|
+
app.bus.send("poi/setCoreAttributes", updates);
|
|
174
95
|
const originalNames = await getPoiOriginalNames(Object.keys(updates));
|
|
175
|
-
app.bus.send(
|
|
176
|
-
functor: processors.mutatePoiName(T, updates, originalNames)
|
|
96
|
+
app.bus.send("map/mutateFeature", {
|
|
97
|
+
functor: processors.mutatePoiName(T, updates, originalNames)
|
|
177
98
|
});
|
|
178
99
|
}
|
|
179
100
|
}
|
|
180
|
-
|
|
181
101
|
function processParkingPOIS(poiMap) {
|
|
182
102
|
const idValuesMap = processors.processParkingPOIS(poiMap);
|
|
183
|
-
app.bus.send(
|
|
103
|
+
app.bus.send("poi/setDynamicData", { plugin: "parking", idValuesMap });
|
|
184
104
|
}
|
|
185
|
-
|
|
186
|
-
const getPOILabels = async idArray => {
|
|
105
|
+
const getPOILabels = async (idArray) => {
|
|
187
106
|
const nameMap = {};
|
|
188
107
|
for (const poiId of idArray) {
|
|
189
|
-
const poi = await app.bus.get(
|
|
108
|
+
const poi = await app.bus.get("poi/getById", { id: poiId });
|
|
190
109
|
if (poi) {
|
|
191
110
|
nameMap[poiId] = poi.name;
|
|
192
111
|
}
|
|
193
112
|
}
|
|
194
113
|
return nameMap;
|
|
195
114
|
};
|
|
196
|
-
|
|
197
|
-
const getPoiOriginalNames = async idArray => {
|
|
115
|
+
const getPoiOriginalNames = async (idArray) => {
|
|
198
116
|
const nameMap = {};
|
|
199
117
|
for (const poiId of idArray) {
|
|
200
|
-
const poi = await app.bus.get(
|
|
118
|
+
const poi = await app.bus.get("poi/getById", { id: poiId });
|
|
201
119
|
if (poi) {
|
|
202
120
|
nameMap[poiId] = poi._originalName ?? poi.name;
|
|
203
121
|
}
|
|
204
122
|
}
|
|
205
123
|
return nameMap;
|
|
206
124
|
};
|
|
207
|
-
|
|
208
|
-
/*
|
|
209
|
-
API response: https://gitlab.com/locuslabs/core-data-team/json-schemas/-/blob/develop/src/api-marketplace/dynamic-queue-data.json
|
|
210
|
-
*/
|
|
211
125
|
async function processSecurityWaitTimes(poiMap) {
|
|
212
126
|
const idValuesMap = processors.processSecurityWaitTimes(poiMap);
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
app.bus.send('map/mutateFeature', {
|
|
219
|
-
functor: processors.mutateSecurityCheckpointLabel(T, idValuesMap, labels),
|
|
127
|
+
app.bus.send("poi/setDynamicData", { plugin: "security", idValuesMap });
|
|
128
|
+
const labels = await getPOILabels(Object.keys(idValuesMap));
|
|
129
|
+
app.bus.send("map/mutateFeature", {
|
|
130
|
+
functor: processors.mutateSecurityCheckpointLabel(T, idValuesMap, labels)
|
|
220
131
|
});
|
|
221
132
|
}
|
|
222
|
-
|
|
223
133
|
function processOpenClosedPois(poiMap) {
|
|
224
134
|
const idValuesMap = processors.processOpenClosedPois(poiMap);
|
|
225
|
-
app.bus.send(
|
|
226
|
-
plugin:
|
|
227
|
-
idValuesMap
|
|
135
|
+
app.bus.send("poi/setDynamicData", {
|
|
136
|
+
plugin: "open-closed-status",
|
|
137
|
+
idValuesMap
|
|
228
138
|
});
|
|
229
139
|
}
|
|
230
|
-
|
|
231
140
|
async function processDynamicRouting(poiMap) {
|
|
232
141
|
const idValuesMap = await processors.processRoutingPois(poiMap);
|
|
233
|
-
app.bus.send(
|
|
142
|
+
app.bus.send("poi/setDynamicRouting", { plugin: "routing", idValuesMap });
|
|
234
143
|
}
|
|
235
|
-
|
|
236
144
|
return {
|
|
237
|
-
init
|
|
145
|
+
init
|
|
238
146
|
};
|
|
239
147
|
}
|
|
240
148
|
|
|
@@ -21,29 +21,21 @@ function _interopNamespaceDefault(e) {
|
|
|
21
21
|
|
|
22
22
|
var R__namespace = /*#__PURE__*/_interopNamespaceDefault(R);
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
*
|
|
26
|
-
* @param {Record<Number, DynamicQueueTime} queueTimes A map of POI Ids to dynamic queue times
|
|
27
|
-
* @param {Record<Number, String>} labels A map of POI Ids to map labels
|
|
28
|
-
* @param {*} feature A GeoJson feature
|
|
29
|
-
* @returns feature
|
|
30
|
-
*/
|
|
31
|
-
const mutateSecurityCheckpointLabel = (T, queueTimes, labels) => feature => {
|
|
24
|
+
const mutateSecurityCheckpointLabel = (T, queueTimes, labels) => (feature) => {
|
|
32
25
|
const id = feature.properties.id;
|
|
33
26
|
const dynamicData = queueTimes[id];
|
|
34
27
|
const label = labels[id];
|
|
35
28
|
if (dynamicData) {
|
|
36
|
-
// should we only show this message when "timeIsReal" is true?
|
|
37
29
|
const { queueTime, isTemporarilyClosed } = dynamicData;
|
|
38
|
-
const secondaryText = isTemporarilyClosed ? T(
|
|
39
|
-
feature.properties.text = `${label}
|
|
30
|
+
const secondaryText = isTemporarilyClosed ? T("ui:Closed") : T("ui:_xx_ minute wait", { count: queueTime });
|
|
31
|
+
feature.properties.text = `${label}
|
|
32
|
+
${secondaryText}`;
|
|
40
33
|
}
|
|
41
34
|
return feature;
|
|
42
35
|
};
|
|
43
|
-
|
|
44
|
-
const mutatePoiName = (_T, nameOverrides, originalNames) => feature => {
|
|
36
|
+
const mutatePoiName = (_T, nameOverrides, originalNames) => (feature) => {
|
|
45
37
|
const id = feature.properties?.id;
|
|
46
|
-
const override = id !==
|
|
38
|
+
const override = id !== void 0 && nameOverrides?.[String(id)];
|
|
47
39
|
if (!override) {
|
|
48
40
|
return feature;
|
|
49
41
|
}
|
|
@@ -58,71 +50,57 @@ const mutatePoiName = (_T, nameOverrides, originalNames) => feature => {
|
|
|
58
50
|
}
|
|
59
51
|
return feature;
|
|
60
52
|
};
|
|
61
|
-
|
|
62
|
-
const processParkingPOIS = poiMap => {
|
|
53
|
+
const processParkingPOIS = (poiMap) => {
|
|
63
54
|
const idValuesMap = R__namespace.pipe(
|
|
64
|
-
R__namespace.filter(poi => poi.category ===
|
|
65
|
-
R__namespace.map(poi => {
|
|
55
|
+
R__namespace.filter((poi) => poi.category === "parking"),
|
|
56
|
+
R__namespace.map((poi) => {
|
|
66
57
|
const da = poi.dynamicAttributes;
|
|
67
58
|
if (!da) {
|
|
68
59
|
throw Error(`No dynamicAttributes defined for parking POI ${poi.poiId}`);
|
|
69
60
|
}
|
|
70
|
-
const age = (Date.now() - poi.timestamp) /
|
|
71
|
-
const props =
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
rateHour: '$ -',
|
|
78
|
-
timeIsReal: false,
|
|
79
|
-
};
|
|
80
|
-
|
|
61
|
+
const age = (Date.now() - poi.timestamp) / 1e3;
|
|
62
|
+
const props = age < da["parking.timeToLive"] ? R__namespace.pick(["lotStatus", "rateDay", "rateHour", "timeIsReal", "timeToTerminal1", "timeToTerminal2"], poi) : {
|
|
63
|
+
lotStatus: da["parking.default"],
|
|
64
|
+
rateDay: "$ -",
|
|
65
|
+
rateHour: "$ -",
|
|
66
|
+
timeIsReal: false
|
|
67
|
+
};
|
|
81
68
|
return { ...props, lastUpdated: poi.timestamp, lotName: poi.lotName };
|
|
82
|
-
})
|
|
69
|
+
})
|
|
83
70
|
)(poiMap);
|
|
84
71
|
return idValuesMap;
|
|
85
72
|
};
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
const pathToOpenClosedData = ['dynamicData', 'openClosed'];
|
|
73
|
+
const processOpenClosedPois = (poiMap) => {
|
|
74
|
+
const pathToOpenClosedData = ["dynamicData", "openClosed"];
|
|
89
75
|
const openClosedPois = R__namespace.filter(R__namespace.hasPath(pathToOpenClosedData), poiMap);
|
|
90
76
|
const openClosedStatuses = R__namespace.map(R__namespace.path(pathToOpenClosedData), openClosedPois);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const isExpired = R__namespace.pipe(R__namespace.prop('expiration'), R__namespace.lt(Date.now()));
|
|
77
|
+
if (R__namespace.all(R__namespace.both(R__namespace.has("isOpen"), R__namespace.has("expiration")), R__namespace.values(openClosedStatuses))) {
|
|
78
|
+
const isExpired = R__namespace.pipe(R__namespace.prop("expiration"), R__namespace.lt(Date.now()));
|
|
94
79
|
const idValuesMap = R__namespace.filter(isExpired, openClosedStatuses);
|
|
95
|
-
|
|
96
80
|
return idValuesMap;
|
|
97
81
|
} else {
|
|
98
|
-
throw Error(
|
|
82
|
+
throw Error("Open Closed poi status is malformed.");
|
|
99
83
|
}
|
|
100
84
|
};
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
API response: https://gitlab.com/locuslabs/core-data-team/json-schemas/-/blob/develop/src/api-marketplace/dynamic-queue-data.json
|
|
104
|
-
*/
|
|
105
|
-
const processSecurityWaitTimes = poiMap => {
|
|
106
|
-
const queuePath = ['dynamicData', 'queue'];
|
|
85
|
+
const processSecurityWaitTimes = (poiMap) => {
|
|
86
|
+
const queuePath = ["dynamicData", "queue"];
|
|
107
87
|
const queuePois = R__namespace.filter(R__namespace.hasPath(queuePath), poiMap);
|
|
108
88
|
const queues = R__namespace.map(R__namespace.path(queuePath), queuePois);
|
|
109
89
|
return R__namespace.map(
|
|
110
|
-
queue => ({
|
|
90
|
+
(queue) => ({
|
|
111
91
|
isTemporarilyClosed: queue.isTemporarilyClosed,
|
|
112
92
|
queueTime: queue.queueTime,
|
|
113
93
|
timeIsReal: !queue.isQueueTimeDefault && queue.expiration > Date.now(),
|
|
114
|
-
lastUpdated: Date.now()
|
|
94
|
+
lastUpdated: Date.now()
|
|
115
95
|
}),
|
|
116
|
-
queues
|
|
96
|
+
queues
|
|
117
97
|
);
|
|
118
98
|
};
|
|
119
|
-
|
|
120
|
-
const processRoutingPois = poiMap => {
|
|
99
|
+
const processRoutingPois = (poiMap) => {
|
|
121
100
|
const now = Date.now();
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
const expiration = R__namespace.path(['dynamicData', 'dynamic-routing', 'expiration'], poi);
|
|
101
|
+
return R__namespace.filter((poi) => {
|
|
102
|
+
const navGraphHidden = R__namespace.path(["dynamicData", "dynamic-routing", "navGraphHidden"], poi);
|
|
103
|
+
const expiration = R__namespace.path(["dynamicData", "dynamic-routing", "expiration"], poi);
|
|
126
104
|
return navGraphHidden === true && expiration > now;
|
|
127
105
|
}, poiMap);
|
|
128
106
|
};
|