fix: prevent asset conflicts between React and Grid.js versions

Add coexistence checks to all enqueue methods to prevent loading
both React and Grid.js assets simultaneously.

Changes:
- ReactAdmin.php: Only enqueue React assets when ?react=1
- Init.php: Skip Grid.js when React active on admin pages
- Form.php, Coupon.php, Access.php: Restore classic assets when ?react=0
- Customer.php, Product.php, License.php: Add coexistence checks

Now the toggle between Classic and React versions works correctly.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
dwindown
2026-04-18 17:02:14 +07:00
parent bd9cdac02e
commit e8fbfb14c1
74973 changed files with 6658406 additions and 71 deletions

13
node_modules/web-vitals/dist/modules/attribution.d.ts generated vendored Normal file
View File

@@ -0,0 +1,13 @@
export { onCLS } from './attribution/onCLS.js';
export { onFCP } from './attribution/onFCP.js';
export { onFID } from './attribution/onFID.js';
export { onINP } from './attribution/onINP.js';
export { onLCP } from './attribution/onLCP.js';
export { onTTFB } from './attribution/onTTFB.js';
export { CLSThresholds } from './onCLS.js';
export { FCPThresholds } from './onFCP.js';
export { FIDThresholds } from './onFID.js';
export { INPThresholds } from './onINP.js';
export { LCPThresholds } from './onLCP.js';
export { TTFBThresholds } from './onTTFB.js';
export * from './types.js';

28
node_modules/web-vitals/dist/modules/attribution.js generated vendored Normal file
View File

@@ -0,0 +1,28 @@
/*
* 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 './attribution/onCLS.js';
export { onFCP } from './attribution/onFCP.js';
export { onFID } from './attribution/onFID.js';
export { onINP } from './attribution/onINP.js';
export { onLCP } from './attribution/onLCP.js';
export { onTTFB } from './attribution/onTTFB.js';
export { CLSThresholds } from './onCLS.js';
export { FCPThresholds } from './onFCP.js';
export { FIDThresholds } from './onFID.js';
export { INPThresholds } from './onINP.js';
export { LCPThresholds } from './onLCP.js';
export { TTFBThresholds } from './onTTFB.js';
export * from './types.js';

View File

@@ -0,0 +1,23 @@
import { CLSReportCallbackWithAttribution, 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: CLSReportCallbackWithAttribution, opts?: ReportOpts) => void;

View File

@@ -0,0 +1,72 @@
/*
* 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) => {
if (metric.entries.length) {
const largestEntry = getLargestLayoutShiftEntry(metric.entries);
if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
const largestSource = getLargestLayoutShiftSource(largestEntry.sources);
if (largestSource) {
metric.attribution = {
largestShiftTarget: getSelector(largestSource.node),
largestShiftTime: largestEntry.startTime,
largestShiftValue: largestEntry.value,
largestShiftSource: largestSource,
largestShiftEntry: largestEntry,
loadState: getLoadState(largestEntry.startTime),
};
return;
}
}
}
// Set an empty object if no other attribution has been set.
metric.attribution = {};
};
/**
* 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) => {
attributeCLS(metric);
onReport(metric);
}), opts);
};

View File

@@ -0,0 +1,8 @@
import { FCPReportCallbackWithAttribution, 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: FCPReportCallbackWithAttribution, opts?: ReportOpts) => void;

View File

@@ -0,0 +1,55 @@
/*
* 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) => {
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);
metric.attribution = {
timeToFirstByte: ttfb,
firstByteToFCP: metric.value - ttfb,
loadState: getLoadState(metric.entries[0].startTime),
navigationEntry,
fcpEntry,
};
return;
}
}
// Set an empty object if no other attribution has been set.
metric.attribution = {
timeToFirstByte: 0,
firstByteToFCP: metric.value,
loadState: getLoadState(getBFCacheRestoreTime()),
};
};
/**
* 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) => {
attributeFCP(metric);
onReport(metric);
}), opts);
};

View File

@@ -0,0 +1,11 @@
import { FIDReportCallbackWithAttribution, 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: FIDReportCallbackWithAttribution, opts?: ReportOpts) => void;

View File

@@ -0,0 +1,43 @@
/*
* 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];
metric.attribution = {
eventTarget: getSelector(fidEntry.target),
eventType: fidEntry.name,
eventTime: fidEntry.startTime,
eventEntry: fidEntry,
loadState: getLoadState(fidEntry.startTime),
};
};
/**
* 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) => {
attributeFID(metric);
onReport(metric);
}), opts);
};

View File

@@ -0,0 +1,29 @@
import { INPReportCallbackWithAttribution, ReportOpts } from '../types.js';
/**
* 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: INPReportCallbackWithAttribution, opts?: ReportOpts) => void;

View File

@@ -0,0 +1,78 @@
/*
* 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 { onINP as unattributedOnINP } from '../onINP.js';
const attributeINP = (metric) => {
if (metric.entries.length) {
const longestEntry = metric.entries.sort((a, b) => {
// Sort by: 1) duration (DESC), then 2) processing time (DESC)
return (b.duration - a.duration ||
b.processingEnd -
b.processingStart -
(a.processingEnd - a.processingStart));
})[0];
// Currently Chrome can return a null target for certain event types
// (especially pointer events). As the event target should be the same
// for all events in the same interaction, we pick the first non-null one.
// TODO: remove when 1367329 is resolved
// https://bugs.chromium.org/p/chromium/issues/detail?id=1367329
const firstEntryWithTarget = metric.entries.find((entry) => entry.target);
metric.attribution = {
eventTarget: getSelector(firstEntryWithTarget && firstEntryWithTarget.target),
eventType: longestEntry.name,
eventTime: longestEntry.startTime,
eventEntry: longestEntry,
loadState: getLoadState(longestEntry.startTime),
};
return;
}
// Set an empty object if no other attribution has been set.
metric.attribution = {};
};
/**
* 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) => {
unattributedOnINP(((metric) => {
attributeINP(metric);
onReport(metric);
}), opts);
};

View File

@@ -0,0 +1,13 @@
import { LCPReportCallbackWithAttribution, 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: LCPReportCallbackWithAttribution, opts?: ReportOpts) => void;

View File

@@ -0,0 +1,82 @@
/*
* 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) => {
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 ? lcpEntry.startTime - activationStart : 0);
const attribution = {
element: getSelector(lcpEntry.element),
timeToFirstByte: ttfb,
resourceLoadDelay: lcpRequestStart - ttfb,
resourceLoadTime: 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;
}
metric.attribution = attribution;
return;
}
}
// Set an empty object if no other attribution has been set.
metric.attribution = {
timeToFirstByte: 0,
resourceLoadDelay: 0,
resourceLoadTime: 0,
elementRenderDelay: metric.value,
};
};
/**
* 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) => {
attributeLCP(metric);
onReport(metric);
}), opts);
};

View File

@@ -0,0 +1,17 @@
import { TTFBReportCallbackWithAttribution, 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: TTFBReportCallbackWithAttribution, opts?: ReportOpts) => void;

View File

@@ -0,0 +1,61 @@
/*
* 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) => {
if (metric.entries.length) {
const navigationEntry = metric.entries[0];
const activationStart = navigationEntry.activationStart || 0;
const dnsStart = Math.max(navigationEntry.domainLookupStart - activationStart, 0);
const connectStart = Math.max(navigationEntry.connectStart - activationStart, 0);
const requestStart = Math.max(navigationEntry.requestStart - activationStart, 0);
metric.attribution = {
waitingTime: dnsStart,
dnsTime: connectStart - dnsStart,
connectionTime: requestStart - connectStart,
requestTime: metric.value - requestStart,
navigationEntry: navigationEntry,
};
return;
}
// Set an empty object if no other attribution has been set.
metric.attribution = {
waitingTime: 0,
dnsTime: 0,
connectionTime: 0,
requestTime: 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) => {
unattributedOnTTFB(((metric) => {
attributeTTFB(metric);
onReport(metric);
}), opts);
};

35
node_modules/web-vitals/dist/modules/deprecated.d.ts generated vendored Normal file
View File

@@ -0,0 +1,35 @@
export {
/**
* @deprecated Use `onCLS()` instead.
*/
onCLS as getCLS, } from './onCLS.js';
export {
/**
* @deprecated Use `onFCP()` instead.
*/
onFCP as getFCP, } from './onFCP.js';
export {
/**
* @deprecated Use `onFID()` instead.
*/
onFID as getFID, } from './onFID.js';
export {
/**
* @deprecated Use `onINP()` instead.
*/
onINP as getINP, } from './onINP.js';
export {
/**
* @deprecated Use `onLCP()` instead.
*/
onLCP as getLCP, } from './onLCP.js';
export {
/**
* @deprecated Use `onTTFB()` instead.
*/
onTTFB as getTTFB, } from './onTTFB.js';
export {
/**
* @deprecated Use `ReportCallback` instead.
*/
ReportCallback as ReportHandler, } from './types.js';

45
node_modules/web-vitals/dist/modules/deprecated.js generated vendored Normal file
View File

@@ -0,0 +1,45 @@
/*
* 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 `onCLS()` instead.
*/
onCLS as getCLS, } from './onCLS.js';
export {
/**
* @deprecated Use `onFCP()` instead.
*/
onFCP as getFCP, } from './onFCP.js';
export {
/**
* @deprecated Use `onFID()` instead.
*/
onFID as getFID, } from './onFID.js';
export {
/**
* @deprecated Use `onINP()` instead.
*/
onINP as getINP, } from './onINP.js';
export {
/**
* @deprecated Use `onLCP()` instead.
*/
onLCP as getLCP, } from './onLCP.js';
export {
/**
* @deprecated Use `onTTFB()` instead.
*/
onTTFB as getTTFB, } from './onTTFB.js';

8
node_modules/web-vitals/dist/modules/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,8 @@
export { onCLS, CLSThresholds } from './onCLS.js';
export { onFCP, FCPThresholds } from './onFCP.js';
export { onFID, FIDThresholds } from './onFID.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';

23
node_modules/web-vitals/dist/modules/index.js generated vendored Normal file
View File

@@ -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 { onCLS, CLSThresholds } from './onCLS.js';
export { onFCP, FCPThresholds } from './onFCP.js';
export { onFID, FIDThresholds } from './onFID.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';

View File

@@ -0,0 +1,6 @@
interface onBFCacheRestoreCallback {
(event: PageTransitionEvent): void;
}
export declare const getBFCacheRestoreTime: () => number;
export declare const onBFCacheRestore: (cb: onBFCacheRestoreCallback) => void;
export {};

25
node_modules/web-vitals/dist/modules/lib/bfcache.js generated vendored Normal file
View File

@@ -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);
};

View File

@@ -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;

View File

@@ -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);
}
}
}
};
};

View File

@@ -0,0 +1 @@
export declare const doubleRAF: (cb: () => unknown) => void;

18
node_modules/web-vitals/dist/modules/lib/doubleRAF.js generated vendored Normal file
View File

@@ -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()));
};

View File

@@ -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;

View File

@@ -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 `v3-${Date.now()}-${Math.floor(Math.random() * (9e12 - 1)) + 1e12}`;
};

View File

@@ -0,0 +1 @@
export declare const getActivationStart: () => number;

View File

@@ -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;
};

View File

@@ -0,0 +1,2 @@
import { LoadState } from '../types.js';
export declare const getLoadState: (timestamp: number) => LoadState;

View File

@@ -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';
};

View File

@@ -0,0 +1,2 @@
import { NavigationTimingPolyfillEntry } from '../types.js';
export declare const getNavigationEntry: () => PerformanceNavigationTiming | NavigationTimingPolyfillEntry | undefined;

View File

@@ -0,0 +1,44 @@
/*
* 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 getNavigationEntryFromPerformanceTiming = () => {
const timing = performance.timing;
const type = performance.navigation.type;
const navigationEntry = {
entryType: 'navigation',
startTime: 0,
type: type == 2 ? 'back_forward' : type === 1 ? 'reload' : 'navigate',
};
for (const key in timing) {
if (key !== 'navigationStart' && key !== 'toJSON') {
navigationEntry[key] = Math.max(timing[key] -
timing.navigationStart, 0);
}
}
return navigationEntry;
};
export const getNavigationEntry = () => {
if (window.__WEB_VITALS_POLYFILL__) {
return (window.performance &&
((performance.getEntriesByType &&
performance.getEntriesByType('navigation')[0]) ||
getNavigationEntryFromPerformanceTiming()));
}
else {
return (window.performance &&
performance.getEntriesByType &&
performance.getEntriesByType('navigation')[0]);
}
};

View File

@@ -0,0 +1 @@
export declare const getSelector: (node: Node | null | undefined, maxLen?: number) => string;

View File

@@ -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;
};

View File

@@ -0,0 +1,3 @@
export declare const getVisibilityWatcher: () => {
readonly firstHiddenTime: number;
};

View File

@@ -0,0 +1,88 @@
/*
* 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.
if (window.__WEB_VITALS_POLYFILL__) {
firstHiddenTime = window.webVitals.firstHiddenTime;
if (firstHiddenTime === Infinity) {
addChangeListeners();
}
}
else {
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;
},
};
};

View File

@@ -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" | "prerender" | "reload" | "back-forward" | "back-forward-cache" | "restore";
};

48
node_modules/web-vitals/dist/modules/lib/initMetric.js generated vendored Normal file
View File

@@ -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,
};
};

20
node_modules/web-vitals/dist/modules/lib/observe.d.ts generated vendored Normal file
View File

@@ -0,0 +1,20 @@
import { FirstInputPolyfillEntry, NavigationTimingPolyfillEntry } from '../types.js';
interface PerformanceEntryMap {
'event': PerformanceEventTiming[];
'paint': PerformancePaintTiming[];
'layout-shift': LayoutShift[];
'largest-contentful-paint': LargestContentfulPaint[];
'first-input': PerformanceEventTiming[] | FirstInputPolyfillEntry[];
'navigation': PerformanceNavigationTiming[] | NavigationTimingPolyfillEntry[];
'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 {};

46
node_modules/web-vitals/dist/modules/lib/observe.js generated vendored Normal file
View File

@@ -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;
};

View File

@@ -0,0 +1,4 @@
export interface OnHiddenCallback {
(event: Event): void;
}
export declare const onHidden: (cb: OnHiddenCallback) => void;

26
node_modules/web-vitals/dist/modules/lib/onHidden.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
/*
* 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) => {
const onHiddenOrPageHide = (event) => {
if (event.type === 'pagehide' || document.visibilityState === 'hidden') {
cb(event);
}
};
addEventListener('visibilitychange', onHiddenOrPageHide, true);
// Some browsers have buggy implementations of visibilitychange,
// so we use pagehide in addition, just to be safe.
addEventListener('pagehide', onHiddenOrPageHide, true);
};

View File

@@ -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;

View File

@@ -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));
};

View File

@@ -0,0 +1 @@
export declare const getFirstHiddenTime: () => number;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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,
});
};

View File

@@ -0,0 +1,4 @@
export interface RunOnceCallback {
(arg: unknown): void;
}
export declare const runOnce: (cb: RunOnceCallback) => (arg: unknown) => void;

24
node_modules/web-vitals/dist/modules/lib/runOnce.js generated vendored Normal file
View File

@@ -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 (arg) => {
if (!called) {
cb(arg);
called = true;
}
};
};

View File

@@ -0,0 +1 @@
export declare const whenActivated: (callback: () => void) => void;

View File

@@ -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();
}
};

25
node_modules/web-vitals/dist/modules/onCLS.d.ts generated vendored Normal file
View File

@@ -0,0 +1,25 @@
import { CLSReportCallback, 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: CLSReportCallback, opts?: ReportOpts) => void;

108
node_modules/web-vitals/dist/modules/onCLS.js generated vendored Normal file
View File

@@ -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);
}
}));
};

10
node_modules/web-vitals/dist/modules/onFCP.d.ts generated vendored Normal file
View File

@@ -0,0 +1,10 @@
import { FCPReportCallback, 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: FCPReportCallback, opts?: ReportOpts) => void;

71
node_modules/web-vitals/dist/modules/onFCP.js generated vendored Normal file
View File

@@ -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);
});
});
}
});
};

13
node_modules/web-vitals/dist/modules/onFID.d.ts generated vendored Normal file
View File

@@ -0,0 +1,13 @@
import { FIDReportCallback, 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: FIDReportCallback, opts?: ReportOpts) => void;

87
node_modules/web-vitals/dist/modules/onFID.js generated vendored Normal file
View File

@@ -0,0 +1,87 @@
/*
* 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();
}));
}
if (window.__WEB_VITALS_POLYFILL__) {
console.warn('The web-vitals "base+polyfill" build is deprecated. See: https://bit.ly/3aqzsGm');
// Prefer the native implementation if available,
if (!po) {
window.webVitals.firstInputPolyfill(handleEntry);
}
onBFCacheRestore(() => {
metric = initMetric('FID');
report = bindReporter(onReport, metric, FIDThresholds, opts.reportAllChanges);
window.webVitals.resetFirstInputPolyfill();
window.webVitals.firstInputPolyfill(handleEntry);
});
}
else {
// Only monitor bfcache restores if the browser supports FID natively.
if (po) {
onBFCacheRestore(() => {
metric = initMetric('FID');
report = bindReporter(onReport, metric, FIDThresholds, opts.reportAllChanges);
resetFirstInputPolyfill();
firstInputPolyfill(handleEntry);
});
}
}
});
};

31
node_modules/web-vitals/dist/modules/onINP.d.ts generated vendored Normal file
View File

@@ -0,0 +1,31 @@
import { INPReportCallback, 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: INPReportCallback, opts?: ReportOpts) => void;

194
node_modules/web-vitals/dist/modules/onINP.js generated vendored Normal file
View File

@@ -0,0 +1,194 @@
/*
* 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 { observe } from './lib/observe.js';
import { onHidden } from './lib/onHidden.js';
import { getInteractionCount, initInteractionCountPolyfill, } from './lib/polyfills/interactionCountPolyfill.js';
import { whenActivated } from './lib/whenActivated.js';
/** Thresholds for INP. See https://web.dev/articles/inp#what_is_a_good_inp_score */
export const INPThresholds = [200, 500];
// 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;
};
// 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 longest interactions on the page (by latency) sorted so the
// longest one is first. The list is as most MAX_INTERACTIONS_TO_CONSIDER long.
let longestInteractionList = [];
// A mapping of longest interactions by their interaction ID.
// This is used for faster lookup.
const longestInteractionMap = {};
/**
* 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.
*/
const processEntry = (entry) => {
// The least-long of the 10 longest interactions.
const minLongestInteraction = longestInteractionList[longestInteractionList.length - 1];
const existingInteraction = longestInteractionMap[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) {
existingInteraction.entries.push(entry);
existingInteraction.latency = Math.max(existingInteraction.latency, entry.duration);
}
else {
const interaction = {
id: entry.interactionId,
latency: entry.duration,
entries: [entry],
};
longestInteractionMap[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);
longestInteractionList.splice(MAX_INTERACTIONS_TO_CONSIDER).forEach((i) => {
delete longestInteractionMap[i.id];
});
}
};
/**
* Returns the estimated p98 longest interaction based on the stored
* interaction candidates and the interaction count for the current page.
*/
const estimateP98LongestInteraction = () => {
const candidateInteractionIndex = Math.min(longestInteractionList.length - 1, Math.floor(getInteractionCountForNavigation() / 50));
return longestInteractionList[candidateInteractionIndex];
};
/**
* 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) => {
// 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) => {
entries.forEach((entry) => {
if (entry.interactionId) {
processEntry(entry);
}
// Entries of type `first-input` don't currently have an `interactionId`,
// so to consider them in INP we have to first check that an existing
// entry doesn't match the `duration` and `startTime`.
// Note that this logic assumes that `event` entries are dispatched
// before `first-input` entries. This is true in Chrome (the only browser
// that currently supports INP).
// TODO(philipwalton): remove once crbug.com/1325826 is fixed.
if (entry.entryType === 'first-input') {
const noMatchingEntry = !longestInteractionList.some((interaction) => {
return interaction.entries.some((prevEntry) => {
return (entry.duration === prevEntry.duration &&
entry.startTime === prevEntry.startTime);
});
});
if (noMatchingEntry) {
processEntry(entry);
}
}
});
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 ?? 40,
});
report = bindReporter(onReport, metric, INPThresholds, opts.reportAllChanges);
if (po) {
// If browser supports interactionId (and so supports INP), also
// observe entries of type `first-input`. This is useful in cases
// where the first interaction is less than the `durationThreshold`.
if ('PerformanceEventTiming' in window &&
'interactionId' in PerformanceEventTiming.prototype) {
po.observe({ type: 'first-input', buffered: true });
}
onHidden(() => {
handleEntries(po.takeRecords());
// If the interaction count shows that there were interactions but
// none were captured by the PerformanceObserver, report a latency of 0.
if (metric.value < 0 && getInteractionCountForNavigation() > 0) {
metric.value = 0;
metric.entries = [];
}
report(true);
});
// Only report after a bfcache restore if the `PerformanceObserver`
// successfully registered.
onBFCacheRestore(() => {
longestInteractionList = [];
// Important, we want the count for the full page here,
// not just for the current navigation.
prevInteractionCount = getInteractionCount();
metric = initMetric('INP');
report = bindReporter(onReport, metric, INPThresholds, opts.reportAllChanges);
});
}
});
};

15
node_modules/web-vitals/dist/modules/onLCP.d.ts generated vendored Normal file
View File

@@ -0,0 +1,15 @@
import { MetricRatingThresholds, LCPReportCallback, 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: LCPReportCallback, opts?: ReportOpts) => void;

98
node_modules/web-vitals/dist/modules/onLCP.js generated vendored Normal file
View File

@@ -0,0 +1,98 @@
/*
* 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';
/** 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) => {
const lastEntry = entries[entries.length - 1];
if (lastEntry) {
// Only report if the page wasn't hidden prior to LCP.
if (lastEntry.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(lastEntry.startTime - getActivationStart(), 0);
metric.entries = [lastEntry];
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, () => setTimeout(stopListening, 0), 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);
});
});
}
});
};

19
node_modules/web-vitals/dist/modules/onTTFB.d.ts generated vendored Normal file
View File

@@ -0,0 +1,19 @@
import { MetricRatingThresholds, ReportOpts, TTFBReportCallback } 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: TTFBReportCallback, opts?: ReportOpts) => void;

88
node_modules/web-vitals/dist/modules/onTTFB.js generated vendored Normal file
View File

@@ -0,0 +1,88 @@
/*
* 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 navEntry = getNavigationEntry();
if (navEntry) {
const responseStart = navEntry.responseStart;
// 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 (responseStart <= 0 || responseStart > performance.now())
return;
// 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(responseStart - getActivationStart(), 0);
metric.entries = [navEntry];
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);
});
}
});
};

1
node_modules/web-vitals/dist/modules/polyfill.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export {};

25
node_modules/web-vitals/dist/modules/polyfill.js generated vendored Normal file
View File

@@ -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.
*/
import { firstInputPolyfill, resetFirstInputPolyfill, } from './lib/polyfills/firstInputPolyfill.js';
import { getFirstHiddenTime } from './lib/polyfills/getFirstHiddenTimePolyfill.js';
resetFirstInputPolyfill();
self.webVitals = {
firstInputPolyfill: firstInputPolyfill,
resetFirstInputPolyfill: resetFirstInputPolyfill,
get firstHiddenTime() {
return getFirstHiddenTime();
},
};

62
node_modules/web-vitals/dist/modules/types.d.ts generated vendored Normal file
View File

@@ -0,0 +1,62 @@
import { FirstInputPolyfillCallback } from './types/polyfills.js';
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';
export interface WebVitalsGlobal {
firstInputPolyfill: (onFirstInput: FirstInputPolyfillCallback) => void;
resetFirstInputPolyfill: () => void;
firstHiddenTime: number;
}
declare global {
interface Window {
webVitals: WebVitalsGlobal;
__WEB_VITALS_POLYFILL__: boolean;
}
}
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 {
renderTime: DOMHighResTimeStamp;
loadTime: DOMHighResTimeStamp;
size: number;
id: string;
url: string;
element?: Element;
}
}

23
node_modules/web-vitals/dist/modules/types.js generated vendored Normal file
View File

@@ -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';

107
node_modules/web-vitals/dist/modules/types/base.d.ts generated vendored Normal file
View File

@@ -0,0 +1,107 @@
import { FirstInputPolyfillEntry, NavigationTimingPolyfillEntry } from './polyfills.js';
import type { CLSMetric } from './cls.js';
import type { FCPMetric } from './fcp.js';
import type { FIDMetric } from './fid.js';
import type { INPMetric } from './inp.js';
import type { LCPMetric } from './lcp.js';
import type { TTFBMetric } 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 | LayoutShift | FirstInputPolyfillEntry | NavigationTimingPolyfillEntry)[];
/**
* 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.
* - '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;
/**
* A version of the `Metric` that is used with the attribution build.
*/
export interface MetricWithAttribution extends Metric {
/**
* An object containing potentially-helpful debugging information that
* can be sent along with the metric value for the current page visit in
* order to help identify issues happening to real-users in the field.
*/
attribution: {
[key: string]: unknown;
};
}
/**
* 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];
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';

16
node_modules/web-vitals/dist/modules/types/base.js generated vendored Normal file
View File

@@ -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 {};

67
node_modules/web-vitals/dist/modules/types/cls.d.ts generated vendored Normal file
View File

@@ -0,0 +1,67 @@
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;
}
/**
* A CLS-specific version of the ReportCallback function.
*/
export interface CLSReportCallback {
(metric: CLSMetric): void;
}
/**
* A CLS-specific version of the ReportCallback function with attribution.
*/
export interface CLSReportCallbackWithAttribution {
(metric: CLSMetricWithAttribution): void;
}

16
node_modules/web-vitals/dist/modules/types/cls.js generated vendored Normal file
View File

@@ -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 {};

59
node_modules/web-vitals/dist/modules/types/fcp.d.ts generated vendored Normal file
View File

@@ -0,0 +1,59 @@
import type { LoadState, Metric } from './base.js';
import { NavigationTimingPolyfillEntry } from './polyfills.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 | NavigationTimingPolyfillEntry;
}
/**
* An FCP-specific version of the Metric object with attribution.
*/
export interface FCPMetricWithAttribution extends FCPMetric {
attribution: FCPAttribution;
}
/**
* An FCP-specific version of the ReportCallback function.
*/
export interface FCPReportCallback {
(metric: FCPMetric): void;
}
/**
* An FCP-specific version of the ReportCallback function with attribution.
*/
export interface FCPReportCallbackWithAttribution {
(metric: FCPMetricWithAttribution): void;
}

16
node_modules/web-vitals/dist/modules/types/fcp.js generated vendored Normal file
View File

@@ -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 {};

60
node_modules/web-vitals/dist/modules/types/fid.d.ts generated vendored Normal file
View File

@@ -0,0 +1,60 @@
import type { LoadState, Metric } from './base.js';
import { FirstInputPolyfillEntry } from './polyfills.js';
/**
* An FID-specific version of the Metric object.
*/
export interface FIDMetric extends Metric {
name: 'FID';
entries: (PerformanceEventTiming | FirstInputPolyfillEntry)[];
}
/**
* 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 (or the
* polyfill entry in browsers that don't support Event Timing).
*/
eventEntry: PerformanceEventTiming | FirstInputPolyfillEntry;
/**
* 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;
}
/**
* An FID-specific version of the ReportCallback function.
*/
export interface FIDReportCallback {
(metric: FIDMetric): void;
}
/**
* An FID-specific version of the ReportCallback function with attribution.
*/
export interface FIDReportCallbackWithAttribution {
(metric: FIDMetricWithAttribution): void;
}

16
node_modules/web-vitals/dist/modules/types/fid.js generated vendored Normal file
View File

@@ -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 {};

59
node_modules/web-vitals/dist/modules/types/inp.d.ts generated vendored Normal file
View File

@@ -0,0 +1,59 @@
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 interacted with for
* the event corresponding to INP. This element will be the `target` of the
* `event` dispatched.
*/
eventTarget?: string;
/**
* The time when the user interacted for the event corresponding to INP.
* This time will match the `timeStamp` value of the `event` dispatched.
*/
eventTime?: number;
/**
* The `type` of the `event` dispatched corresponding to INP.
*/
eventType?: string;
/**
* The `PerformanceEventTiming` entry corresponding to INP.
*/
eventEntry?: PerformanceEventTiming;
/**
* The loading state of the document at the time when the event 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;
}
/**
* An INP-specific version of the ReportCallback function.
*/
export interface INPReportCallback {
(metric: INPMetric): void;
}
/**
* An INP-specific version of the ReportCallback function with attribution.
*/
export interface INPReportCallbackWithAttribution {
(metric: INPMetricWithAttribution): void;
}

16
node_modules/web-vitals/dist/modules/types/inp.js generated vendored Normal file
View File

@@ -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 {};

82
node_modules/web-vitals/dist/modules/types/lcp.d.ts generated vendored Normal file
View File

@@ -0,0 +1,82 @@
import type { Metric } from './base.js';
import { NavigationTimingPolyfillEntry } from './polyfills.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.
*/
resourceLoadTime: 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 | NavigationTimingPolyfillEntry;
/**
* 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;
}
/**
* An LCP-specific version of the ReportCallback function.
*/
export interface LCPReportCallback {
(metric: LCPMetric): void;
}
/**
* An LCP-specific version of the ReportCallback function with attribution.
*/
export interface LCPReportCallbackWithAttribution {
(metric: LCPMetricWithAttribution): void;
}

16
node_modules/web-vitals/dist/modules/types/lcp.js generated vendored Normal file
View File

@@ -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 {};

View File

@@ -0,0 +1,7 @@
export type FirstInputPolyfillEntry = Omit<PerformanceEventTiming, 'processingEnd'>;
export interface FirstInputPolyfillCallback {
(entry: FirstInputPolyfillEntry): void;
}
export type NavigationTimingPolyfillEntry = Omit<PerformanceNavigationTiming, 'initiatorType' | 'nextHopProtocol' | 'redirectCount' | 'transferSize' | 'encodedBodySize' | 'decodedBodySize' | 'type'> & {
type: PerformanceNavigationTiming['type'];
};

View File

@@ -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 {};

60
node_modules/web-vitals/dist/modules/types/ttfb.d.ts generated vendored Normal file
View File

@@ -0,0 +1,60 @@
import type { Metric } from './base.js';
import { NavigationTimingPolyfillEntry } from './polyfills.js';
/**
* A TTFB-specific version of the Metric object.
*/
export interface TTFBMetric extends Metric {
name: 'TTFB';
entries: PerformanceNavigationTiming[] | NavigationTimingPolyfillEntry[];
}
/**
* 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.
*/
export interface TTFBAttribution {
/**
* The total time from when the user initiates loading the page to when the
* DNS lookup begins. This includes redirects, service worker startup, and
* HTTP cache lookup times.
*/
waitingTime: number;
/**
* The total time to resolve the DNS for the current request.
*/
dnsTime: number;
/**
* The total time to create the connection to the requested domain.
*/
connectionTime: number;
/**
* The time 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.
*/
requestTime: 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 | NavigationTimingPolyfillEntry;
}
/**
* A TTFB-specific version of the Metric object with attribution.
*/
export interface TTFBMetricWithAttribution extends TTFBMetric {
attribution: TTFBAttribution;
}
/**
* A TTFB-specific version of the ReportCallback function.
*/
export interface TTFBReportCallback {
(metric: TTFBMetric): void;
}
/**
* A TTFB-specific version of the ReportCallback function with attribution.
*/
export interface TTFBReportCallbackWithAttribution {
(metric: TTFBMetricWithAttribution): void;
}

16
node_modules/web-vitals/dist/modules/types/ttfb.js generated vendored Normal file
View File

@@ -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 {};