@ljharb/now
Advanced tools
| declare function now(): number; | ||
| export = now; |
+24
| 'use strict'; | ||
| var callBind = require('call-bind-apply-helpers'); | ||
| var callBound = require('call-bound'); | ||
| var GetIntrinsic = require('get-intrinsic'); | ||
| var $getTime = callBound('Date.prototype.getTime'); | ||
| var $Date = GetIntrinsic('%Date%'); | ||
| var $now = GetIntrinsic('%Date.now%', true); | ||
| /** @type {import('./browser')} */ | ||
| module.exports = (function () { | ||
| if ( | ||
| typeof performance !== 'undefined' | ||
| && performance | ||
| && typeof performance.now === 'function' | ||
| ) { | ||
| return callBind([performance.now, performance]); | ||
| } | ||
| return $now || function now() { | ||
| return $getTime(new $Date()); | ||
| }; | ||
| }()); |
| declare function now(): number; | ||
| export default now; |
| import { performance } from 'perf_hooks'; | ||
| import callBind from 'call-bind-apply-helpers'; | ||
| export default callBind([performance.now, performance]); |
+7
-0
@@ -8,2 +8,9 @@ # Changelog | ||
| ## [v1.0.1](https://github.com/ljharb/now/compare/v1.0.0...v1.0.1) - 2026-06-08 | ||
| ### Commits | ||
| - [Refactor] add multiple entry points for smaller bundles [`b4be113`](https://github.com/ljharb/now/commit/b4be113c6b0ffb285c24b7f4f875e0524f72ae90) | ||
| - [Tests] use `require-stash` instead of a local `rerequire` helper [`2971bf9`](https://github.com/ljharb/now/commit/2971bf9d5a301e95c65cc057bc4681adbd415f93) | ||
| ## v1.0.0 - 2026-06-08 | ||
@@ -10,0 +17,0 @@ |
@@ -9,7 +9,2 @@ import ljharb from '@ljharb/eslint-config/flat'; | ||
| 'id-length': 'off', | ||
| }, | ||
| }, | ||
| { | ||
| files: ['index.js'], | ||
| rules: { | ||
| 'new-cap': [ | ||
@@ -20,2 +15,3 @@ 'error', { | ||
| ], | ||
| 'no-extra-parens': 'off', | ||
| 'no-magic-numbers': 'off', | ||
@@ -22,0 +18,0 @@ }, |
+2
-3
@@ -7,4 +7,3 @@ 'use strict'; | ||
| var getTime = callBound('Date.prototype.getTime'); | ||
| var $getTime = callBound('Date.prototype.getTime'); | ||
| var $Date = GetIntrinsic('%Date%'); | ||
@@ -33,4 +32,4 @@ var $now = GetIntrinsic('%Date.now%', true); | ||
| return $now || function now() { | ||
| return getTime(new $Date()); | ||
| return $getTime(new $Date()); | ||
| }; | ||
| }()); |
+13
-3
| { | ||
| "name": "@ljharb/now", | ||
| "version": "1.0.0", | ||
| "version": "1.0.1", | ||
| "description": "The current time in milliseconds, from the most precise monotonic clock available (`performance.now` → `process.hrtime` → `Date.now` → `new Date().getTime()`), for measuring elapsed time.", | ||
| "main": "index.js", | ||
| "browser": "browser.js", | ||
| "exports": { | ||
| ".": "./index.js", | ||
| ".": [ | ||
| { | ||
| "browser": "./browser.js", | ||
| "import": "./index.mjs", | ||
| "default": "./index.js" | ||
| }, | ||
| "./index.js" | ||
| ], | ||
| "./package.json": "./package.json" | ||
@@ -61,2 +69,3 @@ }, | ||
| "@types/node": "^25.9.2", | ||
| "@types/semver": "^6.2.7", | ||
| "@types/tape": "^5.8.1", | ||
@@ -71,4 +80,5 @@ "auto-changelog": "^2.6.0", | ||
| "nyc": "^10.3.2", | ||
| "resolve": "^2.0.0-next.7", | ||
| "require-stash": "^1.0.0", | ||
| "safe-publish-latest": "^2.0.0", | ||
| "semver": "^6.3.1", | ||
| "tape": "^5.9.0", | ||
@@ -75,0 +85,0 @@ "typescript": "next" |
+48
-28
| 'use strict'; | ||
| /** @template {object} T @typedef {Record<keyof T, T[keyof T]>} AsRecord */ | ||
| var test = require('tape'); | ||
| var mockProperty = require('mock-property'); | ||
| var rerequire = require('./rerequire'); | ||
| var semver = require('semver'); | ||
| var requireStash = require('require-stash'); | ||
| var hasProcess = typeof process !== 'undefined' | ||
| && !!process | ||
| && typeof process.hrtime === 'function'; | ||
| var browserNow = require('../browser'); | ||
| var hasHrtime = semver.satisfies(process.version, '>= 0.7.6'); | ||
| test('now', function (t) { | ||
@@ -24,9 +27,33 @@ var now = require('../'); | ||
| test('browser', function (t) { | ||
| t.equal(typeof browserNow, 'function', 'is a function'); | ||
| t.equal(typeof browserNow(), 'number', 'returns a number'); | ||
| var a = browserNow(); | ||
| var b = browserNow(); | ||
| t.ok(b >= a, 'is non-decreasing'); | ||
| t.end(); | ||
| }); | ||
| test('browser, without performance', function (t) { | ||
| t.teardown(mockProperty(global, 'performance', { value: undefined })); | ||
| t.teardown(requireStash(__dirname, '../browser')); | ||
| /** @type {import('../browser')} */ | ||
| var bNow = require('../browser'); | ||
| t.equal(bNow, Date.now, 'falls back to Date.now'); | ||
| t.equal(typeof bNow(), 'number', 'returns a number'); | ||
| t.end(); | ||
| }); | ||
| test('fallback tiers', function (t) { | ||
| t.test('process.hrtime tier', { skip: !hasProcess }, function (st) { | ||
| t.test('process.hrtime tier', { skip: !hasHrtime }, function (st) { | ||
| st.teardown(mockProperty(global, 'performance', { value: undefined })); | ||
| st.teardown(function () { rerequire(__dirname, '../'); }); | ||
| st.teardown(requireStash(__dirname, '../')); | ||
| /** @type {import('../')} */ | ||
| var now = rerequire(__dirname, '../'); | ||
| var now = require('../'); | ||
@@ -40,14 +67,13 @@ st.equal(typeof now(), 'number', 'returns a number via process.hrtime'); | ||
| st.teardown(mockProperty(global, 'performance', { value: undefined })); | ||
| if (hasProcess) { | ||
| if (hasHrtime) { | ||
| st.teardown(mockProperty( | ||
| /** @type {Record<keyof typeof process, typeof process[keyof typeof process]>} */ | ||
| (process), | ||
| /** @type {AsRecord<typeof process>} */ (process), | ||
| 'hrtime', | ||
| { value: undefined } | ||
| { 'delete': true } | ||
| )); | ||
| } | ||
| st.teardown(function () { rerequire(__dirname, '../'); }); | ||
| st.teardown(requireStash(__dirname, '../')); | ||
| /** @type {import('../')} */ | ||
| var actual = rerequire(__dirname, '../'); | ||
| var actual = require('../'); | ||
@@ -61,26 +87,20 @@ st.equal(actual, Date.now, 'is Date.now'); | ||
| t.test('new Date().getTime() tier', function (st) { | ||
| st.teardown(mockProperty(global, 'performance', { value: undefined })); | ||
| st.teardown(mockProperty(global, 'performance', { 'delete': true })); | ||
| st.teardown(mockProperty( | ||
| /** @type {Record<keyof DateConstructor, DateConstructor[keyof DateConstructor]>} */ | ||
| (Date), | ||
| /** @type {AsRecord<DateConstructor>} */ (Date), | ||
| 'now', | ||
| { value: undefined } | ||
| { 'delete': true } | ||
| )); | ||
| if (hasProcess) { | ||
| if (hasHrtime) { | ||
| st.teardown(mockProperty( | ||
| /** @type {Record<keyof typeof process, typeof process[keyof typeof process]>} */ | ||
| (process), | ||
| /** @type {AsRecord<typeof process>} */ (process), | ||
| 'hrtime', | ||
| { value: undefined } | ||
| { 'delete': true } | ||
| )); | ||
| } | ||
| st.teardown(function () { | ||
| rerequire(__dirname, 'get-intrinsic'); | ||
| rerequire(__dirname, '../'); | ||
| }); | ||
| st.teardown(requireStash(__dirname, 'get-intrinsic')); | ||
| st.teardown(requireStash(__dirname, '../')); | ||
| rerequire(__dirname, 'get-intrinsic'); | ||
| /** @type {import('../')} */ | ||
| var actual = rerequire(__dirname, '../'); | ||
| var actual = require('../'); | ||
@@ -87,0 +107,0 @@ st.equal(typeof actual(), 'number', 'returns a number via new Date().getTime()'); |
| 'use strict'; | ||
| var resolve = require('resolve'); | ||
| /** | ||
| * @template T | ||
| * @param {string} dirname | ||
| * @param {string} id | ||
| * @returns {T} | ||
| */ | ||
| module.exports = function rerequire(dirname, id) { | ||
| var resolved = resolve.sync(id, { basedir: dirname }); | ||
| delete require.cache[resolved]; | ||
| return require(resolved); | ||
| }; |
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
12251
14.76%17
21.43%172
13.16%20
11.11%