@sangaman/xud
Version:
Exchange Union Daemon
110 lines • 4.74 kB
JavaScript
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("events");
const packets_1 = require("./packets");
const packetTypes = __importStar(require("./packets/types"));
class ParserError {
constructor(type, payload) {
this.type = type;
this.payload = payload;
}
}
exports.ParserError = ParserError;
var ParserErrorType;
(function (ParserErrorType) {
ParserErrorType[ParserErrorType["INVALID_MESSAGE"] = 0] = "INVALID_MESSAGE";
ParserErrorType[ParserErrorType["UNKNOWN_PACKET_TYPE"] = 1] = "UNKNOWN_PACKET_TYPE";
ParserErrorType[ParserErrorType["UNPARSEABLE_MESSAGE"] = 2] = "UNPARSEABLE_MESSAGE";
ParserErrorType[ParserErrorType["MAX_BUFFER_SIZE_EXCEEDED"] = 3] = "MAX_BUFFER_SIZE_EXCEEDED";
})(ParserErrorType || (ParserErrorType = {}));
exports.ParserErrorType = ParserErrorType;
const fromRaw = (raw) => {
let json;
try {
json = JSON.parse(raw);
}
catch (err) {
throw new ParserError(ParserErrorType.UNPARSEABLE_MESSAGE, `${raw}: ${err}`);
}
// check that we have the required fields for an incoming packet
if (typeof json.header === 'object' && typeof json.header.type === 'string' && typeof json.header.id === 'string') {
const packet = json;
switch (packet.header.type) {
case packets_1.PacketType.HELLO:
return new packetTypes.HelloPacket(packet);
case packets_1.PacketType.PING:
return new packetTypes.PingPacket(packet);
case packets_1.PacketType.PONG:
return new packetTypes.PongPacket(packet);
case packets_1.PacketType.ORDER:
return new packetTypes.OrderPacket(packet);
case packets_1.PacketType.ORDER_INVALIDATION:
return new packetTypes.OrderInvalidationPacket(packet);
case packets_1.PacketType.GET_ORDERS:
return new packetTypes.GetOrdersPacket(packet);
case packets_1.PacketType.ORDERS:
return new packetTypes.OrdersPacket(packet);
case packets_1.PacketType.GET_NODES:
return new packetTypes.GetNodesPacket(packet);
case packets_1.PacketType.NODES:
return new packetTypes.NodesPacket(packet);
case packets_1.PacketType.DEAL_REQUEST:
return new packetTypes.DealRequest(packet);
case packets_1.PacketType.DEAL_RESPONSE:
return new packetTypes.DealResponse(packet);
case packets_1.PacketType.SWAP_REQUEST:
return new packetTypes.SwapRequest(packet);
case packets_1.PacketType.SWAP_RESPONSE:
return new packetTypes.SwapResponse(packet);
default:
throw new ParserError(ParserErrorType.UNKNOWN_PACKET_TYPE, packet.header.type);
}
}
else {
throw new ParserError(ParserErrorType.INVALID_MESSAGE, `${raw}`);
}
};
/** Protocol packet parser */
class Parser extends events_1.EventEmitter {
constructor(delimiter, maxBufferSize = Parser.MAX_BUFFER_SIZE) {
super();
this.delimiter = delimiter;
this.maxBufferSize = maxBufferSize;
this.buffer = '';
this.feed = (data) => {
const total = Buffer.byteLength(this.buffer) + Buffer.byteLength(data);
if (total > this.maxBufferSize) {
this.buffer = '';
this.emit('error', new ParserError(ParserErrorType.MAX_BUFFER_SIZE_EXCEEDED, total.toString()));
return;
}
this.buffer += data;
const index = this.buffer.indexOf(this.delimiter);
if (index > -1) {
this.parsePacket(this.buffer.slice(0, index));
const next = this.buffer.slice(index + this.delimiter.length);
this.buffer = '';
this.feed(next);
}
};
this.parsePacket = (packetStr) => {
try {
const packet = fromRaw(packetStr);
this.emit('packet', packet);
}
catch (err) {
this.emit('error', err);
}
};
}
}
Parser.MAX_BUFFER_SIZE = (4 * 1024 * 1024); // in bytes
exports.default = Parser;
//# sourceMappingURL=Parser.js.map