1 | import { _isComputingDerivation } from "mobx";
|
2 | import { fromResource } from "./from-resource";
|
3 | var tickers = {};
|
4 | /**
|
5 | * Disposes of all the internal Observables created by invocations of `now()`.
|
6 | *
|
7 | * The use case for this is to ensure that unit tests can run independent of each other.
|
8 | * You should not call this in regular application code.
|
9 | *
|
10 | * @example
|
11 | * afterEach(() => {
|
12 | * utils.resetNowInternalState()
|
13 | * })
|
14 | */
|
15 | export function resetNowInternalState() {
|
16 | for (var _i = 0, _a = Object.getOwnPropertyNames(tickers); _i < _a.length; _i++) {
|
17 | var key = _a[_i];
|
18 | tickers[key].dispose();
|
19 | delete tickers[key];
|
20 | }
|
21 | }
|
22 | /**
|
23 | * Returns the current date time as epoch number.
|
24 | * The date time is read from an observable which is updated automatically after the given interval.
|
25 | * So basically it treats time as an observable.
|
26 | *
|
27 | * The function takes an interval as parameter, which indicates how often `now()` will return a new value.
|
28 | * If no interval is given, it will update each second. If "frame" is specified, it will update each time a
|
29 | * `requestAnimationFrame` is available.
|
30 | *
|
31 | * Multiple clocks with the same interval will automatically be synchronized.
|
32 | *
|
33 | * Countdown example: https://jsfiddle.net/mweststrate/na0qdmkw/
|
34 | *
|
35 | * @example
|
36 | *
|
37 | * const start = Date.now()
|
38 | *
|
39 | * autorun(() => {
|
40 | * console.log("Seconds elapsed: ", (mobxUtils.now() - start) / 1000)
|
41 | * })
|
42 | *
|
43 | *
|
44 | * @export
|
45 | * @param {(number | "frame")} [interval=1000] interval in milliseconds about how often the interval should update
|
46 | * @returns
|
47 | */
|
48 | export function now(interval) {
|
49 | if (interval === void 0) { interval = 1000; }
|
50 | if (!_isComputingDerivation()) {
|
51 | // See #40
|
52 | return Date.now();
|
53 | }
|
54 | if (!tickers[interval]) {
|
55 | if (typeof interval === "number")
|
56 | tickers[interval] = createIntervalTicker(interval);
|
57 | else
|
58 | tickers[interval] = createAnimationFrameTicker();
|
59 | }
|
60 | return tickers[interval].current();
|
61 | }
|
62 | function createIntervalTicker(interval) {
|
63 | var subscriptionHandle;
|
64 | return fromResource(function (sink) {
|
65 | sink(Date.now());
|
66 | subscriptionHandle = setInterval(function () { return sink(Date.now()); }, interval);
|
67 | }, function () {
|
68 | clearInterval(subscriptionHandle);
|
69 | }, Date.now());
|
70 | }
|
71 | function createAnimationFrameTicker() {
|
72 | var frameBasedTicker = fromResource(function (sink) {
|
73 | sink(Date.now());
|
74 | function scheduleTick() {
|
75 | window.requestAnimationFrame(function () {
|
76 | sink(Date.now());
|
77 | if (frameBasedTicker.isAlive())
|
78 | scheduleTick();
|
79 | });
|
80 | }
|
81 | scheduleTick();
|
82 | }, function () { }, Date.now());
|
83 | return frameBasedTicker;
|
84 | }
|