tardis-dev
Version:
Convenient access to tick-level historical and real-time cryptocurrency market data via Node.js
90 lines • 4.13 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.stream = stream;
exports.streamNormalized = streamNormalized;
const debug_1 = require("./debug");
const handy_1 = require("./handy");
const realtimefeeds_1 = require("./realtimefeeds");
async function* _stream({ exchange, filters, timeoutIntervalMS = 10000, withDisconnects = undefined, onError = undefined }) {
validateStreamOptions(filters);
const realTimeFeed = (0, realtimefeeds_1.createRealTimeFeed)(exchange, filters, timeoutIntervalMS, onError);
for await (const message of realTimeFeed) {
if (message.__disconnect__ === true) {
// __disconnect__ message means that websocket connection has been closed
// notify about it by yielding undefined if flag is set
if (withDisconnects) {
yield undefined;
}
}
else {
yield {
localTimestamp: new Date(),
message
};
}
}
}
function stream({ exchange, filters, timeoutIntervalMS = 10000, withDisconnects = undefined, onError = undefined }) {
let _iterator = _stream({ exchange, filters, timeoutIntervalMS, withDisconnects, onError });
_iterator.__realtime__ = true;
return _iterator;
}
async function* _streamNormalized({ exchange, symbols, timeoutIntervalMS = 10000, withDisconnectMessages = undefined, onError = undefined }, ...normalizers) {
while (true) {
try {
const createMappers = (localTimestamp) => normalizers.map((m) => m(exchange, localTimestamp));
const mappers = createMappers(new Date());
const filters = (0, handy_1.getFilters)(mappers, symbols);
const messages = _stream({
exchange,
withDisconnects: true,
timeoutIntervalMS,
filters,
onError
});
// filter normalized messages by symbol as some exchanges do not offer subscribing to specific symbols for some of the channels
// for example Phemex market24h channel
const upperCaseSymbols = symbols !== undefined ? symbols.map((s) => s.toUpperCase()) : undefined;
const filter = (symbol) => {
return upperCaseSymbols === undefined || upperCaseSymbols.length === 0 || upperCaseSymbols.includes(symbol);
};
const normalizedMessages = (0, handy_1.normalizeMessages)(exchange, symbols, messages, mappers, createMappers, withDisconnectMessages, filter, new Date());
for await (const message of normalizedMessages) {
yield message;
}
}
catch (error) {
if (onError !== undefined) {
onError(error);
}
(0, debug_1.debug)('%s normalize messages error: %o, retrying with new connection...', exchange, error);
if (withDisconnectMessages) {
// yield it as disconnect as well if flag is set
const disconnect = {
type: 'disconnect',
exchange,
localTimestamp: new Date(),
symbols
};
yield disconnect;
}
}
}
}
function validateStreamOptions(filters) {
if (!filters) {
throw new Error(`Invalid "filters" argument. Please provide filters array`);
}
for (let i = 0; i < filters.length; i++) {
const filter = filters[i];
if (filter.symbols && Array.isArray(filter.symbols) === false) {
throw new Error(`Invalid "filters[].symbols" argument: ${filter.symbols}. Please provide array of symbol strings`);
}
}
}
function streamNormalized({ exchange, symbols, timeoutIntervalMS = 10000, withDisconnectMessages = undefined, onError = undefined }, ...normalizers) {
let _iterator = _streamNormalized({ exchange, symbols, timeoutIntervalMS, withDisconnectMessages, onError }, ...normalizers);
_iterator.__realtime__ = true;
return _iterator;
}
//# sourceMappingURL=stream.js.map