UNPKG

@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
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