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
111 lines (94 loc) • 3.71 kB
JavaScript
;
var http = require('node:http');
var https = require('node:https');
var httpsProxyAgent = require('https-proxy-agent');
var fetch = require('node-fetch');
var prepareSDKConfig = require('../deploy/prepareSDKConfig.js');
var _package = require('../package.json.js');
var controller = require('../src/controller.js');
var observable = require('../src/utils/observable.js');
const version = _package.default.version;
const LIB_NAME = 'Atrius Maps JS SDK Client';
function setupFetch(config) {
const httpAgent = new http.Agent({ keepAlive: true });
const httpsAgent = new https.Agent({ keepAlive: true });
// provide easy proxy handling via config.proxy in form of { host, port }
const proxyAgent = config.proxy ? new httpsProxyAgent.HttpsProxyAgent(`http://${config.proxy.host}:${config.proxy.port}`) : null;
// Support a user defined agent - or a proxy agent - else we specify our own, forcing keepAlive to true (which is default in Node >= 19)
const agent = config.agent || proxyAgent || (url => (url.protocol === 'http:' ? httpAgent : httpsAgent));
global.fetch = async (url, options) => fetch(url, { ...options, agent });
}
// logging setup
let sdkLogging = false;
const pad2 = x => (x.toString().length < 2 ? '0' + x : x);
const ts = () => {
const d = new Date();
return `${d.getHours()}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}.${d.getMilliseconds()}`;
};
const logPre = () => `AtriusMaps Node SDK (${ts()}): `;
const log = function () {
if (sdkLogging) {
let msg =
logPre() +
Array.from(arguments)
.map(arg => (typeof arg === 'object' ? JSON.stringify(arg) : arg))
.join(' ');
const lines = msg.split('\n');
if (lines.length > 1) msg = lines[0] + `… (+ ${lines.length - 1} lines)`;
else if (msg.length > 256) msg = msg.substring(0, 255) + `… (length: ${msg.length} chars)`;
console.log(msg);
}
};
// this iterates through available commands and makes them member functions of map
function addCommands(map, commands) {
commands.forEach(sig => {
map[sig.command] = function () {
const cob = { command: sig.command };
for (let i = 0; i < arguments.length; i++) cob[sig.args[i].name] = arguments[i];
return map(cob);
};
});
}
async function newMap(sdkConfig) {
return new Promise((resolve, reject) => {
sdkConfig.headless = true;
setupFetch(sdkConfig); // This installs the fetch function globally (overriding native if exists)
const config = prepareSDKConfig(sdkConfig);
controller.create(config).then(app => {
const map = (payload, arg2) => {
if (typeof payload === 'string') payload = { ...arg2, command: payload };
log('Sending command object: ', payload);
return app.bus
.get('clientAPI/execute', payload)
.then(result => {
log('Received Message: ', result);
return result;
})
.catch(e => {
log('Error: ', e.message); // doesn't seem to ever get called?? WTF?
throw e;
});
};
// map._app = app
observable(map); // make map handle events pub/sub
app.eventListener.observe(function () {
map.fire.apply(map, arguments);
}); // pass it on...
map.on('ready', (eName, data) => {
const { commands /*, customTypes */ } = data.commandJSON;
addCommands(map, commands);
resolve(map);
log('map ready');
});
});
});
}
const Init = {
getVersion: () => version,
newMap: config => newMap(config),
setLogging: flag => {
sdkLogging = flag;
if (flag) log(`${LIB_NAME} v${version} Logging enabled.`);
},
};
module.exports = Init;