@spanwise/rum 0.4.3

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 (53) hide show
  1. package/dist/client.d.ts +51 -0
  2. package/dist/client.d.ts.map +1 -0
  3. package/dist/client.js +186 -0
  4. package/dist/client.js.map +1 -0
  5. package/dist/errors.d.ts +8 -0
  6. package/dist/errors.d.ts.map +1 -0
  7. package/dist/errors.js +67 -0
  8. package/dist/errors.js.map +1 -0
  9. package/dist/events.d.ts +78 -0
  10. package/dist/events.d.ts.map +1 -0
  11. package/dist/events.js +11 -0
  12. package/dist/events.js.map +1 -0
  13. package/dist/index.d.ts +4 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +3 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/instrumentation/fetch.d.ts +16 -0
  18. package/dist/instrumentation/fetch.d.ts.map +1 -0
  19. package/dist/instrumentation/fetch.js +109 -0
  20. package/dist/instrumentation/fetch.js.map +1 -0
  21. package/dist/instrumentation/xhr.d.ts +16 -0
  22. package/dist/instrumentation/xhr.d.ts.map +1 -0
  23. package/dist/instrumentation/xhr.js +129 -0
  24. package/dist/instrumentation/xhr.js.map +1 -0
  25. package/dist/otel.d.ts +55 -0
  26. package/dist/otel.d.ts.map +1 -0
  27. package/dist/otel.js +91 -0
  28. package/dist/otel.js.map +1 -0
  29. package/dist/session.d.ts +11 -0
  30. package/dist/session.d.ts.map +1 -0
  31. package/dist/session.js +176 -0
  32. package/dist/session.js.map +1 -0
  33. package/dist/span-transport.d.ts +18 -0
  34. package/dist/span-transport.d.ts.map +1 -0
  35. package/dist/span-transport.js +83 -0
  36. package/dist/span-transport.js.map +1 -0
  37. package/dist/spans.d.ts +30 -0
  38. package/dist/spans.d.ts.map +1 -0
  39. package/dist/spans.js +21 -0
  40. package/dist/spans.js.map +1 -0
  41. package/dist/trace-context.d.ts +37 -0
  42. package/dist/trace-context.d.ts.map +1 -0
  43. package/dist/trace-context.js +113 -0
  44. package/dist/trace-context.js.map +1 -0
  45. package/dist/transport.d.ts +15 -0
  46. package/dist/transport.d.ts.map +1 -0
  47. package/dist/transport.js +101 -0
  48. package/dist/transport.js.map +1 -0
  49. package/dist/vitals.d.ts +12 -0
  50. package/dist/vitals.d.ts.map +1 -0
  51. package/dist/vitals.js +48 -0
  52. package/dist/vitals.js.map +1 -0
  53. package/package.json +38 -0
@@ -0,0 +1,51 @@
1
+ import { type StorageMode } from "./session.js";
2
+ export type TracingConfig = {
3
+ /** Enable distributed tracing (default: true) */
4
+ enabled?: boolean;
5
+ /** Origins to propagate trace context to (default: same-origin only) */
6
+ propagateToOrigins?: (string | RegExp)[];
7
+ /** Trace fetch requests (default: true) */
8
+ traceFetch?: boolean;
9
+ /** Trace XMLHttpRequest (default: true) */
10
+ traceXHR?: boolean;
11
+ };
12
+ export type BrowserConfig = {
13
+ apiKey: string;
14
+ serviceName?: string;
15
+ baseUrl?: string;
16
+ sampleRate?: number;
17
+ trackClicks?: boolean;
18
+ trackPageViews?: boolean;
19
+ trackVitals?: boolean;
20
+ trackErrors?: boolean;
21
+ /** Track HTTP resources (fetch/XHR) with timing (default: true) */
22
+ trackResources?: boolean;
23
+ /** Distributed tracing configuration */
24
+ tracing?: TracingConfig;
25
+ /**
26
+ * Session storage mode (default: "cookie")
27
+ * - "cookie": Uses cookies with localStorage fallback. Survives OAuth redirects.
28
+ * Requires cookie consent in GDPR regions.
29
+ * - "sessionStorage": Original behavior. Tab-isolated, cleared on tab close.
30
+ * No cookie consent required.
31
+ */
32
+ sessionStorage?: StorageMode;
33
+ };
34
+ export declare function createSpanwiseBrowser(config: BrowserConfig): {
35
+ trackEvent: () => void;
36
+ trackPageView: () => void;
37
+ trackError: () => void;
38
+ setUser: () => void;
39
+ getSessionId: () => null;
40
+ } | {
41
+ trackEvent: (name: string, properties?: Record<string, unknown>) => void;
42
+ trackPageView: (url?: string) => void;
43
+ trackError: (error: Error, options?: {
44
+ requestId?: string;
45
+ traceId?: string;
46
+ }) => void;
47
+ setUser: (id: string, traits?: Record<string, unknown>) => void;
48
+ getSessionId: () => string;
49
+ };
50
+ export type SpanwiseBrowser = ReturnType<typeof createSpanwiseBrowser>;
51
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAYA,OAAO,EACN,KAAK,WAAW,EAIhB,MAAM,cAAc,CAAA;AAIrB,MAAM,MAAM,aAAa,GAAG;IAC3B,iDAAiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,wEAAwE;IACxE,kBAAkB,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;IACxC,2CAA2C;IAC3C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,mEAAmE;IACnE,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,wCAAwC;IACxC,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,WAAW,CAAA;CAC5B,CAAA;AAmBD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa;;;;;;;uBA4CnD,MAAM,eACC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAClC,IAAI;0BAhBsB,MAAM,KAAG,IAAI;wBA6BlC,KAAK,YACF;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAChD,IAAI;kBAKc,MAAM,WAAW,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,IAAI;wBAWtC,MAAM;EAgIpC;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAA"}
package/dist/client.js ADDED
@@ -0,0 +1,186 @@
1
+ import { captureError, setupErrorTracking } from "./errors.js";
2
+ import { createBaseEvent } from "./events.js";
3
+ import { instrumentFetch, updateFetchConfig } from "./instrumentation/fetch.js";
4
+ import { instrumentXHR, updateXHRConfig } from "./instrumentation/xhr.js";
5
+ import { getOrCreateSession, refreshSession, setStorageMode, } from "./session.js";
6
+ import { createTransport } from "./transport.js";
7
+ import { setupVitalsTracking } from "./vitals.js";
8
+ const DEFAULT_BASE_URL = "https://api.spanwise.dev";
9
+ function getClickTarget(element) {
10
+ if (element.id)
11
+ return `#${element.id}`;
12
+ const tag = element.tagName.toLowerCase();
13
+ const classes = Array.from(element.classList).slice(0, 3).join(".");
14
+ if (classes)
15
+ return `${tag}.${classes}`;
16
+ return tag;
17
+ }
18
+ function getClickText(element) {
19
+ const text = element.textContent?.trim().slice(0, 50);
20
+ return text || undefined;
21
+ }
22
+ export function createSpanwiseBrowser(config) {
23
+ // Apply sampling
24
+ const sampleRate = config.sampleRate ?? 1;
25
+ if (Math.random() > sampleRate) {
26
+ // Return no-op client
27
+ return {
28
+ trackEvent: () => { },
29
+ trackPageView: () => { },
30
+ trackError: () => { },
31
+ setUser: () => { },
32
+ getSessionId: () => null,
33
+ };
34
+ }
35
+ const baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
36
+ setStorageMode(config.sessionStorage ?? "cookie");
37
+ const { sessionId } = getOrCreateSession();
38
+ let userId;
39
+ const transport = createTransport({
40
+ apiKey: config.apiKey,
41
+ baseUrl,
42
+ serviceName: config.serviceName,
43
+ });
44
+ function enqueueEvent(event) {
45
+ refreshSession();
46
+ transport.enqueue(event);
47
+ }
48
+ function trackPageView(url) {
49
+ const event = {
50
+ ...createBaseEvent("page_view", sessionId, userId),
51
+ type: "page_view",
52
+ url: url ?? window.location.href,
53
+ data: {
54
+ referrer: document.referrer || undefined,
55
+ title: document.title,
56
+ },
57
+ };
58
+ enqueueEvent(event);
59
+ }
60
+ function trackEvent(name, properties) {
61
+ const event = {
62
+ ...createBaseEvent("custom", sessionId, userId),
63
+ type: "custom",
64
+ data: {
65
+ name,
66
+ properties,
67
+ },
68
+ };
69
+ enqueueEvent(event);
70
+ }
71
+ function trackError(error, options) {
72
+ const event = captureError(error, sessionId, userId, options);
73
+ enqueueEvent(event);
74
+ }
75
+ function setUser(id, traits) {
76
+ userId = id;
77
+ // Update instrumentation configs with new userId
78
+ updateFetchConfig(userId);
79
+ updateXHRConfig(userId);
80
+ // Optionally track user identification as custom event
81
+ if (traits) {
82
+ trackEvent("user_identified", { userId: id, ...traits });
83
+ }
84
+ }
85
+ function getSessionIdValue() {
86
+ return sessionId;
87
+ }
88
+ // Auto-tracking setup
89
+ if (config.trackPageViews !== false) {
90
+ // Track initial page view
91
+ trackPageView();
92
+ // Track SPA navigation
93
+ const originalPushState = history.pushState.bind(history);
94
+ const originalReplaceState = history.replaceState.bind(history);
95
+ history.pushState = (...args) => {
96
+ originalPushState(...args);
97
+ trackPageView();
98
+ };
99
+ history.replaceState = (...args) => {
100
+ originalReplaceState(...args);
101
+ trackPageView();
102
+ };
103
+ window.addEventListener("popstate", () => {
104
+ trackPageView();
105
+ });
106
+ }
107
+ if (config.trackClicks !== false) {
108
+ document.addEventListener("click", (event) => {
109
+ const target = event.target;
110
+ if (!target)
111
+ return;
112
+ // Only track interactive elements
113
+ const interactiveElements = [
114
+ "A",
115
+ "BUTTON",
116
+ "INPUT",
117
+ "SELECT",
118
+ "TEXTAREA",
119
+ ];
120
+ const isInteractive = interactiveElements.includes(target.tagName) ||
121
+ target.closest("a, button") !== null ||
122
+ target.getAttribute("role") === "button";
123
+ if (!isInteractive)
124
+ return;
125
+ const clickEvent = {
126
+ ...createBaseEvent("click", sessionId, userId),
127
+ type: "click",
128
+ data: {
129
+ target: getClickTarget(target),
130
+ text: getClickText(target),
131
+ x: event.clientX,
132
+ y: event.clientY,
133
+ },
134
+ };
135
+ enqueueEvent(clickEvent);
136
+ }, { capture: true });
137
+ }
138
+ if (config.trackVitals !== false) {
139
+ setupVitalsTracking(sessionId, userId, (event) => {
140
+ enqueueEvent(event);
141
+ }, () => {
142
+ transport.flushBeacon();
143
+ });
144
+ }
145
+ if (config.trackErrors !== false) {
146
+ setupErrorTracking(sessionId, userId, (event) => {
147
+ enqueueEvent(event);
148
+ });
149
+ }
150
+ // Resource tracking: capture HTTP requests with timing and trace correlation
151
+ // - trackResources: store resource events in RUM (default: true)
152
+ // - tracing.enabled: inject traceparent headers for backend correlation (default: true)
153
+ // If either is enabled, we instrument fetch/XHR
154
+ const shouldInstrument = config.trackResources !== false || config.tracing?.enabled !== false;
155
+ const shouldStoreResources = config.trackResources !== false;
156
+ if (shouldInstrument) {
157
+ const ingestUrl = `${baseUrl}/v1/ingest`;
158
+ const instrumentationConfig = {
159
+ propagateToOrigins: config.tracing?.propagateToOrigins,
160
+ sessionId,
161
+ userId,
162
+ ingestUrl,
163
+ };
164
+ const onResource = shouldStoreResources
165
+ ? (event) => enqueueEvent(event)
166
+ : () => { }; // traceparent injected but events not stored
167
+ // Capture network errors with URL context (only if error tracking enabled)
168
+ const onNetworkError = config.trackErrors !== false
169
+ ? (event) => enqueueEvent(event)
170
+ : undefined;
171
+ if (config.tracing?.traceFetch !== false) {
172
+ instrumentFetch(instrumentationConfig, onResource, onNetworkError);
173
+ }
174
+ if (config.tracing?.traceXHR !== false) {
175
+ instrumentXHR(instrumentationConfig, onResource, onNetworkError);
176
+ }
177
+ }
178
+ return {
179
+ trackEvent,
180
+ trackPageView,
181
+ trackError,
182
+ setUser,
183
+ getSessionId: getSessionIdValue,
184
+ };
185
+ }
186
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { ErrorEvent } from "./events.js";
2
+ export type ErrorCallback = (event: ErrorEvent) => void;
3
+ export declare function setupErrorTracking(sessionId: string, userId: string | undefined, onError: ErrorCallback): void;
4
+ export declare function captureError(error: Error, sessionId: string, userId: string | undefined, options?: {
5
+ requestId?: string;
6
+ traceId?: string;
7
+ }): ErrorEvent;
8
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAG7C,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;AAkBvD,wBAAgB,kBAAkB,CACjC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,aAAa,GACpB,IAAI,CAuCN;AAED,wBAAgB,YAAY,CAC3B,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,CAAC,EAAE;IACT,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB,GACC,UAAU,CAWZ"}
package/dist/errors.js ADDED
@@ -0,0 +1,67 @@
1
+ import { createBaseEvent } from "./events.js";
2
+ function getSelector(element) {
3
+ if (element.id)
4
+ return `#${element.id}`;
5
+ const tag = element.tagName.toLowerCase();
6
+ const classes = Array.from(element.classList).join(".");
7
+ if (classes)
8
+ return `${tag}.${classes}`;
9
+ return tag;
10
+ }
11
+ function getStackTrace(error) {
12
+ if (!error.stack)
13
+ return undefined;
14
+ // Limit stack trace length
15
+ return error.stack.slice(0, 2000);
16
+ }
17
+ export function setupErrorTracking(sessionId, userId, onError) {
18
+ // Capture unhandled errors
19
+ window.addEventListener("error", (event) => {
20
+ const errorEvent = {
21
+ ...createBaseEvent("error", sessionId, userId),
22
+ type: "error",
23
+ data: {
24
+ message: event.message || "Unknown error",
25
+ stack: event.error ? getStackTrace(event.error) : undefined,
26
+ filename: event.filename,
27
+ lineno: event.lineno,
28
+ colno: event.colno,
29
+ },
30
+ };
31
+ onError(errorEvent);
32
+ });
33
+ // Capture unhandled promise rejections
34
+ window.addEventListener("unhandledrejection", (event) => {
35
+ let message = "Unhandled Promise Rejection";
36
+ let stack;
37
+ if (event.reason instanceof Error) {
38
+ message = event.reason.message;
39
+ stack = getStackTrace(event.reason);
40
+ }
41
+ else if (typeof event.reason === "string") {
42
+ message = event.reason;
43
+ }
44
+ const errorEvent = {
45
+ ...createBaseEvent("error", sessionId, userId),
46
+ type: "error",
47
+ data: {
48
+ message,
49
+ stack,
50
+ },
51
+ };
52
+ onError(errorEvent);
53
+ });
54
+ }
55
+ export function captureError(error, sessionId, userId, options) {
56
+ return {
57
+ ...createBaseEvent("error", sessionId, userId),
58
+ type: "error",
59
+ data: {
60
+ message: error.message,
61
+ stack: getStackTrace(error),
62
+ requestId: options?.requestId,
63
+ traceId: options?.traceId,
64
+ },
65
+ };
66
+ }
67
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAI7C,SAAS,WAAW,CAAC,OAAgB;IACpC,IAAI,OAAO,CAAC,EAAE;QAAE,OAAO,IAAI,OAAO,CAAC,EAAE,EAAE,CAAA;IAEvC,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAA;IACzC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACvD,IAAI,OAAO;QAAE,OAAO,GAAG,GAAG,IAAI,OAAO,EAAE,CAAA;IAEvC,OAAO,GAAG,CAAA;AACX,CAAC;AAED,SAAS,aAAa,CAAC,KAAY;IAClC,IAAI,CAAC,KAAK,CAAC,KAAK;QAAE,OAAO,SAAS,CAAA;IAClC,2BAA2B;IAC3B,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;AAClC,CAAC;AAED,MAAM,UAAU,kBAAkB,CACjC,SAAiB,EACjB,MAA0B,EAC1B,OAAsB;IAEtB,2BAA2B;IAC3B,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QAC1C,MAAM,UAAU,GAAe;YAC9B,GAAG,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC;YAC9C,IAAI,EAAE,OAAO;YACb,IAAI,EAAE;gBACL,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,eAAe;gBACzC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;gBAC3D,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,KAAK,EAAE,KAAK,CAAC,KAAK;aAClB;SACD,CAAA;QACD,OAAO,CAAC,UAAU,CAAC,CAAA;IACpB,CAAC,CAAC,CAAA;IAEF,uCAAuC;IACvC,MAAM,CAAC,gBAAgB,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE;QACvD,IAAI,OAAO,GAAG,6BAA6B,CAAA;QAC3C,IAAI,KAAyB,CAAA;QAE7B,IAAI,KAAK,CAAC,MAAM,YAAY,KAAK,EAAE,CAAC;YACnC,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAA;YAC9B,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QACpC,CAAC;aAAM,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC7C,OAAO,GAAG,KAAK,CAAC,MAAM,CAAA;QACvB,CAAC;QAED,MAAM,UAAU,GAAe;YAC9B,GAAG,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC;YAC9C,IAAI,EAAE,OAAO;YACb,IAAI,EAAE;gBACL,OAAO;gBACP,KAAK;aACL;SACD,CAAA;QACD,OAAO,CAAC,UAAU,CAAC,CAAA;IACpB,CAAC,CAAC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAC3B,KAAY,EACZ,SAAiB,EACjB,MAA0B,EAC1B,OAGC;IAED,OAAO;QACN,GAAG,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC;QAC9C,IAAI,EAAE,OAAO;QACb,IAAI,EAAE;YACL,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC;YAC3B,SAAS,EAAE,OAAO,EAAE,SAAS;YAC7B,OAAO,EAAE,OAAO,EAAE,OAAO;SACzB;KACD,CAAA;AACF,CAAC"}
@@ -0,0 +1,78 @@
1
+ export type RumEventType = "page_view" | "click" | "vitals" | "error" | "custom" | "resource";
2
+ export type BaseEvent = {
3
+ type: RumEventType;
4
+ sessionId: string;
5
+ userId?: string;
6
+ timestamp: number;
7
+ url: string;
8
+ userAgent: string;
9
+ };
10
+ export type PageViewEvent = BaseEvent & {
11
+ type: "page_view";
12
+ data: {
13
+ referrer?: string;
14
+ title: string;
15
+ };
16
+ };
17
+ export type ClickEvent = BaseEvent & {
18
+ type: "click";
19
+ data: {
20
+ target: string;
21
+ text?: string;
22
+ x: number;
23
+ y: number;
24
+ };
25
+ };
26
+ export type VitalsEvent = BaseEvent & {
27
+ type: "vitals";
28
+ data: {
29
+ lcp?: number;
30
+ fid?: number;
31
+ cls?: number;
32
+ inp?: number;
33
+ ttfb?: number;
34
+ fcp?: number;
35
+ };
36
+ };
37
+ export type ErrorEvent = BaseEvent & {
38
+ type: "error";
39
+ data: {
40
+ message: string;
41
+ stack?: string;
42
+ filename?: string;
43
+ lineno?: number;
44
+ colno?: number;
45
+ requestId?: string;
46
+ /** Trace ID for correlation with backend traces */
47
+ traceId?: string;
48
+ /** URL that failed (for fetch/network errors) */
49
+ failedUrl?: string;
50
+ };
51
+ };
52
+ export type CustomEvent = BaseEvent & {
53
+ type: "custom";
54
+ data: {
55
+ name: string;
56
+ properties?: Record<string, unknown>;
57
+ };
58
+ };
59
+ export type ResourceEvent = BaseEvent & {
60
+ type: "resource";
61
+ data: {
62
+ /** Request URL */
63
+ resourceUrl: string;
64
+ /** HTTP method */
65
+ method: string;
66
+ /** HTTP status code */
67
+ status?: number;
68
+ /** Duration in milliseconds */
69
+ duration: number;
70
+ /** Initiator type */
71
+ initiatorType: "fetch" | "xhr";
72
+ /** Trace ID for correlation with backend traces */
73
+ traceId?: string;
74
+ };
75
+ };
76
+ export type RumEvent = PageViewEvent | ClickEvent | VitalsEvent | ErrorEvent | CustomEvent | ResourceEvent;
77
+ export declare function createBaseEvent(type: RumEventType, sessionId: string, userId?: string): BaseEvent;
78
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GACrB,WAAW,GACX,OAAO,GACP,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,UAAU,CAAA;AAEb,MAAM,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,YAAY,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG;IACvC,IAAI,EAAE,WAAW,CAAA;IACjB,IAAI,EAAE;QACL,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,KAAK,EAAE,MAAM,CAAA;KACb,CAAA;CACD,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG;IACpC,IAAI,EAAE,OAAO,CAAA;IACb,IAAI,EAAE;QACL,MAAM,EAAE,MAAM,CAAA;QACd,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,CAAC,EAAE,MAAM,CAAA;QACT,CAAC,EAAE,MAAM,CAAA;KACT,CAAA;CACD,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG;IACrC,IAAI,EAAE,QAAQ,CAAA;IACd,IAAI,EAAE;QACL,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,GAAG,CAAC,EAAE,MAAM,CAAA;KACZ,CAAA;CACD,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG;IACpC,IAAI,EAAE,OAAO,CAAA;IACb,IAAI,EAAE;QACL,OAAO,EAAE,MAAM,CAAA;QACf,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,mDAAmD;QACnD,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,iDAAiD;QACjD,SAAS,CAAC,EAAE,MAAM,CAAA;KAClB,CAAA;CACD,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG;IACrC,IAAI,EAAE,QAAQ,CAAA;IACd,IAAI,EAAE;QACL,IAAI,EAAE,MAAM,CAAA;QACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KACpC,CAAA;CACD,CAAA;AAED,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG;IACvC,IAAI,EAAE,UAAU,CAAA;IAChB,IAAI,EAAE;QACL,kBAAkB;QAClB,WAAW,EAAE,MAAM,CAAA;QACnB,kBAAkB;QAClB,MAAM,EAAE,MAAM,CAAA;QACd,uBAAuB;QACvB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,+BAA+B;QAC/B,QAAQ,EAAE,MAAM,CAAA;QAChB,qBAAqB;QACrB,aAAa,EAAE,OAAO,GAAG,KAAK,CAAA;QAC9B,mDAAmD;QACnD,OAAO,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACD,CAAA;AAED,MAAM,MAAM,QAAQ,GACjB,aAAa,GACb,UAAU,GACV,WAAW,GACX,UAAU,GACV,WAAW,GACX,aAAa,CAAA;AAEhB,wBAAgB,eAAe,CAC9B,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,GACb,SAAS,CASX"}
package/dist/events.js ADDED
@@ -0,0 +1,11 @@
1
+ export function createBaseEvent(type, sessionId, userId) {
2
+ return {
3
+ type,
4
+ sessionId,
5
+ userId,
6
+ timestamp: Date.now(),
7
+ url: window.location.href,
8
+ userAgent: navigator.userAgent,
9
+ };
10
+ }
11
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAiGA,MAAM,UAAU,eAAe,CAC9B,IAAkB,EAClB,SAAiB,EACjB,MAAe;IAEf,OAAO;QACN,IAAI;QACJ,SAAS;QACT,MAAM;QACN,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;QACzB,SAAS,EAAE,SAAS,CAAC,SAAS;KAC9B,CAAA;AACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { createSpanwiseBrowser, type BrowserConfig, type SpanwiseBrowser, type TracingConfig, } from "./client.js";
2
+ export type { RumEvent, RumEventType, PageViewEvent, ClickEvent, VitalsEvent, ErrorEvent, CustomEvent, ResourceEvent, } from "./events.js";
3
+ export { getSessionId, endSession, type StorageMode } from "./session.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,GAClB,MAAM,aAAa,CAAA;AACpB,YAAY,EACX,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,aAAa,GACb,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { createSpanwiseBrowser, } from "./client.js";
2
+ export { getSessionId, endSession } from "./session.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,qBAAqB,GAIrB,MAAM,aAAa,CAAA;AAWpB,OAAO,EAAE,YAAY,EAAE,UAAU,EAAoB,MAAM,cAAc,CAAA"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Fetch instrumentation for browser-side resource tracking.
3
+ * Intercepts fetch calls to inject traceparent headers and capture timing.
4
+ */
5
+ import type { ErrorEvent, ResourceEvent } from "../events.js";
6
+ export type FetchInstrumentationConfig = {
7
+ propagateToOrigins?: (string | RegExp)[];
8
+ sessionId: string;
9
+ userId?: string;
10
+ ingestUrl?: string;
11
+ };
12
+ export type FetchErrorCallback = (event: ErrorEvent) => void;
13
+ export declare function instrumentFetch(config: FetchInstrumentationConfig, onResource: (event: ResourceEvent) => void, onError?: FetchErrorCallback): void;
14
+ export declare function updateFetchConfig(userId?: string): void;
15
+ export declare function restoreFetch(): void;
16
+ //# sourceMappingURL=fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/instrumentation/fetch.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAS7D,MAAM,MAAM,0BAA0B,GAAG;IACxC,kBAAkB,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;IACxC,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;AAkC5D,wBAAgB,eAAe,CAC9B,MAAM,EAAE,0BAA0B,EAClC,UAAU,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,EAC1C,OAAO,CAAC,EAAE,kBAAkB,GAC1B,IAAI,CAmGN;AAED,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAIvD;AAED,wBAAgB,YAAY,IAAI,IAAI,CAOnC"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Fetch instrumentation for browser-side resource tracking.
3
+ * Intercepts fetch calls to inject traceparent headers and capture timing.
4
+ */
5
+ import { createBaseEvent } from "../events.js";
6
+ import { createTraceparent, generateSpanId, generateTraceId, shouldPropagate, } from "../trace-context.js";
7
+ // Module state for monkey-patching. Only one instrumentation instance supported.
8
+ let originalFetch = null;
9
+ let currentConfig = null;
10
+ let onFetchError = null;
11
+ function createResourceEvent(config, url, method, traceId, startTime, duration, status) {
12
+ return {
13
+ type: "resource",
14
+ sessionId: config.sessionId,
15
+ userId: config.userId,
16
+ timestamp: startTime,
17
+ url: window.location.href,
18
+ userAgent: navigator.userAgent,
19
+ data: {
20
+ resourceUrl: url,
21
+ method,
22
+ status,
23
+ duration,
24
+ initiatorType: "fetch",
25
+ traceId,
26
+ },
27
+ };
28
+ }
29
+ export function instrumentFetch(config, onResource, onError) {
30
+ if (originalFetch)
31
+ return;
32
+ originalFetch = window.fetch;
33
+ currentConfig = config;
34
+ onFetchError = onError ?? null;
35
+ window.fetch = async function instrumentedFetch(input, init) {
36
+ const url = typeof input === "string"
37
+ ? input
38
+ : input instanceof URL
39
+ ? input.toString()
40
+ : input.url;
41
+ // Skip internal requests (Next.js RSC, SDK telemetry)
42
+ if (url.includes("_rsc=") ||
43
+ (currentConfig?.ingestUrl && url.startsWith(currentConfig.ingestUrl))) {
44
+ // biome-ignore lint/style/noNonNullAssertion: checked at function entry
45
+ return originalFetch(input, init);
46
+ }
47
+ const method = init?.method ??
48
+ (typeof input !== "string" && !(input instanceof URL)
49
+ ? (input.method ?? "GET")
50
+ : "GET");
51
+ // Only inject traceparent for allowed origins
52
+ const shouldInjectTrace = shouldPropagate(url, currentConfig?.propagateToOrigins);
53
+ let traceId;
54
+ let modifiedInit = init;
55
+ if (shouldInjectTrace) {
56
+ traceId = generateTraceId();
57
+ const spanId = generateSpanId();
58
+ const traceparent = createTraceparent(traceId, spanId, true);
59
+ const headers = new Headers(init?.headers);
60
+ headers.set("traceparent", traceparent);
61
+ modifiedInit = { ...init, headers };
62
+ }
63
+ const startTime = Date.now();
64
+ try {
65
+ // biome-ignore lint/style/noNonNullAssertion: checked at function entry
66
+ const response = await originalFetch(input, modifiedInit);
67
+ const duration = Date.now() - startTime;
68
+ // biome-ignore lint/style/noNonNullAssertion: config set at function entry
69
+ const config = currentConfig;
70
+ onResource(createResourceEvent(config, url, method, traceId, startTime, duration, response.status));
71
+ return response;
72
+ }
73
+ catch (error) {
74
+ const duration = Date.now() - startTime;
75
+ // biome-ignore lint/style/noNonNullAssertion: config set at function entry
76
+ const config = currentConfig;
77
+ onResource(createResourceEvent(config, url, method, traceId, startTime, duration));
78
+ // Emit error event with the failed URL for better debugging
79
+ if (onFetchError && error instanceof Error) {
80
+ const errorEvent = {
81
+ ...createBaseEvent("error", config.sessionId, config.userId),
82
+ type: "error",
83
+ data: {
84
+ message: error.message,
85
+ stack: error.stack?.slice(0, 2000),
86
+ failedUrl: url,
87
+ traceId,
88
+ },
89
+ };
90
+ onFetchError(errorEvent);
91
+ }
92
+ throw error;
93
+ }
94
+ };
95
+ }
96
+ export function updateFetchConfig(userId) {
97
+ if (currentConfig) {
98
+ currentConfig.userId = userId;
99
+ }
100
+ }
101
+ export function restoreFetch() {
102
+ if (originalFetch) {
103
+ window.fetch = originalFetch;
104
+ originalFetch = null;
105
+ currentConfig = null;
106
+ onFetchError = null;
107
+ }
108
+ }
109
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/instrumentation/fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * XMLHttpRequest instrumentation for browser-side resource tracking.
3
+ * Intercepts XHR calls to inject traceparent headers and capture timing.
4
+ */
5
+ import type { ErrorEvent, ResourceEvent } from "../events.js";
6
+ export type XHRInstrumentationConfig = {
7
+ propagateToOrigins?: (string | RegExp)[];
8
+ sessionId: string;
9
+ userId?: string;
10
+ ingestUrl?: string;
11
+ };
12
+ export type XHRErrorCallback = (event: ErrorEvent) => void;
13
+ export declare function instrumentXHR(config: XHRInstrumentationConfig, onResource: (event: ResourceEvent) => void, onError?: XHRErrorCallback): void;
14
+ export declare function updateXHRConfig(userId?: string): void;
15
+ export declare function restoreXHR(): void;
16
+ //# sourceMappingURL=xhr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xhr.d.ts","sourceRoot":"","sources":["../../src/instrumentation/xhr.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAS7D,MAAM,MAAM,wBAAwB,GAAG;IACtC,kBAAkB,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;IACxC,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;AA2C1D,wBAAgB,aAAa,CAC5B,MAAM,EAAE,wBAAwB,EAChC,UAAU,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,EAC1C,OAAO,CAAC,EAAE,gBAAgB,GACxB,IAAI,CA8GN;AAED,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAIrD;AAED,wBAAgB,UAAU,IAAI,IAAI,CAWjC"}