UNPKG

driftless

Version:

Driftless setInterval and setTimeout replacement for Node and the browser

126 lines (102 loc) 4.4 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_CLEAR_TIMEOUT = exports.DEFAULT_SET_TIMEOUT = exports.DEFAULT_NOW_FN = exports.DEFAULT_AGGRESSION = exports.DEFAULT_THRESHOLD_MS = undefined; exports.setDriftless = setDriftless; exports.clearDriftless = clearDriftless; exports.setDriftlessTimeout = setDriftlessTimeout; exports.setDriftlessInterval = setDriftlessInterval; var _present = require('present'); var _present2 = _interopRequireDefault(_present); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var DEFAULT_THRESHOLD_MS = exports.DEFAULT_THRESHOLD_MS = 1; var DEFAULT_AGGRESSION = exports.DEFAULT_AGGRESSION = 1.1; var DEFAULT_NOW_FN = exports.DEFAULT_NOW_FN = function DEFAULT_NOW_FN() { return _present2.default.apply(undefined, arguments); }; var DEFAULT_SET_TIMEOUT = exports.DEFAULT_SET_TIMEOUT = function DEFAULT_SET_TIMEOUT() { return setTimeout.apply(undefined, arguments); }; var DEFAULT_CLEAR_TIMEOUT = exports.DEFAULT_CLEAR_TIMEOUT = function DEFAULT_CLEAR_TIMEOUT() { return clearTimeout.apply(undefined, arguments); }; var timerHandles = {}; var nextId = 0; function tryDriftless(id, opts) { var _this = this, _arguments = arguments; var atMs = opts.atMs, fn = opts.fn, _opts$thresholdMs = opts.thresholdMs, thresholdMs = _opts$thresholdMs === undefined ? DEFAULT_THRESHOLD_MS : _opts$thresholdMs, _opts$aggression = opts.aggression, aggression = _opts$aggression === undefined ? DEFAULT_AGGRESSION : _opts$aggression, _opts$customNow = opts.customNow, customNow = _opts$customNow === undefined ? DEFAULT_NOW_FN : _opts$customNow, _opts$customSetTimeou = opts.customSetTimeout, customSetTimeout = _opts$customSetTimeou === undefined ? DEFAULT_SET_TIMEOUT : _opts$customSetTimeou; var delayMs = atMs - customNow(); var handle = delayMs > thresholdMs ? customSetTimeout(function () { tryDriftless.apply(_this, _arguments); // eslint-disable-line prefer-rest-params }, delayMs / aggression) : customSetTimeout(function () { // Call the function using setTimeout to ensure asynchrony fn(); }, 0); timerHandles[id] = handle; } function setDriftless() { return setDriftless.setDriftlessSpyable.apply(setDriftless, arguments); } // Separate function for testing setDriftless.setDriftlessSpyable = function (opts) { var id = nextId; nextId += 1; tryDriftless(id, opts); return id; }; function clearDriftless(id) { var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var _opts$customClearTime = opts.customClearTimeout, customClearTimeout = _opts$customClearTime === undefined ? DEFAULT_CLEAR_TIMEOUT : _opts$customClearTime; customClearTimeout(timerHandles[id]); } function castToFn(fn) { return typeof fn === 'function' ? fn : new Function(fn); // eslint-disable-line no-new-func } function setDriftlessTimeout(fn, delayMs) { for (var _len = arguments.length, params = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { params[_key - 2] = arguments[_key]; } var callFn = castToFn(fn); return setDriftless({ atMs: DEFAULT_NOW_FN() + delayMs, fn: function fn() { for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } return callFn.call.apply(callFn, [this].concat(_toConsumableArray(args), params)); } }); } function setDriftlessInterval(fn, delayMs) { for (var _len3 = arguments.length, params = Array(_len3 > 2 ? _len3 - 2 : 0), _key3 = 2; _key3 < _len3; _key3++) { params[_key3 - 2] = arguments[_key3]; } var callFn = castToFn(fn); var id = void 0; var opts = { atMs: DEFAULT_NOW_FN() + delayMs, fn: function fn() { opts.atMs += delayMs; tryDriftless(id, opts); for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { args[_key4] = arguments[_key4]; } return callFn.call.apply(callFn, [this].concat(_toConsumableArray(args), params)); } }; id = setDriftless(opts); return id; }