@turnkey/react-wallet-kit
Version:
The easiest and most powerful way to integrate Turnkey's Embedded Wallets into your React applications.
143 lines (140 loc) • 5.88 kB
JavaScript
import { createForOfIteratorHelper as _createForOfIteratorHelper } from '../_virtual/_rollupPluginBabelHelpers.mjs';
// This file contains utility functions for managing timers and timeouts for session management.
// Unfortunately, the delay param in Node Timeouts is a 32-bit signed integer, meaning it can only represent delays up to ~24.8 days.
// This file provides functions to handle long delays by breaking them into smaller chunks.
// These functions are separate from the normal utils function to reduce clutter and improve visibility.
// Use `setTimeoutInMap` for short, frequent nudges (10s), and `setCappedTimeoutInMap` for anything that could exceed ~24.8 days.
var MAX_DELAY_MS = 2147483647; // ~24.8 days
/** @internal */
function toIntMs(x) {
return Math.max(0, Math.floor(Number.isFinite(x) ? x : 0));
}
/**
* @internal A drop-in replacement for `setTimeout` that supports arbitrarily long delays.
*
* ### Why?
* Browsers clamp `setTimeout` delays to a 32-bit signed integer,
* i.e. a maximum of ~24.8 days (`2_147_483_647ms`). Any larger value
* will fire almost immediately. This helper safely schedules timeouts
* that can be months or years into the future.
*
* ### How it works
* - On call, we record a fixed **target timestamp** (`now + delayMs`).
* - We schedule a single "leg" of at most ~24.8 days into the future,
* with an internal `tick` function as the callback.
* - When a leg expires, `tick` checks how much time is left:
* - If `remaining > 0`, it schedules the next leg (`min(MAX_DELAY_MS, remaining)`).
* - If `remaining <= 0`, the full delay has passed and we finally call your `cb()`.
* - At any time, only **one** leg is active. Calling `.clear()` cancels
* the current leg and prevents further hops.
*
* ### Benefits
* - Works seamlessly for both short and very long delays.
* - Survives tab sleep / system suspend: when the tab wakes,
* `tick` re-checks the target timestamp and fires immediately if overdue.
* - No drift accumulation: each hop recalculates based on the fixed target,
* so you always land as close as possible to the intended deadline.
*
* ### Example
* ```ts
* const controller = setCappedTimeout(() => {
* console.log("A whole year later!");
* }, 1000 * 60 * 60 * 24 * 365);
*
* // Cancel if needed
* controller.clear();
* ```
*
* @param cb - Function to run once the full delay has elapsed.
* @param delayMs - Delay in milliseconds (can exceed 2_147_483_647).
* @returns A controller with a `.clear()` method to cancel the timeout.
*/
function setCappedTimeout(cb, delayMs) {
var target = Date.now() + toIntMs(delayMs);
var handle;
var _tick = function tick() {
var remaining = target - Date.now();
if (remaining <= 0) {
cb();
return;
}
handle = window.setTimeout(_tick, Math.min(MAX_DELAY_MS, remaining));
};
_tick();
return {
clear: function clear() {
if (handle !== undefined) {
window.clearTimeout(handle);
handle = undefined;
}
}
};
}
/** @internal Simple one-shot timeout that still returns a controller for uniformity. */
function setTimeoutController(cb, delayMs) {
var ms = toIntMs(delayMs);
var id = window.setTimeout(cb, ms);
return {
clear: function clear() {
return window.clearTimeout(id);
}
};
}
/** @internal Replace any existing timer for `key` with `controller`. */
function putTimer(map, key, controller) {
var _map$key, _map$key$clear;
(_map$key = map[key]) === null || _map$key === void 0 ? void 0 : (_map$key$clear = _map$key.clear) === null || _map$key$clear === void 0 ? void 0 : _map$key$clear.call(_map$key);
map[key] = controller;
}
/** @internal Clear a specific key (noop if missing). */
function clearKey(map, key) {
var _map$key2, _map$key2$clear;
(_map$key2 = map[key]) === null || _map$key2 === void 0 ? void 0 : (_map$key2$clear = _map$key2.clear) === null || _map$key2$clear === void 0 ? void 0 : _map$key2$clear.call(_map$key2);
delete map[key];
}
/** @internal Clear several keys at once (noop on missing). */
function clearKeys(map, keys) {
var _iterator = _createForOfIteratorHelper(keys),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var k = _step.value;
clearKey(map, k);
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
/** @internal Clear all timers in the map. */
function clearAll(map) {
for (var _i = 0, _Object$keys = Object.keys(map); _i < _Object$keys.length; _i++) {
var _map$k, _map$k$clear;
var k = _Object$keys[_i];
(_map$k = map[k]) === null || _map$k === void 0 ? void 0 : (_map$k$clear = _map$k.clear) === null || _map$k$clear === void 0 ? void 0 : _map$k$clear.call(_map$k);
delete map[k];
}
}
/**
* @internal Convenience: set a capped timeout directly into the map for `key`.
* @param map The map to store the timer in (pass in the ref to the timer map)
* @param key The key to associate with the timer
* @param cb The callback to invoke when the timer expires
* @param delayMs The delay in milliseconds before the timer expires
* */
function setCappedTimeoutInMap(map, key, cb, delayMs) {
putTimer(map, key, setCappedTimeout(cb, delayMs));
}
/**
* @internal Convenience: set a regular (short) timeout into the map for `key`.
* @param map The map to store the timer in (pass in the ref to the timer map)
* @param key The key to associate with the timer
* @param cb The callback to invoke when the timer expires
* @param delayMs The delay in milliseconds before the timer expires
*/
function setTimeoutInMap(map, key, cb, delayMs) {
putTimer(map, key, setTimeoutController(cb, delayMs));
}
export { MAX_DELAY_MS, clearAll, clearKey, clearKeys, putTimer, setCappedTimeout, setCappedTimeoutInMap, setTimeoutController, setTimeoutInMap };
//# sourceMappingURL=timers.mjs.map