UNPKG

tardis-dev

Version:

Convenient access to tick-level historical and real-time cryptocurrency market data via Node.js

86 lines 3.97 kB
import { debug } from "./debug.js"; import { getFilters, normalizeMessages } from "./handy.js"; import { createRealTimeFeed } from "./realtimefeeds/index.js"; async function* _stream({ exchange, filters, timeoutIntervalMS = 10000, withDisconnects = undefined, onError = undefined }) { validateStreamOptions(filters); const realTimeFeed = 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 }; } } } export 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 = 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 = 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); } 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`); } } } export 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