UNPKG

mobx-utils

Version:

Utility functions and common patterns for MobX

85 lines (84 loc) 2.84 kB
import { _isComputingDerivation } from "mobx"; import { fromResource } from "./from-resource"; var tickers = {}; /** * Disposes of all the internal Observables created by invocations of `now()`. * * The use case for this is to ensure that unit tests can run independent of each other. * You should not call this in regular application code. * * @example * afterEach(() => { * utils.resetNowInternalState() * }) */ export function resetNowInternalState() { for (var _i = 0, _a = Object.getOwnPropertyNames(tickers); _i < _a.length; _i++) { var key = _a[_i]; tickers[key].dispose(); delete tickers[key]; } } /** * Returns the current date time as epoch number. * The date time is read from an observable which is updated automatically after the given interval. * So basically it treats time as an observable. * * The function takes an interval as parameter, which indicates how often `now()` will return a new value. * If no interval is given, it will update each second. If "frame" is specified, it will update each time a * `requestAnimationFrame` is available. * * Multiple clocks with the same interval will automatically be synchronized. * * Countdown example: https://jsfiddle.net/mweststrate/na0qdmkw/ * * @example * * const start = Date.now() * * autorun(() => { * console.log("Seconds elapsed: ", (mobxUtils.now() - start) / 1000) * }) * * * @export * @param {(number | "frame")} [interval=1000] interval in milliseconds about how often the interval should update * @returns */ export function now(interval) { if (interval === void 0) { interval = 1000; } if (!_isComputingDerivation()) { // See #40 return Date.now(); } if (!tickers[interval]) { if (typeof interval === "number") tickers[interval] = createIntervalTicker(interval); else tickers[interval] = createAnimationFrameTicker(); } return tickers[interval].current(); } function createIntervalTicker(interval) { var subscriptionHandle; return fromResource(function (sink) { sink(Date.now()); subscriptionHandle = setInterval(function () { return sink(Date.now()); }, interval); }, function () { clearInterval(subscriptionHandle); }, Date.now()); } function createAnimationFrameTicker() { var frameBasedTicker = fromResource(function (sink) { sink(Date.now()); function scheduleTick() { window.requestAnimationFrame(function () { sink(Date.now()); if (frameBasedTicker.isAlive()) scheduleTick(); }); } scheduleTick(); }, function () { }, Date.now()); return frameBasedTicker; }