arweave-synchronizer
Version:
A cool tool to process and sync all transactions from a custom GQL query in order to gather metrics for from a specific data protocol.
80 lines (79 loc) • 3.62 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = __importDefault(require("events"));
const ar_gql_1 = require("ar-gql");
const interfaces_1 = require("./interfaces");
const utils_1 = require("./utils");
class Sync extends events_1.default {
constructor(txTags, nTxsPerQuery = 100, delay = 5000) {
super();
this.status = interfaces_1.Status.stopped;
this.txCounter = 0;
this.updateTxPosition = (txs) => {
this.latestTx = txs[txs.length - 1];
this.txCounter += txs.length;
this.emit('response', { txs, txCounter: this.txCounter });
};
this.synchronizeTransactions = () => __awaiter(this, void 0, void 0, function* () {
const query = `{
transactions(
${this.latestTx ? `after: "${this.latestTx.cursor}"` : ''}
first: ${this.nTxsPerQuery}
tags: ${JSON.stringify(this.txTags).replace(/"([^"]+)":/g, '$1:')}
sort: HEIGHT_ASC
) ${utils_1.gqlTransactionConnection}
}`;
this.emit('request');
const txs = (yield (0, ar_gql_1.run)(query)).data.transactions.edges;
this.updateTxPosition(txs);
if (txs.length < this.nTxsPerQuery)
this.emit('synchronized');
else
yield this.synchronizeTransactions();
});
this.getLatestTransactions = () => __awaiter(this, void 0, void 0, function* () {
const query = `{
transactions(
first: 100
tags: ${JSON.stringify(this.txTags).replace(/"([^"]+)":/g, '$1:')}
sort: HEIGHT_DESC
) ${utils_1.gqlTransactionConnection}
}`;
this.emit('request');
const result = (yield (0, ar_gql_1.run)(query)).data.transactions.edges;
const latestTxIndex = result.findIndex(e => { var _a; return e.node.id === ((_a = this.latestTx) === null || _a === void 0 ? void 0 : _a.node.id); });
const txs = result.slice(0, latestTxIndex);
if (txs.length > 0)
this.updateTxPosition(txs);
setTimeout(this.getLatestTransactions, this.delay);
});
this.getStatus = () => this.status;
this.start = () => __awaiter(this, void 0, void 0, function* () {
this.status = interfaces_1.Status.syncing;
this.emit('start');
try {
yield this.synchronizeTransactions();
this.status = interfaces_1.Status.synced;
yield this.getLatestTransactions();
}
catch (e) {
this.emit('exception', e);
}
});
this.txTags = txTags;
this.nTxsPerQuery = nTxsPerQuery;
this.delay = delay;
}
}
exports.default = Sync;