autotel-web 1.10.1 → 1.11.1

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 CHANGED
@@ -85,6 +85,120 @@ app.get('/api/users', async (req, res) => {
85
85
 
86
86
  Open your observability platform (Honeycomb, Datadog, Jaeger, etc.) and see the complete trace from browser → backend → database!
87
87
 
88
+ ## Browser Span Export (lean mode)
89
+
90
+ By default, lean mode only injects `traceparent` headers — no spans are exported from the browser. This means trace UIs like Jaeger may show "missing parent span" because the browser's spanId doesn't exist in the collector.
91
+
92
+ To fix this, set the `endpoint` option. autotel-web will export a lightweight span via `navigator.sendBeacon` for each fetch, so the browser span appears in your collector as the trace root:
93
+
94
+ ```typescript
95
+ init({
96
+ service: 'my-frontend',
97
+ endpoint: '', // same-origin — requires /v1/traces proxy (see below)
98
+ })
99
+ ```
100
+
101
+ ### Collector Proxy
102
+
103
+ Browsers can't send directly to most collectors (CORS). Add a simple proxy route to your API:
104
+
105
+ **Hono:**
106
+
107
+ ```typescript
108
+ app.post('/v1/traces', async (c) => {
109
+ const body = await c.req.arrayBuffer()
110
+ await fetch(`${process.env.OTEL_EXPORTER_OTLP_ENDPOINT}/v1/traces`, {
111
+ method: 'POST',
112
+ headers: { 'Content-Type': 'application/json' },
113
+ body,
114
+ })
115
+ return c.json({ ok: true })
116
+ })
117
+ ```
118
+
119
+ **Express:**
120
+
121
+ ```typescript
122
+ app.post('/v1/traces', express.raw({ type: 'application/json' }), async (req, res) => {
123
+ await fetch(`${process.env.OTEL_EXPORTER_OTLP_ENDPOINT}/v1/traces`, {
124
+ method: 'POST',
125
+ headers: { 'Content-Type': 'application/json' },
126
+ body: req.body,
127
+ })
128
+ res.json({ ok: true })
129
+ })
130
+ ```
131
+
132
+ If using Vite in dev, proxy `/v1/traces` to your API:
133
+
134
+ ```typescript
135
+ // vite.config.ts
136
+ server: {
137
+ proxy: {
138
+ '/v1/traces': { target: 'http://localhost:8787', changeOrigin: true },
139
+ },
140
+ },
141
+ ```
142
+
143
+ ### PostHog Reverse Proxy
144
+
145
+ If you use PostHog for analytics, route events through the same API to bypass ad blockers (typically increases event capture by 10-30%):
146
+
147
+ **Hono:**
148
+
149
+ ```typescript
150
+ const POSTHOG_HOST = process.env.POSTHOG_HOST || 'https://eu.i.posthog.com'
151
+
152
+ app.post('/ingest/*', async (c) => {
153
+ const path = c.req.path.replace('/ingest', '')
154
+ const body = await c.req.arrayBuffer()
155
+ const resp = await fetch(`${POSTHOG_HOST}${path}`, {
156
+ method: 'POST',
157
+ headers: { 'Content-Type': c.req.header('content-type') || 'application/json' },
158
+ body,
159
+ })
160
+ return new Response(resp.body, { status: resp.status, headers: resp.headers })
161
+ })
162
+
163
+ app.get('/ingest/decide*', async (c) => {
164
+ const url = new URL(c.req.url)
165
+ const resp = await fetch(`${POSTHOG_HOST}/decide${url.search}`)
166
+ return new Response(resp.body, { status: resp.status, headers: resp.headers })
167
+ })
168
+ ```
169
+
170
+ **Browser (posthog-js):**
171
+
172
+ ```typescript
173
+ import posthog from 'posthog-js'
174
+
175
+ posthog.init('phc_your_key', {
176
+ api_host: '/ingest', // same-origin proxy
177
+ ui_host: 'https://eu.i.posthog.com', // keep toolbar working
178
+ })
179
+ ```
180
+
181
+ **Vite proxy (dev):**
182
+
183
+ ```typescript
184
+ proxy: {
185
+ '/ingest': { target: 'http://localhost:8787', changeOrigin: true },
186
+ }
187
+ ```
188
+
189
+ See [PostHog reverse proxy docs](https://posthog.com/docs/advanced/proxy) for production setups (managed proxy, Cloudflare Workers, etc.).
190
+
191
+ The resulting trace tree:
192
+
193
+ ```
194
+ browser /api/transfer (CLIENT, root) ← autotel-web
195
+ └─ POST /api/transfer (SERVER) ← autotel / autotel-hono
196
+ └─ sendMoney (INTERNAL) ← your app
197
+ ├─ validate
198
+ ├─ fetchRate
199
+ └─ ...
200
+ ```
201
+
88
202
  ## Full mode (real spans)
89
203
 
90
204
  When you need real browser spans, network timing events, and optional export from the client, use full mode. Same install: `autotel-web`. No Zone.js.
@@ -354,6 +468,14 @@ interface AutotelWebConfig {
354
468
  /** Enable debug logging (default: false) */
355
469
  debug?: boolean
356
470
 
471
+ /**
472
+ * OTLP endpoint for exporting browser spans.
473
+ * When set, a real span is sent via sendBeacon for each fetch,
474
+ * so the traceparent spanId exists in the collector.
475
+ * Use '' for same-origin (requires /v1/traces proxy).
476
+ */
477
+ endpoint?: string
478
+
357
479
  /** Privacy controls for traceparent header injection */
358
480
  privacy?: PrivacyConfig
359
481
  }
@@ -1059,6 +1181,26 @@ app.use(cors({
1059
1181
 
1060
1182
  3. For custom frameworks, manually extract context (see "Backend Integration" above)
1061
1183
 
1184
+ ### Browser spans not appearing in collector
1185
+
1186
+ If you've set `endpoint` but spans don't appear:
1187
+
1188
+ 1. Check the proxy is working: `curl -X POST http://localhost:8787/v1/traces -H 'Content-Type: application/json' -d '{}'`
1189
+ 2. Verify Vite proxy config includes `/v1/traces`
1190
+ 3. Enable `debug: true` — you should see `[autotel-web] flushSpans: sending N span(s)` in the console
1191
+
1192
+ ### Vite dev server caching stale autotel-web
1193
+
1194
+ When using `file:` linked autotel packages in development, Vite caches pre-bundled dependencies in `node_modules/.vite/`. After rebuilding autotel-web, clear this cache:
1195
+
1196
+ ```bash
1197
+ rm -rf node_modules/.vite
1198
+ # or for monorepos
1199
+ rm -rf apps/web/node_modules/.vite
1200
+ ```
1201
+
1202
+ Then restart the Vite dev server. Without this, the browser may run an old version of autotel-web even after rebuilding.
1203
+
1062
1204
  ### TypeScript errors
1063
1205
 
1064
1206
  Ensure you're using TypeScript 5.0+ and have `@types/node` installed:
@@ -1,3 +1,7 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+
1
5
  // src/traceparent.ts
2
6
  function randomHex(bytes) {
3
7
  const buffer = new Uint8Array(bytes);
@@ -84,6 +88,6 @@ function extractContext(traceparent) {
84
88
  };
85
89
  }
86
90
 
87
- export { createTraceparent, extractContext, generateSpanId, generateTraceId, getActiveContext, getTraceparent, parseTraceparent, trace };
88
- //# sourceMappingURL=chunk-FYEN2WET.js.map
89
- //# sourceMappingURL=chunk-FYEN2WET.js.map
91
+ export { __publicField, createTraceparent, extractContext, generateSpanId, generateTraceId, getActiveContext, getTraceparent, parseTraceparent, trace };
92
+ //# sourceMappingURL=chunk-L3S7LTIH.js.map
93
+ //# sourceMappingURL=chunk-L3S7LTIH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/traceparent.ts","../src/functional.ts"],"names":[],"mappings":"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","file":"chunk-L3S7LTIH.js","sourcesContent":["/**\n * Minimal W3C Trace Context implementation for browser\n *\n * Generates traceparent headers in the W3C format:\n * traceparent: 00-{trace-id}-{span-id}-{flags}\n *\n * No OpenTelemetry dependencies - just crypto.getRandomValues()\n */\n\n/**\n * Generate random hex string of specified byte length\n */\nfunction randomHex(bytes: number): string {\n const buffer = new Uint8Array(bytes);\n crypto.getRandomValues(buffer);\n return Array.from(buffer)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * Generate a random 128-bit (16 byte) trace ID\n * @returns 32 character hex string\n */\nexport function generateTraceId(): string {\n return randomHex(16); // 16 bytes = 32 hex chars\n}\n\n/**\n * Generate a random 64-bit (8 byte) span ID\n * @returns 16 character hex string\n */\nexport function generateSpanId(): string {\n return randomHex(8); // 8 bytes = 16 hex chars\n}\n\n/**\n * Create a W3C traceparent header value\n *\n * Format: version-traceId-spanId-flags\n * - version: 00 (W3C Trace Context spec)\n * - traceId: 128-bit hex (32 chars)\n * - spanId: 64-bit hex (16 chars)\n * - flags: 01 (sampled)\n *\n * @param traceId - Optional existing trace ID (for continuing traces)\n * @param parentSpanId - Optional parent span ID (unused in browser, included for API compat)\n * @returns W3C traceparent header value\n *\n * @example\n * ```typescript\n * const header = createTraceparent()\n * // \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01\"\n * ```\n */\nexport function createTraceparent(\n traceId?: string,\n _parentSpanId?: string\n): string {\n const tid = traceId ?? generateTraceId();\n const sid = generateSpanId();\n const flags = '01'; // sampled=1\n\n return `00-${tid}-${sid}-${flags}`;\n}\n\n/**\n * Parse a traceparent header value\n * Useful for extracting trace context from incoming headers\n *\n * @param traceparent - W3C traceparent header value\n * @returns Parsed components or null if invalid\n *\n * @example\n * ```typescript\n * const parsed = parseTraceparent('00-4bf92f...0e4736-00f067...902b7-01')\n * console.log(parsed?.traceId) // \"4bf92f...0e4736\"\n * ```\n */\nexport function parseTraceparent(traceparent: string): {\n version: string;\n traceId: string;\n spanId: string;\n flags: string;\n} | null {\n const parts = traceparent.split('-');\n\n if (parts.length !== 4) {\n return null;\n }\n\n const [version, traceId, spanId, flags] = parts;\n\n // Validate format\n if (\n version.length !== 2 ||\n traceId.length !== 32 ||\n spanId.length !== 16 ||\n flags.length !== 2\n ) {\n return null;\n }\n\n return { version, traceId, spanId, flags };\n}\n","/**\n * Minimal functional API for browser tracing\n *\n * These are DX wrappers that DON'T create real browser spans.\n * The real spans and timing happen on the backend via Autotel.\n *\n * The browser's job is just to propagate trace context via headers.\n */\n\nimport { createTraceparent, parseTraceparent } from './traceparent';\n\n/**\n * Minimal trace context (browser-side)\n *\n * This is a lightweight version that just holds IDs.\n * NO actual span object - the real span lives on the backend.\n */\nexport interface TraceContext {\n /** Current trace ID (may be extracted from request) */\n readonly traceId: string;\n /** Current span ID (generated for this browser \"span\") */\n readonly spanId: string;\n /** Correlation ID (same as trace ID) */\n readonly correlationId: string;\n}\n\n// Store current trace context (if any)\nlet currentContext: TraceContext | undefined;\n\n/**\n * Wrap a function with trace() for better DX\n *\n * **Important:** This does NOT create real spans in the browser.\n * It's purely for API consistency. The real tracing happens on the backend.\n *\n * The traceparent header is automatically injected by init() on fetch/XHR calls.\n *\n * @example Basic usage\n * ```typescript\n * const fetchUser = trace(async (id: string) => {\n * const response = await fetch(`/api/users/${id}`)\n * return response.json()\n * })\n * ```\n *\n * @example With context (for accessing trace IDs)\n * ```typescript\n * const fetchUser = trace(ctx => async (id: string) => {\n * console.log('Trace ID:', ctx.traceId)\n * const response = await fetch(`/api/users/${id}`)\n * return response.json()\n * })\n * ```\n */\nexport function trace<T extends (...args: any[]) => any>(\n fn: T | ((ctx: TraceContext) => T)\n): T {\n // Check if function expects a context parameter (factory pattern)\n const expectsContext = isFactoryPattern(fn);\n\n if (expectsContext) {\n // Factory pattern: trace(ctx => async (data) => ...)\n return ((...args: any[]) => {\n // Generate a new trace context for this call\n const ctx = createContext();\n\n // Call factory to get the actual function\n const actualFn = (fn as (ctx: TraceContext) => T)(ctx);\n\n // Execute the function\n return actualFn(...args);\n }) as T;\n }\n\n // Direct pattern: trace(async (data) => ...)\n // Just return the function as-is since headers are auto-injected\n return fn as T;\n}\n\n/**\n * Check if a function expects a context parameter (factory pattern)\n */\nfunction isFactoryPattern(fn: unknown): boolean {\n if (typeof fn !== 'function') return false;\n\n const fnStr = fn.toString();\n\n // Look for common parameter names that indicate context\n const contextHints = ['ctx', 'context', 'traceContext'];\n\n return contextHints.some((hint) => {\n // Match parameter name at start of function\n const regex = new RegExp(`^\\\\s*(?:async\\\\s+)?(?:function\\\\s*)?\\\\(?\\\\s*${hint}\\\\s*[,)]`);\n return regex.test(fnStr);\n });\n}\n\n/**\n * Create a minimal trace context\n * Generates new IDs for this \"span\" (browser-side only)\n */\nfunction createContext(): TraceContext {\n // Parse the current traceparent if we have one\n // (This would come from SSR or previous span)\n const traceparent = createTraceparent();\n const parsed = parseTraceparent(traceparent);\n\n if (!parsed) {\n // Fallback if parsing fails\n return {\n traceId: '',\n spanId: '',\n correlationId: '',\n };\n }\n\n const ctx: TraceContext = {\n traceId: parsed.traceId,\n spanId: parsed.spanId,\n correlationId: parsed.traceId,\n };\n\n currentContext = ctx;\n return ctx;\n}\n\n/**\n * Get the current trace context (if any)\n *\n * @returns Current trace context or undefined\n *\n * @example\n * ```typescript\n * const ctx = getActiveContext()\n * if (ctx) {\n * console.log('Trace ID:', ctx.traceId)\n * }\n * ```\n */\nexport function getActiveContext(): TraceContext | undefined {\n return currentContext;\n}\n\n/**\n * Manual helper to create a traceparent header\n *\n * Useful if you need to manually set headers or disable auto-instrumentation.\n *\n * @returns W3C traceparent header value\n *\n * @example\n * ```typescript\n * import { init, getTraceparent } from 'autotel-web'\n *\n * // Disable auto-instrumentation\n * init({ service: 'my-app', instrumentFetch: false })\n *\n * // Manually inject headers\n * fetch('/api/data', {\n * headers: {\n * 'traceparent': getTraceparent()\n * }\n * })\n * ```\n */\nexport function getTraceparent(): string {\n return createTraceparent();\n}\n\n/**\n * Extract trace context from a traceparent header\n *\n * Useful for SSR scenarios where you want to continue a trace from the server.\n *\n * @param traceparent - W3C traceparent header value\n * @returns Parsed trace context or undefined if invalid\n *\n * @example\n * ```typescript\n * // In an SSR handler\n * const traceparent = request.headers.get('traceparent')\n * if (traceparent) {\n * const ctx = extractContext(traceparent)\n * console.log('Continuing trace:', ctx?.traceId)\n * }\n * ```\n */\nexport function extractContext(traceparent: string): TraceContext | undefined {\n const parsed = parseTraceparent(traceparent);\n if (!parsed) return undefined;\n\n return {\n traceId: parsed.traceId,\n spanId: parsed.spanId,\n correlationId: parsed.traceId,\n };\n}\n"]}
package/dist/full.d.ts CHANGED
@@ -3,6 +3,52 @@ import { SpanProcessor, Sampler } from '@opentelemetry/sdk-trace-base';
3
3
  import { P as PrivacyConfig } from './functional-04Wr-1U_.js';
4
4
  export { T as TraceContext, e as extractContext, g as getActiveContext, a as getTraceparent, t as trace } from './functional-04Wr-1U_.js';
5
5
 
6
+ /**
7
+ * Browser-safe string redaction. Duplicate of autotel's redact-values.ts.
8
+ * Must NOT import from `autotel` (Node.js package).
9
+ */
10
+ type StringRedactor = (value: string) => string;
11
+
12
+ /**
13
+ * Structured error types for autotel-web error tracking.
14
+ * Compatible with PostHog's $exception_list format and OTel semantic conventions.
15
+ */
16
+
17
+ interface SuppressionRule {
18
+ /** Field to match against */
19
+ key: 'type' | 'value';
20
+ /** Match operator */
21
+ operator: 'exact' | 'contains' | 'regex';
22
+ /** Value or pattern to match */
23
+ value: string;
24
+ }
25
+ interface RateLimitConfig {
26
+ /** Max exceptions per type within the window (default: 10) */
27
+ maxPerType: number;
28
+ /** Time window in milliseconds (default: 10000) */
29
+ windowMs: number;
30
+ }
31
+ interface ErrorTrackingConfig {
32
+ /** Rate limit per exception type */
33
+ rateLimit?: RateLimitConfig;
34
+ /** Suppression rules to filter known noise */
35
+ suppressionRules?: SuppressionRule[];
36
+ /** Capture console.error as exceptions (default: false) */
37
+ captureConsoleErrors?: boolean;
38
+ /** Skip autocapture if window.posthog is detected (default: true) */
39
+ deferToPostHog?: boolean;
40
+ /** Debug logging */
41
+ debug?: boolean;
42
+ /** String redactor for PII in error messages and stack traces */
43
+ redactor?: StringRedactor;
44
+ }
45
+
46
+ /**
47
+ * Manually capture an exception.
48
+ * Use this for caught errors you want to track.
49
+ */
50
+ declare function captureException(error: unknown): void;
51
+
6
52
  /**
7
53
  * Full browser tracing with OpenTelemetry SDK
8
54
  *
@@ -74,6 +120,20 @@ interface AutotelWebFullConfig {
74
120
  * @default false
75
121
  */
76
122
  captureLongTasks?: boolean;
123
+ /**
124
+ * Advanced error tracking configuration.
125
+ * When captureErrors is true (default), this configures rate limiting, suppression, etc.
126
+ */
127
+ errorTracking?: Omit<ErrorTrackingConfig, 'debug'>;
128
+ /** Redact PII from error messages and stack traces before export. Preset or custom config. */
129
+ attributeRedactor?: 'default' | 'strict' | 'pci-dss' | {
130
+ valuePatterns?: Array<{
131
+ name: string;
132
+ pattern: RegExp;
133
+ replacement?: string;
134
+ }>;
135
+ replacement?: string;
136
+ };
77
137
  /** Privacy controls (origin filtering, DNT, GPC). Applied to which requests get traced. */
78
138
  privacy?: PrivacyConfig;
79
139
  /** Enable debug logging. @default false */
@@ -123,4 +183,4 @@ declare function runWithContext<T>(ctx: ReturnType<typeof context.active>, fn: (
123
183
  */
124
184
  declare function resetFullForTesting(): void;
125
185
 
126
- export { type AutotelWebFullConfig, addEvent, initFull, resetFullForTesting, runWithContext, setAttribute, span };
186
+ export { type AutotelWebFullConfig, addEvent, captureException, initFull, resetFullForTesting, runWithContext, setAttribute, span };