vue-use-query
Version:
vue use query
152 lines (151 loc) • 6.25 kB
JavaScript
import { focusManager } from './focusManager';
import { onlineManager } from './onlineManager';
import { sleep } from './utils';
function defaultRetryDelay(failureCount) {
return Math.min(1000 * Math.pow(2, failureCount), 30000);
}
export function isCancelable(value) {
return typeof (value === null || value === void 0 ? void 0 : value.cancel) === 'function';
}
var CancelledError = /** @class */ (function () {
function CancelledError(options) {
this.revert = options === null || options === void 0 ? void 0 : options.revert;
this.silent = options === null || options === void 0 ? void 0 : options.silent;
}
return CancelledError;
}());
export { CancelledError };
export function isCancelledError(value) {
return value instanceof CancelledError;
}
// CLASS
var Retryer = /** @class */ (function () {
function Retryer(config) {
var _this = this;
var cancelRetry = false;
var cancelFn;
var continueFn;
var promiseResolve;
var promiseReject;
this.cancel = function (cancelOptions) { return cancelFn === null || cancelFn === void 0 ? void 0 : cancelFn(cancelOptions); };
this.cancelRetry = function () {
cancelRetry = true;
};
this.continue = function () { return continueFn === null || continueFn === void 0 ? void 0 : continueFn(); };
this.failureCount = 0;
this.isPaused = false;
this.isResolved = false;
this.isTransportCancelable = false;
this.promise = new Promise(function (outerResolve, outerReject) {
promiseResolve = outerResolve;
promiseReject = outerReject;
});
var resolve = function (value) {
var _a;
if (!_this.isResolved) {
_this.isResolved = true;
(_a = config.onSuccess) === null || _a === void 0 ? void 0 : _a.call(config, value);
continueFn === null || continueFn === void 0 ? void 0 : continueFn();
promiseResolve(value);
}
};
var reject = function (value) {
var _a;
if (!_this.isResolved) {
_this.isResolved = true;
(_a = config.onError) === null || _a === void 0 ? void 0 : _a.call(config, value);
continueFn === null || continueFn === void 0 ? void 0 : continueFn();
promiseReject(value);
}
};
var pause = function () {
return new Promise(function (continueResolve) {
var _a;
continueFn = continueResolve;
_this.isPaused = true;
(_a = config.onPause) === null || _a === void 0 ? void 0 : _a.call(config);
}).then(function () {
var _a;
continueFn = undefined;
_this.isPaused = false;
(_a = config.onContinue) === null || _a === void 0 ? void 0 : _a.call(config);
});
};
// Create loop function
var run = function () {
// Do nothing if already resolved
if (_this.isResolved) {
return;
}
var promiseOrValue;
// Execute query
try {
promiseOrValue = config.fn();
}
catch (error) {
promiseOrValue = Promise.reject(error);
}
// Create callback to cancel this fetch
cancelFn = function (cancelOptions) {
if (!_this.isResolved) {
reject(new CancelledError(cancelOptions));
// Cancel transport if supported
if (isCancelable(promiseOrValue)) {
try {
promiseOrValue.cancel();
}
catch (_a) { }
}
}
};
// Check if the transport layer support cancellation
_this.isTransportCancelable = isCancelable(promiseOrValue);
Promise.resolve(promiseOrValue)
.then(resolve)
.catch(function (error) {
var _a, _b, _c;
// Stop if the fetch is already resolved
if (_this.isResolved) {
return;
}
// Do we need to retry the request?
var retry = (_a = config.retry) !== null && _a !== void 0 ? _a : 3;
var retryDelay = (_b = config.retryDelay) !== null && _b !== void 0 ? _b : defaultRetryDelay;
var delay = typeof retryDelay === 'function'
? retryDelay(_this.failureCount, error)
: retryDelay;
var shouldRetry = retry === true ||
(typeof retry === 'number' && _this.failureCount < retry) ||
(typeof retry === 'function' && retry(_this.failureCount, error));
if (cancelRetry || !shouldRetry) {
// We are done if the query does not need to be retried
reject(error);
return;
}
_this.failureCount++;
// Notify on fail
(_c = config.onFail) === null || _c === void 0 ? void 0 : _c.call(config, _this.failureCount, error);
// Delay
sleep(delay)
// Pause if the document is not visible or when the device is offline
.then(function () {
if (!focusManager.isFocused() || !onlineManager.isOnline()) {
return pause();
}
})
.then(function () {
if (cancelRetry) {
reject(error);
}
else {
run();
}
});
});
};
// Start loop
run();
}
return Retryer;
}());
export { Retryer };