diff options
Diffstat (limited to 'frontend-old/node_modules/web-vitals/dist/modules')
88 files changed, 3177 insertions, 0 deletions
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/deprecated.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/deprecated.d.ts new file mode 100644 index 0000000..e29b6dc --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/deprecated.d.ts @@ -0,0 +1,7 @@ +export { +/** + * @deprecated Use `onINP()` instead. + */ +onFID, } from './onFID.js'; +export { FIDThresholds } from '../onFID.js'; +export * from '../types.js'; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/deprecated.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/deprecated.js new file mode 100644 index 0000000..2132ab4 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/deprecated.js @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { +/** + * @deprecated Use `onINP()` instead. + */ +onFID, } from './onFID.js'; +export { FIDThresholds } from '../onFID.js'; +export * from '../types.js'; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/index.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/index.d.ts new file mode 100644 index 0000000..8513e3f --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/index.d.ts @@ -0,0 +1,12 @@ +export { onCLS } from './onCLS.js'; +export { onFCP } from './onFCP.js'; +export { onINP } from './onINP.js'; +export { onLCP } from './onLCP.js'; +export { onTTFB } from './onTTFB.js'; +export { CLSThresholds } from '../onCLS.js'; +export { FCPThresholds } from '../onFCP.js'; +export { INPThresholds } from '../onINP.js'; +export { LCPThresholds } from '../onLCP.js'; +export { TTFBThresholds } from '../onTTFB.js'; +export * from './deprecated.js'; +export * from '../types.js'; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/index.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/index.js new file mode 100644 index 0000000..03702fc --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/index.js @@ -0,0 +1,27 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { onCLS } from './onCLS.js'; +export { onFCP } from './onFCP.js'; +export { onINP } from './onINP.js'; +export { onLCP } from './onLCP.js'; +export { onTTFB } from './onTTFB.js'; +export { CLSThresholds } from '../onCLS.js'; +export { FCPThresholds } from '../onFCP.js'; +export { INPThresholds } from '../onINP.js'; +export { LCPThresholds } from '../onLCP.js'; +export { TTFBThresholds } from '../onTTFB.js'; +export * from './deprecated.js'; +export * from '../types.js'; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onCLS.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onCLS.d.ts new file mode 100644 index 0000000..65e1ca9 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onCLS.d.ts @@ -0,0 +1,23 @@ +import { CLSMetricWithAttribution, ReportOpts } from '../types.js'; +/** + * Calculates the [CLS](https://web.dev/articles/cls) value for the current page and + * calls the `callback` function once the value is ready to be reported, along + * with all `layout-shift` performance entries that were used in the metric + * value calculation. The reported value is a `double` (corresponding to a + * [layout shift score](https://web.dev/articles/cls#layout_shift_score)). + * + * If the `reportAllChanges` configuration option is set to `true`, the + * `callback` function will be called as soon as the value is initially + * determined as well as any time the value changes throughout the page + * lifespan. + * + * _**Important:** CLS should be continually monitored for changes throughout + * the entire lifespan of a page—including if the user returns to the page after + * it's been hidden/backgrounded. However, since browsers often [will not fire + * additional callbacks once the user has backgrounded a + * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden), + * `callback` is always called when the page's visibility state changes to + * hidden. As a result, the `callback` function might be called multiple times + * during the same page load._ + */ +export declare const onCLS: (onReport: (metric: CLSMetricWithAttribution) => void, opts?: ReportOpts) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onCLS.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onCLS.js new file mode 100644 index 0000000..78221fa --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onCLS.js @@ -0,0 +1,74 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { getLoadState } from '../lib/getLoadState.js'; +import { getSelector } from '../lib/getSelector.js'; +import { onCLS as unattributedOnCLS } from '../onCLS.js'; +const getLargestLayoutShiftEntry = (entries) => { + return entries.reduce((a, b) => (a && a.value > b.value ? a : b)); +}; +const getLargestLayoutShiftSource = (sources) => { + return sources.find((s) => s.node && s.node.nodeType === 1) || sources[0]; +}; +const attributeCLS = (metric) => { + // Use an empty object if no other attribution has been set. + let attribution = {}; + if (metric.entries.length) { + const largestEntry = getLargestLayoutShiftEntry(metric.entries); + if (largestEntry && largestEntry.sources && largestEntry.sources.length) { + const largestSource = getLargestLayoutShiftSource(largestEntry.sources); + if (largestSource) { + attribution = { + largestShiftTarget: getSelector(largestSource.node), + largestShiftTime: largestEntry.startTime, + largestShiftValue: largestEntry.value, + largestShiftSource: largestSource, + largestShiftEntry: largestEntry, + loadState: getLoadState(largestEntry.startTime), + }; + } + } + } + // Use Object.assign to set property to keep tsc happy. + const metricWithAttribution = Object.assign(metric, { attribution }); + return metricWithAttribution; +}; +/** + * Calculates the [CLS](https://web.dev/articles/cls) value for the current page and + * calls the `callback` function once the value is ready to be reported, along + * with all `layout-shift` performance entries that were used in the metric + * value calculation. The reported value is a `double` (corresponding to a + * [layout shift score](https://web.dev/articles/cls#layout_shift_score)). + * + * If the `reportAllChanges` configuration option is set to `true`, the + * `callback` function will be called as soon as the value is initially + * determined as well as any time the value changes throughout the page + * lifespan. + * + * _**Important:** CLS should be continually monitored for changes throughout + * the entire lifespan of a page—including if the user returns to the page after + * it's been hidden/backgrounded. However, since browsers often [will not fire + * additional callbacks once the user has backgrounded a + * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden), + * `callback` is always called when the page's visibility state changes to + * hidden. As a result, the `callback` function might be called multiple times + * during the same page load._ + */ +export const onCLS = (onReport, opts) => { + unattributedOnCLS((metric) => { + const metricWithAttribution = attributeCLS(metric); + onReport(metricWithAttribution); + }, opts); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFCP.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFCP.d.ts new file mode 100644 index 0000000..b0b7f37 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFCP.d.ts @@ -0,0 +1,8 @@ +import { FCPMetricWithAttribution, ReportOpts } from '../types.js'; +/** + * Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and + * calls the `callback` function once the value is ready, along with the + * relevant `paint` performance entry used to determine the value. The reported + * value is a `DOMHighResTimeStamp`. + */ +export declare const onFCP: (onReport: (metric: FCPMetricWithAttribution) => void, opts?: ReportOpts) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFCP.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFCP.js new file mode 100644 index 0000000..06e87f6 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFCP.js @@ -0,0 +1,57 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { getBFCacheRestoreTime } from '../lib/bfcache.js'; +import { getLoadState } from '../lib/getLoadState.js'; +import { getNavigationEntry } from '../lib/getNavigationEntry.js'; +import { onFCP as unattributedOnFCP } from '../onFCP.js'; +const attributeFCP = (metric) => { + // Use a default object if no other attribution has been set. + let attribution = { + timeToFirstByte: 0, + firstByteToFCP: metric.value, + loadState: getLoadState(getBFCacheRestoreTime()), + }; + if (metric.entries.length) { + const navigationEntry = getNavigationEntry(); + const fcpEntry = metric.entries[metric.entries.length - 1]; + if (navigationEntry) { + const activationStart = navigationEntry.activationStart || 0; + const ttfb = Math.max(0, navigationEntry.responseStart - activationStart); + attribution = { + timeToFirstByte: ttfb, + firstByteToFCP: metric.value - ttfb, + loadState: getLoadState(metric.entries[0].startTime), + navigationEntry, + fcpEntry, + }; + } + } + // Use Object.assign to set property to keep tsc happy. + const metricWithAttribution = Object.assign(metric, { attribution }); + return metricWithAttribution; +}; +/** + * Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and + * calls the `callback` function once the value is ready, along with the + * relevant `paint` performance entry used to determine the value. The reported + * value is a `DOMHighResTimeStamp`. + */ +export const onFCP = (onReport, opts) => { + unattributedOnFCP((metric) => { + const metricWithAttribution = attributeFCP(metric); + onReport(metricWithAttribution); + }, opts); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFID.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFID.d.ts new file mode 100644 index 0000000..b910f15 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFID.d.ts @@ -0,0 +1,11 @@ +import { FIDMetricWithAttribution, ReportOpts } from '../types.js'; +/** + * Calculates the [FID](https://web.dev/articles/fid) value for the current page and + * calls the `callback` function once the value is ready, along with the + * relevant `first-input` performance entry used to determine the value. The + * reported value is a `DOMHighResTimeStamp`. + * + * _**Important:** since FID is only reported after the user interacts with the + * page, it's possible that it will not be reported for some page loads._ + */ +export declare const onFID: (onReport: (metric: FIDMetricWithAttribution) => void, opts?: ReportOpts) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFID.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFID.js new file mode 100644 index 0000000..52f1ddc --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFID.js @@ -0,0 +1,46 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { getLoadState } from '../lib/getLoadState.js'; +import { getSelector } from '../lib/getSelector.js'; +import { onFID as unattributedOnFID } from '../onFID.js'; +const attributeFID = (metric) => { + const fidEntry = metric.entries[0]; + const attribution = { + eventTarget: getSelector(fidEntry.target), + eventType: fidEntry.name, + eventTime: fidEntry.startTime, + eventEntry: fidEntry, + loadState: getLoadState(fidEntry.startTime), + }; + // Use Object.assign to set property to keep tsc happy. + const metricWithAttribution = Object.assign(metric, { attribution }); + return metricWithAttribution; +}; +/** + * Calculates the [FID](https://web.dev/articles/fid) value for the current page and + * calls the `callback` function once the value is ready, along with the + * relevant `first-input` performance entry used to determine the value. The + * reported value is a `DOMHighResTimeStamp`. + * + * _**Important:** since FID is only reported after the user interacts with the + * page, it's possible that it will not be reported for some page loads._ + */ +export const onFID = (onReport, opts) => { + unattributedOnFID((metric) => { + const metricWithAttribution = attributeFID(metric); + onReport(metricWithAttribution); + }, opts); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onINP.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onINP.d.ts new file mode 100644 index 0000000..217faa0 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onINP.d.ts @@ -0,0 +1,30 @@ +import { INPMetricWithAttribution, ReportOpts } from '../types.js'; +export declare const interactionTargetMap: Map<number, Node>; +/** + * Calculates the [INP](https://web.dev/articles/inp) value for the current + * page and calls the `callback` function once the value is ready, along with + * the `event` performance entries reported for that interaction. The reported + * value is a `DOMHighResTimeStamp`. + * + * A custom `durationThreshold` configuration option can optionally be passed to + * control what `event-timing` entries are considered for INP reporting. The + * default threshold is `40`, which means INP scores of less than 40 are + * reported as 0. Note that this will not affect your 75th percentile INP value + * unless that value is also less than 40 (well below the recommended + * [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold). + * + * If the `reportAllChanges` configuration option is set to `true`, the + * `callback` function will be called as soon as the value is initially + * determined as well as any time the value changes throughout the page + * lifespan. + * + * _**Important:** INP should be continually monitored for changes throughout + * the entire lifespan of a page—including if the user returns to the page after + * it's been hidden/backgrounded. However, since browsers often [will not fire + * additional callbacks once the user has backgrounded a + * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden), + * `callback` is always called when the page's visibility state changes to + * hidden. As a result, the `callback` function might be called multiple times + * during the same page load._ + */ +export declare const onINP: (onReport: (metric: INPMetricWithAttribution) => void, opts?: ReportOpts) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onINP.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onINP.js new file mode 100644 index 0000000..51df8e3 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onINP.js @@ -0,0 +1,256 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { getLoadState } from '../lib/getLoadState.js'; +import { getSelector } from '../lib/getSelector.js'; +import { longestInteractionList, entryPreProcessingCallbacks, longestInteractionMap, } from '../lib/interactions.js'; +import { observe } from '../lib/observe.js'; +import { whenIdle } from '../lib/whenIdle.js'; +import { onINP as unattributedOnINP } from '../onINP.js'; +// The maximum number of previous frames for which data is kept. +// Storing data about previous frames is necessary to handle cases where event +// and LoAF entries are dispatched out of order, and so a buffer of previous +// frame data is needed to determine various bits of INP attribution once all +// the frame-related data has come in. +// In most cases this out-of-order data is only off by a frame or two, so +// keeping the most recent 50 should be more than sufficient. +const MAX_PREVIOUS_FRAMES = 50; +// A PerformanceObserver, observing new `long-animation-frame` entries. +// If this variable is defined it means the browser supports LoAF. +let loafObserver; +// A list of LoAF entries that have been dispatched and could potentially +// intersect with the INP candidate interaction. Note that periodically this +// list is cleaned up and entries that are known to not match INP are removed. +let pendingLoAFs = []; +// An array of groups of all the event timing entries that occurred within a +// particular frame. Note that periodically this array is cleaned up and entries +// that are known to not match INP are removed. +let pendingEntriesGroups = []; +// The `processingEnd` time of most recently-processed event, chronologically. +let latestProcessingEnd = 0; +// A WeakMap to look up the event-timing-entries group of a given entry. +// Note that this only maps from "important" entries: either the first input or +// those with an `interactionId`. +const entryToEntriesGroupMap = new WeakMap(); +// A mapping of interactionIds to the target Node. +export const interactionTargetMap = new Map(); +// A reference to the idle task used to clean up entries from the above +// variables. If the value is -1 it means no task is queue, and if it's +// greater than -1 the value corresponds to the idle callback handle. +let idleHandle = -1; +/** + * Adds new LoAF entries to the `pendingLoAFs` list. + */ +const handleLoAFEntries = (entries) => { + pendingLoAFs = pendingLoAFs.concat(entries); + queueCleanup(); +}; +// Get a reference to the interaction target element in case it's removed +// from the DOM later. +const saveInteractionTarget = (entry) => { + if (entry.interactionId && + entry.target && + !interactionTargetMap.has(entry.interactionId)) { + interactionTargetMap.set(entry.interactionId, entry.target); + } +}; +/** + * Groups entries that were presented within the same animation frame by + * a common `renderTime`. This function works by referencing + * `pendingEntriesGroups` and using an existing render time if one is found + * (otherwise creating a new one). This function also adds all interaction + * entries to an `entryToRenderTimeMap` WeakMap so that the "grouped" entries + * can be looked up later. + */ +const groupEntriesByRenderTime = (entry) => { + const renderTime = entry.startTime + entry.duration; + let group; + latestProcessingEnd = Math.max(latestProcessingEnd, entry.processingEnd); + // Iterate over all previous render times in reverse order to find a match. + // Go in reverse since the most likely match will be at the end. + for (let i = pendingEntriesGroups.length - 1; i >= 0; i--) { + const potentialGroup = pendingEntriesGroups[i]; + // If a group's render time is within 8ms of the entry's render time, + // assume they were part of the same frame and add it to the group. + if (Math.abs(renderTime - potentialGroup.renderTime) <= 8) { + group = potentialGroup; + group.startTime = Math.min(entry.startTime, group.startTime); + group.processingStart = Math.min(entry.processingStart, group.processingStart); + group.processingEnd = Math.max(entry.processingEnd, group.processingEnd); + group.entries.push(entry); + break; + } + } + // If there was no matching group, assume this is a new frame. + if (!group) { + group = { + startTime: entry.startTime, + processingStart: entry.processingStart, + processingEnd: entry.processingEnd, + renderTime, + entries: [entry], + }; + pendingEntriesGroups.push(group); + } + // Store the grouped render time for this entry for reference later. + if (entry.interactionId || entry.entryType === 'first-input') { + entryToEntriesGroupMap.set(entry, group); + } + queueCleanup(); +}; +const queueCleanup = () => { + // Queue cleanup of entries that are not part of any INP candidates. + if (idleHandle < 0) { + idleHandle = whenIdle(cleanupEntries); + } +}; +const cleanupEntries = () => { + // Delete any stored interaction target elements if they're not part of one + // of the 10 longest interactions. + if (interactionTargetMap.size > 10) { + interactionTargetMap.forEach((_, key) => { + if (!longestInteractionMap.has(key)) { + interactionTargetMap.delete(key); + } + }); + } + // Keep all render times that are part of a pending INP candidate or + // that occurred within the 50 most recently-dispatched groups of events. + const longestInteractionGroups = longestInteractionList.map((i) => { + return entryToEntriesGroupMap.get(i.entries[0]); + }); + const minIndex = pendingEntriesGroups.length - MAX_PREVIOUS_FRAMES; + pendingEntriesGroups = pendingEntriesGroups.filter((group, index) => { + if (index >= minIndex) + return true; + return longestInteractionGroups.includes(group); + }); + // Keep all pending LoAF entries that either: + // 1) intersect with entries in the newly cleaned up `pendingEntriesGroups` + // 2) occur after the most recently-processed event entry (for up to MAX_PREVIOUS_FRAMES) + const loafsToKeep = new Set(); + for (let i = 0; i < pendingEntriesGroups.length; i++) { + const group = pendingEntriesGroups[i]; + getIntersectingLoAFs(group.startTime, group.processingEnd).forEach((loaf) => { + loafsToKeep.add(loaf); + }); + } + const prevFrameIndexCutoff = pendingLoAFs.length - 1 - MAX_PREVIOUS_FRAMES; + // Filter `pendingLoAFs` to preserve LoAF order. + pendingLoAFs = pendingLoAFs.filter((loaf, index) => { + if (loaf.startTime > latestProcessingEnd && index > prevFrameIndexCutoff) { + return true; + } + return loafsToKeep.has(loaf); + }); + // Reset the idle callback handle so it can be queued again. + idleHandle = -1; +}; +entryPreProcessingCallbacks.push(saveInteractionTarget, groupEntriesByRenderTime); +const getIntersectingLoAFs = (start, end) => { + const intersectingLoAFs = []; + for (let i = 0, loaf; (loaf = pendingLoAFs[i]); i++) { + // If the LoAF ends before the given start time, ignore it. + if (loaf.startTime + loaf.duration < start) + continue; + // If the LoAF starts after the given end time, ignore it and all + // subsequent pending LoAFs (because they're in time order). + if (loaf.startTime > end) + break; + // Still here? If so this LoAF intersects with the interaction. + intersectingLoAFs.push(loaf); + } + return intersectingLoAFs; +}; +const attributeINP = (metric) => { + const firstEntry = metric.entries[0]; + const group = entryToEntriesGroupMap.get(firstEntry); + const processingStart = firstEntry.processingStart; + const processingEnd = group.processingEnd; + // Sort the entries in processing time order. + const processedEventEntries = group.entries.sort((a, b) => { + return a.processingStart - b.processingStart; + }); + const longAnimationFrameEntries = getIntersectingLoAFs(firstEntry.startTime, processingEnd); + // The first interaction entry may not have a target defined, so use the + // first one found in the entry list. + // TODO: when the following bug is fixed just use `firstInteractionEntry`. + // https://bugs.chromium.org/p/chromium/issues/detail?id=1367329 + // As a fallback, also check the interactionTargetMap (to account for + // cases where the element is removed from the DOM before reporting happens). + const firstEntryWithTarget = metric.entries.find((entry) => entry.target); + const interactionTargetElement = (firstEntryWithTarget && firstEntryWithTarget.target) || + interactionTargetMap.get(firstEntry.interactionId); + // Since entry durations are rounded to the nearest 8ms, we need to clamp + // the `nextPaintTime` value to be higher than the `processingEnd` or + // end time of any LoAF entry. + const nextPaintTimeCandidates = [ + firstEntry.startTime + firstEntry.duration, + processingEnd, + ].concat(longAnimationFrameEntries.map((loaf) => loaf.startTime + loaf.duration)); + const nextPaintTime = Math.max.apply(Math, nextPaintTimeCandidates); + const attribution = { + interactionTarget: getSelector(interactionTargetElement), + interactionTargetElement: interactionTargetElement, + interactionType: firstEntry.name.startsWith('key') ? 'keyboard' : 'pointer', + interactionTime: firstEntry.startTime, + nextPaintTime: nextPaintTime, + processedEventEntries: processedEventEntries, + longAnimationFrameEntries: longAnimationFrameEntries, + inputDelay: processingStart - firstEntry.startTime, + processingDuration: processingEnd - processingStart, + presentationDelay: Math.max(nextPaintTime - processingEnd, 0), + loadState: getLoadState(firstEntry.startTime), + }; + // Use Object.assign to set property to keep tsc happy. + const metricWithAttribution = Object.assign(metric, { attribution }); + return metricWithAttribution; +}; +/** + * Calculates the [INP](https://web.dev/articles/inp) value for the current + * page and calls the `callback` function once the value is ready, along with + * the `event` performance entries reported for that interaction. The reported + * value is a `DOMHighResTimeStamp`. + * + * A custom `durationThreshold` configuration option can optionally be passed to + * control what `event-timing` entries are considered for INP reporting. The + * default threshold is `40`, which means INP scores of less than 40 are + * reported as 0. Note that this will not affect your 75th percentile INP value + * unless that value is also less than 40 (well below the recommended + * [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold). + * + * If the `reportAllChanges` configuration option is set to `true`, the + * `callback` function will be called as soon as the value is initially + * determined as well as any time the value changes throughout the page + * lifespan. + * + * _**Important:** INP should be continually monitored for changes throughout + * the entire lifespan of a page—including if the user returns to the page after + * it's been hidden/backgrounded. However, since browsers often [will not fire + * additional callbacks once the user has backgrounded a + * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden), + * `callback` is always called when the page's visibility state changes to + * hidden. As a result, the `callback` function might be called multiple times + * during the same page load._ + */ +export const onINP = (onReport, opts) => { + if (!loafObserver) { + loafObserver = observe('long-animation-frame', handleLoAFEntries); + } + unattributedOnINP((metric) => { + const metricWithAttribution = attributeINP(metric); + onReport(metricWithAttribution); + }, opts); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onLCP.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onLCP.d.ts new file mode 100644 index 0000000..caa6ea7 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onLCP.d.ts @@ -0,0 +1,13 @@ +import { LCPMetricWithAttribution, ReportOpts } from '../types.js'; +/** + * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and + * calls the `callback` function once the value is ready (along with the + * relevant `largest-contentful-paint` performance entry used to determine the + * value). The reported value is a `DOMHighResTimeStamp`. + * + * If the `reportAllChanges` configuration option is set to `true`, the + * `callback` function will be called any time a new `largest-contentful-paint` + * performance entry is dispatched, or once the final value of the metric has + * been determined. + */ +export declare const onLCP: (onReport: (metric: LCPMetricWithAttribution) => void, opts?: ReportOpts) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onLCP.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onLCP.js new file mode 100644 index 0000000..269323c --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onLCP.js @@ -0,0 +1,83 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { getNavigationEntry } from '../lib/getNavigationEntry.js'; +import { getSelector } from '../lib/getSelector.js'; +import { onLCP as unattributedOnLCP } from '../onLCP.js'; +const attributeLCP = (metric) => { + // Use a default object if no other attribution has been set. + let attribution = { + timeToFirstByte: 0, + resourceLoadDelay: 0, + resourceLoadDuration: 0, + elementRenderDelay: metric.value, + }; + if (metric.entries.length) { + const navigationEntry = getNavigationEntry(); + if (navigationEntry) { + const activationStart = navigationEntry.activationStart || 0; + const lcpEntry = metric.entries[metric.entries.length - 1]; + const lcpResourceEntry = lcpEntry.url && + performance + .getEntriesByType('resource') + .filter((e) => e.name === lcpEntry.url)[0]; + const ttfb = Math.max(0, navigationEntry.responseStart - activationStart); + const lcpRequestStart = Math.max(ttfb, + // Prefer `requestStart` (if TOA is set), otherwise use `startTime`. + lcpResourceEntry + ? (lcpResourceEntry.requestStart || lcpResourceEntry.startTime) - + activationStart + : 0); + const lcpResponseEnd = Math.max(lcpRequestStart, lcpResourceEntry ? lcpResourceEntry.responseEnd - activationStart : 0); + const lcpRenderTime = Math.max(lcpResponseEnd, lcpEntry.startTime - activationStart); + attribution = { + element: getSelector(lcpEntry.element), + timeToFirstByte: ttfb, + resourceLoadDelay: lcpRequestStart - ttfb, + resourceLoadDuration: lcpResponseEnd - lcpRequestStart, + elementRenderDelay: lcpRenderTime - lcpResponseEnd, + navigationEntry, + lcpEntry, + }; + // Only attribution the URL and resource entry if they exist. + if (lcpEntry.url) { + attribution.url = lcpEntry.url; + } + if (lcpResourceEntry) { + attribution.lcpResourceEntry = lcpResourceEntry; + } + } + } + // Use Object.assign to set property to keep tsc happy. + const metricWithAttribution = Object.assign(metric, { attribution }); + return metricWithAttribution; +}; +/** + * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and + * calls the `callback` function once the value is ready (along with the + * relevant `largest-contentful-paint` performance entry used to determine the + * value). The reported value is a `DOMHighResTimeStamp`. + * + * If the `reportAllChanges` configuration option is set to `true`, the + * `callback` function will be called any time a new `largest-contentful-paint` + * performance entry is dispatched, or once the final value of the metric has + * been determined. + */ +export const onLCP = (onReport, opts) => { + unattributedOnLCP((metric) => { + const metricWithAttribution = attributeLCP(metric); + onReport(metricWithAttribution); + }, opts); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onTTFB.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onTTFB.d.ts new file mode 100644 index 0000000..a39d0ad --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onTTFB.d.ts @@ -0,0 +1,17 @@ +import { TTFBMetricWithAttribution, ReportOpts } from '../types.js'; +/** + * Calculates the [TTFB](https://web.dev/articles/ttfb) value for the + * current page and calls the `callback` function once the page has loaded, + * along with the relevant `navigation` performance entry used to determine the + * value. The reported value is a `DOMHighResTimeStamp`. + * + * Note, this function waits until after the page is loaded to call `callback` + * in order to ensure all properties of the `navigation` entry are populated. + * This is useful if you want to report on other metrics exposed by the + * [Navigation Timing API](https://w3c.github.io/navigation-timing/). For + * example, the TTFB metric starts from the page's [time + * origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it + * includes time spent on DNS lookup, connection negotiation, network latency, + * and server processing time. + */ +export declare const onTTFB: (onReport: (metric: TTFBMetricWithAttribution) => void, opts?: ReportOpts) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onTTFB.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onTTFB.js new file mode 100644 index 0000000..cd0d6bb --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onTTFB.js @@ -0,0 +1,76 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { onTTFB as unattributedOnTTFB } from '../onTTFB.js'; +const attributeTTFB = (metric) => { + // Use a default object if no other attribution has been set. + let attribution = { + waitingDuration: 0, + cacheDuration: 0, + dnsDuration: 0, + connectionDuration: 0, + requestDuration: 0, + }; + if (metric.entries.length) { + const navigationEntry = metric.entries[0]; + const activationStart = navigationEntry.activationStart || 0; + // Measure from workerStart or fetchStart so any service worker startup + // time is included in cacheDuration (which also includes other sw time + // anyway, that cannot be accurately split out cross-browser). + const waitEnd = Math.max((navigationEntry.workerStart || navigationEntry.fetchStart) - + activationStart, 0); + const dnsStart = Math.max(navigationEntry.domainLookupStart - activationStart, 0); + const connectStart = Math.max(navigationEntry.connectStart - activationStart, 0); + const connectEnd = Math.max(navigationEntry.connectEnd - activationStart, 0); + attribution = { + waitingDuration: waitEnd, + cacheDuration: dnsStart - waitEnd, + // dnsEnd usually equals connectStart but use connectStart over dnsEnd + // for dnsDuration in case there ever is a gap. + dnsDuration: connectStart - dnsStart, + connectionDuration: connectEnd - connectStart, + // There is often a gap between connectEnd and requestStart. Attribute + // that to requestDuration so connectionDuration remains 0 for + // service worker controlled requests were connectStart and connectEnd + // are the same. + requestDuration: metric.value - connectEnd, + navigationEntry: navigationEntry, + }; + } + // Use Object.assign to set property to keep tsc happy. + const metricWithAttribution = Object.assign(metric, { attribution }); + return metricWithAttribution; +}; +/** + * Calculates the [TTFB](https://web.dev/articles/ttfb) value for the + * current page and calls the `callback` function once the page has loaded, + * along with the relevant `navigation` performance entry used to determine the + * value. The reported value is a `DOMHighResTimeStamp`. + * + * Note, this function waits until after the page is loaded to call `callback` + * in order to ensure all properties of the `navigation` entry are populated. + * This is useful if you want to report on other metrics exposed by the + * [Navigation Timing API](https://w3c.github.io/navigation-timing/). For + * example, the TTFB metric starts from the page's [time + * origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it + * includes time spent on DNS lookup, connection negotiation, network latency, + * and server processing time. + */ +export const onTTFB = (onReport, opts) => { + unattributedOnTTFB((metric) => { + const metricWithAttribution = attributeTTFB(metric); + onReport(metricWithAttribution); + }, opts); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/deprecated.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/deprecated.d.ts new file mode 100644 index 0000000..84d77ae --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/deprecated.d.ts @@ -0,0 +1,5 @@ +export { +/** + * @deprecated Use `onINP()` instead. + */ +onFID, FIDThresholds, } from './onFID.js'; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/deprecated.js b/frontend-old/node_modules/web-vitals/dist/modules/deprecated.js new file mode 100644 index 0000000..42756b9 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/deprecated.js @@ -0,0 +1,20 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { +/** + * @deprecated Use `onINP()` instead. + */ +onFID, FIDThresholds, } from './onFID.js'; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/index.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/index.d.ts new file mode 100644 index 0000000..dfd2263 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/index.d.ts @@ -0,0 +1,7 @@ +export { onCLS, CLSThresholds } from './onCLS.js'; +export { onFCP, FCPThresholds } from './onFCP.js'; +export { onINP, INPThresholds } from './onINP.js'; +export { onLCP, LCPThresholds } from './onLCP.js'; +export { onTTFB, TTFBThresholds } from './onTTFB.js'; +export * from './deprecated.js'; +export * from './types.js'; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/index.js b/frontend-old/node_modules/web-vitals/dist/modules/index.js new file mode 100644 index 0000000..d374950 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/index.js @@ -0,0 +1,22 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { onCLS, CLSThresholds } from './onCLS.js'; +export { onFCP, FCPThresholds } from './onFCP.js'; +export { onINP, INPThresholds } from './onINP.js'; +export { onLCP, LCPThresholds } from './onLCP.js'; +export { onTTFB, TTFBThresholds } from './onTTFB.js'; +export * from './deprecated.js'; +export * from './types.js'; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/bfcache.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/bfcache.d.ts new file mode 100644 index 0000000..0870fd0 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/bfcache.d.ts @@ -0,0 +1,6 @@ +interface onBFCacheRestoreCallback { + (event: PageTransitionEvent): void; +} +export declare const getBFCacheRestoreTime: () => number; +export declare const onBFCacheRestore: (cb: onBFCacheRestoreCallback) => void; +export {}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/bfcache.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/bfcache.js new file mode 100644 index 0000000..48050e3 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/bfcache.js @@ -0,0 +1,25 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +let bfcacheRestoreTime = -1; +export const getBFCacheRestoreTime = () => bfcacheRestoreTime; +export const onBFCacheRestore = (cb) => { + addEventListener('pageshow', (event) => { + if (event.persisted) { + bfcacheRestoreTime = event.timeStamp; + cb(event); + } + }, true); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/bindReporter.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/bindReporter.d.ts new file mode 100644 index 0000000..54880d6 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/bindReporter.d.ts @@ -0,0 +1,26 @@ +import { MetricType, MetricRatingThresholds } from '../types.js'; +export declare const bindReporter: <MetricName extends "CLS" | "FCP" | "FID" | "INP" | "LCP" | "TTFB">(callback: (metric: Extract<import("../types.js").CLSMetric, { + name: MetricName; +}> | Extract<import("../types.js").FCPMetric, { + name: MetricName; +}> | Extract<import("../types.js").FIDMetric, { + name: MetricName; +}> | Extract<import("../types.js").INPMetric, { + name: MetricName; +}> | Extract<import("../types.js").LCPMetric, { + name: MetricName; +}> | Extract<import("../types.js").TTFBMetric, { + name: MetricName; +}>) => void, metric: Extract<import("../types.js").CLSMetric, { + name: MetricName; +}> | Extract<import("../types.js").FCPMetric, { + name: MetricName; +}> | Extract<import("../types.js").FIDMetric, { + name: MetricName; +}> | Extract<import("../types.js").INPMetric, { + name: MetricName; +}> | Extract<import("../types.js").LCPMetric, { + name: MetricName; +}> | Extract<import("../types.js").TTFBMetric, { + name: MetricName; +}>, thresholds: MetricRatingThresholds, reportAllChanges?: boolean) => (forceReport?: boolean) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/bindReporter.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/bindReporter.js new file mode 100644 index 0000000..e1afbbc --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/bindReporter.js @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const getRating = (value, thresholds) => { + if (value > thresholds[1]) { + return 'poor'; + } + if (value > thresholds[0]) { + return 'needs-improvement'; + } + return 'good'; +}; +export const bindReporter = (callback, metric, thresholds, reportAllChanges) => { + let prevValue; + let delta; + return (forceReport) => { + if (metric.value >= 0) { + if (forceReport || reportAllChanges) { + delta = metric.value - (prevValue || 0); + // Report the metric if there's a non-zero delta or if no previous + // value exists (which can happen in the case of the document becoming + // hidden when the metric value is 0). + // See: https://github.com/GoogleChrome/web-vitals/issues/14 + if (delta || prevValue === undefined) { + prevValue = metric.value; + metric.delta = delta; + metric.rating = getRating(metric.value, thresholds); + callback(metric); + } + } + } + }; +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/doubleRAF.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/doubleRAF.d.ts new file mode 100644 index 0000000..7ac0933 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/doubleRAF.d.ts @@ -0,0 +1 @@ +export declare const doubleRAF: (cb: () => unknown) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/doubleRAF.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/doubleRAF.js new file mode 100644 index 0000000..16da945 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/doubleRAF.js @@ -0,0 +1,18 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export const doubleRAF = (cb) => { + requestAnimationFrame(() => requestAnimationFrame(() => cb())); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/generateUniqueID.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/generateUniqueID.d.ts new file mode 100644 index 0000000..a049ad9 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/generateUniqueID.d.ts @@ -0,0 +1,6 @@ +/** + * Performantly generate a unique, 30-char string by combining a version + * number, the current timestamp with a 13-digit number integer. + * @return {string} + */ +export declare const generateUniqueID: () => string; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/generateUniqueID.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/generateUniqueID.js new file mode 100644 index 0000000..5fabcc6 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/generateUniqueID.js @@ -0,0 +1,23 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Performantly generate a unique, 30-char string by combining a version + * number, the current timestamp with a 13-digit number integer. + * @return {string} + */ +export const generateUniqueID = () => { + return `v4-${Date.now()}-${Math.floor(Math.random() * (9e12 - 1)) + 1e12}`; +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getActivationStart.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/getActivationStart.d.ts new file mode 100644 index 0000000..b9f424e --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getActivationStart.d.ts @@ -0,0 +1 @@ +export declare const getActivationStart: () => number; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getActivationStart.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/getActivationStart.js new file mode 100644 index 0000000..6bfcd5b --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getActivationStart.js @@ -0,0 +1,20 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { getNavigationEntry } from './getNavigationEntry.js'; +export const getActivationStart = () => { + const navEntry = getNavigationEntry(); + return (navEntry && navEntry.activationStart) || 0; +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getLoadState.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/getLoadState.d.ts new file mode 100644 index 0000000..a855155 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getLoadState.d.ts @@ -0,0 +1,2 @@ +import { LoadState } from '../types.js'; +export declare const getLoadState: (timestamp: number) => LoadState; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getLoadState.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/getLoadState.js new file mode 100644 index 0000000..cac5b57 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getLoadState.js @@ -0,0 +1,47 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { getNavigationEntry } from './getNavigationEntry.js'; +export const getLoadState = (timestamp) => { + if (document.readyState === 'loading') { + // If the `readyState` is 'loading' there's no need to look at timestamps + // since the timestamp has to be the current time or earlier. + return 'loading'; + } + else { + const navigationEntry = getNavigationEntry(); + if (navigationEntry) { + if (timestamp < navigationEntry.domInteractive) { + return 'loading'; + } + else if (navigationEntry.domContentLoadedEventStart === 0 || + timestamp < navigationEntry.domContentLoadedEventStart) { + // If the `domContentLoadedEventStart` timestamp has not yet been + // set, or if the given timestamp is less than that value. + return 'dom-interactive'; + } + else if (navigationEntry.domComplete === 0 || + timestamp < navigationEntry.domComplete) { + // If the `domComplete` timestamp has not yet been + // set, or if the given timestamp is less than that value. + return 'dom-content-loaded'; + } + } + } + // If any of the above fail, default to loaded. This could really only + // happy if the browser doesn't support the performance timeline, which + // most likely means this code would never run anyway. + return 'complete'; +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.d.ts new file mode 100644 index 0000000..af6a02b --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.d.ts @@ -0,0 +1 @@ +export declare const getNavigationEntry: () => PerformanceNavigationTiming | void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.js new file mode 100644 index 0000000..94ac68e --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.js @@ -0,0 +1,32 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export const getNavigationEntry = () => { + const navigationEntry = self.performance && + performance.getEntriesByType && + performance.getEntriesByType('navigation')[0]; + // Check to ensure the `responseStart` property is present and valid. + // In some cases no value is reported by the browser (for + // privacy/security reasons), and in other cases (bugs) the value is + // negative or is larger than the current page time. Ignore these cases: + // https://github.com/GoogleChrome/web-vitals/issues/137 + // https://github.com/GoogleChrome/web-vitals/issues/162 + // https://github.com/GoogleChrome/web-vitals/issues/275 + if (navigationEntry && + navigationEntry.responseStart > 0 && + navigationEntry.responseStart < performance.now()) { + return navigationEntry; + } +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getSelector.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/getSelector.d.ts new file mode 100644 index 0000000..494212e --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getSelector.d.ts @@ -0,0 +1 @@ +export declare const getSelector: (node: Node | null | undefined, maxLen?: number) => string; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getSelector.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/getSelector.js new file mode 100644 index 0000000..7b18244 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getSelector.js @@ -0,0 +1,48 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const getName = (node) => { + const name = node.nodeName; + return node.nodeType === 1 + ? name.toLowerCase() + : name.toUpperCase().replace(/^#/, ''); +}; +export const getSelector = (node, maxLen) => { + let sel = ''; + try { + while (node && node.nodeType !== 9) { + const el = node; + const part = el.id + ? '#' + el.id + : getName(el) + + (el.classList && + el.classList.value && + el.classList.value.trim() && + el.classList.value.trim().length + ? '.' + el.classList.value.trim().replace(/\s+/g, '.') + : ''); + if (sel.length + part.length > (maxLen || 100) - 1) + return sel || part; + sel = sel ? part + '>' + sel : part; + if (el.id) + break; + node = el.parentNode; + } + } + catch (err) { + // Do nothing... + } + return sel; +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.d.ts new file mode 100644 index 0000000..0832a05 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.d.ts @@ -0,0 +1,3 @@ +export declare const getVisibilityWatcher: () => { + readonly firstHiddenTime: number; +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.js new file mode 100644 index 0000000..4a052db --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.js @@ -0,0 +1,80 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { onBFCacheRestore } from './bfcache.js'; +let firstHiddenTime = -1; +const initHiddenTime = () => { + // If the document is hidden when this code runs, assume it was always + // hidden and the page was loaded in the background, with the one exception + // that visibility state is always 'hidden' during prerendering, so we have + // to ignore that case until prerendering finishes (see: `prerenderingchange` + // event logic below). + return document.visibilityState === 'hidden' && !document.prerendering + ? 0 + : Infinity; +}; +const onVisibilityUpdate = (event) => { + // If the document is 'hidden' and no previous hidden timestamp has been + // set, update it based on the current event data. + if (document.visibilityState === 'hidden' && firstHiddenTime > -1) { + // If the event is a 'visibilitychange' event, it means the page was + // visible prior to this change, so the event timestamp is the first + // hidden time. + // However, if the event is not a 'visibilitychange' event, then it must + // be a 'prerenderingchange' event, and the fact that the document is + // still 'hidden' from the above check means the tab was activated + // in a background state and so has always been hidden. + firstHiddenTime = event.type === 'visibilitychange' ? event.timeStamp : 0; + // Remove all listeners now that a `firstHiddenTime` value has been set. + removeChangeListeners(); + } +}; +const addChangeListeners = () => { + addEventListener('visibilitychange', onVisibilityUpdate, true); + // IMPORTANT: when a page is prerendering, its `visibilityState` is + // 'hidden', so in order to account for cases where this module checks for + // visibility during prerendering, an additional check after prerendering + // completes is also required. + addEventListener('prerenderingchange', onVisibilityUpdate, true); +}; +const removeChangeListeners = () => { + removeEventListener('visibilitychange', onVisibilityUpdate, true); + removeEventListener('prerenderingchange', onVisibilityUpdate, true); +}; +export const getVisibilityWatcher = () => { + if (firstHiddenTime < 0) { + // If the document is hidden when this code runs, assume it was hidden + // since navigation start. This isn't a perfect heuristic, but it's the + // best we can do until an API is available to support querying past + // visibilityState. + firstHiddenTime = initHiddenTime(); + addChangeListeners(); + // Reset the time on bfcache restores. + onBFCacheRestore(() => { + // Schedule a task in order to track the `visibilityState` once it's + // had an opportunity to change to visible in all browsers. + // https://bugs.chromium.org/p/chromium/issues/detail?id=1133363 + setTimeout(() => { + firstHiddenTime = initHiddenTime(); + addChangeListeners(); + }, 0); + }); + } + return { + get firstHiddenTime() { + return firstHiddenTime; + }, + }; +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/initMetric.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/initMetric.d.ts new file mode 100644 index 0000000..b14f969 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/initMetric.d.ts @@ -0,0 +1,21 @@ +export declare const initMetric: <MetricName extends "CLS" | "FCP" | "FID" | "INP" | "LCP" | "TTFB">(name: MetricName, value?: number) => { + name: MetricName; + value: number; + rating: "good"; + delta: number; + entries: (Extract<import("../types.js").CLSMetric, { + name: MetricName; + }> | Extract<import("../types.js").FCPMetric, { + name: MetricName; + }> | Extract<import("../types.js").FIDMetric, { + name: MetricName; + }> | Extract<import("../types.js").INPMetric, { + name: MetricName; + }> | Extract<import("../types.js").LCPMetric, { + name: MetricName; + }> | Extract<import("../types.js").TTFBMetric, { + name: MetricName; + }>)["entries"]; + id: string; + navigationType: "navigate" | "reload" | "back-forward" | "back-forward-cache" | "prerender" | "restore"; +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/initMetric.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/initMetric.js new file mode 100644 index 0000000..30da54e --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/initMetric.js @@ -0,0 +1,48 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { getBFCacheRestoreTime } from './bfcache.js'; +import { generateUniqueID } from './generateUniqueID.js'; +import { getActivationStart } from './getActivationStart.js'; +import { getNavigationEntry } from './getNavigationEntry.js'; +export const initMetric = (name, value) => { + const navEntry = getNavigationEntry(); + let navigationType = 'navigate'; + if (getBFCacheRestoreTime() >= 0) { + navigationType = 'back-forward-cache'; + } + else if (navEntry) { + if (document.prerendering || getActivationStart() > 0) { + navigationType = 'prerender'; + } + else if (document.wasDiscarded) { + navigationType = 'restore'; + } + else if (navEntry.type) { + navigationType = navEntry.type.replace(/_/g, '-'); + } + } + // Use `entries` type specific for the metric. + const entries = []; + return { + name, + value: typeof value === 'undefined' ? -1 : value, + rating: 'good', // If needed, will be updated when reported. `const` to keep the type from widening to `string`. + delta: 0, + entries, + id: generateUniqueID(), + navigationType, + }; +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/interactions.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/interactions.d.ts new file mode 100644 index 0000000..5db2b71 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/interactions.d.ts @@ -0,0 +1,31 @@ +interface Interaction { + id: number; + latency: number; + entries: PerformanceEventTiming[]; +} +interface EntryPreProcessingHook { + (entry: PerformanceEventTiming): void; +} +export declare const longestInteractionList: Interaction[]; +export declare const longestInteractionMap: Map<number, Interaction>; +export declare const DEFAULT_DURATION_THRESHOLD = 40; +export declare const resetInteractions: () => void; +/** + * Returns the estimated p98 longest interaction based on the stored + * interaction candidates and the interaction count for the current page. + */ +export declare const estimateP98LongestInteraction: () => Interaction; +/** + * A list of callback functions to run before each entry is processed. + * Exposing this list allows the attribution build to hook into the + * entry processing pipeline. + */ +export declare const entryPreProcessingCallbacks: EntryPreProcessingHook[]; +/** + * Takes a performance entry and adds it to the list of worst interactions + * if its duration is long enough to make it among the worst. If the + * entry is part of an existing interaction, it is merged and the latency + * and entries list is updated as needed. + */ +export declare const processInteractionEntry: (entry: PerformanceEventTiming) => void; +export {}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/interactions.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/interactions.js new file mode 100644 index 0000000..0466ef1 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/interactions.js @@ -0,0 +1,107 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { getInteractionCount } from './polyfills/interactionCountPolyfill.js'; +// A list of longest interactions on the page (by latency) sorted so the +// longest one is first. The list is at most MAX_INTERACTIONS_TO_CONSIDER long. +export const longestInteractionList = []; +// A mapping of longest interactions by their interaction ID. +// This is used for faster lookup. +export const longestInteractionMap = new Map(); +// The default `durationThreshold` used across this library for observing +// `event` entries via PerformanceObserver. +export const DEFAULT_DURATION_THRESHOLD = 40; +// Used to store the interaction count after a bfcache restore, since p98 +// interaction latencies should only consider the current navigation. +let prevInteractionCount = 0; +/** + * Returns the interaction count since the last bfcache restore (or for the + * full page lifecycle if there were no bfcache restores). + */ +const getInteractionCountForNavigation = () => { + return getInteractionCount() - prevInteractionCount; +}; +export const resetInteractions = () => { + prevInteractionCount = getInteractionCount(); + longestInteractionList.length = 0; + longestInteractionMap.clear(); +}; +/** + * Returns the estimated p98 longest interaction based on the stored + * interaction candidates and the interaction count for the current page. + */ +export const estimateP98LongestInteraction = () => { + const candidateInteractionIndex = Math.min(longestInteractionList.length - 1, Math.floor(getInteractionCountForNavigation() / 50)); + return longestInteractionList[candidateInteractionIndex]; +}; +// To prevent unnecessary memory usage on pages with lots of interactions, +// store at most 10 of the longest interactions to consider as INP candidates. +const MAX_INTERACTIONS_TO_CONSIDER = 10; +/** + * A list of callback functions to run before each entry is processed. + * Exposing this list allows the attribution build to hook into the + * entry processing pipeline. + */ +export const entryPreProcessingCallbacks = []; +/** + * Takes a performance entry and adds it to the list of worst interactions + * if its duration is long enough to make it among the worst. If the + * entry is part of an existing interaction, it is merged and the latency + * and entries list is updated as needed. + */ +export const processInteractionEntry = (entry) => { + entryPreProcessingCallbacks.forEach((cb) => cb(entry)); + // Skip further processing for entries that cannot be INP candidates. + if (!(entry.interactionId || entry.entryType === 'first-input')) + return; + // The least-long of the 10 longest interactions. + const minLongestInteraction = longestInteractionList[longestInteractionList.length - 1]; + const existingInteraction = longestInteractionMap.get(entry.interactionId); + // Only process the entry if it's possibly one of the ten longest, + // or if it's part of an existing interaction. + if (existingInteraction || + longestInteractionList.length < MAX_INTERACTIONS_TO_CONSIDER || + entry.duration > minLongestInteraction.latency) { + // If the interaction already exists, update it. Otherwise create one. + if (existingInteraction) { + // If the new entry has a longer duration, replace the old entries, + // otherwise add to the array. + if (entry.duration > existingInteraction.latency) { + existingInteraction.entries = [entry]; + existingInteraction.latency = entry.duration; + } + else if (entry.duration === existingInteraction.latency && + entry.startTime === existingInteraction.entries[0].startTime) { + existingInteraction.entries.push(entry); + } + } + else { + const interaction = { + id: entry.interactionId, + latency: entry.duration, + entries: [entry], + }; + longestInteractionMap.set(interaction.id, interaction); + longestInteractionList.push(interaction); + } + // Sort the entries by latency (descending) and keep only the top ten. + longestInteractionList.sort((a, b) => b.latency - a.latency); + if (longestInteractionList.length > MAX_INTERACTIONS_TO_CONSIDER) { + longestInteractionList + .splice(MAX_INTERACTIONS_TO_CONSIDER) + .forEach((i) => longestInteractionMap.delete(i.id)); + } + } +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/observe.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/observe.d.ts new file mode 100644 index 0000000..1c8ba5f --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/observe.d.ts @@ -0,0 +1,20 @@ +interface PerformanceEntryMap { + 'event': PerformanceEventTiming[]; + 'first-input': PerformanceEventTiming[]; + 'layout-shift': LayoutShift[]; + 'largest-contentful-paint': LargestContentfulPaint[]; + 'long-animation-frame': PerformanceLongAnimationFrameTiming[]; + 'paint': PerformancePaintTiming[]; + 'navigation': PerformanceNavigationTiming[]; + 'resource': PerformanceResourceTiming[]; +} +/** + * Takes a performance entry type and a callback function, and creates a + * `PerformanceObserver` instance that will observe the specified entry type + * with buffering enabled and call the callback _for each entry_. + * + * This function also feature-detects entry support and wraps the logic in a + * try/catch to avoid errors in unsupporting browsers. + */ +export declare const observe: <K extends keyof PerformanceEntryMap>(type: K, callback: (entries: PerformanceEntryMap[K]) => void, opts?: PerformanceObserverInit) => PerformanceObserver | undefined; +export {}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/observe.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/observe.js new file mode 100644 index 0000000..241971d --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/observe.js @@ -0,0 +1,46 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Takes a performance entry type and a callback function, and creates a + * `PerformanceObserver` instance that will observe the specified entry type + * with buffering enabled and call the callback _for each entry_. + * + * This function also feature-detects entry support and wraps the logic in a + * try/catch to avoid errors in unsupporting browsers. + */ +export const observe = (type, callback, opts) => { + try { + if (PerformanceObserver.supportedEntryTypes.includes(type)) { + const po = new PerformanceObserver((list) => { + // Delay by a microtask to workaround a bug in Safari where the + // callback is invoked immediately, rather than in a separate task. + // See: https://github.com/GoogleChrome/web-vitals/issues/277 + Promise.resolve().then(() => { + callback(list.getEntries()); + }); + }); + po.observe(Object.assign({ + type, + buffered: true, + }, opts || {})); + return po; + } + } + catch (e) { + // Do nothing. + } + return; +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/onHidden.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/onHidden.d.ts new file mode 100644 index 0000000..1e4d041 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/onHidden.d.ts @@ -0,0 +1 @@ +export declare const onHidden: (cb: () => void) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/onHidden.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/onHidden.js new file mode 100644 index 0000000..c78b585 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/onHidden.js @@ -0,0 +1,22 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export const onHidden = (cb) => { + document.addEventListener('visibilitychange', () => { + if (document.visibilityState === 'hidden') { + cb(); + } + }); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.d.ts new file mode 100644 index 0000000..86211bf --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.d.ts @@ -0,0 +1,7 @@ +import { FirstInputPolyfillCallback } from '../../types.js'; +/** + * Accepts a callback to be invoked once the first input delay and event + * are known. + */ +export declare const firstInputPolyfill: (onFirstInput: FirstInputPolyfillCallback) => void; +export declare const resetFirstInputPolyfill: () => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.js new file mode 100644 index 0000000..b3faa59 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.js @@ -0,0 +1,147 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +let firstInputEvent; +let firstInputDelay; +let firstInputTimeStamp; +let callbacks; +const listenerOpts = { passive: true, capture: true }; +const startTimeStamp = new Date(); +/** + * Accepts a callback to be invoked once the first input delay and event + * are known. + */ +export const firstInputPolyfill = (onFirstInput) => { + callbacks.push(onFirstInput); + reportFirstInputDelayIfRecordedAndValid(); +}; +export const resetFirstInputPolyfill = () => { + callbacks = []; + firstInputDelay = -1; + firstInputEvent = null; + eachEventType(addEventListener); +}; +/** + * Records the first input delay and event, so subsequent events can be + * ignored. All added event listeners are then removed. + */ +const recordFirstInputDelay = (delay, event) => { + if (!firstInputEvent) { + firstInputEvent = event; + firstInputDelay = delay; + firstInputTimeStamp = new Date(); + eachEventType(removeEventListener); + reportFirstInputDelayIfRecordedAndValid(); + } +}; +/** + * Reports the first input delay and event (if they're recorded and valid) + * by running the array of callback functions. + */ +const reportFirstInputDelayIfRecordedAndValid = () => { + // In some cases the recorded delay is clearly wrong, e.g. it's negative + // or it's larger than the delta between now and initialization. + // - https://github.com/GoogleChromeLabs/first-input-delay/issues/4 + // - https://github.com/GoogleChromeLabs/first-input-delay/issues/6 + // - https://github.com/GoogleChromeLabs/first-input-delay/issues/7 + if (firstInputDelay >= 0 && + // @ts-ignore (subtracting two dates always returns a number) + firstInputDelay < firstInputTimeStamp - startTimeStamp) { + const entry = { + entryType: 'first-input', + name: firstInputEvent.type, + target: firstInputEvent.target, + cancelable: firstInputEvent.cancelable, + startTime: firstInputEvent.timeStamp, + processingStart: firstInputEvent.timeStamp + firstInputDelay, + }; + callbacks.forEach(function (callback) { + callback(entry); + }); + callbacks = []; + } +}; +/** + * Handles pointer down events, which are a special case. + * Pointer events can trigger main or compositor thread behavior. + * We differentiate these cases based on whether or not we see a + * 'pointercancel' event, which are fired when we scroll. If we're scrolling + * we don't need to report input delay since FID excludes scrolling and + * pinch/zooming. + */ +const onPointerDown = (delay, event) => { + /** + * Responds to 'pointerup' events and records a delay. If a pointer up event + * is the next event after a pointerdown event, then it's not a scroll or + * a pinch/zoom. + */ + const onPointerUp = () => { + recordFirstInputDelay(delay, event); + removePointerEventListeners(); + }; + /** + * Responds to 'pointercancel' events and removes pointer listeners. + * If a 'pointercancel' is the next event to fire after a pointerdown event, + * it means this is a scroll or pinch/zoom interaction. + */ + const onPointerCancel = () => { + removePointerEventListeners(); + }; + /** + * Removes added pointer event listeners. + */ + const removePointerEventListeners = () => { + removeEventListener('pointerup', onPointerUp, listenerOpts); + removeEventListener('pointercancel', onPointerCancel, listenerOpts); + }; + addEventListener('pointerup', onPointerUp, listenerOpts); + addEventListener('pointercancel', onPointerCancel, listenerOpts); +}; +/** + * Handles all input events and records the time between when the event + * was received by the operating system and when it's JavaScript listeners + * were able to run. + */ +const onInput = (event) => { + // Only count cancelable events, which should trigger behavior + // important to the user. + if (event.cancelable) { + // In some browsers `event.timeStamp` returns a `DOMTimeStamp` value + // (epoch time) instead of the newer `DOMHighResTimeStamp` + // (document-origin time). To check for that we assume any timestamp + // greater than 1 trillion is a `DOMTimeStamp`, and compare it using + // the `Date` object rather than `performance.now()`. + // - https://github.com/GoogleChromeLabs/first-input-delay/issues/4 + const isEpochTime = event.timeStamp > 1e12; + const now = isEpochTime ? new Date() : performance.now(); + // Input delay is the delta between when the system received the event + // (e.g. event.timeStamp) and when it could run the callback (e.g. `now`). + const delay = now - event.timeStamp; + if (event.type == 'pointerdown') { + onPointerDown(delay, event); + } + else { + recordFirstInputDelay(delay, event); + } + } +}; +/** + * Invokes the passed callback const for = each event type with t =>he + * `onInput` const and = `listenerOpts =>`. + */ +const eachEventType = (callback) => { + const eventTypes = ['mousedown', 'keydown', 'touchstart', 'pointerdown']; + eventTypes.forEach((type) => callback(type, onInput, listenerOpts)); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.d.ts new file mode 100644 index 0000000..a5dd33e --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.d.ts @@ -0,0 +1 @@ +export declare const getFirstHiddenTime: () => number; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.js new file mode 100644 index 0000000..e1d41f3 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.js @@ -0,0 +1,25 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +let firstHiddenTime = document.visibilityState === 'hidden' ? 0 : Infinity; +const onVisibilityChange = (event) => { + if (document.visibilityState === 'hidden') { + firstHiddenTime = event.timeStamp; + removeEventListener('visibilitychange', onVisibilityChange, true); + } +}; +// Note: do not add event listeners unconditionally (outside of polyfills). +addEventListener('visibilitychange', onVisibilityChange, true); +export const getFirstHiddenTime = () => firstHiddenTime; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.d.ts new file mode 100644 index 0000000..1ed1de3 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.d.ts @@ -0,0 +1,14 @@ +declare global { + interface Performance { + interactionCount: number; + } +} +/** + * Returns the `interactionCount` value using the native API (if available) + * or the polyfill estimate in this module. + */ +export declare const getInteractionCount: () => number; +/** + * Feature detects native support or initializes the polyfill if needed. + */ +export declare const initInteractionCountPolyfill: () => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.js new file mode 100644 index 0000000..f523101 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.js @@ -0,0 +1,50 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { observe } from '../observe.js'; +let interactionCountEstimate = 0; +let minKnownInteractionId = Infinity; +let maxKnownInteractionId = 0; +const updateEstimate = (entries) => { + entries.forEach((e) => { + if (e.interactionId) { + minKnownInteractionId = Math.min(minKnownInteractionId, e.interactionId); + maxKnownInteractionId = Math.max(maxKnownInteractionId, e.interactionId); + interactionCountEstimate = maxKnownInteractionId + ? (maxKnownInteractionId - minKnownInteractionId) / 7 + 1 + : 0; + } + }); +}; +let po; +/** + * Returns the `interactionCount` value using the native API (if available) + * or the polyfill estimate in this module. + */ +export const getInteractionCount = () => { + return po ? interactionCountEstimate : performance.interactionCount || 0; +}; +/** + * Feature detects native support or initializes the polyfill if needed. + */ +export const initInteractionCountPolyfill = () => { + if ('interactionCount' in performance || po) + return; + po = observe('event', updateEstimate, { + type: 'event', + buffered: true, + durationThreshold: 0, + }); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/runOnce.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/runOnce.d.ts new file mode 100644 index 0000000..dbf917a --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/runOnce.d.ts @@ -0,0 +1 @@ +export declare const runOnce: (cb: () => void) => () => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/runOnce.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/runOnce.js new file mode 100644 index 0000000..ea00f53 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/runOnce.js @@ -0,0 +1,24 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export const runOnce = (cb) => { + let called = false; + return () => { + if (!called) { + cb(); + called = true; + } + }; +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/whenActivated.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenActivated.d.ts new file mode 100644 index 0000000..76af10b --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenActivated.d.ts @@ -0,0 +1 @@ +export declare const whenActivated: (callback: () => void) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/whenActivated.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenActivated.js new file mode 100644 index 0000000..c3d853f --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenActivated.js @@ -0,0 +1,23 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export const whenActivated = (callback) => { + if (document.prerendering) { + addEventListener('prerenderingchange', () => callback(), true); + } + else { + callback(); + } +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/whenIdle.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenIdle.d.ts new file mode 100644 index 0000000..b503b5a --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenIdle.d.ts @@ -0,0 +1,5 @@ +/** + * Runs the passed callback during the next idle period, or immediately + * if the browser's visibility state is (or becomes) hidden. + */ +export declare const whenIdle: (cb: () => void) => number; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/whenIdle.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenIdle.js new file mode 100644 index 0000000..bab00c6 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenIdle.js @@ -0,0 +1,36 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { onHidden } from './onHidden.js'; +import { runOnce } from './runOnce.js'; +/** + * Runs the passed callback during the next idle period, or immediately + * if the browser's visibility state is (or becomes) hidden. + */ +export const whenIdle = (cb) => { + const rIC = self.requestIdleCallback || self.setTimeout; + let handle = -1; + cb = runOnce(cb); + // If the document is hidden, run the callback immediately, otherwise + // race an idle callback with the next `visibilitychange` event. + if (document.visibilityState === 'hidden') { + cb(); + } + else { + handle = rIC(cb); + onHidden(cb); + } + return handle; +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onCLS.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/onCLS.d.ts new file mode 100644 index 0000000..c4c56b6 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/onCLS.d.ts @@ -0,0 +1,25 @@ +import { CLSMetric, MetricRatingThresholds, ReportOpts } from './types.js'; +/** Thresholds for CLS. See https://web.dev/articles/cls#what_is_a_good_cls_score */ +export declare const CLSThresholds: MetricRatingThresholds; +/** + * Calculates the [CLS](https://web.dev/articles/cls) value for the current page and + * calls the `callback` function once the value is ready to be reported, along + * with all `layout-shift` performance entries that were used in the metric + * value calculation. The reported value is a `double` (corresponding to a + * [layout shift score](https://web.dev/articles/cls#layout_shift_score)). + * + * If the `reportAllChanges` configuration option is set to `true`, the + * `callback` function will be called as soon as the value is initially + * determined as well as any time the value changes throughout the page + * lifespan. + * + * _**Important:** CLS should be continually monitored for changes throughout + * the entire lifespan of a page—including if the user returns to the page after + * it's been hidden/backgrounded. However, since browsers often [will not fire + * additional callbacks once the user has backgrounded a + * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden), + * `callback` is always called when the page's visibility state changes to + * hidden. As a result, the `callback` function might be called multiple times + * during the same page load._ + */ +export declare const onCLS: (onReport: (metric: CLSMetric) => void, opts?: ReportOpts) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onCLS.js b/frontend-old/node_modules/web-vitals/dist/modules/onCLS.js new file mode 100644 index 0000000..7c75a10 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/onCLS.js @@ -0,0 +1,108 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { onBFCacheRestore } from './lib/bfcache.js'; +import { initMetric } from './lib/initMetric.js'; +import { observe } from './lib/observe.js'; +import { bindReporter } from './lib/bindReporter.js'; +import { doubleRAF } from './lib/doubleRAF.js'; +import { onHidden } from './lib/onHidden.js'; +import { runOnce } from './lib/runOnce.js'; +import { onFCP } from './onFCP.js'; +/** Thresholds for CLS. See https://web.dev/articles/cls#what_is_a_good_cls_score */ +export const CLSThresholds = [0.1, 0.25]; +/** + * Calculates the [CLS](https://web.dev/articles/cls) value for the current page and + * calls the `callback` function once the value is ready to be reported, along + * with all `layout-shift` performance entries that were used in the metric + * value calculation. The reported value is a `double` (corresponding to a + * [layout shift score](https://web.dev/articles/cls#layout_shift_score)). + * + * If the `reportAllChanges` configuration option is set to `true`, the + * `callback` function will be called as soon as the value is initially + * determined as well as any time the value changes throughout the page + * lifespan. + * + * _**Important:** CLS should be continually monitored for changes throughout + * the entire lifespan of a page—including if the user returns to the page after + * it's been hidden/backgrounded. However, since browsers often [will not fire + * additional callbacks once the user has backgrounded a + * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden), + * `callback` is always called when the page's visibility state changes to + * hidden. As a result, the `callback` function might be called multiple times + * during the same page load._ + */ +export const onCLS = (onReport, opts) => { + // Set defaults + opts = opts || {}; + // Start monitoring FCP so we can only report CLS if FCP is also reported. + // Note: this is done to match the current behavior of CrUX. + onFCP(runOnce(() => { + let metric = initMetric('CLS', 0); + let report; + let sessionValue = 0; + let sessionEntries = []; + const handleEntries = (entries) => { + entries.forEach((entry) => { + // Only count layout shifts without recent user input. + if (!entry.hadRecentInput) { + const firstSessionEntry = sessionEntries[0]; + const lastSessionEntry = sessionEntries[sessionEntries.length - 1]; + // If the entry occurred less than 1 second after the previous entry + // and less than 5 seconds after the first entry in the session, + // include the entry in the current session. Otherwise, start a new + // session. + if (sessionValue && + entry.startTime - lastSessionEntry.startTime < 1000 && + entry.startTime - firstSessionEntry.startTime < 5000) { + sessionValue += entry.value; + sessionEntries.push(entry); + } + else { + sessionValue = entry.value; + sessionEntries = [entry]; + } + } + }); + // If the current session value is larger than the current CLS value, + // update CLS and the entries contributing to it. + if (sessionValue > metric.value) { + metric.value = sessionValue; + metric.entries = sessionEntries; + report(); + } + }; + const po = observe('layout-shift', handleEntries); + if (po) { + report = bindReporter(onReport, metric, CLSThresholds, opts.reportAllChanges); + onHidden(() => { + handleEntries(po.takeRecords()); + report(true); + }); + // Only report after a bfcache restore if the `PerformanceObserver` + // successfully registered. + onBFCacheRestore(() => { + sessionValue = 0; + metric = initMetric('CLS', 0); + report = bindReporter(onReport, metric, CLSThresholds, opts.reportAllChanges); + doubleRAF(() => report()); + }); + // Queue a task to report (if nothing else triggers a report first). + // This allows CLS to be reported as soon as FCP fires when + // `reportAllChanges` is true. + setTimeout(report, 0); + } + })); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onFCP.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/onFCP.d.ts new file mode 100644 index 0000000..77e4c00 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/onFCP.d.ts @@ -0,0 +1,10 @@ +import { FCPMetric, MetricRatingThresholds, ReportOpts } from './types.js'; +/** Thresholds for FCP. See https://web.dev/articles/fcp#what_is_a_good_fcp_score */ +export declare const FCPThresholds: MetricRatingThresholds; +/** + * Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and + * calls the `callback` function once the value is ready, along with the + * relevant `paint` performance entry used to determine the value. The reported + * value is a `DOMHighResTimeStamp`. + */ +export declare const onFCP: (onReport: (metric: FCPMetric) => void, opts?: ReportOpts) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onFCP.js b/frontend-old/node_modules/web-vitals/dist/modules/onFCP.js new file mode 100644 index 0000000..f4350cf --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/onFCP.js @@ -0,0 +1,71 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { onBFCacheRestore } from './lib/bfcache.js'; +import { bindReporter } from './lib/bindReporter.js'; +import { doubleRAF } from './lib/doubleRAF.js'; +import { getActivationStart } from './lib/getActivationStart.js'; +import { getVisibilityWatcher } from './lib/getVisibilityWatcher.js'; +import { initMetric } from './lib/initMetric.js'; +import { observe } from './lib/observe.js'; +import { whenActivated } from './lib/whenActivated.js'; +/** Thresholds for FCP. See https://web.dev/articles/fcp#what_is_a_good_fcp_score */ +export const FCPThresholds = [1800, 3000]; +/** + * Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and + * calls the `callback` function once the value is ready, along with the + * relevant `paint` performance entry used to determine the value. The reported + * value is a `DOMHighResTimeStamp`. + */ +export const onFCP = (onReport, opts) => { + // Set defaults + opts = opts || {}; + whenActivated(() => { + const visibilityWatcher = getVisibilityWatcher(); + let metric = initMetric('FCP'); + let report; + const handleEntries = (entries) => { + entries.forEach((entry) => { + if (entry.name === 'first-contentful-paint') { + po.disconnect(); + // Only report if the page wasn't hidden prior to the first paint. + if (entry.startTime < visibilityWatcher.firstHiddenTime) { + // The activationStart reference is used because FCP should be + // relative to page activation rather than navigation start if the + // page was prerendered. But in cases where `activationStart` occurs + // after the FCP, this time should be clamped at 0. + metric.value = Math.max(entry.startTime - getActivationStart(), 0); + metric.entries.push(entry); + report(true); + } + } + }); + }; + const po = observe('paint', handleEntries); + if (po) { + report = bindReporter(onReport, metric, FCPThresholds, opts.reportAllChanges); + // Only report after a bfcache restore if the `PerformanceObserver` + // successfully registered or the `paint` entry exists. + onBFCacheRestore((event) => { + metric = initMetric('FCP'); + report = bindReporter(onReport, metric, FCPThresholds, opts.reportAllChanges); + doubleRAF(() => { + metric.value = performance.now() - event.timeStamp; + report(true); + }); + }); + } + }); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onFID.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/onFID.d.ts new file mode 100644 index 0000000..12c24c2 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/onFID.d.ts @@ -0,0 +1,13 @@ +import { FIDMetric, MetricRatingThresholds, ReportOpts } from './types.js'; +/** Thresholds for FID. See https://web.dev/articles/fid#what_is_a_good_fid_score */ +export declare const FIDThresholds: MetricRatingThresholds; +/** + * Calculates the [FID](https://web.dev/articles/fid) value for the current page and + * calls the `callback` function once the value is ready, along with the + * relevant `first-input` performance entry used to determine the value. The + * reported value is a `DOMHighResTimeStamp`. + * + * _**Important:** since FID is only reported after the user interacts with the + * page, it's possible that it will not be reported for some page loads._ + */ +export declare const onFID: (onReport: (metric: FIDMetric) => void, opts?: ReportOpts) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onFID.js b/frontend-old/node_modules/web-vitals/dist/modules/onFID.js new file mode 100644 index 0000000..c656b58 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/onFID.js @@ -0,0 +1,70 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { onBFCacheRestore } from './lib/bfcache.js'; +import { bindReporter } from './lib/bindReporter.js'; +import { getVisibilityWatcher } from './lib/getVisibilityWatcher.js'; +import { initMetric } from './lib/initMetric.js'; +import { observe } from './lib/observe.js'; +import { onHidden } from './lib/onHidden.js'; +import { firstInputPolyfill, resetFirstInputPolyfill, } from './lib/polyfills/firstInputPolyfill.js'; +import { runOnce } from './lib/runOnce.js'; +import { whenActivated } from './lib/whenActivated.js'; +/** Thresholds for FID. See https://web.dev/articles/fid#what_is_a_good_fid_score */ +export const FIDThresholds = [100, 300]; +/** + * Calculates the [FID](https://web.dev/articles/fid) value for the current page and + * calls the `callback` function once the value is ready, along with the + * relevant `first-input` performance entry used to determine the value. The + * reported value is a `DOMHighResTimeStamp`. + * + * _**Important:** since FID is only reported after the user interacts with the + * page, it's possible that it will not be reported for some page loads._ + */ +export const onFID = (onReport, opts) => { + // Set defaults + opts = opts || {}; + whenActivated(() => { + const visibilityWatcher = getVisibilityWatcher(); + let metric = initMetric('FID'); + let report; + const handleEntry = (entry) => { + // Only report if the page wasn't hidden prior to the first input. + if (entry.startTime < visibilityWatcher.firstHiddenTime) { + metric.value = entry.processingStart - entry.startTime; + metric.entries.push(entry); + report(true); + } + }; + const handleEntries = (entries) => { + entries.forEach(handleEntry); + }; + const po = observe('first-input', handleEntries); + report = bindReporter(onReport, metric, FIDThresholds, opts.reportAllChanges); + if (po) { + onHidden(runOnce(() => { + handleEntries(po.takeRecords()); + po.disconnect(); + })); + onBFCacheRestore(() => { + metric = initMetric('FID'); + report = bindReporter(onReport, metric, FIDThresholds, opts.reportAllChanges); + // Browsers don't re-emit FID on bfcache restore so fake it until you make it + resetFirstInputPolyfill(); + firstInputPolyfill(handleEntry); + }); + } + }); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onINP.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/onINP.d.ts new file mode 100644 index 0000000..50c3e33 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/onINP.d.ts @@ -0,0 +1,31 @@ +import { INPMetric, MetricRatingThresholds, ReportOpts } from './types.js'; +/** Thresholds for INP. See https://web.dev/articles/inp#what_is_a_good_inp_score */ +export declare const INPThresholds: MetricRatingThresholds; +/** + * Calculates the [INP](https://web.dev/articles/inp) value for the current + * page and calls the `callback` function once the value is ready, along with + * the `event` performance entries reported for that interaction. The reported + * value is a `DOMHighResTimeStamp`. + * + * A custom `durationThreshold` configuration option can optionally be passed to + * control what `event-timing` entries are considered for INP reporting. The + * default threshold is `40`, which means INP scores of less than 40 are + * reported as 0. Note that this will not affect your 75th percentile INP value + * unless that value is also less than 40 (well below the recommended + * [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold). + * + * If the `reportAllChanges` configuration option is set to `true`, the + * `callback` function will be called as soon as the value is initially + * determined as well as any time the value changes throughout the page + * lifespan. + * + * _**Important:** INP should be continually monitored for changes throughout + * the entire lifespan of a page—including if the user returns to the page after + * it's been hidden/backgrounded. However, since browsers often [will not fire + * additional callbacks once the user has backgrounded a + * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden), + * `callback` is always called when the page's visibility state changes to + * hidden. As a result, the `callback` function might be called multiple times + * during the same page load._ + */ +export declare const onINP: (onReport: (metric: INPMetric) => void, opts?: ReportOpts) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onINP.js b/frontend-old/node_modules/web-vitals/dist/modules/onINP.js new file mode 100644 index 0000000..25ce110 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/onINP.js @@ -0,0 +1,111 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { onBFCacheRestore } from './lib/bfcache.js'; +import { bindReporter } from './lib/bindReporter.js'; +import { initMetric } from './lib/initMetric.js'; +import { DEFAULT_DURATION_THRESHOLD, processInteractionEntry, estimateP98LongestInteraction, resetInteractions, } from './lib/interactions.js'; +import { observe } from './lib/observe.js'; +import { onHidden } from './lib/onHidden.js'; +import { initInteractionCountPolyfill } from './lib/polyfills/interactionCountPolyfill.js'; +import { whenActivated } from './lib/whenActivated.js'; +import { whenIdle } from './lib/whenIdle.js'; +/** Thresholds for INP. See https://web.dev/articles/inp#what_is_a_good_inp_score */ +export const INPThresholds = [200, 500]; +/** + * Calculates the [INP](https://web.dev/articles/inp) value for the current + * page and calls the `callback` function once the value is ready, along with + * the `event` performance entries reported for that interaction. The reported + * value is a `DOMHighResTimeStamp`. + * + * A custom `durationThreshold` configuration option can optionally be passed to + * control what `event-timing` entries are considered for INP reporting. The + * default threshold is `40`, which means INP scores of less than 40 are + * reported as 0. Note that this will not affect your 75th percentile INP value + * unless that value is also less than 40 (well below the recommended + * [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold). + * + * If the `reportAllChanges` configuration option is set to `true`, the + * `callback` function will be called as soon as the value is initially + * determined as well as any time the value changes throughout the page + * lifespan. + * + * _**Important:** INP should be continually monitored for changes throughout + * the entire lifespan of a page—including if the user returns to the page after + * it's been hidden/backgrounded. However, since browsers often [will not fire + * additional callbacks once the user has backgrounded a + * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden), + * `callback` is always called when the page's visibility state changes to + * hidden. As a result, the `callback` function might be called multiple times + * during the same page load._ + */ +export const onINP = (onReport, opts) => { + // Return if the browser doesn't support all APIs needed to measure INP. + if (!('PerformanceEventTiming' in self && + 'interactionId' in PerformanceEventTiming.prototype)) { + return; + } + // Set defaults + opts = opts || {}; + whenActivated(() => { + // TODO(philipwalton): remove once the polyfill is no longer needed. + initInteractionCountPolyfill(); + let metric = initMetric('INP'); + let report; + const handleEntries = (entries) => { + // Queue the `handleEntries()` callback in the next idle task. + // This is needed to increase the chances that all event entries that + // occurred between the user interaction and the next paint + // have been dispatched. Note: there is currently an experiment + // running in Chrome (EventTimingKeypressAndCompositionInteractionId) + // 123+ that if rolled out fully may make this no longer necessary. + whenIdle(() => { + entries.forEach(processInteractionEntry); + const inp = estimateP98LongestInteraction(); + if (inp && inp.latency !== metric.value) { + metric.value = inp.latency; + metric.entries = inp.entries; + report(); + } + }); + }; + const po = observe('event', handleEntries, { + // Event Timing entries have their durations rounded to the nearest 8ms, + // so a duration of 40ms would be any event that spans 2.5 or more frames + // at 60Hz. This threshold is chosen to strike a balance between usefulness + // and performance. Running this callback for any interaction that spans + // just one or two frames is likely not worth the insight that could be + // gained. + durationThreshold: opts.durationThreshold ?? DEFAULT_DURATION_THRESHOLD, + }); + report = bindReporter(onReport, metric, INPThresholds, opts.reportAllChanges); + if (po) { + // Also observe entries of type `first-input`. This is useful in cases + // where the first interaction is less than the `durationThreshold`. + po.observe({ type: 'first-input', buffered: true }); + onHidden(() => { + handleEntries(po.takeRecords()); + report(true); + }); + // Only report after a bfcache restore if the `PerformanceObserver` + // successfully registered. + onBFCacheRestore(() => { + resetInteractions(); + metric = initMetric('INP'); + report = bindReporter(onReport, metric, INPThresholds, opts.reportAllChanges); + }); + } + }); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onLCP.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/onLCP.d.ts new file mode 100644 index 0000000..44e391c --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/onLCP.d.ts @@ -0,0 +1,15 @@ +import { LCPMetric, MetricRatingThresholds, ReportOpts } from './types.js'; +/** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */ +export declare const LCPThresholds: MetricRatingThresholds; +/** + * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and + * calls the `callback` function once the value is ready (along with the + * relevant `largest-contentful-paint` performance entry used to determine the + * value). The reported value is a `DOMHighResTimeStamp`. + * + * If the `reportAllChanges` configuration option is set to `true`, the + * `callback` function will be called any time a new `largest-contentful-paint` + * performance entry is dispatched, or once the final value of the metric has + * been determined. + */ +export declare const onLCP: (onReport: (metric: LCPMetric) => void, opts?: ReportOpts) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onLCP.js b/frontend-old/node_modules/web-vitals/dist/modules/onLCP.js new file mode 100644 index 0000000..2f9d0f7 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/onLCP.js @@ -0,0 +1,106 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { onBFCacheRestore } from './lib/bfcache.js'; +import { bindReporter } from './lib/bindReporter.js'; +import { doubleRAF } from './lib/doubleRAF.js'; +import { getActivationStart } from './lib/getActivationStart.js'; +import { getVisibilityWatcher } from './lib/getVisibilityWatcher.js'; +import { initMetric } from './lib/initMetric.js'; +import { observe } from './lib/observe.js'; +import { onHidden } from './lib/onHidden.js'; +import { runOnce } from './lib/runOnce.js'; +import { whenActivated } from './lib/whenActivated.js'; +import { whenIdle } from './lib/whenIdle.js'; +/** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */ +export const LCPThresholds = [2500, 4000]; +const reportedMetricIDs = {}; +/** + * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and + * calls the `callback` function once the value is ready (along with the + * relevant `largest-contentful-paint` performance entry used to determine the + * value). The reported value is a `DOMHighResTimeStamp`. + * + * If the `reportAllChanges` configuration option is set to `true`, the + * `callback` function will be called any time a new `largest-contentful-paint` + * performance entry is dispatched, or once the final value of the metric has + * been determined. + */ +export const onLCP = (onReport, opts) => { + // Set defaults + opts = opts || {}; + whenActivated(() => { + const visibilityWatcher = getVisibilityWatcher(); + let metric = initMetric('LCP'); + let report; + const handleEntries = (entries) => { + // If reportAllChanges is set then call this function for each entry, + // otherwise only consider the last one. + if (!opts.reportAllChanges) { + entries = entries.slice(-1); + } + entries.forEach((entry) => { + // Only report if the page wasn't hidden prior to LCP. + if (entry.startTime < visibilityWatcher.firstHiddenTime) { + // The startTime attribute returns the value of the renderTime if it is + // not 0, and the value of the loadTime otherwise. The activationStart + // reference is used because LCP should be relative to page activation + // rather than navigation start if the page was prerendered. But in cases + // where `activationStart` occurs after the LCP, this time should be + // clamped at 0. + metric.value = Math.max(entry.startTime - getActivationStart(), 0); + metric.entries = [entry]; + report(); + } + }); + }; + const po = observe('largest-contentful-paint', handleEntries); + if (po) { + report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges); + const stopListening = runOnce(() => { + if (!reportedMetricIDs[metric.id]) { + handleEntries(po.takeRecords()); + po.disconnect(); + reportedMetricIDs[metric.id] = true; + report(true); + } + }); + // Stop listening after input. Note: while scrolling is an input that + // stops LCP observation, it's unreliable since it can be programmatically + // generated. See: https://github.com/GoogleChrome/web-vitals/issues/75 + ['keydown', 'click'].forEach((type) => { + // Wrap in a setTimeout so the callback is run in a separate task + // to avoid extending the keyboard/click handler to reduce INP impact + // https://github.com/GoogleChrome/web-vitals/issues/383 + addEventListener(type, () => whenIdle(stopListening), { + once: true, + capture: true, + }); + }); + onHidden(stopListening); + // Only report after a bfcache restore if the `PerformanceObserver` + // successfully registered. + onBFCacheRestore((event) => { + metric = initMetric('LCP'); + report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges); + doubleRAF(() => { + metric.value = performance.now() - event.timeStamp; + reportedMetricIDs[metric.id] = true; + report(true); + }); + }); + } + }); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onTTFB.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/onTTFB.d.ts new file mode 100644 index 0000000..14d7e4f --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/onTTFB.d.ts @@ -0,0 +1,19 @@ +import { MetricRatingThresholds, ReportOpts, TTFBMetric } from './types.js'; +/** Thresholds for TTFB. See https://web.dev/articles/ttfb#what_is_a_good_ttfb_score */ +export declare const TTFBThresholds: MetricRatingThresholds; +/** + * Calculates the [TTFB](https://web.dev/articles/ttfb) value for the + * current page and calls the `callback` function once the page has loaded, + * along with the relevant `navigation` performance entry used to determine the + * value. The reported value is a `DOMHighResTimeStamp`. + * + * Note, this function waits until after the page is loaded to call `callback` + * in order to ensure all properties of the `navigation` entry are populated. + * This is useful if you want to report on other metrics exposed by the + * [Navigation Timing API](https://w3c.github.io/navigation-timing/). For + * example, the TTFB metric starts from the page's [time + * origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it + * includes time spent on DNS lookup, connection negotiation, network latency, + * and server processing time. + */ +export declare const onTTFB: (onReport: (metric: TTFBMetric) => void, opts?: ReportOpts) => void; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onTTFB.js b/frontend-old/node_modules/web-vitals/dist/modules/onTTFB.js new file mode 100644 index 0000000..9d12af4 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/onTTFB.js @@ -0,0 +1,79 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { bindReporter } from './lib/bindReporter.js'; +import { initMetric } from './lib/initMetric.js'; +import { onBFCacheRestore } from './lib/bfcache.js'; +import { getNavigationEntry } from './lib/getNavigationEntry.js'; +import { getActivationStart } from './lib/getActivationStart.js'; +import { whenActivated } from './lib/whenActivated.js'; +/** Thresholds for TTFB. See https://web.dev/articles/ttfb#what_is_a_good_ttfb_score */ +export const TTFBThresholds = [800, 1800]; +/** + * Runs in the next task after the page is done loading and/or prerendering. + * @param callback + */ +const whenReady = (callback) => { + if (document.prerendering) { + whenActivated(() => whenReady(callback)); + } + else if (document.readyState !== 'complete') { + addEventListener('load', () => whenReady(callback), true); + } + else { + // Queue a task so the callback runs after `loadEventEnd`. + setTimeout(callback, 0); + } +}; +/** + * Calculates the [TTFB](https://web.dev/articles/ttfb) value for the + * current page and calls the `callback` function once the page has loaded, + * along with the relevant `navigation` performance entry used to determine the + * value. The reported value is a `DOMHighResTimeStamp`. + * + * Note, this function waits until after the page is loaded to call `callback` + * in order to ensure all properties of the `navigation` entry are populated. + * This is useful if you want to report on other metrics exposed by the + * [Navigation Timing API](https://w3c.github.io/navigation-timing/). For + * example, the TTFB metric starts from the page's [time + * origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it + * includes time spent on DNS lookup, connection negotiation, network latency, + * and server processing time. + */ +export const onTTFB = (onReport, opts) => { + // Set defaults + opts = opts || {}; + let metric = initMetric('TTFB'); + let report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges); + whenReady(() => { + const navigationEntry = getNavigationEntry(); + if (navigationEntry) { + // The activationStart reference is used because TTFB should be + // relative to page activation rather than navigation start if the + // page was prerendered. But in cases where `activationStart` occurs + // after the first byte is received, this time should be clamped at 0. + metric.value = Math.max(navigationEntry.responseStart - getActivationStart(), 0); + metric.entries = [navigationEntry]; + report(true); + // Only report TTFB after bfcache restores if a `navigation` entry + // was reported for the initial load. + onBFCacheRestore(() => { + metric = initMetric('TTFB', 0); + report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges); + report(true); + }); + } + }); +}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types.d.ts new file mode 100644 index 0000000..080d366 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types.d.ts @@ -0,0 +1,54 @@ +export * from './types/base.js'; +export * from './types/polyfills.js'; +export * from './types/cls.js'; +export * from './types/fcp.js'; +export * from './types/fid.js'; +export * from './types/inp.js'; +export * from './types/lcp.js'; +export * from './types/ttfb.js'; +interface PerformanceEntryMap { + navigation: PerformanceNavigationTiming; + resource: PerformanceResourceTiming; + paint: PerformancePaintTiming; +} +declare global { + interface Document { + prerendering?: boolean; + wasDiscarded?: boolean; + } + interface Performance { + getEntriesByType<K extends keyof PerformanceEntryMap>(type: K): PerformanceEntryMap[K][]; + } + interface PerformanceObserverInit { + durationThreshold?: number; + } + interface PerformanceNavigationTiming { + activationStart?: number; + } + interface PerformanceEventTiming extends PerformanceEntry { + duration: DOMHighResTimeStamp; + interactionId: number; + } + interface LayoutShiftAttribution { + node?: Node; + previousRect: DOMRectReadOnly; + currentRect: DOMRectReadOnly; + } + interface LayoutShift extends PerformanceEntry { + value: number; + sources: LayoutShiftAttribution[]; + hadRecentInput: boolean; + } + interface LargestContentfulPaint extends PerformanceEntry { + readonly renderTime: DOMHighResTimeStamp; + readonly loadTime: DOMHighResTimeStamp; + readonly size: number; + readonly id: string; + readonly url: string; + readonly element: Element | null; + } + interface PerformanceLongAnimationFrameTiming extends PerformanceEntry { + renderStart: DOMHighResTimeStamp; + duration: DOMHighResTimeStamp; + } +} diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types.js b/frontend-old/node_modules/web-vitals/dist/modules/types.js new file mode 100644 index 0000000..77da260 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types.js @@ -0,0 +1,23 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './types/base.js'; +export * from './types/polyfills.js'; +export * from './types/cls.js'; +export * from './types/fcp.js'; +export * from './types/fid.js'; +export * from './types/inp.js'; +export * from './types/lcp.js'; +export * from './types/ttfb.js'; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/base.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/base.d.ts new file mode 100644 index 0000000..944292b --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/base.d.ts @@ -0,0 +1,101 @@ +import type { CLSMetric, CLSMetricWithAttribution } from './cls.js'; +import type { FCPMetric, FCPMetricWithAttribution } from './fcp.js'; +import type { FIDMetric, FIDMetricWithAttribution } from './fid.js'; +import type { INPMetric, INPMetricWithAttribution } from './inp.js'; +import type { LCPMetric, LCPMetricWithAttribution } from './lcp.js'; +import type { TTFBMetric, TTFBMetricWithAttribution } from './ttfb.js'; +export interface Metric { + /** + * The name of the metric (in acronym form). + */ + name: 'CLS' | 'FCP' | 'FID' | 'INP' | 'LCP' | 'TTFB'; + /** + * The current value of the metric. + */ + value: number; + /** + * The rating as to whether the metric value is within the "good", + * "needs improvement", or "poor" thresholds of the metric. + */ + rating: 'good' | 'needs-improvement' | 'poor'; + /** + * The delta between the current value and the last-reported value. + * On the first report, `delta` and `value` will always be the same. + */ + delta: number; + /** + * A unique ID representing this particular metric instance. This ID can + * be used by an analytics tool to dedupe multiple values sent for the same + * metric instance, or to group multiple deltas together and calculate a + * total. It can also be used to differentiate multiple different metric + * instances sent from the same page, which can happen if the page is + * restored from the back/forward cache (in that case new metrics object + * get created). + */ + id: string; + /** + * Any performance entries relevant to the metric value calculation. + * The array may also be empty if the metric value was not based on any + * entries (e.g. a CLS value of 0 given no layout shifts). + */ + entries: PerformanceEntry[]; + /** + * The type of navigation. + * + * This will be the value returned by the Navigation Timing API (or + * `undefined` if the browser doesn't support that API), with the following + * exceptions: + * - 'back-forward-cache': for pages that are restored from the bfcache. + * - 'back_forward' is renamed to 'back-forward' for consistency. + * - 'prerender': for pages that were prerendered. + * - 'restore': for pages that were discarded by the browser and then + * restored by the user. + */ + navigationType: 'navigate' | 'reload' | 'back-forward' | 'back-forward-cache' | 'prerender' | 'restore'; +} +/** The union of supported metric types. */ +export type MetricType = CLSMetric | FCPMetric | FIDMetric | INPMetric | LCPMetric | TTFBMetric; +/** The union of supported metric attribution types. */ +export type MetricWithAttribution = CLSMetricWithAttribution | FCPMetricWithAttribution | FIDMetricWithAttribution | INPMetricWithAttribution | LCPMetricWithAttribution | TTFBMetricWithAttribution; +/** + * The thresholds of metric's "good", "needs improvement", and "poor" ratings. + * + * - Metric values up to and including [0] are rated "good" + * - Metric values up to and including [1] are rated "needs improvement" + * - Metric values above [1] are "poor" + * + * | Metric value | Rating | + * | --------------- | ------------------- | + * | ≦ [0] | "good" | + * | > [0] and ≦ [1] | "needs improvement" | + * | > [1] | "poor" | + */ +export type MetricRatingThresholds = [number, number]; +/** + * @deprecated Use metric-specific function types instead, such as: + * `(metric: LCPMetric) => void`. If a single callback type is needed for + * multiple metrics, use `(metric: MetricType) => void`. + */ +export interface ReportCallback { + (metric: MetricType): void; +} +export interface ReportOpts { + reportAllChanges?: boolean; + durationThreshold?: number; +} +/** + * The loading state of the document. Note: this value is similar to + * `document.readyState` but it subdivides the "interactive" state into the + * time before and after the DOMContentLoaded event fires. + * + * State descriptions: + * - `loading`: the initial document response has not yet been fully downloaded + * and parsed. This is equivalent to the corresponding `readyState` value. + * - `dom-interactive`: the document has been fully loaded and parsed, but + * scripts may not have yet finished loading and executing. + * - `dom-content-loaded`: the document is fully loaded and parsed, and all + * scripts (except `async` scripts) have loaded and finished executing. + * - `complete`: the document and all of its sub-resources have finished + * loading. This is equivalent to the corresponding `readyState` value. + */ +export type LoadState = 'loading' | 'dom-interactive' | 'dom-content-loaded' | 'complete'; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/base.js b/frontend-old/node_modules/web-vitals/dist/modules/types/base.js new file mode 100644 index 0000000..e997715 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/base.js @@ -0,0 +1,16 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/cls.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/cls.d.ts new file mode 100644 index 0000000..f33cf17 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/cls.d.ts @@ -0,0 +1,55 @@ +import type { LoadState, Metric } from './base.js'; +/** + * A CLS-specific version of the Metric object. + */ +export interface CLSMetric extends Metric { + name: 'CLS'; + entries: LayoutShift[]; +} +/** + * An object containing potentially-helpful debugging information that + * can be sent along with the CLS value for the current page visit in order + * to help identify issues happening to real-users in the field. + */ +export interface CLSAttribution { + /** + * A selector identifying the first element (in document order) that + * shifted when the single largest layout shift contributing to the page's + * CLS score occurred. + */ + largestShiftTarget?: string; + /** + * The time when the single largest layout shift contributing to the page's + * CLS score occurred. + */ + largestShiftTime?: DOMHighResTimeStamp; + /** + * The layout shift score of the single largest layout shift contributing to + * the page's CLS score. + */ + largestShiftValue?: number; + /** + * The `LayoutShiftEntry` representing the single largest layout shift + * contributing to the page's CLS score. (Useful when you need more than just + * `largestShiftTarget`, `largestShiftTime`, and `largestShiftValue`). + */ + largestShiftEntry?: LayoutShift; + /** + * The first element source (in document order) among the `sources` list + * of the `largestShiftEntry` object. (Also useful when you need more than + * just `largestShiftTarget`, `largestShiftTime`, and `largestShiftValue`). + */ + largestShiftSource?: LayoutShiftAttribution; + /** + * The loading state of the document at the time when the largest layout + * shift contribution to the page's CLS score occurred (see `LoadState` + * for details). + */ + loadState?: LoadState; +} +/** + * A CLS-specific version of the Metric object with attribution. + */ +export interface CLSMetricWithAttribution extends CLSMetric { + attribution: CLSAttribution; +} diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/cls.js b/frontend-old/node_modules/web-vitals/dist/modules/types/cls.js new file mode 100644 index 0000000..e997715 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/cls.js @@ -0,0 +1,16 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/fcp.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/fcp.d.ts new file mode 100644 index 0000000..fa4a6e2 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/fcp.d.ts @@ -0,0 +1,46 @@ +import type { LoadState, Metric } from './base.js'; +/** + * An FCP-specific version of the Metric object. + */ +export interface FCPMetric extends Metric { + name: 'FCP'; + entries: PerformancePaintTiming[]; +} +/** + * An object containing potentially-helpful debugging information that + * can be sent along with the FCP value for the current page visit in order + * to help identify issues happening to real-users in the field. + */ +export interface FCPAttribution { + /** + * The time from when the user initiates loading the page until when the + * browser receives the first byte of the response (a.k.a. TTFB). + */ + timeToFirstByte: number; + /** + * The delta between TTFB and the first contentful paint (FCP). + */ + firstByteToFCP: number; + /** + * The loading state of the document at the time when FCP `occurred (see + * `LoadState` for details). Ideally, documents can paint before they finish + * loading (e.g. the `loading` or `dom-interactive` phases). + */ + loadState: LoadState; + /** + * The `PerformancePaintTiming` entry corresponding to FCP. + */ + fcpEntry?: PerformancePaintTiming; + /** + * The `navigation` entry of the current page, which is useful for diagnosing + * general page load issues. This can be used to access `serverTiming` for example: + * navigationEntry?.serverTiming + */ + navigationEntry?: PerformanceNavigationTiming; +} +/** + * An FCP-specific version of the Metric object with attribution. + */ +export interface FCPMetricWithAttribution extends FCPMetric { + attribution: FCPAttribution; +} diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/fcp.js b/frontend-old/node_modules/web-vitals/dist/modules/types/fcp.js new file mode 100644 index 0000000..e997715 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/fcp.js @@ -0,0 +1,16 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/fid.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/fid.d.ts new file mode 100644 index 0000000..25c5bd7 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/fid.d.ts @@ -0,0 +1,46 @@ +import type { LoadState, Metric } from './base.js'; +/** + * An FID-specific version of the Metric object. + */ +export interface FIDMetric extends Metric { + name: 'FID'; + entries: PerformanceEventTiming[]; +} +/** + * An object containing potentially-helpful debugging information that + * can be sent along with the FID value for the current page visit in order + * to help identify issues happening to real-users in the field. + */ +export interface FIDAttribution { + /** + * A selector identifying the element that the user interacted with. This + * element will be the `target` of the `event` dispatched. + */ + eventTarget: string; + /** + * The time when the user interacted. This time will match the `timeStamp` + * value of the `event` dispatched. + */ + eventTime: number; + /** + * The `type` of the `event` dispatched from the user interaction. + */ + eventType: string; + /** + * The `PerformanceEventTiming` entry corresponding to FID. + */ + eventEntry: PerformanceEventTiming; + /** + * The loading state of the document at the time when the first interaction + * occurred (see `LoadState` for details). If the first interaction occurred + * while the document was loading and executing script (e.g. usually in the + * `dom-interactive` phase) it can result in long input delays. + */ + loadState: LoadState; +} +/** + * An FID-specific version of the Metric object with attribution. + */ +export interface FIDMetricWithAttribution extends FIDMetric { + attribution: FIDAttribution; +} diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/fid.js b/frontend-old/node_modules/web-vitals/dist/modules/types/fid.js new file mode 100644 index 0000000..e997715 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/fid.js @@ -0,0 +1,16 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/inp.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/inp.d.ts new file mode 100644 index 0000000..c60e86a --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/inp.d.ts @@ -0,0 +1,103 @@ +import type { LoadState, Metric } from './base.js'; +/** + * An INP-specific version of the Metric object. + */ +export interface INPMetric extends Metric { + name: 'INP'; + entries: PerformanceEventTiming[]; +} +/** + * An object containing potentially-helpful debugging information that + * can be sent along with the INP value for the current page visit in order + * to help identify issues happening to real-users in the field. + */ +export interface INPAttribution { + /** + * A selector identifying the element that the user first interacted with + * as part of the frame where the INP candidate interaction occurred. + * If this value is an empty string, that generally means the element was + * removed from the DOM after the interaction. + */ + interactionTarget: string; + /** + * A reference to the HTML element identified by `interactionTargetSelector`. + * NOTE: for attribution purpose, a selector identifying the element is + * typically more useful than the element itself. However, the element is + * also made available in case additional context is needed. + */ + interactionTargetElement: Node | undefined; + /** + * The time when the user first interacted during the frame where the INP + * candidate interaction occurred (if more than one interaction occurred + * within the frame, only the first time is reported). + */ + interactionTime: DOMHighResTimeStamp; + /** + * The best-guess timestamp of the next paint after the interaction. + * In general, this timestamp is the same as the `startTime + duration` of + * the event timing entry. However, since `duration` values are rounded to + * the nearest 8ms, it can sometimes appear that the paint occurred before + * processing ended (which cannot happen). This value clamps the paint time + * so it's always after `processingEnd` from the Event Timing API and + * `renderStart` from the Long Animation Frame API (where available). + * It also averages the duration values for all entries in the same + * animation frame, which should be closer to the "real" value. + */ + nextPaintTime: DOMHighResTimeStamp; + /** + * The type of interaction, based on the event type of the `event` entry + * that corresponds to the interaction (i.e. the first `event` entry + * containing an `interactionId` dispatched in a given animation frame). + * For "pointerdown", "pointerup", or "click" events this will be "pointer", + * and for "keydown" or "keyup" events this will be "keyboard". + */ + interactionType: 'pointer' | 'keyboard'; + /** + * An array of Event Timing entries that were processed within the same + * animation frame as the INP candidate interaction. + */ + processedEventEntries: PerformanceEventTiming[]; + /** + * If the browser supports the Long Animation Frame API, this array will + * include any `long-animation-frame` entries that intersect with the INP + * candidate interaction's `startTime` and the `processingEnd` time of the + * last event processed within that animation frame. If the browser does not + * support the Long Animation Frame API or no `long-animation-frame` entries + * are detect, this array will be empty. + */ + longAnimationFrameEntries: PerformanceLongAnimationFrameTiming[]; + /** + * The time from when the user interacted with the page until when the + * browser was first able to start processing event listeners for that + * interaction. This time captures the delay before event processing can + * begin due to the main thread being busy with other work. + */ + inputDelay: number; + /** + * The time from when the first event listener started running in response to + * the user interaction until when all event listener processing has finished. + */ + processingDuration: number; + /** + * The time from when the browser finished processing all event listeners for + * the user interaction until the next frame is presented on the screen and + * visible to the user. This time includes work on the main thread (such as + * `requestAnimationFrame()` callbacks, `ResizeObserver` and + * `IntersectionObserver` callbacks, and style/layout calculation) as well + * as off-main-thread work (such as compositor, GPU, and raster work). + */ + presentationDelay: number; + /** + * The loading state of the document at the time when the interaction + * corresponding to INP occurred (see `LoadState` for details). If the + * interaction occurred while the document was loading and executing script + * (e.g. usually in the `dom-interactive` phase) it can result in long delays. + */ + loadState: LoadState; +} +/** + * An INP-specific version of the Metric object with attribution. + */ +export interface INPMetricWithAttribution extends INPMetric { + attribution: INPAttribution; +} diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/inp.js b/frontend-old/node_modules/web-vitals/dist/modules/types/inp.js new file mode 100644 index 0000000..e997715 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/inp.js @@ -0,0 +1,16 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/lcp.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/lcp.d.ts new file mode 100644 index 0000000..2e960e9 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/lcp.d.ts @@ -0,0 +1,69 @@ +import type { Metric } from './base.js'; +/** + * An LCP-specific version of the Metric object. + */ +export interface LCPMetric extends Metric { + name: 'LCP'; + entries: LargestContentfulPaint[]; +} +/** + * An object containing potentially-helpful debugging information that + * can be sent along with the LCP value for the current page visit in order + * to help identify issues happening to real-users in the field. + */ +export interface LCPAttribution { + /** + * The element corresponding to the largest contentful paint for the page. + */ + element?: string; + /** + * The URL (if applicable) of the LCP image resource. If the LCP element + * is a text node, this value will not be set. + */ + url?: string; + /** + * The time from when the user initiates loading the page until when the + * browser receives the first byte of the response (a.k.a. TTFB). See + * [Optimize LCP](https://web.dev/articles/optimize-lcp) for details. + */ + timeToFirstByte: number; + /** + * The delta between TTFB and when the browser starts loading the LCP + * resource (if there is one, otherwise 0). See [Optimize + * LCP](https://web.dev/articles/optimize-lcp) for details. + */ + resourceLoadDelay: number; + /** + * The total time it takes to load the LCP resource itself (if there is one, + * otherwise 0). See [Optimize LCP](https://web.dev/articles/optimize-lcp) for + * details. + */ + resourceLoadDuration: number; + /** + * The delta between when the LCP resource finishes loading until the LCP + * element is fully rendered. See [Optimize + * LCP](https://web.dev/articles/optimize-lcp) for details. + */ + elementRenderDelay: number; + /** + * The `navigation` entry of the current page, which is useful for diagnosing + * general page load issues. This can be used to access `serverTiming` for example: + * navigationEntry?.serverTiming + */ + navigationEntry?: PerformanceNavigationTiming; + /** + * The `resource` entry for the LCP resource (if applicable), which is useful + * for diagnosing resource load issues. + */ + lcpResourceEntry?: PerformanceResourceTiming; + /** + * The `LargestContentfulPaint` entry corresponding to LCP. + */ + lcpEntry?: LargestContentfulPaint; +} +/** + * An LCP-specific version of the Metric object with attribution. + */ +export interface LCPMetricWithAttribution extends LCPMetric { + attribution: LCPAttribution; +} diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/lcp.js b/frontend-old/node_modules/web-vitals/dist/modules/types/lcp.js new file mode 100644 index 0000000..e997715 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/lcp.js @@ -0,0 +1,16 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/polyfills.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/polyfills.d.ts new file mode 100644 index 0000000..e606728 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/polyfills.d.ts @@ -0,0 +1,4 @@ +export type FirstInputPolyfillEntry = Omit<PerformanceEventTiming, 'processingEnd'>; +export interface FirstInputPolyfillCallback { + (entry: FirstInputPolyfillEntry): void; +} diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/polyfills.js b/frontend-old/node_modules/web-vitals/dist/modules/types/polyfills.js new file mode 100644 index 0000000..e997715 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/polyfills.js @@ -0,0 +1,16 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {}; diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/ttfb.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/ttfb.d.ts new file mode 100644 index 0000000..485eeb6 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/ttfb.d.ts @@ -0,0 +1,59 @@ +import type { Metric } from './base.js'; +/** + * A TTFB-specific version of the Metric object. + */ +export interface TTFBMetric extends Metric { + name: 'TTFB'; + entries: PerformanceNavigationTiming[]; +} +/** + * An object containing potentially-helpful debugging information that + * can be sent along with the TTFB value for the current page visit in order + * to help identify issues happening to real-users in the field. + * + * NOTE: these values are primarily useful for page loads not handled via + * service worker, as browsers differ in what they report when service worker + * is involved, see: https://github.com/w3c/navigation-timing/issues/199 + */ +export interface TTFBAttribution { + /** + * The total time from when the user initiates loading the page to when the + * page starts to handle the request. Large values here are typically due + * to HTTP redirects, though other browser processing contributes to this + * duration as well (so even without redirect it's generally not zero). + */ + waitingDuration: number; + /** + * The total time spent checking the HTTP cache for a match. For navigations + * handled via service worker, this duration usually includes service worker + * start-up time as well as time processing `fetch` event listeners, with + * some exceptions, see: https://github.com/w3c/navigation-timing/issues/199 + */ + cacheDuration: number; + /** + * The total time to resolve the DNS for the requested domain. + */ + dnsDuration: number; + /** + * The total time to create the connection to the requested domain. + */ + connectionDuration: number; + /** + * The total time from when the request was sent until the first byte of the + * response was received. This includes network time as well as server + * processing time. + */ + requestDuration: number; + /** + * The `navigation` entry of the current page, which is useful for diagnosing + * general page load issues. This can be used to access `serverTiming` for + * example: navigationEntry?.serverTiming + */ + navigationEntry?: PerformanceNavigationTiming; +} +/** + * A TTFB-specific version of the Metric object with attribution. + */ +export interface TTFBMetricWithAttribution extends TTFBMetric { + attribution: TTFBAttribution; +} diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/ttfb.js b/frontend-old/node_modules/web-vitals/dist/modules/types/ttfb.js new file mode 100644 index 0000000..e997715 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/dist/modules/types/ttfb.js @@ -0,0 +1,16 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {}; |
