@vercel/speed-insights 0.0.1-beta.2 → 0.0.1-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/next/index.cjs +109 -124
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +30 -2
- package/dist/next/index.d.ts +30 -2
- package/dist/next/index.js +98 -130
- package/dist/next/index.js.map +1 -1
- package/dist/remix/index.cjs +191 -0
- package/dist/remix/index.cjs.map +1 -0
- package/dist/remix/index.d.cts +35 -0
- package/dist/remix/index.d.ts +35 -0
- package/dist/remix/index.js +156 -0
- package/dist/remix/index.js.map +1 -0
- package/package.json +10 -4
- package/scripts/postinstall.js +37 -32
- package/tsup.config.js +8 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-

|
|
2
2
|
|
|
3
3
|
<div align="center"><strong>Vercel Speed Insights</strong></div>
|
|
4
4
|
<div align="center">Performance insights for your website</div>
|
package/dist/next/index.cjs
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
9
|
var __export = (target, all) => {
|
|
8
|
-
for (var
|
|
9
|
-
__defProp(target,
|
|
10
|
+
for (var name2 in all)
|
|
11
|
+
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
10
12
|
};
|
|
11
13
|
var __copyProps = (to, from, except, desc) => {
|
|
12
14
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
@@ -16,117 +18,58 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
18
|
}
|
|
17
19
|
return to;
|
|
18
20
|
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
19
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
30
|
|
|
21
31
|
// src/nextjs/index.tsx
|
|
22
32
|
var nextjs_exports = {};
|
|
23
33
|
__export(nextjs_exports, {
|
|
24
|
-
SpeedInsights: () =>
|
|
34
|
+
SpeedInsights: () => SpeedInsights2
|
|
25
35
|
});
|
|
26
36
|
module.exports = __toCommonJS(nextjs_exports);
|
|
37
|
+
var import_react2 = __toESM(require("react"), 1);
|
|
38
|
+
|
|
39
|
+
// src/react/index.tsx
|
|
27
40
|
var import_react = require("react");
|
|
28
41
|
|
|
29
|
-
//
|
|
30
|
-
var
|
|
42
|
+
// package.json
|
|
43
|
+
var name = "@vercel/speed-insights";
|
|
44
|
+
var version = "0.0.1-beta.5";
|
|
45
|
+
|
|
46
|
+
// src/queue.ts
|
|
47
|
+
var initQueue = () => {
|
|
48
|
+
if (window.si)
|
|
49
|
+
return;
|
|
50
|
+
window.si = function a(...params) {
|
|
51
|
+
(window.siq = window.siq || []).push(params);
|
|
52
|
+
};
|
|
53
|
+
};
|
|
31
54
|
|
|
32
55
|
// src/utils.ts
|
|
33
|
-
function
|
|
34
|
-
|
|
35
|
-
if ("connection" in navigator) {
|
|
36
|
-
const connection = navigator.connection;
|
|
37
|
-
if (connection == null ? void 0 : connection.effectiveType) {
|
|
38
|
-
speed = connection.effectiveType;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return speed;
|
|
56
|
+
function isBrowser() {
|
|
57
|
+
return typeof window !== "undefined";
|
|
42
58
|
}
|
|
43
|
-
|
|
44
|
-
function sendBeacon(data) {
|
|
45
|
-
const blob = new Blob([JSON.stringify(data)], {
|
|
46
|
-
type: "text/plain"
|
|
47
|
-
});
|
|
59
|
+
function detectEnvironment() {
|
|
48
60
|
try {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
body: blob,
|
|
53
|
-
keepalive: true,
|
|
54
|
-
mode: "no-cors",
|
|
55
|
-
credentials: "omit"
|
|
56
|
-
});
|
|
57
|
-
} else if ("sendBeacon" in navigator) {
|
|
58
|
-
navigator.sendBeacon(ENDPOINT, blob);
|
|
61
|
+
const env = process.env.NODE_ENV;
|
|
62
|
+
if (env === "development" || env === "test") {
|
|
63
|
+
return "development";
|
|
59
64
|
}
|
|
60
65
|
} catch (e) {
|
|
61
66
|
}
|
|
67
|
+
return "production";
|
|
62
68
|
}
|
|
63
|
-
function
|
|
64
|
-
|
|
65
|
-
return metric.attribution.largestShiftTarget;
|
|
66
|
-
}
|
|
67
|
-
if (metric.name === "FID") {
|
|
68
|
-
return metric.attribution.eventTarget;
|
|
69
|
-
}
|
|
70
|
-
if (metric.name === "LCP") {
|
|
71
|
-
return metric.attribution.element;
|
|
72
|
-
}
|
|
69
|
+
function isDevelopment() {
|
|
70
|
+
return detectEnvironment() === "development";
|
|
73
71
|
}
|
|
74
|
-
function
|
|
75
|
-
if (Number.isInteger(number)) {
|
|
76
|
-
return number;
|
|
77
|
-
}
|
|
78
|
-
const multiplier = Math.pow(10, decimals);
|
|
79
|
-
return Math.floor(number * multiplier) / multiplier;
|
|
80
|
-
}
|
|
81
|
-
function formatMetricValue(metric) {
|
|
82
|
-
if (metric.name === "CLS") {
|
|
83
|
-
return cutDecimal(metric.value, 4);
|
|
84
|
-
}
|
|
85
|
-
if (metric.name === "FID") {
|
|
86
|
-
return cutDecimal(metric.value, 2);
|
|
87
|
-
}
|
|
88
|
-
return Math.round(metric.value);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// src/generic/index.ts
|
|
92
|
-
function sendVitals(metrics, dsn) {
|
|
93
|
-
const speed = getConnectionSpeed();
|
|
94
|
-
if (metrics.length === 0)
|
|
95
|
-
return;
|
|
96
|
-
const payload = {
|
|
97
|
-
dsn,
|
|
98
|
-
speed,
|
|
99
|
-
metrics: metrics.map((metric) => ({
|
|
100
|
-
id: metric.id,
|
|
101
|
-
type: metric.name,
|
|
102
|
-
value: formatMetricValue(metric),
|
|
103
|
-
dynamicPath: metric.dynamicPath,
|
|
104
|
-
href: window.location.href.replace("http://", "https://"),
|
|
105
|
-
// TODO: remove this
|
|
106
|
-
attribution: {
|
|
107
|
-
target: getDomTarget(metric)
|
|
108
|
-
}
|
|
109
|
-
}))
|
|
110
|
-
};
|
|
111
|
-
sendBeacon(payload);
|
|
112
|
-
}
|
|
113
|
-
function watchMetrics(callback) {
|
|
114
|
-
(0, import_attribution.onCLS)(callback);
|
|
115
|
-
(0, import_attribution.onFID)(callback);
|
|
116
|
-
(0, import_attribution.onLCP)(callback);
|
|
117
|
-
(0, import_attribution.onFCP)(callback);
|
|
118
|
-
(0, import_attribution.onINP)(callback);
|
|
119
|
-
(0, import_attribution.onTTFB)(callback);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// src/nextjs/utils.ts
|
|
123
|
-
var import_navigation = require("next/navigation");
|
|
124
|
-
var useDynamicPath = () => {
|
|
125
|
-
const params = (0, import_navigation.useParams)();
|
|
126
|
-
const path = (0, import_navigation.usePathname)();
|
|
127
|
-
return computePathname(path, params);
|
|
128
|
-
};
|
|
129
|
-
function computePathname(pathname, pathParams) {
|
|
72
|
+
function computeRoute(pathname, pathParams) {
|
|
130
73
|
if (pathname === null) {
|
|
131
74
|
return null;
|
|
132
75
|
}
|
|
@@ -166,40 +109,82 @@ function computePathname(pathname, pathParams) {
|
|
|
166
109
|
return result;
|
|
167
110
|
}
|
|
168
111
|
|
|
169
|
-
// src/
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
112
|
+
// src/generic.ts
|
|
113
|
+
var DEV_SCRIPT_URL = `https://va.vercel-scripts.com/v1/speed-insights/script.debug.js`;
|
|
114
|
+
var SCRIPT_URL = `/_vercel/speed-insights/script.js`;
|
|
115
|
+
function inject(props) {
|
|
116
|
+
var _a;
|
|
117
|
+
if (!isBrowser())
|
|
118
|
+
return null;
|
|
119
|
+
initQueue();
|
|
120
|
+
if (props.beforeSend) {
|
|
121
|
+
(_a = window.si) == null ? void 0 : _a.call(window, "beforeSend", props.beforeSend);
|
|
122
|
+
}
|
|
123
|
+
const src = props.scriptSrc || (isDevelopment() ? DEV_SCRIPT_URL : SCRIPT_URL);
|
|
124
|
+
if (document.head.querySelector(`script[src*="${src}"]`))
|
|
125
|
+
return null;
|
|
126
|
+
const script = document.createElement("script");
|
|
127
|
+
script.src = src;
|
|
128
|
+
script.defer = true;
|
|
129
|
+
script.dataset.sdkn = name;
|
|
130
|
+
script.dataset.sdkv = version;
|
|
131
|
+
if (props.sampleRate) {
|
|
132
|
+
script.dataset.sampleRate = props.sampleRate.toString();
|
|
133
|
+
}
|
|
134
|
+
if (props.route) {
|
|
135
|
+
script.dataset.route = props.route;
|
|
136
|
+
}
|
|
137
|
+
if (props.endpoint) {
|
|
138
|
+
script.dataset.endpoint = props.endpoint;
|
|
139
|
+
}
|
|
140
|
+
if (props.token) {
|
|
141
|
+
script.dataset.token = props.token;
|
|
142
|
+
}
|
|
143
|
+
if (isDevelopment() && props.debug === false) {
|
|
144
|
+
script.dataset.debug = "false";
|
|
145
|
+
}
|
|
146
|
+
script.onerror = () => {
|
|
147
|
+
const errorMessage = isDevelopment() ? "Please check if any ad blockers are enabled and try again." : "Be sure to enable Speed Insights for your project and deploy again. See https://vercel.com/docs/speed-insights for more information.";
|
|
148
|
+
console.log(
|
|
149
|
+
`[Vercel Speed Insights] Failed to load script from ${src}. ${errorMessage}`
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
document.head.appendChild(script);
|
|
153
|
+
return {
|
|
154
|
+
setRoute: (route) => {
|
|
155
|
+
script.dataset.route = route;
|
|
182
156
|
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
removeEventListener("pagehide", flush);
|
|
190
|
-
};
|
|
191
|
-
}, [flush]);
|
|
192
|
-
const reportVital = (0, import_react.useCallback)(
|
|
193
|
-
(metric) => {
|
|
194
|
-
vitals.current.push({ ...metric, dynamicPath });
|
|
195
|
-
},
|
|
196
|
-
[dynamicPath]
|
|
197
|
-
);
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// src/react/index.tsx
|
|
161
|
+
function SpeedInsights(props) {
|
|
162
|
+
const setScriptRoute = (0, import_react.useRef)(null);
|
|
198
163
|
(0, import_react.useEffect)(() => {
|
|
199
|
-
|
|
164
|
+
const script = inject(props);
|
|
165
|
+
setScriptRoute.current = (script == null ? void 0 : script.setRoute) || null;
|
|
200
166
|
}, []);
|
|
167
|
+
(0, import_react.useEffect)(() => {
|
|
168
|
+
if (props.route && setScriptRoute.current) {
|
|
169
|
+
setScriptRoute.current(props.route);
|
|
170
|
+
}
|
|
171
|
+
}, [props.route]);
|
|
201
172
|
return null;
|
|
202
173
|
}
|
|
174
|
+
|
|
175
|
+
// src/nextjs/utils.ts
|
|
176
|
+
var import_navigation = require("next/navigation");
|
|
177
|
+
var useRoute = () => {
|
|
178
|
+
const params = (0, import_navigation.useParams)();
|
|
179
|
+
const path = (0, import_navigation.usePathname)();
|
|
180
|
+
return computeRoute(path, params);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// src/nextjs/index.tsx
|
|
184
|
+
function SpeedInsights2(props) {
|
|
185
|
+
const route = useRoute();
|
|
186
|
+
return /* @__PURE__ */ import_react2.default.createElement(SpeedInsights, { ...route && { route }, ...props });
|
|
187
|
+
}
|
|
203
188
|
// Annotate the CommonJS export names for ESM import in node:
|
|
204
189
|
0 && (module.exports = {
|
|
205
190
|
SpeedInsights
|
package/dist/next/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/nextjs/index.tsx","../../src/generic/index.ts","../../src/utils.ts","../../src/nextjs/utils.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport type { Metric, MetricWithAttribution } from 'web-vitals';\nimport { sendVitals, watchMetrics } from '../generic';\nimport type { CollectedMetric } from '../types';\nimport { useDynamicPath } from './utils';\n\ninterface SpeedInsightsProps {\n token: string;\n sampleRate?: number; // Only send a percentage of events to the server to reduce costs\n}\n\nexport function SpeedInsights({ token, sampleRate }: SpeedInsightsProps): null {\n const dynamicPath = useDynamicPath();\n const vitals = useRef<CollectedMetric[]>([]);\n\n const flush = useCallback(() => {\n if (vitals.current.length > 0) {\n if (sampleRate && Math.random() > sampleRate) {\n return;\n }\n const body = vitals.current;\n\n // eslint-disable-next-line no-console -- ok for now\n console.log('flushing', body);\n sendVitals(body, token);\n\n vitals.current = [];\n }\n }, [sampleRate, vitals.current]);\n\n useEffect(() => {\n addEventListener('visibilitychange', flush);\n addEventListener('pagehide', flush);\n return () => {\n removeEventListener('visibilitychange', flush);\n removeEventListener('pagehide', flush);\n };\n }, [flush]);\n\n const reportVital = useCallback(\n (metric: MetricWithAttribution): void => {\n vitals.current.push({ ...metric, dynamicPath });\n },\n [dynamicPath],\n );\n\n useEffect(() => {\n watchMetrics(reportVital as (metric: Metric) => void); // TODO: fix typing -- caused by not properly typed library\n }, []);\n\n return null;\n}\n","import {\n onLCP,\n onFID,\n onCLS,\n onFCP,\n onINP,\n onTTFB,\n} from 'web-vitals/attribution';\nimport type { Metric } from 'web-vitals';\nimport type { CollectedMetric, SpeedInsightsPayload } from '../types';\nimport {\n formatMetricValue,\n getConnectionSpeed,\n getDomTarget,\n sendBeacon,\n} from '../utils';\n\nexport function sendVitals(metrics: CollectedMetric[], dsn: string): void {\n const speed = getConnectionSpeed();\n\n if (metrics.length === 0) return;\n\n const payload: SpeedInsightsPayload = {\n dsn,\n speed,\n metrics: metrics.map((metric) => ({\n id: metric.id,\n type: metric.name,\n value: formatMetricValue(metric),\n dynamicPath: metric.dynamicPath,\n href: window.location.href.replace('http://', 'https://'), // TODO: remove this\n attribution: {\n target: getDomTarget(metric),\n },\n })),\n };\n sendBeacon(payload as never);\n}\n\nexport function watchMetrics(callback: (metric: Metric) => void): void {\n onCLS(callback);\n onFID(callback);\n onLCP(callback);\n onFCP(callback);\n onINP(callback);\n onTTFB(callback);\n}\n","import type { MetricWithAttribution } from 'web-vitals';\nimport type { CollectedMetric } from './types';\n\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nexport function getConnectionSpeed(): string {\n let speed = '';\n if ('connection' in navigator) {\n const connection = navigator.connection as never as\n | {\n effectiveType?: string;\n }\n | undefined;\n if (connection?.effectiveType) {\n speed = connection.effectiveType;\n }\n }\n return speed;\n}\n\nconst ENDPOINT = 'https://vitals.vercel-insights.com/v2/vitals';\n\nexport function sendBeacon(\n data: Record<string, string | number> | URLSearchParams | undefined,\n): void {\n const blob = new Blob([JSON.stringify(data)], {\n type: 'text/plain',\n });\n try {\n if ('keepalive' in Request.prototype) {\n void fetch(ENDPOINT, {\n method: 'POST',\n body: blob,\n keepalive: true,\n mode: 'no-cors',\n credentials: 'omit',\n });\n } else if ('sendBeacon' in navigator) {\n // Use sendBeacon as a fallback\n navigator.sendBeacon(ENDPOINT, blob);\n }\n } catch (e) {\n /* empty */\n }\n}\n\nexport function getDomTarget(\n metric: MetricWithAttribution,\n): string | undefined {\n if (metric.name === 'CLS') {\n return metric.attribution.largestShiftTarget as string;\n }\n if (metric.name === 'FID') {\n return metric.attribution.eventTarget as string;\n }\n if (metric.name === 'LCP') {\n return metric.attribution.element as string;\n }\n}\n\nexport function cutDecimal(number: number, decimals: number): number {\n if (Number.isInteger(number)) {\n return number;\n }\n\n const multiplier = Math.pow(10, decimals);\n return Math.floor(number * multiplier) / multiplier;\n}\n\nexport function formatMetricValue(metric: CollectedMetric): number {\n if (metric.name === 'CLS') {\n return cutDecimal(metric.value, 4);\n }\n if (metric.name === 'FID') {\n return cutDecimal(metric.value, 2);\n }\n return Math.round(metric.value);\n}\n","'use client';\nimport { useParams, usePathname } from 'next/navigation';\n\nexport const useDynamicPath = (): string | null => {\n const params = useParams();\n const path = usePathname();\n\n return computePathname(path, params);\n};\n\n// Refined version from dvoytenko\n// https://github.com/vercel/front/pull/25076\nfunction computePathname(\n pathname: string | null,\n pathParams: Record<string, string | string[]> | null,\n): string | null {\n if (pathname === null) {\n return null;\n }\n if (pathname === '' || !pathParams) {\n return pathname;\n }\n let result = pathname;\n for (const [key, valueOrArray] of Object.entries(pathParams)) {\n let value: string;\n let expr: string;\n if (Array.isArray(valueOrArray)) {\n // An array-based segment, e.g. \"/[...slugs]\".\n expr = `...${key}`;\n value = valueOrArray.join('/');\n } else {\n // A single dynamic segment, e.g. \"/posts/[pid]\".\n expr = key;\n value = valueOrArray;\n }\n if (!value) {\n continue;\n }\n let start = 0;\n while (start !== -1) {\n start = result.indexOf(`/${value}`, start);\n if (start !== -1) {\n const end = start + value.length + 2;\n if (\n end >= result.length ||\n result[end] === '/' ||\n result[end] === '?' ||\n result[end] === '#'\n ) {\n result = `${result.substring(\n 0,\n start + 1,\n )}[${expr}]${result.substring(end)}`;\n break;\n }\n start += value.length + 1;\n }\n }\n }\n return result;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/nextjs/index.tsx","../../src/react/index.tsx","../../package.json","../../src/queue.ts","../../src/utils.ts","../../src/generic.ts","../../src/nextjs/utils.ts"],"sourcesContent":["import React from 'react';\nimport { SpeedInsights as SpeedInsightsScript } from '../react';\nimport type { SpeedInsightsProps } from '../types';\nimport { useRoute } from './utils';\n\nexport function SpeedInsights(\n props: Omit<SpeedInsightsProps, 'route'>,\n): JSX.Element {\n const route = useRoute();\n\n return <SpeedInsightsScript {...(route && { route })} {...props} />;\n}\n","'use client';\nimport { useEffect, useRef } from 'react';\nimport type { SpeedInsightsProps } from '../types';\nimport { inject } from '../generic';\n\nexport function SpeedInsights(props: SpeedInsightsProps): JSX.Element | null {\n const setScriptRoute = useRef<((path: string) => void) | null>(null);\n useEffect(() => {\n const script = inject(props);\n\n setScriptRoute.current = script?.setRoute || null;\n }, []);\n\n useEffect(() => {\n if (props.route && setScriptRoute.current) {\n setScriptRoute.current(props.route);\n }\n }, [props.route]);\n\n return null;\n}\n","{\n \"name\": \"@vercel/speed-insights\",\n \"version\": \"0.0.1-beta.5\",\n \"description\": \"Speed Insights is a tool for measuring web performance and providing suggestions for improvement.\",\n \"keywords\": [\n \"speed-insights\",\n \"vercel\"\n ],\n \"repository\": {\n \"url\": \"github:vercel/speed-insights\",\n \"directory\": \"packages/web\"\n },\n \"license\": \"MPL-2.0\",\n \"type\": \"module\",\n \"exports\": {\n \"./package.json\": \"./package.json\",\n \".\": {\n \"browser\": \"./dist/index.js\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n },\n \"./next\": {\n \"browser\": \"./dist/next/index.js\",\n \"import\": \"./dist/next/index.js\",\n \"require\": \"./dist/next/index.cjs\"\n },\n \"./remix\": {\n \"browser\": \"./dist/remix/index.js\",\n \"import\": \"./dist/remix/index.js\",\n \"require\": \"./dist/remix/index.cjs\"\n }\n },\n \"main\": \"dist/index.js\",\n \"types\": \"dist/index.d.ts\",\n \"typesVersions\": {\n \"*\": {\n \"*\": [\n \"dist/index.d.ts\"\n ],\n \"react\": [\n \"dist/react/index.d.ts\"\n ],\n \"next\": [\n \"dist/next/index.d.ts\"\n ],\n \"remix\": [\n \"dist/remix/index.d.ts\"\n ]\n }\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"postinstall\": \"node scripts/postinstall.js\",\n \"lint\": \"eslint .\",\n \"lint-fix\": \"eslint . --fix\",\n \"test\": \"jest\",\n \"type-check\": \"tsc --noEmit\"\n },\n \"devDependencies\": {\n \"@remix-run/react\": \"^2.0.1\",\n \"@swc/core\": \"^1.3.82\",\n \"@swc/jest\": \"^0.2.29\",\n \"@testing-library/jest-dom\": \"^6.1.2\",\n \"@testing-library/react\": \"^14.0.0\",\n \"@types/jest\": \"^29.5.4\",\n \"@types/node\": \"^20.5.9\",\n \"@types/react\": \"^18.2.21\",\n \"jest\": \"^29.6.4\",\n \"jest-environment-jsdom\": \"^29.6.4\",\n \"next\": \"^13.4.19\",\n \"react\": \"^18.2.0\",\n \"react-dom\": \"^18.2.0\",\n \"tsup\": \"7.2.0\"\n }\n}\n","export const initQueue = (): void => {\n // initialize va until script is loaded\n if (window.si) return;\n\n window.si = function a(...params): void {\n (window.siq = window.siq || []).push(params);\n };\n};\n","export function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nfunction detectEnvironment(): 'development' | 'production' {\n try {\n const env = process.env.NODE_ENV;\n if (env === 'development' || env === 'test') {\n return 'development';\n }\n } catch (e) {\n // do nothing, this is okay\n }\n return 'production';\n}\n\nexport function isProduction(): boolean {\n return detectEnvironment() === 'production';\n}\n\nexport function isDevelopment(): boolean {\n return detectEnvironment() === 'development';\n}\n\nexport function computeRoute(\n pathname: string | null,\n pathParams: Record<string, string | string[]> | null,\n): string | null {\n if (pathname === null) {\n return null;\n }\n if (pathname === '' || !pathParams) {\n return pathname;\n }\n let result = pathname;\n for (const [key, valueOrArray] of Object.entries(pathParams)) {\n let value: string;\n let expr: string;\n if (Array.isArray(valueOrArray)) {\n // An array-based segment, e.g. \"/[...slugs]\".\n expr = `...${key}`;\n value = valueOrArray.join('/');\n } else {\n // A single dynamic segment, e.g. \"/posts/[pid]\".\n expr = key;\n value = valueOrArray;\n }\n if (!value) {\n continue;\n }\n let start = 0;\n while (start !== -1) {\n start = result.indexOf(`/${value}`, start);\n if (start !== -1) {\n const end = start + value.length + 2;\n if (\n end >= result.length ||\n result[end] === '/' ||\n result[end] === '?' ||\n result[end] === '#'\n ) {\n result = `${result.substring(\n 0,\n start + 1,\n )}[${expr}]${result.substring(end)}`;\n break;\n }\n start += value.length + 1;\n }\n }\n }\n return result;\n}\n","import { name as packageName, version } from '../package.json';\nimport { initQueue } from './queue';\nimport type { SpeedInsightsProps } from './types';\nimport { isBrowser, isDevelopment } from './utils';\n\nconst DEV_SCRIPT_URL = `https://va.vercel-scripts.com/v1/speed-insights/script.debug.js`;\nconst SCRIPT_URL = `/_vercel/speed-insights/script.js`;\n\n/**\n * Injects the Vercel Speed Insights script into the page head and starts tracking page views. Read more in our [documentation](https://vercel.com/docs/speed-insights).\n * @param [props] - Speed Insights options.\n * @param [props.debug] - Whether to enable debug logging in development. Defaults to `true`.\n * @param [props.beforeSend] - A middleware function to modify events before they are sent. Should return the event object or `null` to cancel the event.\n */\nfunction inject(props: SpeedInsightsProps): {\n setRoute: (route: string) => void;\n} | null {\n if (!isBrowser()) return null;\n\n initQueue();\n\n if (props.beforeSend) {\n window.si?.('beforeSend', props.beforeSend);\n }\n const src =\n props.scriptSrc || (isDevelopment() ? DEV_SCRIPT_URL : SCRIPT_URL);\n\n if (document.head.querySelector(`script[src*=\"${src}\"]`)) return null;\n\n const script = document.createElement('script');\n script.src = src;\n script.defer = true;\n script.dataset.sdkn = packageName;\n script.dataset.sdkv = version;\n\n if (props.sampleRate) {\n script.dataset.sampleRate = props.sampleRate.toString();\n }\n if (props.route) {\n script.dataset.route = props.route;\n }\n if (props.endpoint) {\n script.dataset.endpoint = props.endpoint;\n }\n if (props.token) {\n script.dataset.token = props.token;\n }\n if (isDevelopment() && props.debug === false) {\n script.dataset.debug = 'false';\n }\n\n script.onerror = (): void => {\n const errorMessage = isDevelopment()\n ? 'Please check if any ad blockers are enabled and try again.'\n : 'Be sure to enable Speed Insights for your project and deploy again. See https://vercel.com/docs/speed-insights for more information.';\n\n // eslint-disable-next-line no-console -- Logging is okay here\n console.log(\n `[Vercel Speed Insights] Failed to load script from ${src}. ${errorMessage}`,\n );\n };\n\n document.head.appendChild(script);\n\n return {\n setRoute: (route: string): void => {\n script.dataset.route = route;\n },\n };\n}\n\nexport { inject };\nexport type { SpeedInsightsProps };\n\n// eslint-disable-next-line import/no-default-export -- Allow default export\nexport default {\n inject,\n};\n","'use client';\nimport { useParams, usePathname } from 'next/navigation';\nimport { computeRoute } from '../utils';\n\nexport const useRoute = (): string | null => {\n const params = useParams();\n const path = usePathname();\n\n return computeRoute(path, params);\n};\n"],"mappings":"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","names":["SpeedInsights","import_react","SpeedInsights","React"]}
|
package/dist/next/index.d.cts
CHANGED
|
@@ -1,7 +1,35 @@
|
|
|
1
1
|
interface SpeedInsightsProps {
|
|
2
|
-
token
|
|
2
|
+
token?: string;
|
|
3
3
|
sampleRate?: number;
|
|
4
|
+
route?: string;
|
|
5
|
+
beforeSend?: BeforeSendMiddleware;
|
|
6
|
+
debug?: boolean;
|
|
7
|
+
scriptSrc?: string;
|
|
8
|
+
endpoint?: string;
|
|
4
9
|
}
|
|
5
|
-
|
|
10
|
+
type EventTypes = 'vital';
|
|
11
|
+
interface Event {
|
|
12
|
+
type: EventTypes;
|
|
13
|
+
url: string;
|
|
14
|
+
}
|
|
15
|
+
type BeforeSendMiddleware = (data: Event) => Event | null | undefined | false;
|
|
16
|
+
interface Functions {
|
|
17
|
+
beforeSend?: BeforeSendMiddleware;
|
|
18
|
+
}
|
|
19
|
+
interface SpeedInsights$1<T extends keyof Functions = keyof Functions> {
|
|
20
|
+
queue: [T, Functions[T]][];
|
|
21
|
+
addAction: (action: T, data: Functions[T]) => void;
|
|
22
|
+
}
|
|
23
|
+
declare global {
|
|
24
|
+
interface Window {
|
|
25
|
+
/** Base interface to track events */
|
|
26
|
+
si?: SpeedInsights$1['addAction'];
|
|
27
|
+
/** Queue for speed insights datapoints, before the library is loaded */
|
|
28
|
+
siq?: SpeedInsights$1['queue'];
|
|
29
|
+
sil?: boolean;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
declare function SpeedInsights(props: Omit<SpeedInsightsProps, 'route'>): JSX.Element;
|
|
6
34
|
|
|
7
35
|
export { SpeedInsights };
|
package/dist/next/index.d.ts
CHANGED
|
@@ -1,7 +1,35 @@
|
|
|
1
1
|
interface SpeedInsightsProps {
|
|
2
|
-
token
|
|
2
|
+
token?: string;
|
|
3
3
|
sampleRate?: number;
|
|
4
|
+
route?: string;
|
|
5
|
+
beforeSend?: BeforeSendMiddleware;
|
|
6
|
+
debug?: boolean;
|
|
7
|
+
scriptSrc?: string;
|
|
8
|
+
endpoint?: string;
|
|
4
9
|
}
|
|
5
|
-
|
|
10
|
+
type EventTypes = 'vital';
|
|
11
|
+
interface Event {
|
|
12
|
+
type: EventTypes;
|
|
13
|
+
url: string;
|
|
14
|
+
}
|
|
15
|
+
type BeforeSendMiddleware = (data: Event) => Event | null | undefined | false;
|
|
16
|
+
interface Functions {
|
|
17
|
+
beforeSend?: BeforeSendMiddleware;
|
|
18
|
+
}
|
|
19
|
+
interface SpeedInsights$1<T extends keyof Functions = keyof Functions> {
|
|
20
|
+
queue: [T, Functions[T]][];
|
|
21
|
+
addAction: (action: T, data: Functions[T]) => void;
|
|
22
|
+
}
|
|
23
|
+
declare global {
|
|
24
|
+
interface Window {
|
|
25
|
+
/** Base interface to track events */
|
|
26
|
+
si?: SpeedInsights$1['addAction'];
|
|
27
|
+
/** Queue for speed insights datapoints, before the library is loaded */
|
|
28
|
+
siq?: SpeedInsights$1['queue'];
|
|
29
|
+
sil?: boolean;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
declare function SpeedInsights(props: Omit<SpeedInsightsProps, 'route'>): JSX.Element;
|
|
6
34
|
|
|
7
35
|
export { SpeedInsights };
|
package/dist/next/index.js
CHANGED
|
@@ -1,116 +1,42 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/nextjs/index.tsx
|
|
4
|
-
import
|
|
4
|
+
import React from "react";
|
|
5
5
|
|
|
6
|
-
// src/
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
// src/react/index.tsx
|
|
7
|
+
import { useEffect, useRef } from "react";
|
|
8
|
+
|
|
9
|
+
// package.json
|
|
10
|
+
var name = "@vercel/speed-insights";
|
|
11
|
+
var version = "0.0.1-beta.5";
|
|
12
|
+
|
|
13
|
+
// src/queue.ts
|
|
14
|
+
var initQueue = () => {
|
|
15
|
+
if (window.si)
|
|
16
|
+
return;
|
|
17
|
+
window.si = function a(...params) {
|
|
18
|
+
(window.siq = window.siq || []).push(params);
|
|
19
|
+
};
|
|
20
|
+
};
|
|
15
21
|
|
|
16
22
|
// src/utils.ts
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
if ("connection" in navigator) {
|
|
20
|
-
const connection = navigator.connection;
|
|
21
|
-
if (connection == null ? void 0 : connection.effectiveType) {
|
|
22
|
-
speed = connection.effectiveType;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
return speed;
|
|
23
|
+
function isBrowser() {
|
|
24
|
+
return typeof window !== "undefined";
|
|
26
25
|
}
|
|
27
|
-
|
|
28
|
-
function sendBeacon(data) {
|
|
29
|
-
const blob = new Blob([JSON.stringify(data)], {
|
|
30
|
-
type: "text/plain"
|
|
31
|
-
});
|
|
26
|
+
function detectEnvironment() {
|
|
32
27
|
try {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
body: blob,
|
|
37
|
-
keepalive: true,
|
|
38
|
-
mode: "no-cors",
|
|
39
|
-
credentials: "omit"
|
|
40
|
-
});
|
|
41
|
-
} else if ("sendBeacon" in navigator) {
|
|
42
|
-
navigator.sendBeacon(ENDPOINT, blob);
|
|
28
|
+
const env = process.env.NODE_ENV;
|
|
29
|
+
if (env === "development" || env === "test") {
|
|
30
|
+
return "development";
|
|
43
31
|
}
|
|
44
32
|
} catch (e) {
|
|
45
33
|
}
|
|
34
|
+
return "production";
|
|
46
35
|
}
|
|
47
|
-
function
|
|
48
|
-
|
|
49
|
-
return metric.attribution.largestShiftTarget;
|
|
50
|
-
}
|
|
51
|
-
if (metric.name === "FID") {
|
|
52
|
-
return metric.attribution.eventTarget;
|
|
53
|
-
}
|
|
54
|
-
if (metric.name === "LCP") {
|
|
55
|
-
return metric.attribution.element;
|
|
56
|
-
}
|
|
36
|
+
function isDevelopment() {
|
|
37
|
+
return detectEnvironment() === "development";
|
|
57
38
|
}
|
|
58
|
-
function
|
|
59
|
-
if (Number.isInteger(number)) {
|
|
60
|
-
return number;
|
|
61
|
-
}
|
|
62
|
-
const multiplier = Math.pow(10, decimals);
|
|
63
|
-
return Math.floor(number * multiplier) / multiplier;
|
|
64
|
-
}
|
|
65
|
-
function formatMetricValue(metric) {
|
|
66
|
-
if (metric.name === "CLS") {
|
|
67
|
-
return cutDecimal(metric.value, 4);
|
|
68
|
-
}
|
|
69
|
-
if (metric.name === "FID") {
|
|
70
|
-
return cutDecimal(metric.value, 2);
|
|
71
|
-
}
|
|
72
|
-
return Math.round(metric.value);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// src/generic/index.ts
|
|
76
|
-
function sendVitals(metrics, dsn) {
|
|
77
|
-
const speed = getConnectionSpeed();
|
|
78
|
-
if (metrics.length === 0)
|
|
79
|
-
return;
|
|
80
|
-
const payload = {
|
|
81
|
-
dsn,
|
|
82
|
-
speed,
|
|
83
|
-
metrics: metrics.map((metric) => ({
|
|
84
|
-
id: metric.id,
|
|
85
|
-
type: metric.name,
|
|
86
|
-
value: formatMetricValue(metric),
|
|
87
|
-
dynamicPath: metric.dynamicPath,
|
|
88
|
-
href: window.location.href.replace("http://", "https://"),
|
|
89
|
-
// TODO: remove this
|
|
90
|
-
attribution: {
|
|
91
|
-
target: getDomTarget(metric)
|
|
92
|
-
}
|
|
93
|
-
}))
|
|
94
|
-
};
|
|
95
|
-
sendBeacon(payload);
|
|
96
|
-
}
|
|
97
|
-
function watchMetrics(callback) {
|
|
98
|
-
onCLS(callback);
|
|
99
|
-
onFID(callback);
|
|
100
|
-
onLCP(callback);
|
|
101
|
-
onFCP(callback);
|
|
102
|
-
onINP(callback);
|
|
103
|
-
onTTFB(callback);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// src/nextjs/utils.ts
|
|
107
|
-
import { useParams, usePathname } from "next/navigation";
|
|
108
|
-
var useDynamicPath = () => {
|
|
109
|
-
const params = useParams();
|
|
110
|
-
const path = usePathname();
|
|
111
|
-
return computePathname(path, params);
|
|
112
|
-
};
|
|
113
|
-
function computePathname(pathname, pathParams) {
|
|
39
|
+
function computeRoute(pathname, pathParams) {
|
|
114
40
|
if (pathname === null) {
|
|
115
41
|
return null;
|
|
116
42
|
}
|
|
@@ -150,41 +76,83 @@ function computePathname(pathname, pathParams) {
|
|
|
150
76
|
return result;
|
|
151
77
|
}
|
|
152
78
|
|
|
153
|
-
// src/
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
79
|
+
// src/generic.ts
|
|
80
|
+
var DEV_SCRIPT_URL = `https://va.vercel-scripts.com/v1/speed-insights/script.debug.js`;
|
|
81
|
+
var SCRIPT_URL = `/_vercel/speed-insights/script.js`;
|
|
82
|
+
function inject(props) {
|
|
83
|
+
var _a;
|
|
84
|
+
if (!isBrowser())
|
|
85
|
+
return null;
|
|
86
|
+
initQueue();
|
|
87
|
+
if (props.beforeSend) {
|
|
88
|
+
(_a = window.si) == null ? void 0 : _a.call(window, "beforeSend", props.beforeSend);
|
|
89
|
+
}
|
|
90
|
+
const src = props.scriptSrc || (isDevelopment() ? DEV_SCRIPT_URL : SCRIPT_URL);
|
|
91
|
+
if (document.head.querySelector(`script[src*="${src}"]`))
|
|
92
|
+
return null;
|
|
93
|
+
const script = document.createElement("script");
|
|
94
|
+
script.src = src;
|
|
95
|
+
script.defer = true;
|
|
96
|
+
script.dataset.sdkn = name;
|
|
97
|
+
script.dataset.sdkv = version;
|
|
98
|
+
if (props.sampleRate) {
|
|
99
|
+
script.dataset.sampleRate = props.sampleRate.toString();
|
|
100
|
+
}
|
|
101
|
+
if (props.route) {
|
|
102
|
+
script.dataset.route = props.route;
|
|
103
|
+
}
|
|
104
|
+
if (props.endpoint) {
|
|
105
|
+
script.dataset.endpoint = props.endpoint;
|
|
106
|
+
}
|
|
107
|
+
if (props.token) {
|
|
108
|
+
script.dataset.token = props.token;
|
|
109
|
+
}
|
|
110
|
+
if (isDevelopment() && props.debug === false) {
|
|
111
|
+
script.dataset.debug = "false";
|
|
112
|
+
}
|
|
113
|
+
script.onerror = () => {
|
|
114
|
+
const errorMessage = isDevelopment() ? "Please check if any ad blockers are enabled and try again." : "Be sure to enable Speed Insights for your project and deploy again. See https://vercel.com/docs/speed-insights for more information.";
|
|
115
|
+
console.log(
|
|
116
|
+
`[Vercel Speed Insights] Failed to load script from ${src}. ${errorMessage}`
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
document.head.appendChild(script);
|
|
120
|
+
return {
|
|
121
|
+
setRoute: (route) => {
|
|
122
|
+
script.dataset.route = route;
|
|
166
123
|
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
removeEventListener("pagehide", flush);
|
|
174
|
-
};
|
|
175
|
-
}, [flush]);
|
|
176
|
-
const reportVital = useCallback(
|
|
177
|
-
(metric) => {
|
|
178
|
-
vitals.current.push({ ...metric, dynamicPath });
|
|
179
|
-
},
|
|
180
|
-
[dynamicPath]
|
|
181
|
-
);
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/react/index.tsx
|
|
128
|
+
function SpeedInsights(props) {
|
|
129
|
+
const setScriptRoute = useRef(null);
|
|
182
130
|
useEffect(() => {
|
|
183
|
-
|
|
131
|
+
const script = inject(props);
|
|
132
|
+
setScriptRoute.current = (script == null ? void 0 : script.setRoute) || null;
|
|
184
133
|
}, []);
|
|
134
|
+
useEffect(() => {
|
|
135
|
+
if (props.route && setScriptRoute.current) {
|
|
136
|
+
setScriptRoute.current(props.route);
|
|
137
|
+
}
|
|
138
|
+
}, [props.route]);
|
|
185
139
|
return null;
|
|
186
140
|
}
|
|
141
|
+
|
|
142
|
+
// src/nextjs/utils.ts
|
|
143
|
+
import { useParams, usePathname } from "next/navigation";
|
|
144
|
+
var useRoute = () => {
|
|
145
|
+
const params = useParams();
|
|
146
|
+
const path = usePathname();
|
|
147
|
+
return computeRoute(path, params);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
// src/nextjs/index.tsx
|
|
151
|
+
function SpeedInsights2(props) {
|
|
152
|
+
const route = useRoute();
|
|
153
|
+
return /* @__PURE__ */ React.createElement(SpeedInsights, { ...route && { route }, ...props });
|
|
154
|
+
}
|
|
187
155
|
export {
|
|
188
|
-
SpeedInsights
|
|
156
|
+
SpeedInsights2 as SpeedInsights
|
|
189
157
|
};
|
|
190
158
|
//# sourceMappingURL=index.js.map
|