New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@barchart/marketdata-api-js

Package Overview
Dependencies
Maintainers
1
Versions
170
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@barchart/marketdata-api-js - npm Package Compare versions

Comparing version 3.1.19 to 3.1.20

2

bower.json
{
"name": "barchart-marketdata-api",
"version": "3.1.18",
"version": "3.1.20",
"homepage": "https://github.com/barchart/marketdata-api-js",

@@ -5,0 +5,0 @@ "description": "Barchart Market Data API for JavaScript",

const version = require('./../../../lib/index').version;
const Connection = require('./../../../lib/connection/websocket/browser/Connection'),
const Connection = require('./../../../lib/connection/websocket/Connection'),
symbolResolver = require('./../../../lib/util/symbolResolver');

@@ -5,0 +5,0 @@

@@ -105,29 +105,2 @@ var gulp = require('gulp');

gulp.task('execute-browser-tests', function () {
return gulp.src('test/dist/barchart-marketdata-api-tests-' + getVersionForComponent() + '.js')
.pipe(jasmine());
});
gulp.task('execute-node-tests', function () {
return gulp.src(['lib/index.js', 'test/specs/**/*.js'])
.pipe(jasmine());
});
gulp.task('execute-tests', function (callback) {
runSequence(
'build-browser-tests',
'execute-node-tests',
'execute-browser-tests',
function (error) {
if (error) {
console.log(error.message);
}
callback(error);
});
});
gulp.task('test', [ 'execute-tests' ]);
gulp.task('release', function (callback) {

@@ -140,3 +113,2 @@ runSequence(

'build-browser-tests',
'execute-node-tests',
'document',

@@ -143,0 +115,0 @@ 'commit-changes',

@@ -1,2 +0,2 @@

const Connection = require('./Connection');
const Connection = require('./websocket/Connection');

@@ -3,0 +3,0 @@ module.exports = (() => {

@@ -1,13 +0,897 @@

const ConnectionBase = require('./../ConnectionBase');
const utilities = require('@barchart/marketdata-utilities-js');
const array = require('./../../common/lang/array'),
object = require('./../../common/lang/object');
const ConnectionBase = require('./../ConnectionBase'),
parseMessage = require('./../../messageParser/parseMessage');
module.exports = (() => {
'use strict';
const _API_VERSION = 4;
let _window = null;
try {
_window = self || null;
} catch (e) {
_window = null;
}
if (_window === null) {
_window = window;
}
const state = {
connecting: 'CONNECTING',
authenticating: 'LOGGING_IN',
authenticated: 'LOGGED_IN',
disconnected: 'DISCONNECTED'
};
const ascii = {
soh: '\x01',
etx: '\x03',
lf: '\x0A',
dc4: '\x14'
};
const _RECONNECT_INTERVAL = 5000;
const _HEARTBEAT_INTERVAL = 10000;
function ConnectionInternal(marketState) {
const __marketState = marketState;
let __state = state.disconnected;
let __suppressReconnect = false;
let __pollingFrequency = null;
let __connection = null;
let __watchdog = null;
let __lastMessageTime = null;
let __activeConsumerSymbols = {};
let __knownConsumerSymbols = {};
let __pendingProfileLookups = {};
const __listeners = {
marketDepth: {},
marketUpdate: {},
cumulativeVolume: {},
events: [],
timestamp: []
};
let __tasks = [];
let __commands = [];
let __feedMessages = [];
let __networkMessages = [];
const __loginInfo = {
username: null,
password: null,
server: null
};
let __decoder;
if (_window.TextDecoder) {
__decoder = new TextDecoder();
} else {
__decoder = {
decode: function (arr) {
return String.fromCharCode.apply(null, new Uint8Array(arr));
}
};
}
function addTask(id, symbol) {
const lastIndex = __tasks.length - 1;
if (lastIndex > 0 && __tasks[lastIndex].id === id) {
__tasks[lastIndex].symbols.push(symbol);
} else {
__tasks.push({ id: id, symbols: [symbol] });
}
}
function broadcastEvent(eventId, message) {
let listeners;
switch (eventId) {
case 'events':
listeners = __listeners.events;
break;
case 'marketDepth':
listeners = __listeners.marketDepth[message.symbol];
break;
case 'marketUpdate':
listeners = __listeners.marketUpdate[message.symbol];
break;
case 'timestamp':
listeners = __listeners.timestamp;
break;
}
if (listeners) {
listeners.forEach(listener => listener(message));
}
}
function enqueueGoTasks() {
getProducerSymbols([__listeners.marketUpdate, __listeners.cumulativeVolume]).forEach((symbol) => {
addTask('MU_GO', symbol);
});
getProducerSymbols([__listeners.marketDepth]).forEach((symbol) => {
addTask('MD_GO', symbol);
});
}
function enqueueStopTasks() {
getProducerSymbols([__listeners.marketUpdate, __listeners.cumulativeVolume]).forEach((symbol) => {
addTask('MU_STOP', symbol);
});
getProducerSymbols([__listeners.marketDepth]).forEach((symbol) => {
addTask('MU_STOP', symbol);
});
}
function clearTasks() {
__tasks = [];
}
function connect(server, username, password) {
if (__connection || __suppressReconnect) {
return;
}
__loginInfo.username = username;
__loginInfo.password = password;
__loginInfo.server = server;
if (_window.WebSocket) {
__state = state.disconnected;
__connection = new WebSocket('wss://' + __loginInfo.server + '/jerq');
__connection.binaryType = "arraybuffer";
if (!__watchdog) {
__watchdog = _window.setInterval(() => {
if (!__lastMessageTime && __connection) {
/* we should have seen a message in 10 seconds */
/* trigger close event to handle reconnect */
/* sending logout if we can to prevent CIP lockouts */
console.log(new Date() + ' bouncing, heartbeat timeout');
try {
if (__connection.readyState === WebSocket.OPEN) {
__connection.send('LOGOUT\r\n');
}
__connection.close();
} catch (e) {
console.warn('failed to send LOGOUT', e);
}
}
__lastMessageTime = null;
}, _HEARTBEAT_INTERVAL);
}
__connection.onclose = (evt) => {
console.warn(new Date() + ' connection closed. pending messages', __networkMessages);
__connection.onclose = null;
__connection.onopen = null;
__connection.onmessage = null;
__connection = null;
__lastMessageTime = null;
// there is a race condition. it's possible that the setTimeout
// that triggers pumpMessages will never fire, never triggering badLogin
// we do not reconnect if jerq explicitly says, - Login Failed.
//
if (__networkMessages.length === 1 && __networkMessages[0].indexOf('-') === 0) {
console.warn('not triggering reconnect: bad credentails');
disconnect();
return;
}
__state = state.disconnected;
broadcastEvent('events', { event: 'disconnect' });
if (__suppressReconnect) {
console.warn('not triggering reconnect: user has logged out.');
return;
}
setTimeout(() => {
connect(__loginInfo.server, __loginInfo.username, __loginInfo.password);
/* let's not DDoS */
clearTasks();
enqueueGoTasks();
}, (_RECONNECT_INTERVAL + Math.floor(Math.random() * _HEARTBEAT_INTERVAL)));
};
__connection.onmessage = (evt) => {
__lastMessageTime = 1;
if (evt.data instanceof ArrayBuffer) {
let msg = __decoder.decode(evt.data);
if (msg) {
__networkMessages.push(msg);
}
} else {
__networkMessages.push(evt.data);
}
};
__connection.onopen = (evt) => {
console.log(new Date() + ' connection open.');
};
} else {
console.warn('Websockets are not supported by this browser.');
}
}
function disconnect() {
console.warn('shutting down.');
__state = state.disconnected;
if (__watchdog !== null) {
_window.clearInterval(__watchdog);
}
if (__connection !== null) {
__connection.send('LOGOUT\r\n');
__connection.close();
}
__watchdog = null;
__lastMessageTime = null;
__tasks = [];
__commands = [];
__feedMessages = [];
}
function handleNetworkMessage(message) {
if (__state === state.disconnected) {
__state = state.connecting;
}
if (__state === state.connecting) {
const lines = message.split('\n');
lines.forEach((line) => {
if (line == '+++') {
__state = state.authenticating;
__commands.splice(0, 0, 'LOGIN ' + __loginInfo.username + ':' + __loginInfo.password + " VERSION=" + _API_VERSION + "\r\n");
}
});
} else if (__state === state.authenticating) {
const firstCharacter = message.charAt(0);
if (firstCharacter === '+') {
__state = state.authenticated;
broadcastEvent('events', { event: 'login success' });
} else if (firstCharacter === '-') {
disconnect();
broadcastEvent('events', { event: 'login fail' });
}
}
if (__state === state.authenticated) {
__feedMessages.push(message);
}
}
function getProducerSymbols(listenerMaps) {
const producerSymbols = listenerMaps.reduce((symbols, listenerMap) => {
return symbols.concat(object.keys(listenerMap));
}, [ ]);
return array.unique(producerSymbols);
}
function getProducerListenerExists(producerSymbol, listenerMaps) {
const consumerSymbols = __knownConsumerSymbols[producerSymbol] || [ ];
return consumerSymbols.some(consumerSymbol => getConsumerListenerExists(consumerSymbol, listenerMaps));
}
function getConsumerListenerExists(consumerSymbol, listenerMaps) {
return listenerMaps.some(listenerMap => listenerMap.hasOwnProperty(consumerSymbol) && listenerMap[consumerSymbol].length !== 0);
}
function addKnownConsumerSymbol(consumerSymbol, producerSymbol) {
if (!__knownConsumerSymbols.hasOwnProperty(producerSymbol)) {
__knownConsumerSymbols[producerSymbol] = [ ];
}
const consumerSymbols = __knownConsumerSymbols[producerSymbol];
if (!consumerSymbols.some(candidate => candidate === consumerSymbol)) {
consumerSymbols.push(consumerSymbol);
}
}
function getActiveConsumerSymbols(producerSymbol) {
const knownConsumerSymbols = __knownConsumerSymbols[producerSymbol] || [ ];
const activeConsumerSymbols = knownConsumerSymbols.filter((knownConsumerSymbol) => {
return getConsumerListenerExists(knownConsumerSymbol, [ __listeners.marketDepth, __listeners.marketUpdate, __listeners.cumulativeVolume ]);
});
return activeConsumerSymbols;
}
function off() {
if (arguments.length < 2) {
throw new Error("Wrong number of arguments. Must pass in an eventId and handler.");
}
const eventId = arguments[0];
const handler = arguments[1];
let symbol;
if (arguments.length > 2) {
symbol = arguments[2];
} else {
symbol = null;
}
const removeHandler = (listeners) => {
const listenersToFilter = listeners || [];
return listenersToFilter.filter((candidate) => {
return candidate !== handler;
});
};
const unsubscribe = (stopTaskName, listenerMap, sharedListenerMaps) => {
const consumerSymbol = symbol;
const producerSymbol = utilities.symbolParser.getProducerSymbol(consumerSymbol);
const listenerMaps = sharedListenerMaps.concat(listenerMap);
let previousProducerListenerExists = getProducerListenerExists(producerSymbol, listenerMaps);
let currentProducerListenerExists;
listenerMap[consumerSymbol] = removeHandler(listenerMap[consumerSymbol] || []);
currentProducerListenerExists = getProducerListenerExists(producerSymbol, listenerMaps);
if (previousProducerListenerExists && !currentProducerListenerExists) {
addTask(stopTaskName, producerSymbol);
}
__activeConsumerSymbols[producerSymbol] = getActiveConsumerSymbols(producerSymbol);
};
switch (eventId) {
case 'events':
__listeners.events = removeHandler(__listeners.events);
break;
case 'marketDepth':
if (arguments.length < 3) {
throw new Error("Invalid arguments. Invoke as follows: off('marketDepth', handler, symbol)");
}
unsubscribe("MD_STOP", __listeners.marketDepth, []);
break;
case 'marketUpdate':
if (arguments.length < 3) {
throw new Error("Invalid arguments. Invoke as follows: off('marketUpdate', handler, symbol)");
}
unsubscribe("MU_STOP", __listeners.marketUpdate, [__listeners.cumulativeVolume]);
break;
case 'cumulativeVolume':
if (arguments.length < 3) {
throw new Error("Invalid arguments. Invoke as follows: off('cumulativeVolume', handler, symbol)");
}
unsubscribe("MU_STOP", __listeners.cumulativeVolume, [__listeners.marketUpdate]);
__marketState.getCumulativeVolume(symbol, (container) => {
container.off('events', handler);
});
break;
case 'timestamp':
__listeners.timestamp = removeHandler(__listeners.timestamp);
break;
}
}
function on() {
if (arguments.length < 2) {
throw new Error("Bad number of arguments. Must pass in an eventId and handler.");
}
const eventId = arguments[0];
const handler = arguments[1];
let symbol;
if (arguments.length > 2) {
symbol = arguments[2];
} else {
symbol = null;
}
const addListener = (listeners) => {
listeners = listeners || [];
const add = !listeners.some((candidate) => {
return candidate === handler;
});
let updatedListeners;
if (add) {
updatedListeners = listeners.slice(0);
updatedListeners.push(handler);
} else {
updatedListeners = listeners;
}
return updatedListeners;
};
const subscribe = (streamingTaskName, snapshotTaskName, listenerMap, sharedListenerMaps) => {
const consumerSymbol = symbol;
const producerSymbol = utilities.symbolParser.getProducerSymbol(consumerSymbol);
addKnownConsumerSymbol(consumerSymbol, producerSymbol);
const producerListenerExists = getProducerListenerExists(producerSymbol, sharedListenerMaps.concat(listenerMap));
listenerMap[consumerSymbol] = addListener(listenerMap[consumerSymbol]);
if (producerListenerExists) {
addTask(snapshotTaskName, producerSymbol);
} else {
addTask(streamingTaskName, producerSymbol);
}
__activeConsumerSymbols[producerSymbol] = getActiveConsumerSymbols(producerSymbol);
};
switch (eventId) {
case 'events':
__listeners.events = addListener(__listeners.events);
break;
case 'marketDepth':
if (arguments.length < 3) {
throw new Error("Invalid arguments. Invoke as follows: on('marketDepth', handler, symbol)");
}
subscribe("MD_GO", "MD_REFRESH", __listeners.marketDepth, []);
if (__marketState.getBook(symbol)) {
handler({ type: 'INIT', symbol: symbol });
}
break;
case 'marketUpdate':
if (arguments.length < 3) {
throw new Error("Invalid arguments. Invoke as follows: on('marketUpdate', handler, symbol)");
}
subscribe("MU_GO", "MU_REFRESH", __listeners.marketUpdate, [__listeners.cumulativeVolume]);
if (__marketState.getQuote(symbol)) {
handler({ type: 'INIT', symbol: symbol });
}
break;
case 'cumulativeVolume':
if (arguments.length < 3) {
throw new Error("Invalid arguments. Invoke as follows: on('cumulativeVolume', handler, symbol)");
}
subscribe("MU_GO", "MU_REFRESH", __listeners.cumulativeVolume, [__listeners.marketUpdate]);
__marketState.getCumulativeVolume(symbol, (container) => {
container.on('events', handler);
});
break;
case 'timestamp':
__listeners.timestamp = addListener(__listeners.timestamp);
break;
}
}
function processMessage(message) {
__marketState.processMessage(message);
switch (message.type) {
case 'BOOK':
broadcastEvent('marketDepth', message);
break;
case 'TIMESTAMP':
broadcastEvent('timestamp', __marketState.getTimestamp());
break;
default:
broadcastEvent('marketUpdate', message);
break;
}
}
function onNewMessage(raw) {
let message;
try {
message = parseMessage(raw);
if (message.type) {
if (message.symbol) {
let consumerSymbols = __activeConsumerSymbols[message.symbol] || [];
if (__pendingProfileLookups.hasOwnProperty(message.symbol)) {
consumerSymbols = array.unique(consumerSymbols.concat(__pendingProfileLookups[message.symbol]));
delete __pendingProfileLookups[message.symbol];
}
consumerSymbols.forEach((consumerSymbol) => {
let messageToProcess;
if (consumerSymbol === message.symbol) {
messageToProcess = message;
} else {
messageToProcess = Object.assign({}, message);
messageToProcess.symbol = consumerSymbol;
}
processMessage(messageToProcess);
});
} else {
processMessage(message);
}
} else {
console.log(raw);
}
} catch (e) {
console.error(e);
console.log(message);
}
}
function processCommands() {
if ((__state === state.authenticating || __state === state.authenticated) && __connection) {
let command = __commands.shift();
// it's possible that on re-connect, the GO commands would be sent before the login
// commands causing logout.
if (__state === state.authenticating && command && command.indexOf('GO') === 0) {
console.log('pushing back GO command until fully authenticated.');
__commands.push(command);
} else {
while (command) {
console.log(command);
__connection.send(command);
command = __commands.shift();
}
}
}
setTimeout(processCommands, 200);
}
function processFeedMessages() {
const suffixLength = 9;
let done = false;
while (!done) {
let s = __feedMessages.shift();
if (!s) {
done = true;
} else {
let skip = false;
let msgType = 1; // Assume DDF message containing \x03
let idx = -1;
let idxETX = s.indexOf(ascii.etx);
let idxNL = s.indexOf(ascii.lf);
if ((idxNL > -1) && ((idxETX < 0) || (idxNL < idxETX))) {
idx = idxNL;
msgType = 2;
}
else if (idxETX > -1) {
idx = idxETX;
}
if (idx > -1) {
let epos = idx + 1;
if (msgType == 1) {
if (s.length < idx + suffixLength + 1) {
if (__feedMessages.length > 0)
__feedMessages[0] = s + __feedMessages[0];
else {
__feedMessages.unshift(s);
done = true;
}
skip = true;
} else if (s.substr(idx + 1, 1) == ascii.dc4) {
epos += suffixLength + 1;
}
}
if (!skip) {
let s2 = s.substring(0, epos);
if (msgType == 2) {
s2 = s2.trim();
} else {
idx = s2.indexOf(ascii.soh);
if (idx > 0) {
s2 = s2.substring(idx);
}
}
if (s2.length > 0) {
onNewMessage(s2);
}
s = s.substring(epos);
if (s.length > 0) {
if (__feedMessages.length > 0) {
__feedMessages[0] = s + __feedMessages[0];
} else {
__feedMessages.unshift(s);
}
}
}
} else {
if (s.length > 0) {
if (__feedMessages.length > 0) {
__feedMessages[0] = s + __feedMessages[0];
} else {
__feedMessages.unshift(s);
done = true;
}
}
}
}
if (__feedMessages.length === 0) {
done = true;
}
}
setTimeout(processFeedMessages, 125);
}
function pumpMessages() {
let message = __networkMessages.shift();
while (message) {
handleNetworkMessage(message);
message = __networkMessages.shift();
}
setTimeout(pumpMessages, 125);
}
function pumpStreamingTasks(forced) {
if (__state === state.authenticated) {
while (__tasks.length > 0) {
const task = __tasks.shift();
if (task.callback) {
task.callback();
} else if (task.id) {
let command = '';
let suffix = '';
switch (task.id) {
case 'MD_GO':
command = 'GO';
suffix = 'Bb';
break;
case 'MU_GO':
command = 'GO';
suffix = 'Ssc';
break;
case 'MD_REFRESH':
command = 'GO';
suffix = 'b';
break;
case 'MU_REFRESH':
command = 'GO';
suffix = 'sc';
break;
case 'P_SNAPSHOT':
command = 'GO';
suffix = 's';
break;
case 'MD_STOP':
command = 'STOP';
suffix = 'Bb';
break;
case 'MU_STOP':
command = 'STOP';
suffix = 'Ssc';
break;
}
const uniqueSymbols = array.unique(task.symbols);
let batchSize;
if (task.id === 'MD_GO' || task.id === 'MD_STOP') {
batchSize = 1;
} else {
batchSize = 250;
}
while (uniqueSymbols.length > 0) {
const batch = uniqueSymbols.splice(0, batchSize);
__commands.push(`${command} ${batch.join(',')}=${suffix}`);
}
}
}
}
if (forced) {
return;
}
resetTaskPump(false);
}
function pumpPollingTasks() {
if (__state === state.authenticated && __commands.length === 0) {
__tasks = [];
const getBatches = (symbols) => {
const partitions = [];
while (symbols.length !== 0) {
partitions.push(symbols.splice(0, 250));
}
return partitions;
};
const quoteBatches = getBatches(getProducerSymbols([__listeners.marketUpdate, __listeners.cumulativeVolume]));
quoteBatches.forEach((batch) => {
__commands.push(`GO ${batch.join(',')}=sc`);
});
const bookBatches = getBatches(getProducerSymbols([__listeners.marketDepth]));
quoteBatches.forEach((batch) => {
__commands.push(`GO ${batch.join(',')}=b`);
});
const profileBatches = getBatches(array.unique(object.keys(__pendingProfileLookups)).filter(s => !quoteBatches.some(q => q === s)));
profileBatches.forEach((batch) => {
__commands.push(`GO ${batch.join(',')}=s`);
});
}
resetTaskPump(true);
}
function setPollingFrequency(pollingFrequency) {
if (__pollingFrequency === pollingFrequency) {
return;
}
__pollingFrequency = pollingFrequency;
}
function getActiveSymbolCount() {
return getProducerSymbols([__listeners.marketDepth, __listeners.marketUpdate, __listeners.cumulativeVolume]).length;
}
function resetTaskPump(polling) {
let pumpDelegate;
let milliseconds;
if (__pollingFrequency) {
if (!polling) {
enqueueStopTasks();
pumpStreamingTasks(true);
}
pumpDelegate = pumpPollingTasks;
milliseconds = __pollingFrequency;
} else {
if (polling) {
enqueueGoTasks();
}
pumpDelegate = pumpStreamingTasks;
milliseconds = 250;
}
setTimeout(pumpDelegate, milliseconds);
}
setTimeout(processCommands, 200);
setTimeout(pumpMessages, 125);
setTimeout(processFeedMessages, 125);
setTimeout(resetTaskPump, 250);
function initializeConnection(server, username, password) {
__suppressReconnect = false;
connect(server, username, password);
}
function terminateConnection() {
__suppressReconnect = true;
__loginInfo.username = null;
__loginInfo.password = null;
__loginInfo.server = null;
disconnect();
}
function handleProfileRequest(consumerSymbol) {
const producerSymbol = utilities.symbolParser.getProducerSymbol(consumerSymbol);
const pendingConsumerSymbols = __pendingProfileLookups[producerSymbol] || [ ];
if (!pendingConsumerSymbols.some(candidate => candidate === consumerSymbol)) {
pendingConsumerSymbols.push(consumerSymbol);
}
if (!pendingConsumerSymbols.some(candidate => candidate === producerSymbol)) {
pendingConsumerSymbols.push(producerSymbol);
}
__pendingProfileLookups[producerSymbol] = pendingConsumerSymbols;
addTask('P_SNAPSHOT', producerSymbol);
}
return {
connect: initializeConnection,
disconnect: terminateConnection,
off: off,
on: on,
getActiveSymbolCount: getActiveSymbolCount,
setPollingFrequency: setPollingFrequency,
handleProfileRequest: handleProfileRequest
};
}
/**
* <p>Entry point for library. This implementation is intended for Node.js environments.</p>
* <p><strong>Implementation is incomplete. Do not attempt to use.</strong></p>
* Entry point for library. This implementation is intended for browser environments and uses built-in Websocket support.
*
* @public
* @extends ConnectionBase
* @variation node.js
* @variation browser
*/

@@ -17,34 +901,36 @@ class Connection extends ConnectionBase {

super();
this._internal = ConnectionInternal(this.getMarketState());
}
_connect() {
throw new Error('The "_connect" has not been implemented.');
this._internal.connect(this.getServer(), this.getUsername(), this.getPassword());
}
_disconnect() {
throw new Error('The "_disconnect" has not been implemented.');
this._internal.disconnect();
}
_on() {
throw new Error('The "_on" has not been implemented.');
this._internal.on.apply(this._internal, arguments);
}
_off() {
throw new Error('The "_off" has not been implemented.');
this._internal.off.apply(this._internal, arguments);
}
_getMarketState() {
throw new Error('The "_getMarketState" has not been implemented.');
}
_getActiveSymbolCount() {
throw new Error('The "_getActiveSymbolCount" has not been implemented.');
return this._internal.getActiveSymbolCount();
}
_onPollingFrequencyChanged(pollingFrequency) {
throw new Error('The "_onPollingFrequencyChanged" has not been implemented.');
return this._internal.setPollingFrequency(pollingFrequency);
}
_handleProfileRequest(symbol) {
this._internal.handleProfileRequest(symbol);
}
toString() {
return '[ConnectionBase]';
return '[Connection]';
}

@@ -51,0 +937,0 @@ }

@@ -20,4 +20,4 @@ const connection = require('./connection/index'),

version: '3.1.19'
version: '3.1.20'
};
})();

@@ -0,1 +1,3 @@

const xhr = require('xhr');
module.exports = (() => {

@@ -5,9 +7,9 @@ 'use strict';

/**
* Promise-based utility function for resolving symbol aliases (e.g. ES*1 is a reference
* to the front month for the ES contract -- not a concrete symbol). This implementation
* is for use Node.js environments.
* Promise-based utility for resolving symbol aliases (e.g. ES*1 is a reference
* to the front month for the ES contract -- not a concrete symbol). This
* implementation is for use in browser environments.
*
* @public
* @param {string} - The symbol to lookup (i.e. the alias).
* @returns {Promise}
* @returns {Promise<string>}
*/

@@ -17,5 +19,38 @@ return function(symbol) {

.then(() => {
throw new Error('Unable to resolve symbol, this environment is not supported.');
if (typeof symbol !== 'string') {
throw new Error('The "symbol" argument must be a string.');
}
if (symbol.length === 0) {
throw new Error('The "symbol" argument must be at least one character.');
}
return new Promise((resolveCallback, rejectCallback) => {
try {
const options = {
url: `https://instruments-prod.aws.barchart.com/instruments/${encodeURIComponent(symbol)}`,
method: 'GET'
};
xhr(options, (error, response, body) => {
if (error) {
rejectCallback(error);
} else if (response.statusCode !== 200) {
rejectCallback(`The server returned an HTTP ${response.statusCode} response code.`);
} else {
const response = JSON.parse(body);
if (!response || !response.instrument || !response.instrument.symbol) {
rejectCallback(`The server was unable to resolve symbol ${symbol}.`);
} else {
resolveCallback(response.instrument.symbol);
}
}
});
} catch (e) {
rejectCallback(e);
}
});
});
};
})();
{
"name": "@barchart/marketdata-api-js",
"version": "3.1.19",
"version": "3.1.20",
"description": "Barchart client library for streaming market data from JERQ servers using JavaScript",

@@ -72,6 +72,2 @@ "author": {

},
"browser": {
"./lib/connection/websocket/Connection.js": "./lib/connection/websocket/browser/Connection.js",
"./lib/util/symbolResolver.js": "./lib/util/browser/symbolResolver.js"
},
"browserify": {

@@ -78,0 +74,0 @@ "transform": [

@@ -14,7 +14,2 @@ # @barchart/marketdata-api-js

## Roadmap
At some point, server environments (i.e. Node.js) will be supported.
## Run The Example

@@ -24,3 +19,3 @@

./examples/example.html
./example/browser/example.html

@@ -27,0 +22,0 @@ Or, the visit the hosted version of the example page:

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc