diff options
Diffstat (limited to 'includes/external/school/node_modules/w3c-hr-time')
10 files changed, 381 insertions, 0 deletions
diff --git a/includes/external/school/node_modules/w3c-hr-time/CHANGELOG.md b/includes/external/school/node_modules/w3c-hr-time/CHANGELOG.md new file mode 100644 index 0000000..0153e7c --- /dev/null +++ b/includes/external/school/node_modules/w3c-hr-time/CHANGELOG.md @@ -0,0 +1,19 @@ +# Change log + +## 1.0.2 (2020-03-05) + +* Do not allow infinite loops when calculating `hrtime()`'s offset relative to UNIX time. ([#9]) +* Add a LICENSE file. ([#3]) +* Add Tidelift sponsorship link to README. + +## 1.0.1 (2018-01-03) + +* Make `performance.toJSON()` return an object with `timeOrigin` property, per [clarifications from specification authors][heycam/webidl#505]. + +## 1.0.0 (2018-01-02) + +* Initial release. + +[heycam/webidl#505]: https://github.com/heycam/webidl/pull/505 +[#3]: https://github.com/jsdom/w3c-hr-time/issues/3 +[#9]: https://github.com/jsdom/w3c-hr-time/issues/9 diff --git a/includes/external/school/node_modules/w3c-hr-time/LICENSE.md b/includes/external/school/node_modules/w3c-hr-time/LICENSE.md new file mode 100644 index 0000000..da9400b --- /dev/null +++ b/includes/external/school/node_modules/w3c-hr-time/LICENSE.md @@ -0,0 +1,21 @@ +# The MIT License (MIT) + +Copyright (c) 2017 Tiancheng "Timothy" Gu and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/includes/external/school/node_modules/w3c-hr-time/README.md b/includes/external/school/node_modules/w3c-hr-time/README.md new file mode 100644 index 0000000..8269230 --- /dev/null +++ b/includes/external/school/node_modules/w3c-hr-time/README.md @@ -0,0 +1,130 @@ +# w3c-hr-time + +This module implements the W3C [High Resolution Time Level 2][HR-TIME] specification. It provides exactly three exports: + +- `Performance` class +- `getGlobalMonotonicClockMS(): number` +- `clockIsAccurate: boolean` + +In all APIs, a "high-resolution timestamp" means a number in milliseconds that may have a fractional part, if the system clock is accurate enough (see "Clock accuracy" section below). It is identical to the [`DOMHighResTimeStamp`][] type in the High Resolution Time spec. + +Portability is paramount to this module. It uses only APIs exposed from Node.js core like `Date.now()` and `process.hrtime()` and does not use or require any native modules. It also employs the [browser-process-hrtime][] module for graceful degrades for platforms that do not have `process.hrtime()` (such as browsers). + +## `Performance` class + +```js +const { Performance } = require("w3c-hr-time"); +const performance = new Performance(); + +console.log(performance.timeOrigin); +// Prints a number close to Date.now() but that may have fractional parts, like +// 1514888563819.351. + +console.log(new Date(performance.timeOrigin)); +// Prints a date close to new Date(), like 2018-01-02T10:22:43.819Z. + +setTimeout(() => { + console.log(performance.now()); + // Prints a number close to 5000, like 5008.023059. +}, 5000); +``` + +Perhaps the most interesting export is the [`Performance`][] class. By constructing the class, you can get an instance quite similar to the `window.performance` object in browsers. Specifically, the following APIs are implemented: + +* [`performance.now(): number`][`Performance#now()`] returns the high-resolution duration since the construction of the `Performance` object. +* [`performance.timeOrigin: number`][`Performance#timeOrigin`] is a high-resolution timestamp of the `Performance` object's construction, expressed in [Unix time][]. +* [`performance.toJSON(): object`][`Performance#toJSON()`] returns an object with `timeOrigin` property set to the corresponding value of this object. This allows serializing the `Performance` object with `JSON.stringify()`. In browsers, the returned object may contain additional properties such as `navigation` and `timing`. However, those properties are specific to browser navigation and are unsuitable for a Node.js implementation. Furthermore, they are specified not in the High Resolution Time spec but in [Navigation Timing][NAVIGATION-TIMING], and are thereby outside the scope of this module. + +### Limitations + +This module does not aim for full [Web IDL][WEBIDL] conformance, so things like `performance.toJSON.call({})` will not throw `TypeError`s like it does in browsers. If you need full Web IDL conformance, you may be interested in the [webidl2js][] module. + +The `Performance` class provided also does not have `mark()`, `measure()`, `getEntries()`, and such functions. They are specified in other specs than High Resolution Timing, such as [User Timing][USER-TIMING] (marks and measures) and [Performance Timeline][PERFORMANCE-TIMELINE] (entries management). Those specs extend the definition of the `Performance` class defined in High Resolution Timing, and to implement those specs you can extend the `Performance` class exported by this module. + +Due to the limitations of the APIs exposed through Node.js, the construction of a `Performance` object may take up to 1 millisecond to gather information for high-resolution `timeOrigin`. + +## Global monotonic clock + +The High Resolution Time spec defines a [global monotonic clock][] that is "shared by time origin's *[sic]*, is monotonically increasing and not subject to system clock adjustments or system clock skew, and whose reference point is the Unix time." + +This module exports a function `getGlobalMonotonicClockMS()` that is the basis of all timing functions used my this module when a monotonic time is required. It returns a high-resolution timestamp whose zero value is at some arbitrary point in the past. (For the current high-resolution timestamp based on the Unix epoch, use `new Performance().timeOrigin` instead.) + +```js +const { getGlobalMonotonicClockMS } = require("w3c-hr-time"); + +const start = getGlobalMonotonicClockMS(); +console.log(start); +// Prints a millisecond timestamp based on an arbitrary point in the past, like +// 280249733.012151. + +setTimeout(() => { + console.log(getGlobalMonotonicClockMS() - a); + // Prints a number close to 5000, like 5006.156536. +}, 5000); +``` + +Unlike other functions that return only integer timestamps if the system clock does not provide enough resolution, this function may still return timestamps with fractional parts on those systems with less accurate clocks. See "Clock accuracy" section below for more information. + +## Clock accuracy + +The High Resolution Time spec [states][HR-TIME §4] that + +> A [`DOMHighResTimeStamp`][] *SHOULD* represent a time in milliseconds accurate to 5 microseconds - see [8. Privacy and Security][HR-TIME §8]. +> +> If the User Agent is unable to provide a time value accurate to 5 microseconds due to hardware or software constraints, the User Agent can represent a [`DOMHighResTimeStamp`][] as a time in milliseconds accurate to a millisecond. + +This module implements this suggestion faithfully. It executes a test at `require()`-time to determine if the system clock (both `Date.now()` and `process.hrtime()`) is accurate enough to 5 microseconds. The result of this test can be accessed through the exported `clockIsAccurate` boolean value. + +```js +const { Performance, clockIsAccurate } = require("w3c-hr-time"); + +const performance = new Performance(); + +if (!clockIsAccurate) { + console.assert(Number.isInteger(performance.timeOrigin)); + console.assert(Number.isInteger(performance.now())); +} +``` + +If `clockIsAccurate` is false, `performance.timeOrigin` and `performance.now()` are always rounded to millisecond accuracy. `getGlobalMonotonicClockMS()` however is exempt from this requirement due to its best-effort nature, and the fact that it is not an API exposed by the High Resolution Time spec. + +## Clock drift + +[Clock drift][clock drift] can be observed through system or user clock adjustments -- that is, the speed at which `Date.now()` changes may be faster or slower than real time if there is a pending adjustment to the system clock, for example through NTP synchronizing. + +In the spec, the [global monotonic clock][] is defined to be immune to such drifts. Correspondingly, the APIs exposed through this module that are defined using the global monotonic clock such as `performance.now()` and `getGlobalMonotonicClockMS()` are also guaranteed to reflect real time. + +For example, if `performance.now()` returns 1000, it is guaranteed that the time of this call is exactly one second since the construction of the `Performance` object. But the difference in `Date.now()`'s value from the construction of the `Performance` object to when `performance.now()` returns 1000 may not be exactly 1000. You may also see `performance.now() - Date.now()` diverge over time as a result of clock drifts. + +On the other hand, `performance.timeOrigin` returns the *[Unix time][]* at which the `Performance` object is constructed and relies on the current time exposed through `Date.now()`. That means that it is susceptible to clock drifts that has occurred before the `Performance` object was constructed. + +## Supporting w3c-hr-time + +The jsdom project (including w3c-hr-time) is a community-driven project maintained by a team of [volunteers](https://github.com/orgs/jsdom/people). You could support us by: + +- [Getting professional support for w3c-hr-time](https://tidelift.com/subscription/pkg/npm-w3c-hr-time?utm_source=npm-w3c-hr-time&utm_medium=referral&utm_campaign=readme) as part of a Tidelift subscription. Tidelift helps making open source sustainable for us while giving teams assurances for maintenance, licensing, and security. +- Contributing directly to the project. + +## License + +This software is licensed under the MIT license. See LICENSE.md file for more detail. + +[HR-TIME]: https://w3c.github.io/hr-time/ +[NAVIGATION-TIMING]: https://w3c.github.io/navigation-timing/ +[PERFORMANCE-TIMELINE]: https://w3c.github.io/performance-timeline/ +[USER-TIMING]: https://w3c.github.io/user-timing/ +[WEBIDL]: https://heycam.github.io/webidl/ + +[HR-TIME §4]: https://w3c.github.io/hr-time/#dom-domhighrestimestamp +[HR-TIME §8]: https://w3c.github.io/hr-time/#privacy-security + +[`DOMHighResTimeStamp`]: https://w3c.github.io/hr-time/#dom-domhighrestimestamp +[`Performance`]: https://w3c.github.io/hr-time/#dfn-performance +[`Performance#now()`]: https://w3c.github.io/hr-time/#dom-performance-now +[`Performance#timeOrigin`]: https://w3c.github.io/hr-time/#dom-performance-timeorigin +[`Performance#toJSON()`]: https://w3c.github.io/hr-time/#dom-performance-tojson +[browser-process-hrtime]: https://www.npmjs.com/package/browser-process-hrtime +[clock drift]: https://en.wikipedia.org/wiki/Clock_drift +[global monotonic clock]: https://w3c.github.io/hr-time/#dfn-global-monotonic-clock +[Unix time]: https://en.wikipedia.org/wiki/Unix_time +[webidl2js]: https://github.com/jsdom/webidl2js diff --git a/includes/external/school/node_modules/w3c-hr-time/index.js b/includes/external/school/node_modules/w3c-hr-time/index.js new file mode 100644 index 0000000..bb50695 --- /dev/null +++ b/includes/external/school/node_modules/w3c-hr-time/index.js @@ -0,0 +1,11 @@ +"use strict"; + +const { getGlobalMonotonicClockMS } = require("./lib/global-monotonic-clock"); +const { Performance } = require("./lib/performance"); +const clockIsAccurate = require("./lib/clock-is-accurate"); + +module.exports = { + Performance, + getGlobalMonotonicClockMS, + clockIsAccurate +}; diff --git a/includes/external/school/node_modules/w3c-hr-time/lib/calculate-clock-offset.js b/includes/external/school/node_modules/w3c-hr-time/lib/calculate-clock-offset.js new file mode 100644 index 0000000..8659d30 --- /dev/null +++ b/includes/external/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/includes/external/school/node_modules/w3c-hr-time/lib/clock-is-accurate.js b/includes/external/school/node_modules/w3c-hr-time/lib/clock-is-accurate.js new file mode 100644 index 0000000..920b499 --- /dev/null +++ b/includes/external/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/includes/external/school/node_modules/w3c-hr-time/lib/global-monotonic-clock.js b/includes/external/school/node_modules/w3c-hr-time/lib/global-monotonic-clock.js new file mode 100644 index 0000000..4e9aee9 --- /dev/null +++ b/includes/external/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/includes/external/school/node_modules/w3c-hr-time/lib/performance.js b/includes/external/school/node_modules/w3c-hr-time/lib/performance.js new file mode 100644 index 0000000..4bcfbc3 --- /dev/null +++ b/includes/external/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/includes/external/school/node_modules/w3c-hr-time/lib/utils.js b/includes/external/school/node_modules/w3c-hr-time/lib/utils.js new file mode 100644 index 0000000..045981f --- /dev/null +++ b/includes/external/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 }; diff --git a/includes/external/school/node_modules/w3c-hr-time/package.json b/includes/external/school/node_modules/w3c-hr-time/package.json new file mode 100644 index 0000000..c46d929 --- /dev/null +++ b/includes/external/school/node_modules/w3c-hr-time/package.json @@ -0,0 +1,26 @@ +{ + "name": "w3c-hr-time", + "version": "1.0.2", + "description": "An implementation of the W3C High Resolution Time Level 2 specification.", + "main": "index.js", + "repository": "https://github.com/jsdom/w3c-hr-time", + "author": "Timothy Gu <timothygu99@gmail.com>", + "license": "MIT", + "private": false, + "dependencies": { + "browser-process-hrtime": "^1.0.0" + }, + "devDependencies": { + "eslint": "^4.14.0", + "eslint-plugin-jest": "^21.5.0", + "jest": "^24.1.0" + }, + "scripts": { + "test": "jest", + "lint": "eslint ." + }, + "files": [ + "lib", + "index.js" + ] +} |