@atomiqlabs/sdk
Version:
atomiq labs SDK for cross-chain swaps between smart chains and bitcoin
138 lines (137 loc) • 4.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParamDecoder = void 0;
const buffer_1 = require("buffer");
function ensureBuffer(input) {
if (input instanceof buffer_1.Buffer)
return input;
return buffer_1.Buffer.from(input);
}
class ParamDecoder {
constructor() {
this.frameData = [];
this.frameDataLength = 0;
this.closed = false;
this.params = {};
}
/**
* Called when a frame is fully ready such that it can be parsed
*
* @param data Frame data
* @private
*/
onFrameRead(data) {
const obj = JSON.parse(data.toString());
for (let key in obj) {
if (this.params[key] == null) {
this.params[key] = {
promise: Promise.resolve(obj[key])
};
}
else {
const resolveFn = this.params[key].resolve;
if (resolveFn != null) {
resolveFn(obj[key]);
delete this.params[key].resolve;
delete this.params[key].reject;
}
}
}
}
/**
* Called when data is read from the underlying source
*
* @param data Data that has been read from the underlying source
* @protected
*/
onData(data) {
let leavesBuffer = data;
while (leavesBuffer != null && leavesBuffer.length > 0) {
if (this.frameHeader == null) {
if (leavesBuffer.length <= 4) {
this.frameHeader = leavesBuffer;
leavesBuffer = null;
}
else {
this.frameHeader = ensureBuffer(leavesBuffer.subarray(0, 4));
leavesBuffer = ensureBuffer(leavesBuffer.subarray(4));
}
}
else if (this.frameHeader.length < 4) {
const requiredLen = 4 - this.frameHeader.length;
if (leavesBuffer.length <= requiredLen) {
this.frameHeader = buffer_1.Buffer.concat([this.frameHeader, leavesBuffer]);
leavesBuffer = null;
}
else {
this.frameHeader = buffer_1.Buffer.concat([this.frameHeader, leavesBuffer.subarray(0, requiredLen)]);
leavesBuffer = ensureBuffer(leavesBuffer.subarray(requiredLen));
}
}
if (leavesBuffer == null)
continue;
if (this.frameHeader == null || this.frameHeader.length < 4)
continue;
const frameLength = this.frameHeader.readUint32LE != null ? this.frameHeader.readUint32LE() : this.frameHeader.readUInt32LE();
const requiredLen = frameLength - this.frameDataLength;
if (leavesBuffer.length <= requiredLen) {
this.frameData.push(leavesBuffer);
this.frameDataLength += leavesBuffer.length;
leavesBuffer = null;
}
else {
this.frameData.push(leavesBuffer.subarray(0, requiredLen));
this.frameDataLength += requiredLen;
leavesBuffer = leavesBuffer.subarray(requiredLen);
}
if (frameLength === this.frameDataLength) {
//Message read success
this.onFrameRead(buffer_1.Buffer.concat(this.frameData));
delete this.frameHeader;
this.frameData = [];
this.frameDataLength = 0;
}
}
}
/**
* Called when the underlying source ends/closes/cancels
* @protected
*/
onEnd() {
for (let key in this.params) {
this.params[key].reject?.(new Error("EOF before field seen!"));
}
this.closed = true;
}
/**
* Called when an error happens with the underlying stream
*
* @param e Error
* @protected
*/
onError(e) {
for (let key in this.params) {
this.params[key].reject?.(e);
}
this.closed = true;
}
getParam(key) {
if (this.params[key] == null) {
if (this.closed)
return Promise.reject(new Error("Stream already closed without param received!"));
let resolve;
let reject;
const promise = new Promise((_resolve, _reject) => {
resolve = _resolve;
reject = _reject;
});
this.params[key] = {
resolve: resolve,
reject: reject,
promise
};
}
return this.params[key].promise;
}
}
exports.ParamDecoder = ParamDecoder;