UNPKG

@bsv/wallet-toolbox-client

Version:
192 lines 6.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ServiceCollection = void 0; const MAX_RESET_COUNTS = 32; const MAX_CALL_HISTORY = 32; class ServiceCollection { constructor(serviceName, services) { this.serviceName = serviceName; this._historyByProvider = {}; this.services = services || []; this._index = 0; this.since = new Date(); } add(s) { this.services.push(s); return this; } remove(name) { this.services = this.services.filter(s => s.name !== name); } get name() { return this.services[this._index].name; } get service() { return this.services[this._index].service; } getServiceToCall(i) { const name = this.services[i].name; const service = this.services[i].service; const call = { name, when: new Date(), msecs: 0, success: false, result: undefined, error: undefined }; return { serviceName: this.serviceName, providerName: name, service, call }; } get serviceToCall() { return this.getServiceToCall(this._index); } get allServicesToCall() { const all = []; for (let i = 0; i < this.services.length; i++) { all.push(this.getServiceToCall(i)); } return all; } /** * Used to de-prioritize a service call by moving it to the end of the list. * @param stc */ moveServiceToLast(stc) { const index = this.services.findIndex(s => s.name === stc.providerName); if (index !== -1) { const [service] = this.services.splice(index, 1); this.services.push(service); } } get allServices() { return this.services.map(x => x.service); } get count() { return this.services.length; } get index() { return this._index; } reset() { this._index = 0; } next() { this._index = (this._index + 1) % this.count; return this._index; } clone() { return new ServiceCollection(this.serviceName, [...this.services]); } _addServiceCall(providerName, call) { const now = new Date(); let h = this._historyByProvider[providerName]; if (!h) { h = { serviceName: this.serviceName, providerName: providerName, calls: [], totalCounts: { success: 0, failure: 0, error: 0, since: this.since, until: now }, resetCounts: [{ success: 0, failure: 0, error: 0, since: this.since, until: now }] }; this._historyByProvider[providerName] = h; } h.calls.unshift(call); h.calls = h.calls.slice(0, MAX_CALL_HISTORY); h.totalCounts.until = now; h.resetCounts[0].until = now; return h; } getDuration(since) { const now = new Date(); if (typeof since === 'string') since = new Date(since); return now.getTime() - since.getTime(); } addServiceCallSuccess(stc, result) { const call = stc.call; call.success = true; call.result = result; call.error = undefined; call.msecs = this.getDuration(call.when); const h = this._addServiceCall(stc.providerName, call); h.totalCounts.success++; h.resetCounts[0].success++; } addServiceCallFailure(stc, result) { const call = stc.call; call.success = false; call.result = result; call.error = undefined; call.msecs = this.getDuration(call.when); const h = this._addServiceCall(this.name, call); h.totalCounts.failure++; h.resetCounts[0].failure++; } addServiceCallError(stc, error) { const call = stc.call; call.success = false; call.result = undefined; call.error = error; call.msecs = this.getDuration(call.when); const h = this._addServiceCall(this.name, call); h.totalCounts.failure++; h.totalCounts.error++; h.resetCounts[0].failure++; h.resetCounts[0].error++; } /** * @returns A copy of current service call history */ getServiceCallHistory(reset) { const now = new Date(); const history = { serviceName: this.serviceName, historyByProvider: {} }; for (const name of Object.keys(this._historyByProvider)) { const h = this._historyByProvider[name]; const c = { serviceName: h.serviceName, providerName: h.providerName, calls: h.calls.map(c => ({ when: dateToString(c.when), msecs: c.msecs, success: c.success, result: c.result, error: c.error ? { message: c.error.message, code: c.error.code } : undefined })), totalCounts: { success: h.totalCounts.success, failure: h.totalCounts.failure, error: h.totalCounts.error, since: dateToString(h.totalCounts.since), until: dateToString(h.totalCounts.until) }, resetCounts: [] }; for (let i = 0; i < h.resetCounts.length; i++) { const r = h.resetCounts[i]; c.resetCounts.push({ success: r.success, failure: r.failure, error: r.error, since: dateToString(r.since), until: dateToString(r.until) }); } history.historyByProvider[name] = c; if (reset) { // Make sure intervals are continuous. h.resetCounts[0].until = now; // insert a new resetCounts interval h.resetCounts.unshift({ success: 0, failure: 0, error: 0, // start of new interval since: now, // end of new interval, gets bumped with each new call added until: now }); // limit history to most recent intervals h.resetCounts = h.resetCounts.slice(0, MAX_CALL_HISTORY); } } return history; function dateToString(d) { return typeof d === 'string' ? d : d.toISOString(); } } } exports.ServiceCollection = ServiceCollection; //# sourceMappingURL=ServiceCollection.js.map