raiden-ts
Version:
Raiden Light Client Typescript/Javascript SDK
100 lines • 4.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.withdrawMetaFromRequest = exports.matchWithdraw = exports.retrySendUntil$ = exports.dispatchAndWait$ = exports.exponentialBackoff = void 0;
const rxjs_1 = require("rxjs");
const operators_1 = require("rxjs/operators");
const actions_1 = require("../../messages/actions");
const actions_2 = require("../../utils/actions");
const rx_1 = require("../../utils/rx");
const state_1 = require("../state");
/**
* Exponential back-off infinite generator
*
* @param start - First yielded value
* @param max - Ceiling of values, won't increase above this number
* @param multiplier - Multiply yielded value by this factor on each iteration
* @yields Numbers representing delays in exponential backoff strategy of growth
*/
function* exponentialBackoff(start = 1e3, max = 60e3, multiplier = 1.4) {
let delay = start;
while (true) {
yield delay;
delay = Math.min(max, Math.ceil(delay * multiplier));
}
}
exports.exponentialBackoff = exponentialBackoff;
/**
* Dispatches an actions and waits until a condition is satisfied.
*
* @param action$ - Observable of actions that will be monitored
* @param request - The request/action that will be dispatched
* @param predicate - The condition that will that was to be satisfied for the observable to
* complete
* @returns Observable of the request type.
*/
function dispatchAndWait$(action$, request, predicate) {
return (0, rxjs_1.merge)(
// wait until respective success/failure action is seen before completing
action$.pipe((0, operators_1.filter)(predicate), (0, operators_1.take)(1),
// don't output success/failure action, just wait for first match to complete
(0, operators_1.ignoreElements)()),
// output once
(0, rxjs_1.of)(request));
}
exports.dispatchAndWait$ = dispatchAndWait$;
/**
* Retry sending a message until some condition is met
*
* @param send - messageSend.request to be sent
* @param action$ - RaidenActions observable
* @param notifier - Stops retrying when this notifier emits
* @param delayMs - Delay between retries, or Iterator yielding delays
* @returns Observable which retry messageSend.request until notifier emits
*/
function retrySendUntil$(send, action$, notifier, delayMs = 30e3) {
let first = true;
return (0, rxjs_1.defer)(() => {
if (first) {
first = false;
}
else if (send.payload.userId) {
// from 1st retry on, pop payload.userId, to force re-fetch presence/metadata
const { userId: _, ...payload } = send.payload;
send = { ...send, payload };
}
return dispatchAndWait$(action$, send, (0, actions_2.isResponseOf)(actions_1.messageSend, send.meta));
}).pipe((0, rx_1.repeatUntil)(notifier, delayMs), (0, rx_1.completeWith)(action$));
}
exports.retrySendUntil$ = retrySendUntil$;
/**
* Creates a type-guard function which verifies 'msg' is of given type between withdraw messages
* and that total_withdraw and expiration matches given 'data'.
* May be used to find matching messages in [[ChannelEnd]]'s 'pendingWithdraws' array
*
* @param type - Literal type tag to filter
* @param data - Optional data to match, either in 'meta' or another 'message' format
* @returns Typeguard function to check for matching withdraw protocol messages
*/
function matchWithdraw(type, data) {
return (msg) => msg.type === type &&
(!data ||
(msg.expiration.eq(data.expiration) &&
msg.total_withdraw.eq('totalWithdraw' in data ? data.totalWithdraw : data.total_withdraw)));
}
exports.matchWithdraw = matchWithdraw;
/**
* @param req - WithdrawRequest message
* @param channel - Channel in which it was received
* @returns withdraw async action meta for respective request
*/
function withdrawMetaFromRequest(req, channel) {
return {
tokenNetwork: channel.tokenNetwork,
partner: channel.partner.address,
direction: req.participant === channel.partner.address ? state_1.Direction.RECEIVED : state_1.Direction.SENT,
expiration: req.expiration.toNumber(),
totalWithdraw: req.total_withdraw,
};
}
exports.withdrawMetaFromRequest = withdrawMetaFromRequest;
//# sourceMappingURL=utils.js.map