{"version":3,"file":"time.mjs","names":[],"sources":["../../src/entries/time.ts"],"sourcesContent":["/** One second in milliseconds. */\nexport const ONE_SECOND = 1000\n\n/** One minute in milliseconds. */\nexport const ONE_MINUTE = 60 * ONE_SECOND\n\n/** One hour in milliseconds. */\nexport const ONE_HOUR = 60 * ONE_MINUTE\n\n/** One day in milliseconds. */\nexport const ONE_DAY = 24 * 60 * 60 * 1000\n\n/** One year in milliseconds. */\nexport const ONE_YEAR = 365 * 24 * 60 * 60 * 1000\n\n/** Duration in milliseconds. */\nexport type Duration = number & { d: 'Duration in ms' }\n\n/** Duration in nanoseconds (used by the server-side event format). */\nexport type ServerDuration = number & { s: 'Duration in ns' }\n\n/** Unix epoch timestamp in milliseconds. */\nexport type TimeStamp = number & { t: 'Epoch time' }\n\n/**\n * Time relative to the navigation start, in milliseconds. Used for timing events relative to\n * when the page was loaded (sourced from `performance.now()`).\n */\nexport type RelativeTime = number & { r: 'Time relative to navigation start' } & { d: 'Duration in ms' }\n\n/** Pair of a relative time and its corresponding absolute timestamp. */\nexport interface ClocksState {\n  relative: RelativeTime\n  timeStamp: TimeStamp\n}\n\n/**\n * Returns the current time as a Unix timestamp in milliseconds.\n *\n * Prefer this over `Date.now()` because some environments incorrectly polyfill `Date.now` —\n * for example, old versions of `datejs` patched it to return a `Date` instance instead of a\n * number, which silently breaks arithmetic. `new Date().getTime()` is unaffected by such patches.\n *\n * @returns Current Unix timestamp in milliseconds.\n */\nexport function dateNow(): number {\n  return new Date().getTime()\n}\n\n/**\n * Returns the current time as a {@link TimeStamp}.\n *\n * @returns Current Unix timestamp in milliseconds, typed as {@link TimeStamp}.\n */\nexport function timeStampNow(): TimeStamp {\n  return dateNow() as TimeStamp\n}\n\n/**\n * Computes the elapsed duration between two timestamps or relative times.\n *\n * @param start - The start time.\n * @param end - The end time.\n * @returns The elapsed duration in milliseconds.\n */\nexport function elapsed(start: TimeStamp, end: TimeStamp): Duration\nexport function elapsed(start: RelativeTime, end: RelativeTime): Duration\nexport function elapsed(start: number, end: number) {\n  return (end - start) as Duration\n}\n\n/**\n * Converts a {@link Duration} (milliseconds) to a {@link ServerDuration} (nanoseconds).\n *\n * @param duration - The duration in milliseconds to convert.\n * @returns The duration in nanoseconds, or `undefined` if the input is `undefined`.\n */\nexport function toServerDuration(duration: Duration): ServerDuration\nexport function toServerDuration(duration: Duration | undefined): ServerDuration | undefined\nexport function toServerDuration(duration: Duration | undefined) {\n  if (typeof duration !== 'number') {\n    return duration\n  }\n  return Math.round(duration * 1e6) as ServerDuration\n}\n\n/**\n * Adds two numeric time values, preserving the branded type of the result.\n *\n * @returns `a + b` typed as `TimeStamp`, `RelativeTime`, or `Duration` depending on the overload.\n */\nexport function addDuration(a: TimeStamp, b: Duration): TimeStamp\nexport function addDuration(a: RelativeTime, b: Duration): RelativeTime\nexport function addDuration(a: Duration, b: Duration): Duration\nexport function addDuration(a: number, b: number) {\n  return a + b\n}\n\n/**\n * Returns the current relative time in milliseconds since navigation start, sourced from\n * `performance.now()`. In Node.js (≥16), this is relative to the process start time.\n *\n * @returns Current relative time as a {@link RelativeTime}.\n */\nexport function relativeNow(): RelativeTime {\n  return performance.now() as RelativeTime\n}\n\n/**\n * Returns the current time as both a relative time and an absolute timestamp.\n *\n * @returns A {@link ClocksState} with the current relative and absolute times.\n */\nexport function clocksNow(): ClocksState {\n  return { relative: relativeNow(), timeStamp: timeStampNow() }\n}\n\n/**\n * Returns the clocks state at the navigation/process origin (relative = 0).\n *\n * @returns A {@link ClocksState} with `relative = 0` and the navigation start timestamp.\n */\nexport function clocksOrigin(): ClocksState {\n  return { relative: 0 as RelativeTime, timeStamp: getTimeOrigin() }\n}\n\n/**\n * Converts a relative time to a {@link ClocksState} with a corrected absolute timestamp.\n * Applies a drift correction when the system clock moved forward relative to `performance.now()`.\n *\n * @param relative - The relative time to convert.\n * @returns A {@link ClocksState} with the relative time and its corrected absolute timestamp.\n */\nexport function relativeToClocks(relative: RelativeTime): ClocksState {\n  return { relative, timeStamp: getCorrectedTimeStamp(relative) }\n}\n\n/**\n * Converts an absolute timestamp to a {@link ClocksState} with its corresponding relative time.\n *\n * @param timeStamp - The absolute timestamp to convert.\n * @returns A {@link ClocksState} with the timestamp and its relative time since navigation start.\n */\nexport function timeStampToClocks(timeStamp: TimeStamp): ClocksState {\n  return { relative: toRelativeTime(timeStamp), timeStamp }\n}\n\n/**\n * Converts an absolute timestamp to a relative time since navigation start.\n *\n * @param timestamp - An absolute Unix timestamp.\n * @returns The corresponding {@link RelativeTime} since navigation start.\n */\nexport function toRelativeTime(timestamp: TimeStamp): RelativeTime {\n  return (timestamp - getTimeOrigin()) as RelativeTime\n}\n\n/**\n * Converts a relative time since navigation start to an absolute timestamp.\n *\n * @param relativeTime - Time in milliseconds since navigation start.\n * @returns The corresponding absolute {@link TimeStamp}.\n */\nexport function toTimeStamp(relativeTime: RelativeTime): TimeStamp {\n  return Math.round(addDuration(getTimeOrigin(), relativeTime)) as TimeStamp\n}\n\n/**\n * Returns `true` if the given value is more likely a relative time than an absolute timestamp.\n * Heuristic: values smaller than one year are treated as relative.\n *\n * @param time - A value that may be either a {@link RelativeTime} or a {@link TimeStamp}.\n */\nexport function isRelativeTime(time: RelativeTime | TimeStamp): time is RelativeTime {\n  return time < ONE_YEAR\n}\n\n/**\n * Returns the drift in milliseconds between `Date.now()` and `performance.now()` relative to\n * navigation start. A positive value means the system clock ran ahead of the performance timer.\n *\n * @returns Clock drift in milliseconds.\n */\nexport function clockDrift(): number {\n  return Math.round(dateNow() - addDuration(getTimeOrigin(), performance.now() as Duration))\n}\n\n/**\n * Time origin slightly changes on some rare cases — cache it.\n */\nlet timeOrigin: TimeStamp | undefined\n\n/**\n * Returns the time origin — the start of the current navigation in browsers, or the process\n * start time in Node.js.\n *\n * Prefers `performance.timing.navigationStart` over `performance.timeOrigin` because\n * `timeOrigin` can be much farther in the past than the actual navigation start (Firefox 71,\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1429926) and is not supported in Safari <15.\n * Falls back to `performance.timeOrigin` in environments without `performance.timing`\n * (Service Workers, Node.js)\n *\n * @returns The time origin as a {@link TimeStamp}.\n */\nexport function getTimeOrigin(): TimeStamp {\n  if (timeOrigin === undefined) {\n    timeOrigin = (performance.timing?.navigationStart ?? performance.timeOrigin) as TimeStamp\n  }\n  return timeOrigin\n}\n\nfunction getCorrectedTimeStamp(relativeTime: RelativeTime): TimeStamp {\n  const correctedOrigin = (dateNow() - performance.now()) as TimeStamp\n  // apply correction only for positive drift\n  if (correctedOrigin > getTimeOrigin()) {\n    return Math.round(addDuration(correctedOrigin, relativeTime)) as TimeStamp\n  }\n  return toTimeStamp(relativeTime)\n}\n"],"mappings":";;AACA,MAAa,aAAa;;AAG1B,MAAa,aAAa,KAAK;;AAG/B,MAAa,WAAW,KAAK;;AAG7B,MAAa,UAAU,OAAU,KAAK;;AAGtC,MAAa,WAAW,MAAM,KAAK,KAAK,KAAK;;;;;;;;;;AAgC7C,SAAgB,UAAkB;CAChC,wBAAO,IAAI,KAAK,EAAA,CAAE,QAAQ;AAC5B;;;;;;AAOA,SAAgB,eAA0B;CACxC,OAAO,QAAQ;AACjB;AAWA,SAAgB,QAAQ,OAAe,KAAa;CAClD,OAAQ,MAAM;AAChB;AAUA,SAAgB,iBAAiB,UAAgC;CAC/D,IAAI,OAAO,aAAa,UACtB,OAAO;CAET,OAAO,KAAK,MAAM,WAAW,GAAG;AAClC;AAUA,SAAgB,YAAY,GAAW,GAAW;CAChD,OAAO,IAAI;AACb;;;;;;;AAQA,SAAgB,cAA4B;CAC1C,OAAO,YAAY,IAAI;AACzB;;;;;;AAOA,SAAgB,YAAyB;CACvC,OAAO;EAAE,UAAU,YAAY;EAAG,WAAW,aAAa;CAAE;AAC9D;;;;;;AAOA,SAAgB,eAA4B;CAC1C,OAAO;EAAE,UAAU;EAAmB,WAAW,cAAc;CAAE;AACnE;;;;;;;;AASA,SAAgB,iBAAiB,UAAqC;CACpE,OAAO;EAAE;EAAU,WAAW,sBAAsB,QAAQ;CAAE;AAChE;;;;;;;AAQA,SAAgB,kBAAkB,WAAmC;CACnE,OAAO;EAAE,UAAU,eAAe,SAAS;EAAG;CAAU;AAC1D;;;;;;;AAQA,SAAgB,eAAe,WAAoC;CACjE,OAAQ,YAAY,cAAc;AACpC;;;;;;;AAQA,SAAgB,YAAY,cAAuC;CACjE,OAAO,KAAK,MAAM,YAAY,cAAc,GAAG,YAAY,CAAC;AAC9D;;;;;;;AAQA,SAAgB,eAAe,MAAsD;CACnF,OAAO,OAAO;AAChB;;;;;;;AAQA,SAAgB,aAAqB;CACnC,OAAO,KAAK,MAAM,QAAQ,IAAI,YAAY,cAAc,GAAG,YAAY,IAAI,CAAa,CAAC;AAC3F;;;;AAKA,IAAI;;;;;;;;;;;;;AAcJ,SAAgB,gBAA2B;CACzC,IAAI,eAAe,KAAA,GACjB,aAAc,YAAY,QAAQ,mBAAmB,YAAY;CAEnE,OAAO;AACT;AAEA,SAAS,sBAAsB,cAAuC;CACpE,MAAM,kBAAmB,QAAQ,IAAI,YAAY,IAAI;CAErD,IAAI,kBAAkB,cAAc,GAClC,OAAO,KAAK,MAAM,YAAY,iBAAiB,YAAY,CAAC;CAE9D,OAAO,YAAY,YAAY;AACjC"}