@faststats/web 0.5.0 → 0.7.0
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/dist/chunks/api-urls-Dp2XNjRF.js +46 -0
- package/dist/chunks/identifiers-BvRNbiwA.js +21 -0
- package/dist/chunks/{replay-CLfrGjqj.d.ts → replay-BeC2XA4N.d.ts} +35 -9
- package/dist/chunks/send-data-DR1JUXka.js +201 -0
- package/dist/error.d.ts +2 -1
- package/dist/error.js +135 -2
- package/dist/feature-flags.js +32 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.js +462 -1
- package/dist/replay.d.ts +1 -1
- package/dist/replay.js +579 -1
- package/dist/web-vitals.d.ts +3 -4
- package/dist/web-vitals.js +94 -1
- package/package.json +2 -2
- package/dist/chunks/api-urls-Bh77rElT.js +0 -1
- package/dist/chunks/identifiers-DcGHdsnG.js +0 -1
- package/dist/chunks/send-data-CIbuTxPh.js +0 -1
package/dist/web-vitals.js
CHANGED
|
@@ -1 +1,94 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import { a as resolveBaseUrl, o as sanitizeUrl, r as URLS, t as ANALYTICS_BASE } from "./chunks/api-urls-Dp2XNjRF.js";
|
|
2
|
+
import { r as getSessionContext, t as sendData } from "./chunks/send-data-DR1JUXka.js";
|
|
3
|
+
//#region src/web-vitals.ts
|
|
4
|
+
const METRIC_NAMES = /* @__PURE__ */ new Set([
|
|
5
|
+
"CLS",
|
|
6
|
+
"INP",
|
|
7
|
+
"LCP",
|
|
8
|
+
"FCP",
|
|
9
|
+
"TTFB"
|
|
10
|
+
]);
|
|
11
|
+
var WebVitalsTracker = class {
|
|
12
|
+
options;
|
|
13
|
+
endpoint;
|
|
14
|
+
metrics = /* @__PURE__ */ new Map();
|
|
15
|
+
started = false;
|
|
16
|
+
flushing = false;
|
|
17
|
+
initialUrl = "";
|
|
18
|
+
session = null;
|
|
19
|
+
constructor(options) {
|
|
20
|
+
this.options = options;
|
|
21
|
+
this.endpoint = `${resolveBaseUrl(options.baseUrl, ANALYTICS_BASE)}${URLS.vitals}`;
|
|
22
|
+
}
|
|
23
|
+
async start() {
|
|
24
|
+
if (this.started || typeof window === "undefined") return;
|
|
25
|
+
this.started = true;
|
|
26
|
+
this.initialUrl = sanitizeUrl(window.location.href, this.options.trackHash ?? false);
|
|
27
|
+
this.session = getSessionContext(this.options.siteKey);
|
|
28
|
+
const mod = await (this.options.attribution ? import("web-vitals/attribution") : import("web-vitals"));
|
|
29
|
+
if (!this.started) return;
|
|
30
|
+
const changes = { reportAllChanges: true };
|
|
31
|
+
mod.onCLS(this.onMetric, changes);
|
|
32
|
+
mod.onINP(this.onMetric, changes);
|
|
33
|
+
mod.onLCP(this.onMetric, changes);
|
|
34
|
+
mod.onFCP(this.onMetric);
|
|
35
|
+
mod.onTTFB(this.onMetric);
|
|
36
|
+
}
|
|
37
|
+
stop(discard = false) {
|
|
38
|
+
if (!this.started) return;
|
|
39
|
+
this.started = false;
|
|
40
|
+
if (discard) this.metrics.clear();
|
|
41
|
+
else this.flush();
|
|
42
|
+
}
|
|
43
|
+
onPageHidden(persisted = false) {
|
|
44
|
+
if (persisted) return;
|
|
45
|
+
queueMicrotask(() => void this.flush());
|
|
46
|
+
}
|
|
47
|
+
onMetric = (metric) => {
|
|
48
|
+
if (!this.started) return;
|
|
49
|
+
const name = metric.name;
|
|
50
|
+
if (!METRIC_NAMES.has(name) || !Number.isFinite(metric.value) || metric.value < 0) return;
|
|
51
|
+
const { id, rating, delta, navigationType } = metric;
|
|
52
|
+
const attribution = "attribution" in metric && metric.attribution ? metric.attribution : void 0;
|
|
53
|
+
this.metrics.set(name, {
|
|
54
|
+
metric: name,
|
|
55
|
+
value: metric.value,
|
|
56
|
+
attributes: {
|
|
57
|
+
id,
|
|
58
|
+
rating,
|
|
59
|
+
delta,
|
|
60
|
+
navigationType,
|
|
61
|
+
...attribution
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
async flush() {
|
|
66
|
+
if (!this.metrics.size || this.flushing) return;
|
|
67
|
+
this.flushing = true;
|
|
68
|
+
const batch = this.metrics;
|
|
69
|
+
this.metrics = /* @__PURE__ */ new Map();
|
|
70
|
+
const session = this.session ?? getSessionContext(this.options.siteKey);
|
|
71
|
+
let sent = false;
|
|
72
|
+
try {
|
|
73
|
+
sent = await sendData({
|
|
74
|
+
url: this.endpoint,
|
|
75
|
+
data: JSON.stringify({
|
|
76
|
+
token: this.options.siteKey,
|
|
77
|
+
sessionId: session.sessionId,
|
|
78
|
+
windowId: session.windowId,
|
|
79
|
+
vitals: [...batch.values()],
|
|
80
|
+
metadata: { url: this.initialUrl }
|
|
81
|
+
}),
|
|
82
|
+
debug: this.options.debug,
|
|
83
|
+
debugPrefix: "[WebVitals]"
|
|
84
|
+
});
|
|
85
|
+
} finally {
|
|
86
|
+
if (!sent) {
|
|
87
|
+
for (const [name, vital] of batch) if (!this.metrics.has(name)) this.metrics.set(name, vital);
|
|
88
|
+
}
|
|
89
|
+
this.flushing = false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
//#endregion
|
|
94
|
+
export { WebVitalsTracker as default };
|
package/package.json
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"publishConfig": {
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
|
-
"version": "0.
|
|
45
|
+
"version": "0.7.0",
|
|
46
46
|
"scripts": {
|
|
47
47
|
"build": "tsdown && bun run check-size",
|
|
48
48
|
"dev": "bun run build",
|
|
@@ -60,6 +60,6 @@
|
|
|
60
60
|
"@rrweb/record": "^2.1.0",
|
|
61
61
|
"@rrweb/rrweb-plugin-console-record": "^2.1.0",
|
|
62
62
|
"@rrweb/rrweb-plugin-sequential-id-record": "^2.1.0",
|
|
63
|
-
"web-vitals": "^
|
|
63
|
+
"web-vitals": "^6.0.0"
|
|
64
64
|
}
|
|
65
65
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e=`https://metrics.faststats.dev`,t=`https://flags.faststats.dev`;function n(e,t){return e?.replace(/\/+$/,``)||t}const r={events:`/v1/web`,identify:`/v1/identify`,replay:`/v1/replay`,vitals:`/v1/vitals`,flags:`/v1/check`},i=[`utm_source`,`utm_medium`,`utm_campaign`,`utm_term`,`utm_content`];function a(){let e={page:location.pathname,url:location.href,referrer:document.referrer||null,title:document.title||``};if(!location.search)return e;let t=new URLSearchParams(location.search);for(let n of i){let r=t.get(n);r&&(e[n]=r)}return e}export{n as a,a as i,t as n,r,e as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e,n as t}from"./send-data-CIbuTxPh.js";const n=`faststats_anon_id`;function r(){try{return globalThis.localStorage}catch{return}}function i(){let e=r();if(!e)return``;try{let r=e.getItem(n);if(r)return r;let i=t();return e.setItem(n,i),i}catch{return``}}function a(t){return t??e()?``:i()}function o(e){if(e)return``;try{let e=r();if(!e)return``;e.removeItem(n)}catch{return``}return i()}export{o as n,a as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e=`faststats_session`;let t=!1,n=null;const r=new Set;function i(e){try{return globalThis[e]}catch{return null}}function a(){return typeof crypto<`u`&&`randomUUID`in crypto?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}function o(){let t=i(`localStorage`);if(!t)return n;let r=t.getItem(e);if(r)try{let e=JSON.parse(r);if(e.id)return e}catch{}return n}function s(t){let r=i(`localStorage`);if(!r){n=t;return}try{r.setItem(e,JSON.stringify(t))}catch{n=t}}function c(){n=null;try{i(`localStorage`)?.removeItem(e)}catch{}}function l(e,t){return t-e.activity>=18e5||t-e.start>=864e5}function u(e,t){for(let n of r)n(e,t)}function d(e,t){let r=Date.now();if(e)return n?t&&(n.activity=r):n={id:a(),start:r,activity:r},{session:n,rotated:!1,previous:null};let i=o();if(i&&!l(i,r))return t&&(i.activity=r,s(i)),{session:i,rotated:!1,previous:null};let c=i,u={id:a(),start:r,activity:r};return s(u),{session:u,rotated:c!==null,previous:c}}function f(e,t,n){if(t)return n;let r=`faststats_window_id_${e}`,o=i(`sessionStorage`);if(!o)return n;try{let e=o.getItem(r);if(e)return e;let t=a();return o.setItem(r,t),t}catch{return n}}function p(e,t,n,r){let i=r??f(e,n,t.id);return{sessionId:t.id,windowId:i,sessionStart:t.start}}function m(e){t=e,n=null}function h(){return t}function g(e,n){let r=n??t,{session:i}=d(r,!1);return p(e,i,r)}function _(e,n){let r=n??t,{session:i,rotated:a,previous:o}=d(r,!0);if(!a||!o)return null;let s=f(e,r,i.id),c={prev:p(e,o,r,s),next:p(e,i,r,s)};return u(c.prev,c.next),c}function v(e){let r=t,o=g(e,r);if(c(),r){let e=Date.now();n={id:a(),start:e,activity:e}}else try{i(`sessionStorage`)?.removeItem(`faststats_window_id_${e}`)}catch{}let s=g(e,r);return o.sessionId!==s.sessionId&&u(o,s),s}function y(e){return r.add(e),()=>r.delete(e)}async function b(e){let{url:t,data:n,contentType:r=`application/json`,headers:i={},debug:a=!1,debugPrefix:o=`[Analytics]`,useBeacon:s=!0,keepalive:c=!0,signal:l}=e;if(l?.aborted)return!1;if(s&&typeof globalThis.navigator?.sendBeacon==`function`)try{let e=n instanceof Blob||typeof Blob>`u`?n:new Blob([n],{type:r});if(globalThis.navigator.sendBeacon(t,e))return a&&console.log(`${o} Sent via beacon`),!0}catch{}try{let e=await fetch(t,{method:`POST`,body:n,headers:{"Content-Type":r,...i},keepalive:c,credentials:`omit`,signal:l}),s=e.ok;if(a){let t=s?`${o} Sent via fetch`:`${o} Failed: ${e.status}`;console[s?`log`:`warn`](t)}return s}catch{return a&&console.warn(`${o} Failed to send`),!1}}export{y as a,_ as c,h as i,a as n,v as o,g as r,m as s,b as t};
|