routeflow-browser 0.1.1 → 0.1.4

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/client.d.ts CHANGED
@@ -2,6 +2,10 @@
2
2
  * HTTP client for sending events to Routeflow backend.
3
3
  */
4
4
  import { IngestPayload } from "./types";
5
+ /**
6
+ * Get the RouteFlow backend URL (for telemetry ingestion).
7
+ */
8
+ export declare function getRouteflowBackendUrl(): string;
5
9
  /**
6
10
  * Send events to Routeflow backend.
7
11
  */
package/dist/client.js CHANGED
@@ -1,17 +1,21 @@
1
1
  /**
2
2
  * HTTP client for sending events to Routeflow backend.
3
3
  */
4
- // Use localhost for development, production URL for deployed environments
5
- const BACKEND_URL = window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1"
6
- ? "http://127.0.0.1:5004"
7
- : "https://routeflow-backend-production.up.railway.app";
4
+ // Hardcoded RouteFlow backend URL - always use production
5
+ const ROUTEFLOW_BACKEND_URL = "https://routeflow-backend-production.up.railway.app";
8
6
  const INGEST_ENDPOINT = "/v1/ingest";
7
+ /**
8
+ * Get the RouteFlow backend URL (for telemetry ingestion).
9
+ */
10
+ export function getRouteflowBackendUrl() {
11
+ return ROUTEFLOW_BACKEND_URL;
12
+ }
9
13
  /**
10
14
  * Send events to Routeflow backend.
11
15
  */
12
16
  export async function sendEvents(payload, ingestKey) {
13
17
  try {
14
- const url = `${BACKEND_URL}${INGEST_ENDPOINT}`;
18
+ const url = `${ROUTEFLOW_BACKEND_URL}${INGEST_ENDPOINT}`;
15
19
  const body = JSON.stringify(payload);
16
20
  // Use fetch with keepalive for best reliability
17
21
  const success = await fetch(url, {
@@ -16,7 +16,7 @@ class ExternalSpanTracker {
16
16
  };
17
17
  this.flushTimer = null;
18
18
  this.SDK_NAME = "@routeflow/browser";
19
- this.SDK_VERSION = "0.1.0"; // TODO: sync with package.json
19
+ this.SDK_VERSION = "0.1.4";
20
20
  this.config = config;
21
21
  this.startFlushTimer();
22
22
  }
@@ -1,10 +1,14 @@
1
1
  /**
2
2
  * Fetch patching for correlation headers and external span tracking.
3
+ *
4
+ * This SDK patches fetch() to:
5
+ * 1. Add correlation headers to requests to user's app backend
6
+ * 2. Track external requests and send telemetry to RouteFlow backend
3
7
  */
4
8
  /**
5
- * Patch window.fetch to add correlation headers.
9
+ * Patch window.fetch to add correlation headers and track external requests.
6
10
  */
7
- export declare function patchFetch(enableExternalTracking: boolean): void;
11
+ export declare function patchFetch(enableExternalTracking: boolean, backendUrl?: string): void;
8
12
  /**
9
13
  * Restore original fetch.
10
14
  */
@@ -1,5 +1,9 @@
1
1
  /**
2
2
  * Fetch patching for correlation headers and external span tracking.
3
+ *
4
+ * This SDK patches fetch() to:
5
+ * 1. Add correlation headers to requests to user's app backend
6
+ * 2. Track external requests and send telemetry to RouteFlow backend
3
7
  */
4
8
  import { isSameOrigin } from "./validate";
5
9
  import { getOrCreateSessionId, generateTraceId } from "./trace";
@@ -11,10 +15,33 @@ const FRONTEND_ROUTE_HEADER = "x-routeflow-frontend-route";
11
15
  let originalFetch;
12
16
  let isPatched = false;
13
17
  let trackExternal = false;
18
+ let userBackendUrl = ""; // User's app backend URL for header injection
14
19
  /**
15
- * Patch window.fetch to add correlation headers.
20
+ * Check if a URL should receive correlation headers.
21
+ * Returns true if:
22
+ * - URL matches the configured user backend URL, OR
23
+ * - No backend URL configured and request is same-origin
16
24
  */
17
- export function patchFetch(enableExternalTracking) {
25
+ function shouldInjectHeaders(url) {
26
+ // If user explicitly configured their backend URL, match against it
27
+ if (userBackendUrl) {
28
+ try {
29
+ const requestUrl = new URL(url, window.location.href);
30
+ const backendUrlObj = new URL(userBackendUrl, window.location.href);
31
+ // Match by origin (protocol + hostname + port)
32
+ return requestUrl.origin === backendUrlObj.origin;
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ }
38
+ // Fallback: inject headers for same-origin requests
39
+ return isSameOrigin(url);
40
+ }
41
+ /**
42
+ * Patch window.fetch to add correlation headers and track external requests.
43
+ */
44
+ export function patchFetch(enableExternalTracking, backendUrl) {
18
45
  if (isPatched) {
19
46
  return;
20
47
  }
@@ -23,6 +50,7 @@ export function patchFetch(enableExternalTracking) {
23
50
  }
24
51
  originalFetch = window.fetch;
25
52
  trackExternal = enableExternalTracking;
53
+ userBackendUrl = backendUrl || "";
26
54
  window.fetch = async function patchedFetch(input, init) {
27
55
  // Convert input to URL string
28
56
  const url = typeof input === "string"
@@ -30,13 +58,14 @@ export function patchFetch(enableExternalTracking) {
30
58
  : input instanceof URL
31
59
  ? input.href
32
60
  : input.url;
61
+ const shouldInject = shouldInjectHeaders(url);
33
62
  const sameOrigin = isSameOrigin(url);
34
- // Add correlation headers for same-origin requests
35
- // For external requests, we'll add headers in trackAndFetch if tracking is enabled
36
- if (sameOrigin) {
63
+ // Add correlation headers to requests going to user's app backend
64
+ if (shouldInject) {
37
65
  init = addCorrelationHeaders(input, init);
38
66
  }
39
- // Track external spans if enabled (will also add correlation headers)
67
+ // Track external spans if enabled and not same-origin
68
+ // This sends telemetry to the RouteFlow backend
40
69
  if (trackExternal && !sameOrigin) {
41
70
  return trackAndFetch(url, init);
42
71
  }
@@ -46,7 +75,7 @@ export function patchFetch(enableExternalTracking) {
46
75
  isPatched = true;
47
76
  }
48
77
  /**
49
- * Add correlation headers to same-origin requests.
78
+ * Add RouteFlow correlation headers to requests going to user's app backend.
50
79
  */
51
80
  function addCorrelationHeaders(input, init) {
52
81
  // Get or create headers
@@ -72,16 +101,13 @@ function addCorrelationHeaders(input, init) {
72
101
  };
73
102
  }
74
103
  /**
75
- * Track external fetch call and execute it.
76
- * Also adds correlation headers to tracked external requests.
104
+ * Track external fetch call and send telemetry to RouteFlow backend.
105
+ * This does NOT add correlation headers - those are only for same-origin requests.
77
106
  */
78
107
  async function trackAndFetch(url, init) {
79
108
  const startTime = performance.now();
80
109
  let response = null;
81
110
  let error = null;
82
- // Add correlation headers to tracked external requests
83
- // This allows backends in your infrastructure to correlate requests
84
- init = addCorrelationHeaders(url, init);
85
111
  try {
86
112
  response = await originalFetch(url, init);
87
113
  return response;
@@ -92,6 +118,7 @@ async function trackAndFetch(url, init) {
92
118
  }
93
119
  finally {
94
120
  const endTime = performance.now();
121
+ // This sends telemetry data to RouteFlow backend
95
122
  trackExternalFetch(url, init, startTime, endTime, response, error);
96
123
  }
97
124
  }
package/dist/init.js CHANGED
@@ -15,6 +15,7 @@ let config = {
15
15
  externalAllowlist: [],
16
16
  flushIntervalMs: 1000,
17
17
  maxQueueSize: 5000,
18
+ backendUrl: "",
18
19
  };
19
20
  /**
20
21
  * Detect environment from deployment platform environment variables.
@@ -94,6 +95,7 @@ export function initRouteflow(opts) {
94
95
  externalAllowlist: opts?.externalAllowlist || [],
95
96
  flushIntervalMs: opts?.flushIntervalMs ?? 1000,
96
97
  maxQueueSize: opts?.maxQueueSize ?? 5000,
98
+ backendUrl: opts?.backendUrl || "",
97
99
  };
98
100
  // Try to get ingest key from window if not provided
99
101
  if (!config.ingestKey && typeof window !== "undefined") {
@@ -107,8 +109,8 @@ export function initRouteflow(opts) {
107
109
  initRouteTracking();
108
110
  // Initialize session ID (persists across page navigation within session)
109
111
  getOrCreateSessionId();
110
- // Patch fetch for correlation headers
111
- patchFetch(config.trackExternal);
112
+ // Patch fetch for correlation headers (pass user's backend URL)
113
+ patchFetch(config.trackExternal, config.backendUrl);
112
114
  // Initialize external span tracking if enabled
113
115
  if (config.trackExternal) {
114
116
  initExternalSpanTracking({
package/dist/types.d.ts CHANGED
@@ -19,6 +19,8 @@ export interface RouteflowInitOptions {
19
19
  flushIntervalMs?: number;
20
20
  /** Maximum queue size before dropping events (default: 5000) */
21
21
  maxQueueSize?: number;
22
+ /** User's app backend URL for header injection (default: same-origin only) */
23
+ backendUrl?: string;
22
24
  }
23
25
  export interface ExternalSpanEvent {
24
26
  type: "frontend_external_request_observed";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "routeflow-browser",
3
- "version": "0.1.1",
3
+ "version": "0.1.4",
4
4
  "description": "Browser SDK for Routeflow - Frontend to backend correlation and external dependency tracking",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",