@debugbundle/sdk-browser 1.4.0 → 1.5.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.
Files changed (40) hide show
  1. package/README.md +27 -0
  2. package/dist/analytics-friction.d.ts +8 -0
  3. package/dist/analytics-friction.d.ts.map +1 -0
  4. package/dist/analytics-friction.js +59 -0
  5. package/dist/analytics-friction.js.map +1 -0
  6. package/dist/analytics-normalization.d.ts +17 -0
  7. package/dist/analytics-normalization.d.ts.map +1 -0
  8. package/dist/analytics-normalization.js +276 -0
  9. package/dist/analytics-normalization.js.map +1 -0
  10. package/dist/analytics.d.ts +41 -0
  11. package/dist/analytics.d.ts.map +1 -0
  12. package/dist/analytics.js +410 -0
  13. package/dist/analytics.js.map +1 -0
  14. package/dist/capture-helpers.d.ts +11 -0
  15. package/dist/capture-helpers.d.ts.map +1 -0
  16. package/dist/capture-helpers.js +156 -0
  17. package/dist/capture-helpers.js.map +1 -0
  18. package/dist/event-pipeline.d.ts +13 -0
  19. package/dist/event-pipeline.d.ts.map +1 -0
  20. package/dist/event-pipeline.js +96 -0
  21. package/dist/event-pipeline.js.map +1 -0
  22. package/dist/event-transport.d.ts +31 -0
  23. package/dist/event-transport.d.ts.map +1 -0
  24. package/dist/event-transport.js +217 -0
  25. package/dist/event-transport.js.map +1 -0
  26. package/dist/index.d.ts +10 -31
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +147 -672
  29. package/dist/index.js.map +1 -1
  30. package/dist/probes.d.ts +39 -0
  31. package/dist/probes.d.ts.map +1 -0
  32. package/dist/probes.js +190 -0
  33. package/dist/probes.js.map +1 -0
  34. package/dist/runtime.d.ts +4 -2
  35. package/dist/runtime.d.ts.map +1 -1
  36. package/dist/runtime.js +52 -0
  37. package/dist/runtime.js.map +1 -1
  38. package/dist/types.d.ts +123 -1
  39. package/dist/types.d.ts.map +1 -1
  40. package/package.json +3 -3
package/README.md CHANGED
@@ -102,6 +102,33 @@ Network wrapping is designed to preserve normal browser behavior. The SDK suppor
102
102
 
103
103
  `tracePropagationTargets` is separate from the relay `endpoint`. Same-origin application requests receive trace headers by default. For split frontend/backend deployments, add the backend API origin, such as `https://api.example.com`, when cross-origin first-party requests should receive `X-DebugBundle-Trace-Id` and be eligible for policy-driven request-failure promotion. Third-party absolute URLs are not traced by default.
104
104
 
105
+ ### AnalyticsBundle Capture
106
+
107
+ Analytics is opt-in and remains separate from debug capture:
108
+
109
+ ```ts
110
+ debugbundle.init({
111
+ transportMode: "relay",
112
+ endpoint: "/debugbundle/browser",
113
+ service: "checkout-web",
114
+ environment: "production",
115
+ analytics: {
116
+ enabled: true,
117
+ trackActions: true
118
+ }
119
+ });
120
+
121
+ debugbundle.analytics.marker("checkout.validation_failed", {
122
+ attempt_bucket: 3
123
+ });
124
+ ```
125
+
126
+ `marker()` emits a bounded `journey_marker` with a privacy-safe marker key and optional low-cardinality dimensions. `trackActions: true` additionally emits generic structural action keys such as `click.button` and `click.link`; it is independent from debug `captureClicks` and never retains target text, selectors, IDs, URLs, attributes, or form values. `trackFrictionSignals` defaults to true and emits only fixed `friction.repeated_click`, `friction.dead_click`, and `friction.backtrack` markers from bounded in-memory click timing and route reversal heuristics; it never serializes target-derived data. The SDK emits one `session_summary` before a non-persisted `pagehide` and reuses its existing beacon/keepalive flush path. It does not emit a summary when a page enters the back-forward cache.
127
+
128
+ For direct-cloud installs, `privacyMode: "standard"` keeps an opaque first-party anonymous visitor value in browser storage under a key derived from the SHA-256 digest of the public write-only project token. Events contain only a separate SHA-256-derived `visitor_id_hash`, enabling returning-visitor metrics without persisting or emitting the token or raw value. The SDK removes that value when consent is withdrawn or server settings force strict privacy. If browser storage or Web Crypto is unavailable, it safely falls back to session-only analytics. Relay installs remain session-only for visitor identity until the relay has an authenticated project-scope bootstrap; the relay/ingestion path still enforces project settings.
129
+
130
+ For direct-cloud installs, the SDK explicitly requests the project analytics capture block from `GET /v1/sdk/config` once during initialization. That server block can only restrict a local analytics opt-in: it can disable capture, turn off page/route/action capture, require explicit consent, or force strict privacy. It cannot enable analytics or broaden capture. Relay installs do not fetch it because the browser must not hold a project token.
131
+
105
132
  Handled HTTP responses do not need to throw an exception to become request incidents. A failed response can emit a standalone `request_event` when it is first-party for trace propagation and matches the active capture preset, `immediate_client_error_statuses`, or an `immediate_client_error_path_rules` entry. Unpromoted `4xx` responses remain breadcrumbs/context.
106
133
 
107
134
  ### Local beforeSend hook
@@ -0,0 +1,8 @@
1
+ export declare class BrowserAnalyticsFrictionTracker {
2
+ private clickStates;
3
+ private recentRouteTransition;
4
+ reset(): void;
5
+ recordClick(targetIdentity: unknown, isStructuralTarget: boolean, isDeadClickCandidate: boolean, nowMs: number): "friction.repeated_click" | "friction.dead_click" | null;
6
+ recordRouteTransition(fromPath: string | null, toPath: string | null, nowMs: number): "friction.backtrack" | null;
7
+ }
8
+ //# sourceMappingURL=analytics-friction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics-friction.d.ts","sourceRoot":"","sources":["../src/analytics-friction.ts"],"names":[],"mappings":"AAiBA,qBAAa,+BAA+B;IAC1C,OAAO,CAAC,WAAW,CAA6C;IAChE,OAAO,CAAC,qBAAqB,CAAqC;IAE3D,KAAK,IAAI,IAAI;IAKb,WAAW,CAChB,cAAc,EAAE,OAAO,EACvB,kBAAkB,EAAE,OAAO,EAC3B,oBAAoB,EAAE,OAAO,EAC7B,KAAK,EAAE,MAAM,GACZ,yBAAyB,GAAG,qBAAqB,GAAG,IAAI;IAuCpD,qBAAqB,CAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,KAAK,EAAE,MAAM,GACZ,oBAAoB,GAAG,IAAI;CAc/B"}
@@ -0,0 +1,59 @@
1
+ const FRICTION_CLICK_THRESHOLD = 3;
2
+ const FRICTION_CLICK_WINDOW_MS = 2_000;
3
+ const FRICTION_CLICK_COOLDOWN_MS = 10_000;
4
+ const FRICTION_BACKTRACK_WINDOW_MS = 10_000;
5
+ export class BrowserAnalyticsFrictionTracker {
6
+ clickStates = new WeakMap();
7
+ recentRouteTransition = null;
8
+ reset() {
9
+ this.clickStates = new WeakMap();
10
+ this.recentRouteTransition = null;
11
+ }
12
+ recordClick(targetIdentity, isStructuralTarget, isDeadClickCandidate, nowMs) {
13
+ if (targetIdentity === null || typeof targetIdentity !== "object") {
14
+ return null;
15
+ }
16
+ const prior = this.clickStates.get(targetIdentity);
17
+ if (prior !== undefined && nowMs < prior.cooldownUntilMs) {
18
+ return null;
19
+ }
20
+ const count = prior !== undefined && nowMs - prior.lastClickedAtMs <= FRICTION_CLICK_WINDOW_MS ? prior.count + 1 : 1;
21
+ const nextState = {
22
+ count,
23
+ lastClickedAtMs: nowMs,
24
+ cooldownUntilMs: 0
25
+ };
26
+ if (count < FRICTION_CLICK_THRESHOLD) {
27
+ this.clickStates.set(targetIdentity, nextState);
28
+ return null;
29
+ }
30
+ const markerKey = isStructuralTarget
31
+ ? "friction.repeated_click"
32
+ : isDeadClickCandidate
33
+ ? "friction.dead_click"
34
+ : null;
35
+ if (markerKey === null) {
36
+ this.clickStates.set(targetIdentity, nextState);
37
+ return null;
38
+ }
39
+ this.clickStates.set(targetIdentity, {
40
+ count: 0,
41
+ lastClickedAtMs: nowMs,
42
+ cooldownUntilMs: nowMs + FRICTION_CLICK_COOLDOWN_MS
43
+ });
44
+ return markerKey;
45
+ }
46
+ recordRouteTransition(fromPath, toPath, nowMs) {
47
+ if (fromPath === null || toPath === null || fromPath === toPath) {
48
+ return null;
49
+ }
50
+ const prior = this.recentRouteTransition;
51
+ const isBacktrack = prior !== null &&
52
+ nowMs - prior.occurredAtMs <= FRICTION_BACKTRACK_WINDOW_MS &&
53
+ prior.fromPath === toPath &&
54
+ prior.toPath === fromPath;
55
+ this.recentRouteTransition = { fromPath, toPath, occurredAtMs: nowMs };
56
+ return isBacktrack ? "friction.backtrack" : null;
57
+ }
58
+ }
59
+ //# sourceMappingURL=analytics-friction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics-friction.js","sourceRoot":"","sources":["../src/analytics-friction.ts"],"names":[],"mappings":"AAAA,MAAM,wBAAwB,GAAG,CAAC,CAAC;AACnC,MAAM,wBAAwB,GAAG,KAAK,CAAC;AACvC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAC1C,MAAM,4BAA4B,GAAG,MAAM,CAAC;AAc5C,MAAM,OAAO,+BAA+B;IAClC,WAAW,GAAG,IAAI,OAAO,EAA8B,CAAC;IACxD,qBAAqB,GAAgC,IAAI,CAAC;IAE3D,KAAK;QACV,IAAI,CAAC,WAAW,GAAG,IAAI,OAAO,EAA8B,CAAC;QAC7D,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;IACpC,CAAC;IAEM,WAAW,CAChB,cAAuB,EACvB,kBAA2B,EAC3B,oBAA6B,EAC7B,KAAa;QAEb,IAAI,cAAc,KAAK,IAAI,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE,CAAC;YAClE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACnD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,GAAG,KAAK,CAAC,eAAe,EAAE,CAAC;YACzD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,KAAK,SAAS,IAAI,KAAK,GAAG,KAAK,CAAC,eAAe,IAAI,wBAAwB,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrH,MAAM,SAAS,GAAuB;YACpC,KAAK;YACL,eAAe,EAAE,KAAK;YACtB,eAAe,EAAE,CAAC;SACnB,CAAC;QACF,IAAI,KAAK,GAAG,wBAAwB,EAAE,CAAC;YACrC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,SAAS,GAAG,kBAAkB;YAClC,CAAC,CAAC,yBAAyB;YAC3B,CAAC,CAAC,oBAAoB;gBACpB,CAAC,CAAC,qBAAqB;gBACvB,CAAC,CAAC,IAAI,CAAC;QACX,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,cAAc,EAAE;YACnC,KAAK,EAAE,CAAC;YACR,eAAe,EAAE,KAAK;YACtB,eAAe,EAAE,KAAK,GAAG,0BAA0B;SACpD,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;IACnB,CAAC;IAEM,qBAAqB,CAC1B,QAAuB,EACvB,MAAqB,EACrB,KAAa;QAEb,IAAI,QAAQ,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;YAChE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,qBAAqB,CAAC;QACzC,MAAM,WAAW,GACf,KAAK,KAAK,IAAI;YACd,KAAK,GAAG,KAAK,CAAC,YAAY,IAAI,4BAA4B;YAC1D,KAAK,CAAC,QAAQ,KAAK,MAAM;YACzB,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC;QAC5B,IAAI,CAAC,qBAAqB,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;QACvE,OAAO,WAAW,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC;IACnD,CAAC;CACF"}
@@ -0,0 +1,17 @@
1
+ import type { ActiveConfig, BrowserAnalyticsCustomDimensions, BrowserAnalyticsDimensions, BrowserAnalyticsEventEnvelope, BrowserAnalyticsPrivacyMode, BrowserDeviceInfo } from "./types.js";
2
+ export interface StandardAnalyticsVisitor {
3
+ storageKey: string;
4
+ visitorIdHash: string;
5
+ }
6
+ export declare function resolveStandardAnalyticsVisitor(projectToken: string): Promise<StandardAnalyticsVisitor | null>;
7
+ export declare function removeStoredAnalyticsVisitor(storageKey: string): void;
8
+ export declare function normalizeAnalyticsPrivacyMode(value: unknown): BrowserAnalyticsPrivacyMode;
9
+ export declare function getAnalyticsProjectTokenFields(config: ActiveConfig): Record<string, string>;
10
+ export declare function normalizeAnalyticsSignal(signal: Partial<BrowserAnalyticsEventEnvelope["payload"]["signal"]>): BrowserAnalyticsEventEnvelope["payload"]["signal"];
11
+ export declare function getStructuralActionKey(target: Record<string, unknown>): string | null;
12
+ export declare function isDeadClickCandidate(target: Record<string, unknown>): boolean;
13
+ export declare function normalizeAnalyticsRoute(path: string | null | undefined, title: string | null): BrowserAnalyticsEventEnvelope["payload"]["route"];
14
+ export declare function sanitizeAnalyticsCustomDimensions(input: Record<string, unknown>): BrowserAnalyticsCustomDimensions;
15
+ export declare function omitBuiltInAnalyticsDimensions(dimensions: BrowserAnalyticsCustomDimensions): BrowserAnalyticsCustomDimensions;
16
+ export declare function buildAnalyticsDimensions(device: BrowserDeviceInfo | null, trackReferrers: boolean, customDimensions: BrowserAnalyticsCustomDimensions): BrowserAnalyticsDimensions;
17
+ //# sourceMappingURL=analytics-normalization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics-normalization.d.ts","sourceRoot":"","sources":["../src/analytics-normalization.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,YAAY,EACZ,gCAAgC,EAEhC,0BAA0B,EAC1B,6BAA6B,EAC7B,2BAA2B,EAC3B,iBAAiB,EAClB,MAAM,YAAY,CAAC;AA6CpB,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,+BAA+B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAcpH;AAED,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAMrE;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,2BAA2B,CAEzF;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAE3F;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,OAAO,CAAC,6BAA6B,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,GAClE,6BAA6B,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAQpD;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CAiBrF;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAG7E;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,KAAK,EAAE,MAAM,GAAG,IAAI,GACnB,6BAA6B,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAqBnD;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,gCAAgC,CAgBlH;AAED,wBAAgB,8BAA8B,CAC5C,UAAU,EAAE,gCAAgC,GAC3C,gCAAgC,CAMlC;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,iBAAiB,GAAG,IAAI,EAChC,cAAc,EAAE,OAAO,EACvB,gBAAgB,EAAE,gCAAgC,GACjD,0BAA0B,CAqB5B"}
@@ -0,0 +1,276 @@
1
+ import { createBrowserTraceId, getCryptoSource, getDocumentSource, getLocalStorageSource, getLocationSource } from "./runtime.js";
2
+ const MAX_CUSTOM_DIMENSIONS = 8;
3
+ const MAX_CUSTOM_KEY_LENGTH = 64;
4
+ const MAX_CUSTOM_STRING_LENGTH = 128;
5
+ const SIGNAL_KEY_PATTERN = /^[A-Za-z][A-Za-z0-9_.:-]*$/;
6
+ const CUSTOM_KEY_PATTERN = /^[A-Za-z][A-Za-z0-9_.-]*$/;
7
+ const SENSITIVE_KEY_PATTERN = /(password|passwd|secret|token|authorization|cookie|email|phone|address|card|credit|ssn|user.?id|order.?id|ticket.?id|workspace.?id)/i;
8
+ const STRUCTURAL_ACTION_KEYS_BY_TAG = {
9
+ a: "click.link",
10
+ button: "click.button",
11
+ input: "click.input",
12
+ select: "click.select",
13
+ summary: "click.summary"
14
+ };
15
+ const STRUCTURAL_ACTION_KEYS_BY_ROLE = {
16
+ button: "click.button",
17
+ checkbox: "click.checkbox",
18
+ link: "click.link",
19
+ menuitem: "click.menuitem",
20
+ radio: "click.radio",
21
+ switch: "click.switch",
22
+ tab: "click.tab"
23
+ };
24
+ const STRUCTURAL_INPUT_TYPES = new Set(["button", "checkbox", "radio", "reset", "submit"]);
25
+ const NON_FRICTION_CONTROL_TAGS = new Set(["input", "textarea", "select", "option", "label"]);
26
+ const STANDARD_VISITOR_STORAGE_PREFIX = "debugbundle.analytics.visitor.v1";
27
+ const BUILT_IN_DIMENSION_KEYS = new Set([
28
+ "auth_state",
29
+ "device_type",
30
+ "browser_family",
31
+ "browser_major",
32
+ "os_family",
33
+ "os_major",
34
+ "language",
35
+ "locale",
36
+ "viewport_bucket",
37
+ "referrer_domain",
38
+ "utm_source",
39
+ "utm_medium",
40
+ "utm_campaign",
41
+ "country_code",
42
+ "region_code"
43
+ ]);
44
+ export async function resolveStandardAnalyticsVisitor(projectToken) {
45
+ const projectScopeHash = await hashAnalyticsValue(projectToken);
46
+ if (projectScopeHash === null) {
47
+ return null;
48
+ }
49
+ const storageKey = `${STANDARD_VISITOR_STORAGE_PREFIX}.${projectScopeHash.slice("sha256:".length)}`;
50
+ const visitorId = getOrCreateStoredVisitor(storageKey);
51
+ if (visitorId === null) {
52
+ return null;
53
+ }
54
+ const visitorIdHash = await hashAnalyticsValue(`${projectScopeHash}:${visitorId}`);
55
+ return visitorIdHash === null ? null : { storageKey, visitorIdHash };
56
+ }
57
+ export function removeStoredAnalyticsVisitor(storageKey) {
58
+ try {
59
+ getLocalStorageSource()?.removeItem(storageKey);
60
+ }
61
+ catch {
62
+ // Storage access must never affect host application behavior.
63
+ }
64
+ }
65
+ export function normalizeAnalyticsPrivacyMode(value) {
66
+ return value === "standard" || value === "custom" ? value : "strict";
67
+ }
68
+ export function getAnalyticsProjectTokenFields(config) {
69
+ return config.projectToken === null ? {} : { project_token: config.projectToken };
70
+ }
71
+ export function normalizeAnalyticsSignal(signal) {
72
+ return {
73
+ action_key: normalizeSignalKey(signal.action_key),
74
+ funnel_key: normalizeSignalKey(signal.funnel_key),
75
+ step_key: normalizeSignalKey(signal.step_key),
76
+ conversion_key: normalizeSignalKey(signal.conversion_key),
77
+ marker_key: normalizeSignalKey(signal.marker_key)
78
+ };
79
+ }
80
+ export function getStructuralActionKey(target) {
81
+ const role = normalizeStructuralActionValue(target["role"]);
82
+ if (role !== null && STRUCTURAL_ACTION_KEYS_BY_ROLE[role] !== undefined) {
83
+ return STRUCTURAL_ACTION_KEYS_BY_ROLE[role];
84
+ }
85
+ const tagName = normalizeStructuralActionValue(target["tagName"]);
86
+ if (tagName === null) {
87
+ return null;
88
+ }
89
+ if (tagName === "input") {
90
+ const inputType = normalizeStructuralActionValue(target["type"]);
91
+ if (inputType !== null && STRUCTURAL_INPUT_TYPES.has(inputType)) {
92
+ return `click.input.${inputType}`;
93
+ }
94
+ }
95
+ return STRUCTURAL_ACTION_KEYS_BY_TAG[tagName] ?? null;
96
+ }
97
+ export function isDeadClickCandidate(target) {
98
+ const tagName = normalizeStructuralActionValue(target["tagName"]);
99
+ return tagName !== null && !NON_FRICTION_CONTROL_TAGS.has(tagName);
100
+ }
101
+ export function normalizeAnalyticsRoute(path, title) {
102
+ if (typeof path !== "string" || path.trim().length === 0) {
103
+ return null;
104
+ }
105
+ try {
106
+ const parsed = new URL(path, getLocationSource()?.href ?? "https://debugbundle.local");
107
+ return { path: parsed.pathname || "/", normalized_path: parsed.pathname || "/", title: normalizeTitle(title) };
108
+ }
109
+ catch {
110
+ const queryIndex = path.indexOf("?");
111
+ const fragmentIndex = path.indexOf("#");
112
+ const end = queryIndex === -1
113
+ ? (fragmentIndex === -1 ? path.length : fragmentIndex)
114
+ : fragmentIndex === -1 ? queryIndex : Math.min(queryIndex, fragmentIndex);
115
+ const normalized = path.slice(0, end).trim();
116
+ if (normalized.length === 0) {
117
+ return null;
118
+ }
119
+ const normalizedPath = normalized.startsWith("/") ? normalized : `/${normalized}`;
120
+ return { path: normalizedPath, normalized_path: normalizedPath, title: normalizeTitle(title) };
121
+ }
122
+ }
123
+ export function sanitizeAnalyticsCustomDimensions(input) {
124
+ const output = {};
125
+ for (const [rawKey, rawValue] of Object.entries(input)) {
126
+ if (Object.keys(output).length >= MAX_CUSTOM_DIMENSIONS) {
127
+ break;
128
+ }
129
+ const key = normalizeCustomDimensionKey(rawKey);
130
+ if (key === null || BUILT_IN_DIMENSION_KEYS.has(key)) {
131
+ continue;
132
+ }
133
+ const value = normalizeCustomDimensionValue(key, rawValue);
134
+ if (value !== undefined) {
135
+ output[key] = value;
136
+ }
137
+ }
138
+ return output;
139
+ }
140
+ export function omitBuiltInAnalyticsDimensions(dimensions) {
141
+ const output = { ...dimensions };
142
+ for (const key of BUILT_IN_DIMENSION_KEYS) {
143
+ delete output[key];
144
+ }
145
+ return output;
146
+ }
147
+ export function buildAnalyticsDimensions(device, trackReferrers, customDimensions) {
148
+ const language = normalizeLocale(device?.language ?? null);
149
+ const locationSource = getLocationSource();
150
+ const params = new URLSearchParams(typeof locationSource?.search === "string" ? locationSource.search.replace(/^\?/, "") : "");
151
+ return {
152
+ auth_state: normalizeAuthState(customDimensions["auth_state"]),
153
+ device_type: device?.device_type ?? "unknown",
154
+ browser_family: normalizeDimensionText(device?.browser.name ?? null, 80),
155
+ browser_major: parseMajorVersion(device?.browser.version ?? null),
156
+ os_family: normalizeDimensionText(device?.os.name ?? null, 80),
157
+ os_major: parseMajorVersion(device?.os.version ?? null),
158
+ language,
159
+ locale: language,
160
+ viewport_bucket: getViewportBucket(device),
161
+ referrer_domain: trackReferrers ? getReferrerDomain() : null,
162
+ utm_source: normalizeDimensionText(params.get("utm_source"), 128),
163
+ utm_medium: normalizeDimensionText(params.get("utm_medium"), 128),
164
+ utm_campaign: normalizeDimensionText(params.get("utm_campaign"), 128),
165
+ country_code: null,
166
+ region_code: null
167
+ };
168
+ }
169
+ function getOrCreateStoredVisitor(storageKey) {
170
+ const storage = getLocalStorageSource();
171
+ if (storage === null) {
172
+ return null;
173
+ }
174
+ try {
175
+ const existing = storage.getItem(storageKey);
176
+ if (typeof existing === "string" && /^[a-f0-9-]{16,128}$/i.test(existing)) {
177
+ return existing;
178
+ }
179
+ const visitorId = createBrowserTraceId();
180
+ if (!/^[a-f0-9-]{16,128}$/i.test(visitorId)) {
181
+ return null;
182
+ }
183
+ storage.setItem(storageKey, visitorId);
184
+ return visitorId;
185
+ }
186
+ catch {
187
+ return null;
188
+ }
189
+ }
190
+ async function hashAnalyticsValue(value) {
191
+ const cryptoSource = getCryptoSource();
192
+ const TextEncoderConstructor = globalThis["TextEncoder"];
193
+ if (typeof cryptoSource?.subtle?.digest !== "function" || TextEncoderConstructor === undefined) {
194
+ return null;
195
+ }
196
+ const digest = await cryptoSource.subtle.digest("SHA-256", new TextEncoderConstructor().encode(value));
197
+ return `sha256:${Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
198
+ }
199
+ function normalizeSignalKey(value) {
200
+ if (typeof value !== "string") {
201
+ return null;
202
+ }
203
+ const trimmed = value.trim();
204
+ return SIGNAL_KEY_PATTERN.test(trimmed) && trimmed.length <= 120 ? trimmed : null;
205
+ }
206
+ function normalizeStructuralActionValue(value) {
207
+ if (typeof value !== "string") {
208
+ return null;
209
+ }
210
+ const normalized = value.trim().toLowerCase();
211
+ return normalized.length > 0 && normalized.length <= 32 ? normalized : null;
212
+ }
213
+ function normalizeTitle(value) {
214
+ if (typeof value !== "string") {
215
+ return null;
216
+ }
217
+ const trimmed = value.trim();
218
+ return trimmed.length > 0 ? trimmed.slice(0, 200) : null;
219
+ }
220
+ function normalizeCustomDimensionKey(value) {
221
+ const trimmed = value.trim();
222
+ return trimmed.length > 0 && trimmed.length <= MAX_CUSTOM_KEY_LENGTH && CUSTOM_KEY_PATTERN.test(trimmed) && !SENSITIVE_KEY_PATTERN.test(trimmed)
223
+ ? trimmed
224
+ : null;
225
+ }
226
+ function normalizeCustomDimensionValue(key, value) {
227
+ if (value === null || typeof value === "boolean") {
228
+ return value;
229
+ }
230
+ if (typeof value === "number" && Number.isFinite(value) && value >= -1_000_000 && value <= 1_000_000) {
231
+ return value;
232
+ }
233
+ if (typeof value !== "string") {
234
+ return undefined;
235
+ }
236
+ const trimmed = value.trim();
237
+ return trimmed.length > 0 && trimmed.length <= MAX_CUSTOM_STRING_LENGTH && !SENSITIVE_KEY_PATTERN.test(trimmed) && !SENSITIVE_KEY_PATTERN.test(key)
238
+ ? trimmed
239
+ : undefined;
240
+ }
241
+ function normalizeAuthState(value) {
242
+ return value === "authenticated" || value === "unknown" ? value : "anonymous";
243
+ }
244
+ function normalizeDimensionText(value, maxLength) {
245
+ if (typeof value !== "string") {
246
+ return null;
247
+ }
248
+ const trimmed = value.trim();
249
+ return trimmed.length > 0 ? trimmed.slice(0, maxLength) : null;
250
+ }
251
+ function normalizeLocale(value) {
252
+ const normalized = normalizeDimensionText(value, 35);
253
+ return normalized !== null && /^[A-Za-z]{2,8}(-[A-Za-z0-9]{1,8})*$/.test(normalized) ? normalized : null;
254
+ }
255
+ function parseMajorVersion(value) {
256
+ const major = typeof value === "string" ? Number.parseInt(value.split(".")[0] ?? "", 10) : Number.NaN;
257
+ return Number.isFinite(major) && major >= 0 ? major : null;
258
+ }
259
+ function getViewportBucket(device) {
260
+ const width = device?.viewport.width ?? 0;
261
+ return width <= 0 ? "unknown" : width < 640 ? "small" : width < 1024 ? "medium" : "large";
262
+ }
263
+ function getReferrerDomain() {
264
+ const referrer = getDocumentSource()?.referrer;
265
+ if (typeof referrer !== "string" || referrer.trim().length === 0) {
266
+ return null;
267
+ }
268
+ try {
269
+ const hostname = new URL(referrer).hostname;
270
+ return hostname.length > 0 && hostname.length <= 255 ? hostname : null;
271
+ }
272
+ catch {
273
+ return null;
274
+ }
275
+ }
276
+ //# sourceMappingURL=analytics-normalization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics-normalization.js","sourceRoot":"","sources":["../src/analytics-normalization.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { type ActiveConfig, type BrowserAnalyticsEventEnvelope, type BrowserRemoteAnalyticsConfig, type BrowserDeviceInfo, type DebugBundleBrowserAnalytics, type DebugBundleBrowserAnalyticsConfig } from "./types.js";
2
+ export declare class BrowserAnalyticsController {
3
+ private readonly host;
4
+ private active;
5
+ private lastRoute;
6
+ private sessionSummaryCaptured;
7
+ private readonly frictionTracker;
8
+ constructor(host: {
9
+ getConfig(): ActiveConfig | null;
10
+ getDeviceInfo(): BrowserDeviceInfo | null;
11
+ getCurrentRoute(): string | null;
12
+ getSessionId(): string;
13
+ enqueue(event: BrowserAnalyticsEventEnvelope): void;
14
+ });
15
+ readonly api: DebugBundleBrowserAnalytics;
16
+ configure(config: DebugBundleBrowserAnalyticsConfig | undefined, options?: {
17
+ deferCapture?: boolean;
18
+ }): void;
19
+ markCaptureReady(): void;
20
+ reset(): void;
21
+ captureSessionStart(): void;
22
+ captureSessionSummary(): void;
23
+ prepareForUnload(): void;
24
+ captureInitialPageView(): void;
25
+ captureRouteChange(path: string): void;
26
+ applyRemoteSettings(remote: BrowserRemoteAnalyticsConfig): void;
27
+ shouldCaptureStructuralActions(): boolean;
28
+ shouldCaptureFrictionSignals(): boolean;
29
+ captureStructuralAction(target: Record<string, unknown>): void;
30
+ captureFrictionClick(target: Record<string, unknown>, targetIdentity: unknown): void;
31
+ private capturePageView;
32
+ private captureBacktrackFriction;
33
+ private captureSignal;
34
+ private enqueue;
35
+ private initializeStandardVisitor;
36
+ private clearStandardVisitor;
37
+ private flushPendingEvents;
38
+ private setContext;
39
+ private captureWhenReady;
40
+ }
41
+ //# sourceMappingURL=analytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"AAkBA,OAAO,EAGL,KAAK,YAAY,EAEjB,KAAK,6BAA6B,EAGlC,KAAK,4BAA4B,EACjC,KAAK,iBAAiB,EACtB,KAAK,2BAA2B,EAChC,KAAK,iCAAiC,EAEvC,MAAM,YAAY,CAAC;AAiCpB,qBAAa,0BAA0B;IAOnC,OAAO,CAAC,QAAQ,CAAC,IAAI;IANvB,OAAO,CAAC,MAAM,CAA6C;IAC3D,OAAO,CAAC,SAAS,CAA2D;IAC5E,OAAO,CAAC,sBAAsB,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAyC;gBAGtD,IAAI,EAAE;QACrB,SAAS,IAAI,YAAY,GAAG,IAAI,CAAC;QACjC,aAAa,IAAI,iBAAiB,GAAG,IAAI,CAAC;QAC1C,eAAe,IAAI,MAAM,GAAG,IAAI,CAAC;QACjC,YAAY,IAAI,MAAM,CAAC;QACvB,OAAO,CAAC,KAAK,EAAE,6BAA6B,GAAG,IAAI,CAAC;KACrD;IAGH,SAAgB,GAAG,EAAE,2BAA2B,CAyC9C;IAEK,SAAS,CACd,MAAM,EAAE,iCAAiC,GAAG,SAAS,EACrD,OAAO,GAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAO,GACvC,IAAI;IAmDA,gBAAgB,IAAI,IAAI;IAgBxB,KAAK,IAAI,IAAI;IAOb,mBAAmB,IAAI,IAAI;IAQ3B,qBAAqB,IAAI,IAAI;IAU7B,gBAAgB,IAAI,IAAI;IAQxB,sBAAsB,IAAI,IAAI;IAQ9B,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQtC,mBAAmB,CAAC,MAAM,EAAE,4BAA4B,GAAG,IAAI;IA2B/D,8BAA8B,IAAI,OAAO;IAIzC,4BAA4B,IAAI,OAAO;IAIvC,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAiB9D,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,EAAE,OAAO,GAAG,IAAI;IAqB3F,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,wBAAwB;IAoBhC,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,OAAO;YAuED,yBAAyB;IAwCvC,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,UAAU;IAkBlB,OAAO,CAAC,gBAAgB;CAazB"}