diff options
Diffstat (limited to 'school/node_modules/w3c-hr-time/lib')
5 files changed, 174 insertions, 0 deletions
diff --git a/school/node_modules/w3c-hr-time/lib/calculate-clock-offset.js b/school/node_modules/w3c-hr-time/lib/calculate-clock-offset.js new file mode 100644 index 0000000..8659d30 --- /dev/null +++ b/school/node_modules/w3c-hr-time/lib/calculate-clock-offset.js @@ -0,0 +1,39 @@ +"use strict"; + +// This files implements the calculation of the offset between the global monotonic clock and UNIX time. This value is +// known as |t1| in the calculation of "time origin timestamp" in the spec. This value needs to be calculated once and +// can be used in all subsequent Performance instances. +// +// However, if the clock is not fast enough, the export is undefined to signify that we should use Date.now() to get the +// time origin timestamp with millisecond accuracy, per spec. + +const { getGlobalMonotonicClockMS } = require("./global-monotonic-clock"); +const clockIsAccurate = require("./clock-is-accurate"); + +// This function assumes the clock is accurate. +function calculateClockOffset() { + const start = Date.now(); + let cur = start; + // Limit the iterations, just in case we're running in an environment where Date.now() has been mocked and is + // constant. + for (let i = 0; i < 1e6 && cur === start; i++) { + cur = Date.now(); + } + + // At this point |cur| "just" became equal to the next millisecond -- the unseen digits after |cur| are approximately + // all 0, and |cur| is the closest to the actual value of the UNIX time. Now, get the current global monotonic clock + // value and do the remaining calculations. + + return cur - getGlobalMonotonicClockMS(); +} + +if (clockIsAccurate) { + // Warm up the function. + calculateClockOffset(); + calculateClockOffset(); + calculateClockOffset(); + + module.exports = calculateClockOffset; +} else { + module.exports = undefined; +} diff --git a/school/node_modules/w3c-hr-time/lib/clock-is-accurate.js b/school/node_modules/w3c-hr-time/lib/clock-is-accurate.js new file mode 100644 index 0000000..920b499 --- /dev/null +++ b/school/node_modules/w3c-hr-time/lib/clock-is-accurate.js @@ -0,0 +1,61 @@ +"use strict"; + +const { hrtime } = require("./utils"); + +// The HR-TIME spec calls for 5-μs accuracy. Check that we have that in both hrtime() and Date.now(). + +function testClockAccuracy() { + // Test hrtime() first. The check is simpler and more stable, and we use hrtime() to measure Date.now()'s performance. + const roundTrip = hrtime(hrtime()); + if (roundTrip[0] > 1 || roundTrip[1] > 5e3 * 2) { + return false; + } + + // Test Date.now() twice: first with a looser bound (10 μs) but with a smaller run time to filter out very bad + // Date.now() performance, and then with a tighter bound (5 μs) to check we have the accuracy we need. + let times; + // eslint-disable-next-line no-unused-vars + let cur; + let start; + let end; + + times = 100; + start = hrtime(); + while (times-- > 0) { + cur = Date.now(); + } + end = hrtime(start); + if ((end[0] * 1e9 + end[1]) > 1000000) { + return false; + } + + times = 10000; + start = hrtime(); + while (times-- > 0) { + cur = Date.now(); + } + end = hrtime(start); + if ((end[0] * 1e9 + end[1]) > 50000000) { + return false; + } + + return true; +} + +// Warm up the function. +testClockAccuracy(); +testClockAccuracy(); +testClockAccuracy(); + +const TIMES = 5; +const THRESHOLD = 0.6 * TIMES; +let accurates = 0; +for (let i = 0; i < TIMES; i++) { + if (testClockAccuracy()) { + accurates++; + } +} + +const isAccurate = accurates >= THRESHOLD; + +module.exports = isAccurate; diff --git a/school/node_modules/w3c-hr-time/lib/global-monotonic-clock.js b/school/node_modules/w3c-hr-time/lib/global-monotonic-clock.js new file mode 100644 index 0000000..4e9aee9 --- /dev/null +++ b/school/node_modules/w3c-hr-time/lib/global-monotonic-clock.js @@ -0,0 +1,10 @@ +"use strict"; + +const { hrtime, toMS } = require("./utils"); + +// Returns the DOMHighResTimeStamp representing the high resolution time value of the global monotonic clock. +function getGlobalMonotonicClockMS() { + return toMS(hrtime()); +} + +module.exports = { getGlobalMonotonicClockMS }; diff --git a/school/node_modules/w3c-hr-time/lib/performance.js b/school/node_modules/w3c-hr-time/lib/performance.js new file mode 100644 index 0000000..4bcfbc3 --- /dev/null +++ b/school/node_modules/w3c-hr-time/lib/performance.js @@ -0,0 +1,53 @@ +"use strict"; + +// Actual implementation of the Performance class. + +const clockIsAccurate = require("./clock-is-accurate"); +const calculateClockOffset = require("./calculate-clock-offset"); +const { hrtime, toMS } = require("./utils"); + +const kTimeOrigin = Symbol("time origin"); +const kTimeOriginTimestamp = Symbol("time origin timestamp"); + +class Performance { + constructor() { + // Time origin. + const timeOrigin = hrtime(); + this[kTimeOrigin] = timeOrigin; + + if (clockIsAccurate) { + // Let |t1| be the DOMHighResTimeStamp representing the high resolution Unix time at which the global monotonic + // clock is zero. This has to be calculated for every Performance object to account for clock drifts. + const t1 = calculateClockOffset(); + + // Let |t2| be the DOMHighResTimeStamp representing the high resolution time value of the global monotonic clock + // at global's time origin. + const t2 = toMS(timeOrigin); + + // Return the sum of |t1| and |t2|. + this[kTimeOriginTimestamp] = t1 + t2; + } else { + // Clock isn't accurate enough. Use millisecond accuracy per spec. + const cur = Date.now(); + this[kTimeOriginTimestamp] = cur; + } + } + + // The timeOrigin getter actually returns the time origin timestamp, not the raw time origin. + get timeOrigin() { + return this[kTimeOriginTimestamp]; + } + + now() { + const diff = toMS(hrtime(this[kTimeOrigin])); + return clockIsAccurate ? diff : Math.round(diff); + } + + toJSON() { + return { + timeOrigin: this.timeOrigin + }; + } +} + +module.exports = { Performance }; diff --git a/school/node_modules/w3c-hr-time/lib/utils.js b/school/node_modules/w3c-hr-time/lib/utils.js new file mode 100644 index 0000000..045981f --- /dev/null +++ b/school/node_modules/w3c-hr-time/lib/utils.js @@ -0,0 +1,11 @@ +"use strict"; + +// Browserify's process implementation doesn't have hrtime, and this package is small so not much of a burden for +// Node.js users. +const hrtime = require("browser-process-hrtime"); + +function toMS([sec, nanosec]) { + return sec * 1e3 + nanosec / 1e6; +} + +module.exports = { hrtime, toMS }; |