diff options
Diffstat (limited to 'vanilla/node_modules/undici/lib/util')
| -rw-r--r-- | vanilla/node_modules/undici/lib/util/cache.js | 405 | ||||
| -rw-r--r-- | vanilla/node_modules/undici/lib/util/date.js | 653 | ||||
| -rw-r--r-- | vanilla/node_modules/undici/lib/util/promise.js | 28 | ||||
| -rw-r--r-- | vanilla/node_modules/undici/lib/util/runtime-features.js | 124 | ||||
| -rw-r--r-- | vanilla/node_modules/undici/lib/util/stats.js | 32 | ||||
| -rw-r--r-- | vanilla/node_modules/undici/lib/util/timers.js | 425 |
6 files changed, 0 insertions, 1667 deletions
diff --git a/vanilla/node_modules/undici/lib/util/cache.js b/vanilla/node_modules/undici/lib/util/cache.js deleted file mode 100644 index b7627d0..0000000 --- a/vanilla/node_modules/undici/lib/util/cache.js +++ /dev/null @@ -1,405 +0,0 @@ -'use strict' - -const { - safeHTTPMethods, - pathHasQueryOrFragment -} = require('../core/util') - -const { serializePathWithQuery } = require('../core/util') - -/** - * @param {import('../../types/dispatcher.d.ts').default.DispatchOptions} opts - */ -function makeCacheKey (opts) { - if (!opts.origin) { - throw new Error('opts.origin is undefined') - } - - let fullPath = opts.path || '/' - - if (opts.query && !pathHasQueryOrFragment(opts.path)) { - fullPath = serializePathWithQuery(fullPath, opts.query) - } - - return { - origin: opts.origin.toString(), - method: opts.method, - path: fullPath, - headers: opts.headers - } -} - -/** - * @param {Record<string, string[] | string>} - * @returns {Record<string, string[] | string>} - */ -function normalizeHeaders (opts) { - let headers - if (opts.headers == null) { - headers = {} - } else if (typeof opts.headers[Symbol.iterator] === 'function') { - headers = {} - for (const x of opts.headers) { - if (!Array.isArray(x)) { - throw new Error('opts.headers is not a valid header map') - } - const [key, val] = x - if (typeof key !== 'string' || typeof val !== 'string') { - throw new Error('opts.headers is not a valid header map') - } - headers[key.toLowerCase()] = val - } - } else if (typeof opts.headers === 'object') { - headers = {} - - for (const key of Object.keys(opts.headers)) { - headers[key.toLowerCase()] = opts.headers[key] - } - } else { - throw new Error('opts.headers is not an object') - } - - return headers -} - -/** - * @param {any} key - */ -function assertCacheKey (key) { - if (typeof key !== 'object') { - throw new TypeError(`expected key to be object, got ${typeof key}`) - } - - for (const property of ['origin', 'method', 'path']) { - if (typeof key[property] !== 'string') { - throw new TypeError(`expected key.${property} to be string, got ${typeof key[property]}`) - } - } - - if (key.headers !== undefined && typeof key.headers !== 'object') { - throw new TypeError(`expected headers to be object, got ${typeof key}`) - } -} - -/** - * @param {any} value - */ -function assertCacheValue (value) { - if (typeof value !== 'object') { - throw new TypeError(`expected value to be object, got ${typeof value}`) - } - - for (const property of ['statusCode', 'cachedAt', 'staleAt', 'deleteAt']) { - if (typeof value[property] !== 'number') { - throw new TypeError(`expected value.${property} to be number, got ${typeof value[property]}`) - } - } - - if (typeof value.statusMessage !== 'string') { - throw new TypeError(`expected value.statusMessage to be string, got ${typeof value.statusMessage}`) - } - - if (value.headers != null && typeof value.headers !== 'object') { - throw new TypeError(`expected value.rawHeaders to be object, got ${typeof value.headers}`) - } - - if (value.vary !== undefined && typeof value.vary !== 'object') { - throw new TypeError(`expected value.vary to be object, got ${typeof value.vary}`) - } - - if (value.etag !== undefined && typeof value.etag !== 'string') { - throw new TypeError(`expected value.etag to be string, got ${typeof value.etag}`) - } -} - -/** - * @see https://www.rfc-editor.org/rfc/rfc9111.html#name-cache-control - * @see https://www.iana.org/assignments/http-cache-directives/http-cache-directives.xhtml - - * @param {string | string[]} header - * @returns {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives} - */ -function parseCacheControlHeader (header) { - /** - * @type {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives} - */ - const output = {} - - let directives - if (Array.isArray(header)) { - directives = [] - - for (const directive of header) { - directives.push(...directive.split(',')) - } - } else { - directives = header.split(',') - } - - for (let i = 0; i < directives.length; i++) { - const directive = directives[i].toLowerCase() - const keyValueDelimiter = directive.indexOf('=') - - let key - let value - if (keyValueDelimiter !== -1) { - key = directive.substring(0, keyValueDelimiter).trimStart() - value = directive.substring(keyValueDelimiter + 1) - } else { - key = directive.trim() - } - - switch (key) { - case 'min-fresh': - case 'max-stale': - case 'max-age': - case 's-maxage': - case 'stale-while-revalidate': - case 'stale-if-error': { - if (value === undefined || value[0] === ' ') { - continue - } - - if ( - value.length >= 2 && - value[0] === '"' && - value[value.length - 1] === '"' - ) { - value = value.substring(1, value.length - 1) - } - - const parsedValue = parseInt(value, 10) - // eslint-disable-next-line no-self-compare - if (parsedValue !== parsedValue) { - continue - } - - if (key === 'max-age' && key in output && output[key] >= parsedValue) { - continue - } - - output[key] = parsedValue - - break - } - case 'private': - case 'no-cache': { - if (value) { - // The private and no-cache directives can be unqualified (aka just - // `private` or `no-cache`) or qualified (w/ a value). When they're - // qualified, it's a list of headers like `no-cache=header1`, - // `no-cache="header1"`, or `no-cache="header1, header2"` - // If we're given multiple headers, the comma messes us up since - // we split the full header by commas. So, let's loop through the - // remaining parts in front of us until we find one that ends in a - // quote. We can then just splice all of the parts in between the - // starting quote and the ending quote out of the directives array - // and continue parsing like normal. - // https://www.rfc-editor.org/rfc/rfc9111.html#name-no-cache-2 - if (value[0] === '"') { - // Something like `no-cache="some-header"` OR `no-cache="some-header, another-header"`. - - // Add the first header on and cut off the leading quote - const headers = [value.substring(1)] - - let foundEndingQuote = value[value.length - 1] === '"' - if (!foundEndingQuote) { - // Something like `no-cache="some-header, another-header"` - // This can still be something invalid, e.g. `no-cache="some-header, ...` - for (let j = i + 1; j < directives.length; j++) { - const nextPart = directives[j] - const nextPartLength = nextPart.length - - headers.push(nextPart.trim()) - - if (nextPartLength !== 0 && nextPart[nextPartLength - 1] === '"') { - foundEndingQuote = true - break - } - } - } - - if (foundEndingQuote) { - let lastHeader = headers[headers.length - 1] - if (lastHeader[lastHeader.length - 1] === '"') { - lastHeader = lastHeader.substring(0, lastHeader.length - 1) - headers[headers.length - 1] = lastHeader - } - - if (key in output) { - output[key] = output[key].concat(headers) - } else { - output[key] = headers - } - } - } else { - // Something like `no-cache="some-header"` - if (key in output) { - output[key] = output[key].concat(value) - } else { - output[key] = [value] - } - } - - break - } - } - // eslint-disable-next-line no-fallthrough - case 'public': - case 'no-store': - case 'must-revalidate': - case 'proxy-revalidate': - case 'immutable': - case 'no-transform': - case 'must-understand': - case 'only-if-cached': - if (value) { - // These are qualified (something like `public=...`) when they aren't - // allowed to be, skip - continue - } - - output[key] = true - break - default: - // Ignore unknown directives as per https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.3-1 - continue - } - } - - return output -} - -/** - * @param {string | string[]} varyHeader Vary header from the server - * @param {Record<string, string | string[]>} headers Request headers - * @returns {Record<string, string | string[]>} - */ -function parseVaryHeader (varyHeader, headers) { - if (typeof varyHeader === 'string' && varyHeader.includes('*')) { - return headers - } - - const output = /** @type {Record<string, string | string[] | null>} */ ({}) - - const varyingHeaders = typeof varyHeader === 'string' - ? varyHeader.split(',') - : varyHeader - - for (const header of varyingHeaders) { - const trimmedHeader = header.trim().toLowerCase() - - output[trimmedHeader] = headers[trimmedHeader] ?? null - } - - return output -} - -/** - * Note: this deviates from the spec a little. Empty etags ("", W/"") are valid, - * however, including them in cached resposnes serves little to no purpose. - * - * @see https://www.rfc-editor.org/rfc/rfc9110.html#name-etag - * - * @param {string} etag - * @returns {boolean} - */ -function isEtagUsable (etag) { - if (etag.length <= 2) { - // Shortest an etag can be is two chars (just ""). This is where we deviate - // from the spec requiring a min of 3 chars however - return false - } - - if (etag[0] === '"' && etag[etag.length - 1] === '"') { - // ETag: ""asd123"" or ETag: "W/"asd123"", kinda undefined behavior in the - // spec. Some servers will accept these while others don't. - // ETag: "asd123" - return !(etag[1] === '"' || etag.startsWith('"W/')) - } - - if (etag.startsWith('W/"') && etag[etag.length - 1] === '"') { - // ETag: W/"", also where we deviate from the spec & require a min of 3 - // chars - // ETag: for W/"", W/"asd123" - return etag.length !== 4 - } - - // Anything else - return false -} - -/** - * @param {unknown} store - * @returns {asserts store is import('../../types/cache-interceptor.d.ts').default.CacheStore} - */ -function assertCacheStore (store, name = 'CacheStore') { - if (typeof store !== 'object' || store === null) { - throw new TypeError(`expected type of ${name} to be a CacheStore, got ${store === null ? 'null' : typeof store}`) - } - - for (const fn of ['get', 'createWriteStream', 'delete']) { - if (typeof store[fn] !== 'function') { - throw new TypeError(`${name} needs to have a \`${fn}()\` function`) - } - } -} -/** - * @param {unknown} methods - * @returns {asserts methods is import('../../types/cache-interceptor.d.ts').default.CacheMethods[]} - */ -function assertCacheMethods (methods, name = 'CacheMethods') { - if (!Array.isArray(methods)) { - throw new TypeError(`expected type of ${name} needs to be an array, got ${methods === null ? 'null' : typeof methods}`) - } - - if (methods.length === 0) { - throw new TypeError(`${name} needs to have at least one method`) - } - - for (const method of methods) { - if (!safeHTTPMethods.includes(method)) { - throw new TypeError(`element of ${name}-array needs to be one of following values: ${safeHTTPMethods.join(', ')}, got ${method}`) - } - } -} - -/** - * Creates a string key for request deduplication purposes. - * This key is used to identify in-flight requests that can be shared. - * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} cacheKey - * @param {Set<string>} [excludeHeaders] Set of lowercase header names to exclude from the key - * @returns {string} - */ -function makeDeduplicationKey (cacheKey, excludeHeaders) { - // Create a deterministic string key from the cache key - // Include origin, method, path, and sorted headers - let key = `${cacheKey.origin}:${cacheKey.method}:${cacheKey.path}` - - if (cacheKey.headers) { - const sortedHeaders = Object.keys(cacheKey.headers).sort() - for (const header of sortedHeaders) { - // Skip excluded headers - if (excludeHeaders?.has(header.toLowerCase())) { - continue - } - const value = cacheKey.headers[header] - key += `:${header}=${Array.isArray(value) ? value.join(',') : value}` - } - } - - return key -} - -module.exports = { - makeCacheKey, - normalizeHeaders, - assertCacheKey, - assertCacheValue, - parseCacheControlHeader, - parseVaryHeader, - isEtagUsable, - assertCacheMethods, - assertCacheStore, - makeDeduplicationKey -} diff --git a/vanilla/node_modules/undici/lib/util/date.js b/vanilla/node_modules/undici/lib/util/date.js deleted file mode 100644 index 99dd150..0000000 --- a/vanilla/node_modules/undici/lib/util/date.js +++ /dev/null @@ -1,653 +0,0 @@ -'use strict' - -/** - * @see https://www.rfc-editor.org/rfc/rfc9110.html#name-date-time-formats - * - * @param {string} date - * @returns {Date | undefined} - */ -function parseHttpDate (date) { - // Sun, 06 Nov 1994 08:49:37 GMT ; IMF-fixdate - // Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format - // Sunday, 06-Nov-94 08:49:37 GMT ; obsolete RFC 850 format - - switch (date[3]) { - case ',': return parseImfDate(date) - case ' ': return parseAscTimeDate(date) - default: return parseRfc850Date(date) - } -} - -/** - * @see https://httpwg.org/specs/rfc9110.html#preferred.date.format - * - * @param {string} date - * @returns {Date | undefined} - */ -function parseImfDate (date) { - if ( - date.length !== 29 || - date[4] !== ' ' || - date[7] !== ' ' || - date[11] !== ' ' || - date[16] !== ' ' || - date[19] !== ':' || - date[22] !== ':' || - date[25] !== ' ' || - date[26] !== 'G' || - date[27] !== 'M' || - date[28] !== 'T' - ) { - return undefined - } - - let weekday = -1 - if (date[0] === 'S' && date[1] === 'u' && date[2] === 'n') { // Sunday - weekday = 0 - } else if (date[0] === 'M' && date[1] === 'o' && date[2] === 'n') { // Monday - weekday = 1 - } else if (date[0] === 'T' && date[1] === 'u' && date[2] === 'e') { // Tuesday - weekday = 2 - } else if (date[0] === 'W' && date[1] === 'e' && date[2] === 'd') { // Wednesday - weekday = 3 - } else if (date[0] === 'T' && date[1] === 'h' && date[2] === 'u') { // Thursday - weekday = 4 - } else if (date[0] === 'F' && date[1] === 'r' && date[2] === 'i') { // Friday - weekday = 5 - } else if (date[0] === 'S' && date[1] === 'a' && date[2] === 't') { // Saturday - weekday = 6 - } else { - return undefined // Not a valid day of the week - } - - let day = 0 - if (date[5] === '0') { - // Single digit day, e.g. "Sun Nov 6 08:49:37 1994" - const code = date.charCodeAt(6) - if (code < 49 || code > 57) { - return undefined // Not a digit - } - day = code - 48 // Convert ASCII code to number - } else { - const code1 = date.charCodeAt(5) - if (code1 < 49 || code1 > 51) { - return undefined // Not a digit between 1 and 3 - } - const code2 = date.charCodeAt(6) - if (code2 < 48 || code2 > 57) { - return undefined // Not a digit - } - day = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number - } - - let monthIdx = -1 - if ( - (date[8] === 'J' && date[9] === 'a' && date[10] === 'n') - ) { - monthIdx = 0 // Jan - } else if ( - (date[8] === 'F' && date[9] === 'e' && date[10] === 'b') - ) { - monthIdx = 1 // Feb - } else if ( - (date[8] === 'M' && date[9] === 'a') - ) { - if (date[10] === 'r') { - monthIdx = 2 // Mar - } else if (date[10] === 'y') { - monthIdx = 4 // May - } else { - return undefined // Invalid month - } - } else if ( - (date[8] === 'J') - ) { - if (date[9] === 'a' && date[10] === 'n') { - monthIdx = 0 // Jan - } else if (date[9] === 'u') { - if (date[10] === 'n') { - monthIdx = 5 // Jun - } else if (date[10] === 'l') { - monthIdx = 6 // Jul - } else { - return undefined // Invalid month - } - } else { - return undefined // Invalid month - } - } else if ( - (date[8] === 'A') - ) { - if (date[9] === 'p' && date[10] === 'r') { - monthIdx = 3 // Apr - } else if (date[9] === 'u' && date[10] === 'g') { - monthIdx = 7 // Aug - } else { - return undefined // Invalid month - } - } else if ( - (date[8] === 'S' && date[9] === 'e' && date[10] === 'p') - ) { - monthIdx = 8 // Sep - } else if ( - (date[8] === 'O' && date[9] === 'c' && date[10] === 't') - ) { - monthIdx = 9 // Oct - } else if ( - (date[8] === 'N' && date[9] === 'o' && date[10] === 'v') - ) { - monthIdx = 10 // Nov - } else if ( - (date[8] === 'D' && date[9] === 'e' && date[10] === 'c') - ) { - monthIdx = 11 // Dec - } else { - // Not a valid month - return undefined - } - - const yearDigit1 = date.charCodeAt(12) - if (yearDigit1 < 48 || yearDigit1 > 57) { - return undefined // Not a digit - } - const yearDigit2 = date.charCodeAt(13) - if (yearDigit2 < 48 || yearDigit2 > 57) { - return undefined // Not a digit - } - const yearDigit3 = date.charCodeAt(14) - if (yearDigit3 < 48 || yearDigit3 > 57) { - return undefined // Not a digit - } - const yearDigit4 = date.charCodeAt(15) - if (yearDigit4 < 48 || yearDigit4 > 57) { - return undefined // Not a digit - } - const year = (yearDigit1 - 48) * 1000 + (yearDigit2 - 48) * 100 + (yearDigit3 - 48) * 10 + (yearDigit4 - 48) - - let hour = 0 - if (date[17] === '0') { - const code = date.charCodeAt(18) - if (code < 48 || code > 57) { - return undefined // Not a digit - } - hour = code - 48 // Convert ASCII code to number - } else { - const code1 = date.charCodeAt(17) - if (code1 < 48 || code1 > 50) { - return undefined // Not a digit between 0 and 2 - } - const code2 = date.charCodeAt(18) - if (code2 < 48 || code2 > 57) { - return undefined // Not a digit - } - if (code1 === 50 && code2 > 51) { - return undefined // Hour cannot be greater than 23 - } - hour = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number - } - - let minute = 0 - if (date[20] === '0') { - const code = date.charCodeAt(21) - if (code < 48 || code > 57) { - return undefined // Not a digit - } - minute = code - 48 // Convert ASCII code to number - } else { - const code1 = date.charCodeAt(20) - if (code1 < 48 || code1 > 53) { - return undefined // Not a digit between 0 and 5 - } - const code2 = date.charCodeAt(21) - if (code2 < 48 || code2 > 57) { - return undefined // Not a digit - } - minute = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number - } - - let second = 0 - if (date[23] === '0') { - const code = date.charCodeAt(24) - if (code < 48 || code > 57) { - return undefined // Not a digit - } - second = code - 48 // Convert ASCII code to number - } else { - const code1 = date.charCodeAt(23) - if (code1 < 48 || code1 > 53) { - return undefined // Not a digit between 0 and 5 - } - const code2 = date.charCodeAt(24) - if (code2 < 48 || code2 > 57) { - return undefined // Not a digit - } - second = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number - } - - const result = new Date(Date.UTC(year, monthIdx, day, hour, minute, second)) - return result.getUTCDay() === weekday ? result : undefined -} - -/** - * @see https://httpwg.org/specs/rfc9110.html#obsolete.date.formats - * - * @param {string} date - * @returns {Date | undefined} - */ -function parseAscTimeDate (date) { - // This is assumed to be in UTC - - if ( - date.length !== 24 || - date[7] !== ' ' || - date[10] !== ' ' || - date[19] !== ' ' - ) { - return undefined - } - - let weekday = -1 - if (date[0] === 'S' && date[1] === 'u' && date[2] === 'n') { // Sunday - weekday = 0 - } else if (date[0] === 'M' && date[1] === 'o' && date[2] === 'n') { // Monday - weekday = 1 - } else if (date[0] === 'T' && date[1] === 'u' && date[2] === 'e') { // Tuesday - weekday = 2 - } else if (date[0] === 'W' && date[1] === 'e' && date[2] === 'd') { // Wednesday - weekday = 3 - } else if (date[0] === 'T' && date[1] === 'h' && date[2] === 'u') { // Thursday - weekday = 4 - } else if (date[0] === 'F' && date[1] === 'r' && date[2] === 'i') { // Friday - weekday = 5 - } else if (date[0] === 'S' && date[1] === 'a' && date[2] === 't') { // Saturday - weekday = 6 - } else { - return undefined // Not a valid day of the week - } - - let monthIdx = -1 - if ( - (date[4] === 'J' && date[5] === 'a' && date[6] === 'n') - ) { - monthIdx = 0 // Jan - } else if ( - (date[4] === 'F' && date[5] === 'e' && date[6] === 'b') - ) { - monthIdx = 1 // Feb - } else if ( - (date[4] === 'M' && date[5] === 'a') - ) { - if (date[6] === 'r') { - monthIdx = 2 // Mar - } else if (date[6] === 'y') { - monthIdx = 4 // May - } else { - return undefined // Invalid month - } - } else if ( - (date[4] === 'J') - ) { - if (date[5] === 'a' && date[6] === 'n') { - monthIdx = 0 // Jan - } else if (date[5] === 'u') { - if (date[6] === 'n') { - monthIdx = 5 // Jun - } else if (date[6] === 'l') { - monthIdx = 6 // Jul - } else { - return undefined // Invalid month - } - } else { - return undefined // Invalid month - } - } else if ( - (date[4] === 'A') - ) { - if (date[5] === 'p' && date[6] === 'r') { - monthIdx = 3 // Apr - } else if (date[5] === 'u' && date[6] === 'g') { - monthIdx = 7 // Aug - } else { - return undefined // Invalid month - } - } else if ( - (date[4] === 'S' && date[5] === 'e' && date[6] === 'p') - ) { - monthIdx = 8 // Sep - } else if ( - (date[4] === 'O' && date[5] === 'c' && date[6] === 't') - ) { - monthIdx = 9 // Oct - } else if ( - (date[4] === 'N' && date[5] === 'o' && date[6] === 'v') - ) { - monthIdx = 10 // Nov - } else if ( - (date[4] === 'D' && date[5] === 'e' && date[6] === 'c') - ) { - monthIdx = 11 // Dec - } else { - // Not a valid month - return undefined - } - - let day = 0 - if (date[8] === ' ') { - // Single digit day, e.g. "Sun Nov 6 08:49:37 1994" - const code = date.charCodeAt(9) - if (code < 49 || code > 57) { - return undefined // Not a digit - } - day = code - 48 // Convert ASCII code to number - } else { - const code1 = date.charCodeAt(8) - if (code1 < 49 || code1 > 51) { - return undefined // Not a digit between 1 and 3 - } - const code2 = date.charCodeAt(9) - if (code2 < 48 || code2 > 57) { - return undefined // Not a digit - } - day = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number - } - - let hour = 0 - if (date[11] === '0') { - const code = date.charCodeAt(12) - if (code < 48 || code > 57) { - return undefined // Not a digit - } - hour = code - 48 // Convert ASCII code to number - } else { - const code1 = date.charCodeAt(11) - if (code1 < 48 || code1 > 50) { - return undefined // Not a digit between 0 and 2 - } - const code2 = date.charCodeAt(12) - if (code2 < 48 || code2 > 57) { - return undefined // Not a digit - } - if (code1 === 50 && code2 > 51) { - return undefined // Hour cannot be greater than 23 - } - hour = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number - } - - let minute = 0 - if (date[14] === '0') { - const code = date.charCodeAt(15) - if (code < 48 || code > 57) { - return undefined // Not a digit - } - minute = code - 48 // Convert ASCII code to number - } else { - const code1 = date.charCodeAt(14) - if (code1 < 48 || code1 > 53) { - return undefined // Not a digit between 0 and 5 - } - const code2 = date.charCodeAt(15) - if (code2 < 48 || code2 > 57) { - return undefined // Not a digit - } - minute = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number - } - - let second = 0 - if (date[17] === '0') { - const code = date.charCodeAt(18) - if (code < 48 || code > 57) { - return undefined // Not a digit - } - second = code - 48 // Convert ASCII code to number - } else { - const code1 = date.charCodeAt(17) - if (code1 < 48 || code1 > 53) { - return undefined // Not a digit between 0 and 5 - } - const code2 = date.charCodeAt(18) - if (code2 < 48 || code2 > 57) { - return undefined // Not a digit - } - second = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number - } - - const yearDigit1 = date.charCodeAt(20) - if (yearDigit1 < 48 || yearDigit1 > 57) { - return undefined // Not a digit - } - const yearDigit2 = date.charCodeAt(21) - if (yearDigit2 < 48 || yearDigit2 > 57) { - return undefined // Not a digit - } - const yearDigit3 = date.charCodeAt(22) - if (yearDigit3 < 48 || yearDigit3 > 57) { - return undefined // Not a digit - } - const yearDigit4 = date.charCodeAt(23) - if (yearDigit4 < 48 || yearDigit4 > 57) { - return undefined // Not a digit - } - const year = (yearDigit1 - 48) * 1000 + (yearDigit2 - 48) * 100 + (yearDigit3 - 48) * 10 + (yearDigit4 - 48) - - const result = new Date(Date.UTC(year, monthIdx, day, hour, minute, second)) - return result.getUTCDay() === weekday ? result : undefined -} - -/** - * @see https://httpwg.org/specs/rfc9110.html#obsolete.date.formats - * - * @param {string} date - * @returns {Date | undefined} - */ -function parseRfc850Date (date) { - let commaIndex = -1 - - let weekday = -1 - if (date[0] === 'S') { - if (date[1] === 'u' && date[2] === 'n' && date[3] === 'd' && date[4] === 'a' && date[5] === 'y') { - weekday = 0 // Sunday - commaIndex = 6 - } else if (date[1] === 'a' && date[2] === 't' && date[3] === 'u' && date[4] === 'r' && date[5] === 'd' && date[6] === 'a' && date[7] === 'y') { - weekday = 6 // Saturday - commaIndex = 8 - } - } else if (date[0] === 'M' && date[1] === 'o' && date[2] === 'n' && date[3] === 'd' && date[4] === 'a' && date[5] === 'y') { - weekday = 1 // Monday - commaIndex = 6 - } else if (date[0] === 'T') { - if (date[1] === 'u' && date[2] === 'e' && date[3] === 's' && date[4] === 'd' && date[5] === 'a' && date[6] === 'y') { - weekday = 2 // Tuesday - commaIndex = 7 - } else if (date[1] === 'h' && date[2] === 'u' && date[3] === 'r' && date[4] === 's' && date[5] === 'd' && date[6] === 'a' && date[7] === 'y') { - weekday = 4 // Thursday - commaIndex = 8 - } - } else if (date[0] === 'W' && date[1] === 'e' && date[2] === 'd' && date[3] === 'n' && date[4] === 'e' && date[5] === 's' && date[6] === 'd' && date[7] === 'a' && date[8] === 'y') { - weekday = 3 // Wednesday - commaIndex = 9 - } else if (date[0] === 'F' && date[1] === 'r' && date[2] === 'i' && date[3] === 'd' && date[4] === 'a' && date[5] === 'y') { - weekday = 5 // Friday - commaIndex = 6 - } else { - // Not a valid day name - return undefined - } - - if ( - date[commaIndex] !== ',' || - (date.length - commaIndex - 1) !== 23 || - date[commaIndex + 1] !== ' ' || - date[commaIndex + 4] !== '-' || - date[commaIndex + 8] !== '-' || - date[commaIndex + 11] !== ' ' || - date[commaIndex + 14] !== ':' || - date[commaIndex + 17] !== ':' || - date[commaIndex + 20] !== ' ' || - date[commaIndex + 21] !== 'G' || - date[commaIndex + 22] !== 'M' || - date[commaIndex + 23] !== 'T' - ) { - return undefined - } - - let day = 0 - if (date[commaIndex + 2] === '0') { - // Single digit day, e.g. "Sun Nov 6 08:49:37 1994" - const code = date.charCodeAt(commaIndex + 3) - if (code < 49 || code > 57) { - return undefined // Not a digit - } - day = code - 48 // Convert ASCII code to number - } else { - const code1 = date.charCodeAt(commaIndex + 2) - if (code1 < 49 || code1 > 51) { - return undefined // Not a digit between 1 and 3 - } - const code2 = date.charCodeAt(commaIndex + 3) - if (code2 < 48 || code2 > 57) { - return undefined // Not a digit - } - day = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number - } - - let monthIdx = -1 - if ( - (date[commaIndex + 5] === 'J' && date[commaIndex + 6] === 'a' && date[commaIndex + 7] === 'n') - ) { - monthIdx = 0 // Jan - } else if ( - (date[commaIndex + 5] === 'F' && date[commaIndex + 6] === 'e' && date[commaIndex + 7] === 'b') - ) { - monthIdx = 1 // Feb - } else if ( - (date[commaIndex + 5] === 'M' && date[commaIndex + 6] === 'a' && date[commaIndex + 7] === 'r') - ) { - monthIdx = 2 // Mar - } else if ( - (date[commaIndex + 5] === 'A' && date[commaIndex + 6] === 'p' && date[commaIndex + 7] === 'r') - ) { - monthIdx = 3 // Apr - } else if ( - (date[commaIndex + 5] === 'M' && date[commaIndex + 6] === 'a' && date[commaIndex + 7] === 'y') - ) { - monthIdx = 4 // May - } else if ( - (date[commaIndex + 5] === 'J' && date[commaIndex + 6] === 'u' && date[commaIndex + 7] === 'n') - ) { - monthIdx = 5 // Jun - } else if ( - (date[commaIndex + 5] === 'J' && date[commaIndex + 6] === 'u' && date[commaIndex + 7] === 'l') - ) { - monthIdx = 6 // Jul - } else if ( - (date[commaIndex + 5] === 'A' && date[commaIndex + 6] === 'u' && date[commaIndex + 7] === 'g') - ) { - monthIdx = 7 // Aug - } else if ( - (date[commaIndex + 5] === 'S' && date[commaIndex + 6] === 'e' && date[commaIndex + 7] === 'p') - ) { - monthIdx = 8 // Sep - } else if ( - (date[commaIndex + 5] === 'O' && date[commaIndex + 6] === 'c' && date[commaIndex + 7] === 't') - ) { - monthIdx = 9 // Oct - } else if ( - (date[commaIndex + 5] === 'N' && date[commaIndex + 6] === 'o' && date[commaIndex + 7] === 'v') - ) { - monthIdx = 10 // Nov - } else if ( - (date[commaIndex + 5] === 'D' && date[commaIndex + 6] === 'e' && date[commaIndex + 7] === 'c') - ) { - monthIdx = 11 // Dec - } else { - // Not a valid month - return undefined - } - - const yearDigit1 = date.charCodeAt(commaIndex + 9) - if (yearDigit1 < 48 || yearDigit1 > 57) { - return undefined // Not a digit - } - const yearDigit2 = date.charCodeAt(commaIndex + 10) - if (yearDigit2 < 48 || yearDigit2 > 57) { - return undefined // Not a digit - } - - let year = (yearDigit1 - 48) * 10 + (yearDigit2 - 48) // Convert ASCII codes to number - - // RFC 6265 states that the year is in the range 1970-2069. - // @see https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.1 - // - // 3. If the year-value is greater than or equal to 70 and less than or - // equal to 99, increment the year-value by 1900. - // 4. If the year-value is greater than or equal to 0 and less than or - // equal to 69, increment the year-value by 2000. - year += year < 70 ? 2000 : 1900 - - let hour = 0 - if (date[commaIndex + 12] === '0') { - const code = date.charCodeAt(commaIndex + 13) - if (code < 48 || code > 57) { - return undefined // Not a digit - } - hour = code - 48 // Convert ASCII code to number - } else { - const code1 = date.charCodeAt(commaIndex + 12) - if (code1 < 48 || code1 > 50) { - return undefined // Not a digit between 0 and 2 - } - const code2 = date.charCodeAt(commaIndex + 13) - if (code2 < 48 || code2 > 57) { - return undefined // Not a digit - } - if (code1 === 50 && code2 > 51) { - return undefined // Hour cannot be greater than 23 - } - hour = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number - } - - let minute = 0 - if (date[commaIndex + 15] === '0') { - const code = date.charCodeAt(commaIndex + 16) - if (code < 48 || code > 57) { - return undefined // Not a digit - } - minute = code - 48 // Convert ASCII code to number - } else { - const code1 = date.charCodeAt(commaIndex + 15) - if (code1 < 48 || code1 > 53) { - return undefined // Not a digit between 0 and 5 - } - const code2 = date.charCodeAt(commaIndex + 16) - if (code2 < 48 || code2 > 57) { - return undefined // Not a digit - } - minute = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number - } - - let second = 0 - if (date[commaIndex + 18] === '0') { - const code = date.charCodeAt(commaIndex + 19) - if (code < 48 || code > 57) { - return undefined // Not a digit - } - second = code - 48 // Convert ASCII code to number - } else { - const code1 = date.charCodeAt(commaIndex + 18) - if (code1 < 48 || code1 > 53) { - return undefined // Not a digit between 0 and 5 - } - const code2 = date.charCodeAt(commaIndex + 19) - if (code2 < 48 || code2 > 57) { - return undefined // Not a digit - } - second = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number - } - - const result = new Date(Date.UTC(year, monthIdx, day, hour, minute, second)) - return result.getUTCDay() === weekday ? result : undefined -} - -module.exports = { - parseHttpDate -} diff --git a/vanilla/node_modules/undici/lib/util/promise.js b/vanilla/node_modules/undici/lib/util/promise.js deleted file mode 100644 index 048f86e..0000000 --- a/vanilla/node_modules/undici/lib/util/promise.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict' - -/** - * @template {*} T - * @typedef {Object} DeferredPromise - * @property {Promise<T>} promise - * @property {(value?: T) => void} resolve - * @property {(reason?: any) => void} reject - */ - -/** - * @template {*} T - * @returns {DeferredPromise<T>} An object containing a promise and its resolve/reject methods. - */ -function createDeferredPromise () { - let res - let rej - const promise = new Promise((resolve, reject) => { - res = resolve - rej = reject - }) - - return { promise, resolve: res, reject: rej } -} - -module.exports = { - createDeferredPromise -} diff --git a/vanilla/node_modules/undici/lib/util/runtime-features.js b/vanilla/node_modules/undici/lib/util/runtime-features.js deleted file mode 100644 index 3e62dc0..0000000 --- a/vanilla/node_modules/undici/lib/util/runtime-features.js +++ /dev/null @@ -1,124 +0,0 @@ -'use strict' - -/** @typedef {`node:${string}`} NodeModuleName */ - -/** @type {Record<NodeModuleName, () => any>} */ -const lazyLoaders = { - __proto__: null, - 'node:crypto': () => require('node:crypto'), - 'node:sqlite': () => require('node:sqlite'), - 'node:worker_threads': () => require('node:worker_threads'), - 'node:zlib': () => require('node:zlib') -} - -/** - * @param {NodeModuleName} moduleName - * @returns {boolean} - */ -function detectRuntimeFeatureByNodeModule (moduleName) { - try { - lazyLoaders[moduleName]() - return true - } catch (err) { - if (err.code !== 'ERR_UNKNOWN_BUILTIN_MODULE' && err.code !== 'ERR_NO_CRYPTO') { - throw err - } - return false - } -} - -/** - * @param {NodeModuleName} moduleName - * @param {string} property - * @returns {boolean} - */ -function detectRuntimeFeatureByExportedProperty (moduleName, property) { - const module = lazyLoaders[moduleName]() - return typeof module[property] !== 'undefined' -} - -const runtimeFeaturesByExportedProperty = /** @type {const} */ (['markAsUncloneable', 'zstd']) - -/** @type {Record<RuntimeFeatureByExportedProperty, [NodeModuleName, string]>} */ -const exportedPropertyLookup = { - markAsUncloneable: ['node:worker_threads', 'markAsUncloneable'], - zstd: ['node:zlib', 'createZstdDecompress'] -} - -/** @typedef {typeof runtimeFeaturesByExportedProperty[number]} RuntimeFeatureByExportedProperty */ - -const runtimeFeaturesAsNodeModule = /** @type {const} */ (['crypto', 'sqlite']) -/** @typedef {typeof runtimeFeaturesAsNodeModule[number]} RuntimeFeatureByNodeModule */ - -const features = /** @type {const} */ ([ - ...runtimeFeaturesAsNodeModule, - ...runtimeFeaturesByExportedProperty -]) - -/** @typedef {typeof features[number]} Feature */ - -/** - * @param {Feature} feature - * @returns {boolean} - */ -function detectRuntimeFeature (feature) { - if (runtimeFeaturesAsNodeModule.includes(/** @type {RuntimeFeatureByNodeModule} */ (feature))) { - return detectRuntimeFeatureByNodeModule(`node:${feature}`) - } else if (runtimeFeaturesByExportedProperty.includes(/** @type {RuntimeFeatureByExportedProperty} */ (feature))) { - const [moduleName, property] = exportedPropertyLookup[feature] - return detectRuntimeFeatureByExportedProperty(moduleName, property) - } - throw new TypeError(`unknown feature: ${feature}`) -} - -/** - * @class - * @name RuntimeFeatures - */ -class RuntimeFeatures { - /** @type {Map<Feature, boolean>} */ - #map = new Map() - - /** - * Clears all cached feature detections. - */ - clear () { - this.#map.clear() - } - - /** - * @param {Feature} feature - * @returns {boolean} - */ - has (feature) { - return ( - this.#map.get(feature) ?? this.#detectRuntimeFeature(feature) - ) - } - - /** - * @param {Feature} feature - * @param {boolean} value - */ - set (feature, value) { - if (features.includes(feature) === false) { - throw new TypeError(`unknown feature: ${feature}`) - } - this.#map.set(feature, value) - } - - /** - * @param {Feature} feature - * @returns {boolean} - */ - #detectRuntimeFeature (feature) { - const result = detectRuntimeFeature(feature) - this.#map.set(feature, result) - return result - } -} - -const instance = new RuntimeFeatures() - -module.exports.runtimeFeatures = instance -module.exports.default = instance diff --git a/vanilla/node_modules/undici/lib/util/stats.js b/vanilla/node_modules/undici/lib/util/stats.js deleted file mode 100644 index a13132e..0000000 --- a/vanilla/node_modules/undici/lib/util/stats.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict' - -const { - kConnected, - kPending, - kRunning, - kSize, - kFree, - kQueued -} = require('../core/symbols') - -class ClientStats { - constructor (client) { - this.connected = client[kConnected] - this.pending = client[kPending] - this.running = client[kRunning] - this.size = client[kSize] - } -} - -class PoolStats { - constructor (pool) { - this.connected = pool[kConnected] - this.free = pool[kFree] - this.pending = pool[kPending] - this.queued = pool[kQueued] - this.running = pool[kRunning] - this.size = pool[kSize] - } -} - -module.exports = { ClientStats, PoolStats } diff --git a/vanilla/node_modules/undici/lib/util/timers.js b/vanilla/node_modules/undici/lib/util/timers.js deleted file mode 100644 index 14984d4..0000000 --- a/vanilla/node_modules/undici/lib/util/timers.js +++ /dev/null @@ -1,425 +0,0 @@ -'use strict' - -/** - * This module offers an optimized timer implementation designed for scenarios - * where high precision is not critical. - * - * The timer achieves faster performance by using a low-resolution approach, - * with an accuracy target of within 500ms. This makes it particularly useful - * for timers with delays of 1 second or more, where exact timing is less - * crucial. - * - * It's important to note that Node.js timers are inherently imprecise, as - * delays can occur due to the event loop being blocked by other operations. - * Consequently, timers may trigger later than their scheduled time. - */ - -/** - * The fastNow variable contains the internal fast timer clock value. - * - * @type {number} - */ -let fastNow = 0 - -/** - * RESOLUTION_MS represents the target resolution time in milliseconds. - * - * @type {number} - * @default 1000 - */ -const RESOLUTION_MS = 1e3 - -/** - * TICK_MS defines the desired interval in milliseconds between each tick. - * The target value is set to half the resolution time, minus 1 ms, to account - * for potential event loop overhead. - * - * @type {number} - * @default 499 - */ -const TICK_MS = (RESOLUTION_MS >> 1) - 1 - -/** - * fastNowTimeout is a Node.js timer used to manage and process - * the FastTimers stored in the `fastTimers` array. - * - * @type {NodeJS.Timeout} - */ -let fastNowTimeout - -/** - * The kFastTimer symbol is used to identify FastTimer instances. - * - * @type {Symbol} - */ -const kFastTimer = Symbol('kFastTimer') - -/** - * The fastTimers array contains all active FastTimers. - * - * @type {FastTimer[]} - */ -const fastTimers = [] - -/** - * These constants represent the various states of a FastTimer. - */ - -/** - * The `NOT_IN_LIST` constant indicates that the FastTimer is not included - * in the `fastTimers` array. Timers with this status will not be processed - * during the next tick by the `onTick` function. - * - * A FastTimer can be re-added to the `fastTimers` array by invoking the - * `refresh` method on the FastTimer instance. - * - * @type {-2} - */ -const NOT_IN_LIST = -2 - -/** - * The `TO_BE_CLEARED` constant indicates that the FastTimer is scheduled - * for removal from the `fastTimers` array. A FastTimer in this state will - * be removed in the next tick by the `onTick` function and will no longer - * be processed. - * - * This status is also set when the `clear` method is called on the FastTimer instance. - * - * @type {-1} - */ -const TO_BE_CLEARED = -1 - -/** - * The `PENDING` constant signifies that the FastTimer is awaiting processing - * in the next tick by the `onTick` function. Timers with this status will have - * their `_idleStart` value set and their status updated to `ACTIVE` in the next tick. - * - * @type {0} - */ -const PENDING = 0 - -/** - * The `ACTIVE` constant indicates that the FastTimer is active and waiting - * for its timer to expire. During the next tick, the `onTick` function will - * check if the timer has expired, and if so, it will execute the associated callback. - * - * @type {1} - */ -const ACTIVE = 1 - -/** - * The onTick function processes the fastTimers array. - * - * @returns {void} - */ -function onTick () { - /** - * Increment the fastNow value by the TICK_MS value, despite the actual time - * that has passed since the last tick. This approach ensures independence - * from the system clock and delays caused by a blocked event loop. - * - * @type {number} - */ - fastNow += TICK_MS - - /** - * The `idx` variable is used to iterate over the `fastTimers` array. - * Expired timers are removed by replacing them with the last element in the array. - * Consequently, `idx` is only incremented when the current element is not removed. - * - * @type {number} - */ - let idx = 0 - - /** - * The len variable will contain the length of the fastTimers array - * and will be decremented when a FastTimer should be removed from the - * fastTimers array. - * - * @type {number} - */ - let len = fastTimers.length - - while (idx < len) { - /** - * @type {FastTimer} - */ - const timer = fastTimers[idx] - - // If the timer is in the ACTIVE state and the timer has expired, it will - // be processed in the next tick. - if (timer._state === PENDING) { - // Set the _idleStart value to the fastNow value minus the TICK_MS value - // to account for the time the timer was in the PENDING state. - timer._idleStart = fastNow - TICK_MS - timer._state = ACTIVE - } else if ( - timer._state === ACTIVE && - fastNow >= timer._idleStart + timer._idleTimeout - ) { - timer._state = TO_BE_CLEARED - timer._idleStart = -1 - timer._onTimeout(timer._timerArg) - } - - if (timer._state === TO_BE_CLEARED) { - timer._state = NOT_IN_LIST - - // Move the last element to the current index and decrement len if it is - // not the only element in the array. - if (--len !== 0) { - fastTimers[idx] = fastTimers[len] - } - } else { - ++idx - } - } - - // Set the length of the fastTimers array to the new length and thus - // removing the excess FastTimers elements from the array. - fastTimers.length = len - - // If there are still active FastTimers in the array, refresh the Timer. - // If there are no active FastTimers, the timer will be refreshed again - // when a new FastTimer is instantiated. - if (fastTimers.length !== 0) { - refreshTimeout() - } -} - -function refreshTimeout () { - // If the fastNowTimeout is already set and the Timer has the refresh()- - // method available, call it to refresh the timer. - // Some timer objects returned by setTimeout may not have a .refresh() - // method (e.g. mocked timers in tests). - if (fastNowTimeout?.refresh) { - fastNowTimeout.refresh() - // fastNowTimeout is not instantiated yet or refresh is not availabe, - // create a new Timer. - } else { - clearTimeout(fastNowTimeout) - fastNowTimeout = setTimeout(onTick, TICK_MS) - // If the Timer has an unref method, call it to allow the process to exit, - // if there are no other active handles. When using fake timers or mocked - // environments (like Jest), .unref() may not be defined, - fastNowTimeout?.unref() - } -} - -/** - * The `FastTimer` class is a data structure designed to store and manage - * timer information. - */ -class FastTimer { - [kFastTimer] = true - - /** - * The state of the timer, which can be one of the following: - * - NOT_IN_LIST (-2) - * - TO_BE_CLEARED (-1) - * - PENDING (0) - * - ACTIVE (1) - * - * @type {-2|-1|0|1} - * @private - */ - _state = NOT_IN_LIST - - /** - * The number of milliseconds to wait before calling the callback. - * - * @type {number} - * @private - */ - _idleTimeout = -1 - - /** - * The time in milliseconds when the timer was started. This value is used to - * calculate when the timer should expire. - * - * @type {number} - * @default -1 - * @private - */ - _idleStart = -1 - - /** - * The function to be executed when the timer expires. - * @type {Function} - * @private - */ - _onTimeout - - /** - * The argument to be passed to the callback when the timer expires. - * - * @type {*} - * @private - */ - _timerArg - - /** - * @constructor - * @param {Function} callback A function to be executed after the timer - * expires. - * @param {number} delay The time, in milliseconds that the timer should wait - * before the specified function or code is executed. - * @param {*} arg - */ - constructor (callback, delay, arg) { - this._onTimeout = callback - this._idleTimeout = delay - this._timerArg = arg - - this.refresh() - } - - /** - * Sets the timer's start time to the current time, and reschedules the timer - * to call its callback at the previously specified duration adjusted to the - * current time. - * Using this on a timer that has already called its callback will reactivate - * the timer. - * - * @returns {void} - */ - refresh () { - // In the special case that the timer is not in the list of active timers, - // add it back to the array to be processed in the next tick by the onTick - // function. - if (this._state === NOT_IN_LIST) { - fastTimers.push(this) - } - - // If the timer is the only active timer, refresh the fastNowTimeout for - // better resolution. - if (!fastNowTimeout || fastTimers.length === 1) { - refreshTimeout() - } - - // Setting the state to PENDING will cause the timer to be reset in the - // next tick by the onTick function. - this._state = PENDING - } - - /** - * The `clear` method cancels the timer, preventing it from executing. - * - * @returns {void} - * @private - */ - clear () { - // Set the state to TO_BE_CLEARED to mark the timer for removal in the next - // tick by the onTick function. - this._state = TO_BE_CLEARED - - // Reset the _idleStart value to -1 to indicate that the timer is no longer - // active. - this._idleStart = -1 - } -} - -/** - * This module exports a setTimeout and clearTimeout function that can be - * used as a drop-in replacement for the native functions. - */ -module.exports = { - /** - * The setTimeout() method sets a timer which executes a function once the - * timer expires. - * @param {Function} callback A function to be executed after the timer - * expires. - * @param {number} delay The time, in milliseconds that the timer should - * wait before the specified function or code is executed. - * @param {*} [arg] An optional argument to be passed to the callback function - * when the timer expires. - * @returns {NodeJS.Timeout|FastTimer} - */ - setTimeout (callback, delay, arg) { - // If the delay is less than or equal to the RESOLUTION_MS value return a - // native Node.js Timer instance. - return delay <= RESOLUTION_MS - ? setTimeout(callback, delay, arg) - : new FastTimer(callback, delay, arg) - }, - /** - * The clearTimeout method cancels an instantiated Timer previously created - * by calling setTimeout. - * - * @param {NodeJS.Timeout|FastTimer} timeout - */ - clearTimeout (timeout) { - // If the timeout is a FastTimer, call its own clear method. - if (timeout[kFastTimer]) { - /** - * @type {FastTimer} - */ - timeout.clear() - // Otherwise it is an instance of a native NodeJS.Timeout, so call the - // Node.js native clearTimeout function. - } else { - clearTimeout(timeout) - } - }, - /** - * The setFastTimeout() method sets a fastTimer which executes a function once - * the timer expires. - * @param {Function} callback A function to be executed after the timer - * expires. - * @param {number} delay The time, in milliseconds that the timer should - * wait before the specified function or code is executed. - * @param {*} [arg] An optional argument to be passed to the callback function - * when the timer expires. - * @returns {FastTimer} - */ - setFastTimeout (callback, delay, arg) { - return new FastTimer(callback, delay, arg) - }, - /** - * The clearTimeout method cancels an instantiated FastTimer previously - * created by calling setFastTimeout. - * - * @param {FastTimer} timeout - */ - clearFastTimeout (timeout) { - timeout.clear() - }, - /** - * The now method returns the value of the internal fast timer clock. - * - * @returns {number} - */ - now () { - return fastNow - }, - /** - * Trigger the onTick function to process the fastTimers array. - * Exported for testing purposes only. - * Marking as deprecated to discourage any use outside of testing. - * @deprecated - * @param {number} [delay=0] The delay in milliseconds to add to the now value. - */ - tick (delay = 0) { - fastNow += delay - RESOLUTION_MS + 1 - onTick() - onTick() - }, - /** - * Reset FastTimers. - * Exported for testing purposes only. - * Marking as deprecated to discourage any use outside of testing. - * @deprecated - */ - reset () { - fastNow = 0 - fastTimers.length = 0 - clearTimeout(fastNowTimeout) - fastNowTimeout = null - }, - /** - * Exporting for testing purposes only. - * Marking as deprecated to discourage any use outside of testing. - * @deprecated - */ - kFastTimer -} |
