Skip to content

Commit

Permalink
Release. Bump version number
Browse files Browse the repository at this point in the history
  • Loading branch information
bryaningl3 committed Oct 14, 2024
1 parent ae93a33 commit 0061a26
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 36 deletions.
2 changes: 1 addition & 1 deletion docs/_coverpage.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Barchart Market Data SDK <small>JavaScript 6.2.6</small>
# Barchart Market Data SDK <small>JavaScript 6.3.0</small>

> Inject real-time market data into your JavaScript applications
Expand Down
177 changes: 144 additions & 33 deletions example/browser/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ module.exports = (() => {

},{"./../../../lib/connection/Connection":2,"./../../../lib/marketState/Profile":20,"./../../../lib/meta":22,"./../../../lib/utilities/data/AssetClass":27,"./../../../lib/utilities/data/timezones":29,"./../../../lib/utilities/format/decimal":31,"./../../../lib/utilities/format/price":34,"./../../../lib/utilities/format/quote":35,"./../../../lib/utilities/format/specialized/cmdtyView":36}],2:[function(require,module,exports){
const array = require('@barchart/common-js/lang/array'),
assert = require('@barchart/common-js/lang/assert'),
object = require('@barchart/common-js/lang/object');
const ConnectionBase = require('./ConnectionBase'),
parseMessage = require('./../utilities/parse/ddf/message');
Expand All @@ -468,6 +469,10 @@ module.exports = (() => {
'use strict';

const _API_VERSION = 4;
const mode = {
credentials: 'credentials',
token: 'token'
};
const state = {
connecting: 'CONNECTING',
authenticating: 'LOGGING_IN',
Expand Down Expand Up @@ -499,6 +504,8 @@ module.exports = (() => {
};
const _RECONNECT_INTERVAL = 5000;
const _WATCHDOG_INTERVAL = 10000;
const regex = {};
regex.hostname = /^(?:(wss|ws):\/\/)?(.+?)(?::(\d+))?$/i;
function ConnectionInternal(marketState, instance) {
const __logger = LoggerFactory.getLogger('@barchart/marketdata-api-js');
const __instance = instance;
Expand All @@ -508,6 +515,7 @@ module.exports = (() => {
let __xmlParser = null;
let __connection = null;
let __connectionState = state.disconnected;
let __connectionCount = 0;
let __paused = false;
let __reconnectAllowed = false;
let __pollingFrequency = null;
Expand All @@ -532,9 +540,12 @@ module.exports = (() => {
timestamp: []
};
const __loginInfo = {
mode: null,
hostname: null,
username: null,
password: null
password: null,
jwtProvider: null,
jwtPromise: null
};
let __decoder = null;
let __diagnosticsController = null;
Expand Down Expand Up @@ -585,16 +596,17 @@ module.exports = (() => {
*
* @private
* @param {String} hostname
* @param {String} username
* @param {String} password
* @param {String=} username
* @param {String=} password
* @param {WebSocketAdapterFactory} webSocketAdapterFactory
* @param {XmlParserFactory} xmlParserFactory
* @param {Callbacks.JwtProvider} jwtProvider
*/
function initializeConnection(hostname, username, password, webSocketAdapterFactory, xmlParserFactory) {
function initializeConnection(hostname, username, password, webSocketAdapterFactory, xmlParserFactory, jwtProvider) {
__connectionFactory = webSocketAdapterFactory;
__xmlParserFactory = xmlParserFactory;
__reconnectAllowed = true;
connect(hostname, username, password);
connect(hostname, username, password, jwtProvider);
}

/**
Expand All @@ -608,9 +620,12 @@ module.exports = (() => {
event: 'disconnecting'
});
__reconnectAllowed = false;
__loginInfo.mode = null;
__loginInfo.hostname = null;
__loginInfo.username = null;
__loginInfo.password = null;
__loginInfo.hostname = null;
__loginInfo.jwtProvider = null;
__loginInfo.jwtPromise = null;
__knownConsumerSymbols = {};
__pendingProfileSymbols = {};
__listeners.marketDepth = {};
Expand All @@ -622,45 +637,104 @@ module.exports = (() => {
disconnect();
}

/**
* Attempts to read a JWT from an external provider.
*
* @private
* @param {Callbacks.JwtProvider} jwtProvider
* @returns {Promise<string|null>}
*/
function getJwt(jwtProvider) {
const connectionCount = __connectionCount;
return Promise.resolve().then(() => {
__logger.log(`Connection [ ${__instance} ]: Requesting JWT for connection attempt [ ${connectionCount} ].`);
return jwtProvider();
}).then(jwt => {
__logger.log(`Connection [ ${__instance} ]: Request for JWT was successful for connection attempt [ ${connectionCount} ].`);
if (__connectionCount !== connectionCount) {
return null;
}
if (typeof jwt !== 'string') {
__logger.warn(`Connection [ ${__instance} ]: Unable to extract JWT.`);
return null;
}
return jwt;
}).catch(e => {
__logger.warn(`Connection [ ${__instance} ]: Request for JWT failed for connection attempt [ ${connectionCount} ].`);
return null;
});
}

/**
* Attempts to establish a connection to JERQ.
*
* @private
* @param {String} hostname
* @param {String} username
* @param {String} password
*/
function connect(hostname, username, password) {
if (!hostname) {
throw new Error('Unable to connect, the "hostname" argument is required.');
}
if (!username) {
* @param {String=} username
* @param {String=} password
* @param {Callbacks.JwtProvider=} jwtProvider
*/
function connect(hostname, username, password, jwtProvider) {
assert.argumentIsRequired(hostname, 'hostname', String);
assert.argumentIsOptional(username, 'username', String);
assert.argumentIsOptional(password, 'password', String);
assert.argumentIsOptional(jwtProvider, 'jwtProvider', Function);
if (!username && !jwtProvider) {
throw new Error('Unable to connect, the "username" argument is required.');
}
if (!password) {
if (!password && !jwtProvider) {
throw new Error('Unable to connect, the "password" argument is required.');
}
if (__connection !== null) {
__logger.warn(`Connection [ ${__instance} ]: Unable to connect, a connection already exists.`);
return;
}
ensureExchangeMetadata();
__logger.log(`Connection [ ${__instance} ]: Initializing. Version [ ${version} ]. Using [ ${username}@${hostname} ].`);
__xmlParser = __xmlParserFactory.build();
__connectionCount = __connectionCount + 1;
__logger.log(`Connection [ ${__instance} ]: Starting connection attempt [ ${__connectionCount} ] using [ ${jwtProvider ? 'JWT' : 'credentials-based'} ] authentication.`);
let protocol;
let host;
let port;
if (hostname === 'localhost') {
protocol = 'ws';
host = 'localhost';
port = 8080;
} else {
protocol = 'wss';
port = 443;
const match = hostname.match(regex.hostname);
if (match !== null && match[1]) {
protocol = match[1];
} else {
protocol = 'wss';
}
if (match !== null && match[2]) {
host = match[2];
} else {
host = hostname;
}
if (match !== null && match[3]) {
port = parseInt(match[3]);
} else {
port = protocol === 'ws' ? 80 : 443;
}
}
__loginInfo.username = username;
__loginInfo.password = password;
__loginInfo.hostname = hostname;
__loginInfo.username = null;
__loginInfo.password = null;
__loginInfo.jwtProvider = null;
__loginInfo.jwtPromise = null;
if (jwtProvider) {
__loginInfo.mode = mode.token;
__loginInfo.jwtProvider = jwtProvider;
__loginInfo.jwtPromise = getJwt(jwtProvider);
} else {
__loginInfo.mode = mode.credentials;
__loginInfo.username = username;
__loginInfo.password = password;
}
__xmlParser = __xmlParserFactory.build();
__connectionState = state.disconnected;
__connection = __connectionFactory.build(`${protocol}://${__loginInfo.hostname}:${port}/jerq`);
__logger.log(`Connection [ ${__instance} ]: Opening connection to [ ${protocol}://${host}:${port} ].`);
__connection = __connectionFactory.build(`${protocol}://${host}:${port}/jerq`);
__connection.binaryType = 'arraybuffer';
__decoder = __connection.getDecoder();
__connection.onopen = () => {
Expand Down Expand Up @@ -708,7 +782,7 @@ module.exports = (() => {
}
if (__reconnectAllowed) {
__logger.log(`Connection [ ${__instance} ]: Scheduling reconnect attempt.`);
const reconnectAction = () => connect(__loginInfo.hostname, __loginInfo.username, __loginInfo.password);
const reconnectAction = () => connect(__loginInfo.hostname, __loginInfo.username, __loginInfo.password, __loginInfo.jwtProvider);
const reconnectDelay = _RECONNECT_INTERVAL + Math.floor(Math.random() * _WATCHDOG_INTERVAL);
setTimeout(reconnectAction, reconnectDelay);
}
Expand Down Expand Up @@ -1145,8 +1219,31 @@ module.exports = (() => {
}
if (lines.some(line => line === '+++')) {
__connectionState = state.authenticating;
__logger.log(`Connection [ ${__instance} ]: Sending credentials.`);
__connection.send(`LOGIN ${__loginInfo.username}:${__loginInfo.password} VERSION=${_API_VERSION}\r\n`);
let connectionCount = __connectionCount;
if (__loginInfo.mode === mode.credentials) {
__connection.send(`LOGIN ${__loginInfo.username}:${__loginInfo.password} VERSION=${_API_VERSION}\r\n`);
return;
}
if (__loginInfo.mode === mode.token) {
const jwtPromise = __loginInfo.jwtPromise || Promise.resolve(null);
jwtPromise.then(jwt => {
if (__connectionCount !== connectionCount) {
return;
}
if (__connectionState !== state.authenticating) {
return;
}
if (jwt === null) {
broadcastEvent('events', {
event: 'jwt acquisition failed'
});
disconnect();
return;
}
__connection.send(`TOKEN ${jwt} VERSION=${_API_VERSION}\r\n`);
});
return;
}
}
} else if (__connectionState === state.authenticating) {
const lines = message.split('\n');
Expand Down Expand Up @@ -2028,7 +2125,7 @@ module.exports = (() => {
this._internal = ConnectionInternal(this.getMarketState(), this._getInstance());
}
_connect(webSocketAdapterFactory, xmlParserFactory) {
this._internal.connect(this.getHostname(), this.getUsername(), this.getPassword(), webSocketAdapterFactory, xmlParserFactory);
this._internal.connect(this.getHostname(), this.getUsername(), this.getPassword(), webSocketAdapterFactory, xmlParserFactory, this.getJwtProvider());
}
_disconnect() {
this._internal.disconnect();
Expand Down Expand Up @@ -2070,7 +2167,7 @@ module.exports = (() => {
return Connection;
})();

},{"./../logging/LoggerFactory":15,"./../meta":22,"./../utilities/parse/ddf/message":38,"./../utilities/parsers/SymbolParser":41,"./ConnectionBase":3,"./diagnostics/DiagnosticsControllerBase":7,"./snapshots/exchanges/retrieveExchanges":8,"./snapshots/profiles/retrieveExtensions":9,"./snapshots/quotes/retrieveExtensions":10,"./snapshots/quotes/retrieveSnapshots":11,"@barchart/common-js/lang/array":51,"@barchart/common-js/lang/object":54}],3:[function(require,module,exports){
},{"./../logging/LoggerFactory":15,"./../meta":22,"./../utilities/parse/ddf/message":38,"./../utilities/parsers/SymbolParser":41,"./ConnectionBase":3,"./diagnostics/DiagnosticsControllerBase":7,"./snapshots/exchanges/retrieveExchanges":8,"./snapshots/profiles/retrieveExtensions":9,"./snapshots/quotes/retrieveExtensions":10,"./snapshots/quotes/retrieveSnapshots":11,"@barchart/common-js/lang/array":51,"@barchart/common-js/lang/assert":52,"@barchart/common-js/lang/object":54}],3:[function(require,module,exports){
const is = require('@barchart/common-js/lang/is');
const Environment = require('./../environment/Environment'),
EnvironmentForBrowsers = require('./../environment/EnvironmentForBrowsers');
Expand All @@ -2094,6 +2191,7 @@ module.exports = (() => {
this._hostname = null;
this._username = null;
this._password = null;
this._jwtProvider = null;
this._environment = environment || new EnvironmentForBrowsers();
this._marketState = new MarketState(symbol => this._handleProfileRequest(symbol));
this._pollingFrequency = null;
Expand All @@ -2110,15 +2208,17 @@ module.exports = (() => {
*
* @public
* @param {string} hostname - Barchart hostname (contact [email protected])
* @param {string} username - Your username (contact [email protected])
* @param {string} password - Your password (contact [email protected])
* @param {string=} username - Your username (contact [email protected])
* @param {string=} password - Your password (contact [email protected])
* @param {WebSocketAdapterFactory=} webSocketAdapterFactory - Strategy for creating a {@link WebSocketAdapterFactory} instances (overrides {@link Environment} settings).
* @param {XmlParserFactory=} xmlParserFactory - Strategy for creating a {@link WebSocketAdapterFactory} instances (overrides {@link Environment} settings).
* @param {Callbacks.JwtProvider=} jwtProvider - A function which returns a JWT (or a promise for a JWT) that is used as an alternative for actual credentials.
*/
connect(hostname, username, password, webSocketAdapterFactory, xmlParserFactory) {
connect(hostname, username, password, webSocketAdapterFactory, xmlParserFactory, jwtProvider) {
this._hostname = hostname;
this._username = username;
this._password = password;
this._username = username || null;
this._password = password || null;
this._jwtProvider = jwtProvider || null;
this._connect(webSocketAdapterFactory || this._environment.getWebSocketAdapterFactory(), xmlParserFactory || this._environment.getXmlParserFactory());
}

Expand All @@ -2142,6 +2242,7 @@ module.exports = (() => {
this._hostname = null;
this._username = null;
this._password = null;
this._jwtProvider = null;
this._disconnect();
}

Expand Down Expand Up @@ -2428,6 +2529,16 @@ module.exports = (() => {
return this._username;
}

/**
* The username used to authenticate to Barchart.
*
* @public
* @returns {null|Callbacks.JwtProvider}
*/
getJwtProvider() {
return this._jwtProvider;
}

/**
* Gets a unique identifier for the current instance.
*
Expand Down Expand Up @@ -5309,7 +5420,7 @@ module.exports = (() => {
'use strict';

return {
version: '6.2.6'
version: '6.3.0'
};
})();

Expand Down
2 changes: 1 addition & 1 deletion lib/meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ module.exports = (() => {
'use strict';

return {
version: '6.2.6'
version: '6.3.0'
};
})();
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@barchart/marketdata-api-js",
"version": "6.2.6",
"version": "6.3.0",
"description": "SDK for streaming market data from Barchart.com",
"author": {
"name": "Eero Pikat",
Expand Down

0 comments on commit 0061a26

Please sign in to comment.