UNPKG

tardis-machine

Version:

Locally runnable server with built-in data caching, providing both tick-level historical and consolidated real-time cryptocurrency market data via HTTP and WebSocket APIs

76 lines 3.43 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.replayHttp = void 0; const events_1 = require("events"); const tardis_dev_1 = require("tardis-dev"); const url_1 = __importDefault(require("url")); const debug_1 = require("../debug"); const replayHttp = async (req, res) => { try { const startTimestamp = new Date().getTime(); const parsedQuery = url_1.default.parse(req.url, true).query; const optionsString = parsedQuery['options']; const replayOptions = JSON.parse(optionsString); (0, debug_1.debug)('GET /replay request started, options: %o', replayOptions); const streamedMessagesCount = await writeMessagesToResponse(res, replayOptions); const endTimestamp = new Date().getTime(); (0, debug_1.debug)('GET /replay request finished, options: %o, time: %d seconds, total messages count:%d', replayOptions, (endTimestamp - startTimestamp) / 1000, streamedMessagesCount); } catch (e) { const errorInfo = { responseText: e.responseText, message: e.message, url: e.url }; (0, debug_1.debug)('GET /replay request error: %o', e); console.error('GET /replay request error:', e); if (!res.finished) { res.statusCode = e.status || 500; res.end(JSON.stringify(errorInfo)); } } }; exports.replayHttp = replayHttp; async function writeMessagesToResponse(res, replayOptions) { const responsePrefixBuffer = Buffer.from('{"localTimestamp":"'); const responseMiddleBuffer = Buffer.from('","message":'); const responseSuffixBuffer = Buffer.from('}\n'); const newLineBuffer = Buffer.from('\n'); const BATCH_SIZE = 32; // not 100% sure that's necessary since we're returning ndjson in fact, not json res.setHeader('Content-Type', 'application/x-json-stream'); let buffers = []; let totalMessagesCount = 0; const messages = (0, tardis_dev_1.replay)({ ...replayOptions, skipDecoding: true }); for await (let messageWithTimestamp of messages) { totalMessagesCount++; if (messageWithTimestamp === undefined) { // if received message is undefined (disconnect) // return it as new line buffers.push(newLineBuffer); } else { // instead of writing each message directly to response, // let's batch them and send in BATCH_SIZE batches (each message is 5 buffers: prefix etc) // also instead of converting messages to string or parsing them let's manually stich together desired json response using buffers which is faster buffers.push(responsePrefixBuffer, messageWithTimestamp.localTimestamp, responseMiddleBuffer, messageWithTimestamp.message, responseSuffixBuffer); if (buffers.length >= BATCH_SIZE * 5) { const ok = res.write(Buffer.concat(buffers)); buffers = []; if (!ok) { await (0, events_1.once)(res, 'drain'); } } } } if (buffers.length > 0) { res.write(Buffer.concat(buffers)); buffers = []; } res.end(''); return totalMessagesCount; } //# sourceMappingURL=replay.js.map