@pydantic/logfire-browser 0.17.0-alpha.1 → 0.17.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/README.md CHANGED
@@ -19,7 +19,13 @@ If you're instrumenting Cloudflare, see the [Logfire CF workers package](https:/
19
19
 
20
20
  ## Basic usage
21
21
 
22
- See the [Logfire Browser docs for a primer](https://logfire.pydantic.dev/docs/integrations/javascript/browser/). Ready to run examples are available in the repository [in vanilla browser](https://github.com/pydantic/logfire-js/tree/main/examples/browser) and [Next.js variants](https://github.com/pydantic/logfire-js/tree/main/examples/nextjs-client-side-instrumentation).
22
+ See the [Logfire Browser docs for a primer](https://logfire.pydantic.dev/docs/integrations/javascript/browser/). Ready to run examples are available in the repository [in vanilla browser](https://github.com/pydantic/logfire-js/tree/main/examples/browser), [with RUM and replay](https://github.com/pydantic/logfire-js/tree/main/examples/browser-rum-replay), and [in Next.js variants](https://github.com/pydantic/logfire-js/tree/main/examples/nextjs-client-side-instrumentation).
23
+
24
+ Build the workspace packages before running the Vite examples. The standalone
25
+ examples use same-origin browser URLs and development-only Express helpers that
26
+ bind to `127.0.0.1`, accept exact configured origins, and inject the Logfire
27
+ write token server-side. Do not put a write token in a browser bundle or treat
28
+ those loopback helpers as a production proxy design.
23
29
 
24
30
  ## Managed Variables
25
31
 
@@ -70,9 +76,13 @@ or 4 hours of total duration by default. Spans get `session.id` and
70
76
  `browser.session.id`; `session.id` is the OpenTelemetry semantic attribute and
71
77
  `browser.session.id` is emitted for Logfire Platform compatibility.
72
78
 
73
- By default, session-enabled spans also get `url.full` and `url.path` from the
74
- current page URL. If your app has sensitive query strings or fragments, provide
75
- a sanitizer or suppress URL attributes:
79
+ By default, session-enabled spans also get `logfire.page.url.full` and
80
+ `logfire.page.url.path` from the current page URL. The full value is
81
+ `location.origin + location.pathname`, while the path value is
82
+ `location.pathname`; query strings and fragments are excluded. Network spans
83
+ may independently use OpenTelemetry `url.*` attributes for their request
84
+ target. Provide a callback to customize page attributes, explicitly restore the
85
+ raw page URL, or suppress them:
76
86
 
77
87
  ```js
78
88
  logfire.configure({
@@ -80,10 +90,7 @@ logfire.configure({
80
90
  serviceName: 'browser-app',
81
91
  rum: {
82
92
  session: {
83
- urlAttributes: (url) => ({
84
- full: `${url.origin}${url.pathname}`,
85
- path: url.pathname,
86
- }),
93
+ urlAttributes: (url) => ({ full: url.href, path: url.pathname }),
87
94
  },
88
95
  },
89
96
  })
@@ -120,7 +127,8 @@ logfire.configure({
120
127
  The SDK dynamically loads `web-vitals/attribution` only when `rum.webVitals` is
121
128
  enabled. It records LCP, INP, CLS, FCP, and TTFB as short spans named
122
129
  `web_vital.lcp`, `web_vital.inp`, `web_vital.cls`, `web_vital.fcp`, and
123
- `web_vital.ttfb`.
130
+ `web_vital.ttfb`. These point events carry exact
131
+ `logfire.span_type = 'log'`.
124
132
 
125
133
  Each span includes base attributes such as `web_vital.name`,
126
134
  `web_vital.value`, `web_vital.delta`, `web_vital.id`, `web_vital.rating`, and
@@ -150,6 +158,13 @@ logfire.configure({
150
158
  })
151
159
  ```
152
160
 
161
+ Web Vitals observers live for the page lifetime. The first successful startup
162
+ fixes `reportAllChanges`, `generateTarget`, and
163
+ `includeProcessedEventEntries`; later `configure()` calls can update the tracer
164
+ and metric destination but ignore changed observer options with a diagnostic
165
+ warning. If the initial lazy load or observer startup fails, a later
166
+ `configure()` call retries it.
167
+
153
168
  To emit native OpenTelemetry histogram metrics in parallel with those spans,
154
169
  configure a browser-safe metrics proxy and opt Web Vitals into metrics:
155
170
 
@@ -171,7 +186,9 @@ logfire.configure({
171
186
  Metric export is disabled unless top-level `metrics.metricUrl` is configured,
172
187
  and `rum.webVitals.metrics` requires that transport. The SDK uses a local
173
188
  OpenTelemetry `MeterProvider`; it does not replace the application's global
174
- meter provider.
189
+ meter provider. If that metrics runtime fails to start, the SDK emits an
190
+ explicit diagnostic and continues Web Vitals span reporting without a metric
191
+ recorder. It never retries configured authentication with empty headers.
175
192
 
176
193
  Web Vitals metrics are histograms named
177
194
  `logfire.browser.web_vital.lcp`, `logfire.browser.web_vital.inp`,
@@ -181,15 +198,17 @@ uses unit `1`.
181
198
 
182
199
  Metric data point attributes are intentionally low-cardinality:
183
200
  `web_vital.name` and `web_vital.rating` by default. They do not include
184
- `session.id`, `browser.session.id`, `url.full`, `url.path`, Web Vital
201
+ `session.id`, `browser.session.id`, `logfire.page.url.full`,
202
+ `logfire.page.url.path`, Web Vital
185
203
  ids/deltas, DOM selectors, attribution fields, or raw PerformanceEntry data. Use
186
- spans for raw-sample drilldown, session/replay correlation, exact URL context,
187
- and attribution selectors.
204
+ spans for raw-sample drilldown, session/replay correlation, exact page context,
205
+ and attribution selectors. When metrics are configured, Logfire Platform should
206
+ treat these histograms as the aggregate Web Vitals surface.
188
207
 
189
208
  For modern single-page apps, these are standard document-level Web Vitals, not
190
- route-level soft-navigation metrics. Span URL attributes describe the browser
191
- URL when the callback fires; route-specific Core Web Vitals need separate route
192
- or soft-navigation instrumentation. To add a route dimension to metrics, pass a
209
+ route-level soft-navigation metrics. Span page URL attributes describe the
210
+ browser URL when the callback fires; route-specific Core Web Vitals need
211
+ separate route or soft-navigation instrumentation. To add a route dimension to metrics, pass a
193
212
  low-cardinality template such as `/products/:id` through
194
213
  `rum.webVitals.metrics.attributes`.
195
214
 
@@ -210,7 +229,7 @@ npm install @pydantic/logfire-session-replay
210
229
  ```js
211
230
  import * as logfire from '@pydantic/logfire-browser'
212
231
 
213
- logfire.configure({
232
+ const cleanup = logfire.configure({
214
233
  traceUrl: '/logfire-proxy/v1/traces',
215
234
  serviceName: 'browser-app',
216
235
  sessionReplay: {
@@ -219,16 +238,36 @@ logfire.configure({
219
238
  headers: async () => ({
220
239
  'X-CSRF': await getCsrfToken(),
221
240
  }),
241
+ maskAllText: true,
222
242
  maskAllInputs: true,
223
243
  },
224
244
  })
245
+
246
+ // The property exists synchronously whenever sessionReplay is configured.
247
+ await cleanup.sessionReplay?.flush()
248
+ await cleanup.sessionReplay?.stop() // replay only; tracing remains active
249
+ await cleanup() // full SDK cleanup
225
250
  ```
226
251
 
227
252
  `sessionReplay` implies default browser session attributes. Replay chunks and
228
- browser spans share `session.id` / `browser.session.id`, and spans started
229
- while replay is active get `logfire.session_replay.active` and
230
- `logfire.session_replay.mode`. The browser integration intentionally does not
231
- poll active trace context into replay chunks.
253
+ browser spans share `session.id` / `browser.session.id`. Spans started after
254
+ replay has loaded and sampled into `full` or `buffer` mode get
255
+ `logfire.session_replay.active` and `logfire.session_replay.mode`. Those active
256
+ attributes are truthful best-effort annotations, not the primary correlation
257
+ key; early spans should be correlated to replay by browser session id and replay
258
+ time bounds. The browser integration intentionally does not poll active trace
259
+ context into replay chunks.
260
+
261
+ Before lazy replay startup completes, after startup failure, and after replay is
262
+ stopped, the facade reports `mode: 'off'` and `recording: false`. Its `stop()`
263
+ method is idempotent and generation-scoped. Session identity remains available
264
+ through `getBrowserSessionId()`, not the replay facade.
265
+
266
+ Browser-session inactivity currently means span inactivity: replay startup
267
+ initializes and touches the session once before loading the optional peer, but
268
+ subsequent replay events only peek at the session id and do not refresh the
269
+ timeout. Span starts are the ongoing automatic activity;
270
+ `getBrowserSessionId()` also explicitly touches the session.
232
271
 
233
272
  Use a backend proxy for browser replay uploads. The proxy should authenticate
234
273
  the browser request with your application session or CSRF mechanism and add the
@@ -247,11 +286,32 @@ logfire.configure({
247
286
  })
248
287
  ```
249
288
 
250
- Do not use direct tokens in normal browser applications. Replay may capture
251
- console, fetch/XHR, navigation, and DOM events. Keep the default input masking
252
- enabled, use `blockSelector` or `maskTextSelector` for sensitive page regions,
253
- and set `captureConsole`, `captureNetwork`, or `captureNavigation` to `false`
254
- when those side channels are not appropriate.
289
+ When the document becomes hidden or receives `pagehide`, replay makes a bounded
290
+ best-effort start of the earliest compressed chunks. Its 48,000-byte aggregate
291
+ budget is shared across its own unfinished keepalive requests, while the
292
+ browser's keepalive quota is also shared with unrelated page traffic. Delivery
293
+ after page freeze or termination is therefore not guaranteed. Functional
294
+ `headers` and `token` values are resolved for every upload; an asynchronous
295
+ resolver can finish too late for a lifecycle request, so prefer credentials that
296
+ are synchronously available from your same-origin proxy flow.
297
+
298
+ Ordinary replay uploads automatically fall back to synchronous gzip if a
299
+ restrictive Content Security Policy blocks the compressor worker. The fallback
300
+ preserves the batch and is remembered for the active replay controller, but it
301
+ may briefly use the main thread.
302
+
303
+ Do not use direct tokens in normal browser applications. Replay masks all
304
+ rendered text and input values by default, leaves console capture off, and
305
+ removes query strings and fragments from captured page, fetch/XHR, and
306
+ navigation URLs. Network and navigation capture remain enabled. These defaults
307
+ are inherited when the corresponding browser options are omitted.
308
+
309
+ Use `blockSelector` to omit a subtree. Set `maskAllText: false` only when
310
+ visible text recording is acceptable; `maskTextSelector` can then selectively
311
+ mask sensitive regions. `captureConsole: true` is an explicit opt-in, and
312
+ `redactUrlPatterns: []` explicitly restores raw replay URLs. Text masking does
313
+ not scrub DOM attributes, CSS content, resource URLs, or arbitrary custom-event
314
+ payloads, so those values still require application-side care.
255
315
 
256
316
  When testing replay locally, browser privacy extensions or ad blockers may block
257
317
  requests or dynamic imports whose URLs contain terms such as `session-replay`.
@@ -343,6 +403,42 @@ If any cleanup step fails, Logfire still attempts the later steps before
343
403
  returning the first failure. Later calls return the same settled cleanup promise
344
404
  rather than starting another cleanup cycle.
345
405
 
406
+ Await cleanup before configuring Logfire again on the same page:
407
+
408
+ ```js
409
+ const cleanupA = logfire.configure({
410
+ traceUrl: '/client-traces/a',
411
+ serviceName: 'browser-app-a',
412
+ })
413
+
414
+ await cleanupA()
415
+
416
+ const cleanupB = logfire.configure({
417
+ traceUrl: '/client-traces/b',
418
+ serviceName: 'browser-app-b',
419
+ })
420
+ ```
421
+
422
+ Calling `configure()` while a configuration is active or cleaning throws
423
+ `logfire-browser: a configuration is already active; await its cleanup before configuring again`.
424
+ New spans are non-recording between configurations. Spans retain the provider
425
+ generation selected when they start, so end A spans before cleanup A to
426
+ guarantee their export; they are not migrated to B. If cleanup rejects, later
427
+ configuration is refused until the page reloads because an old producer may
428
+ still be active.
429
+
430
+ Logfire installs one page-stable OpenTelemetry tracer provider, context manager,
431
+ and default propagator only when those globals are not already application-owned.
432
+ Normal cleanup never disables page globals. If the application owns a context
433
+ manager, register it before Logfire and omit `contextManager` from
434
+ `configure()`. A Logfire-owned manager remains enabled across generations and
435
+ cannot be replaced with a different instance.
436
+
437
+ Same-page reconfiguration requires bundler deduplication of both
438
+ `@pydantic/logfire-browser` and `logfire`. Reconfiguration across duplicate
439
+ physical package copies is unsupported because their lifecycle state is not
440
+ shared.
441
+
346
442
  Browser pages also get OpenTelemetry's built-in batch-processor auto-flush on
347
443
  document hide. The underlying batch span processor calls `forceFlush()` when the
348
444
  document becomes hidden or emits `pagehide`, which helps export spans during
@@ -0,0 +1 @@
1
+ import{diag as e}from"@opentelemetry/api";const t={CLS:{boundaries:[.01,.05,.1,.15,.25,.5,1],description:`Cumulative Layout Shift score recorded in browser sessions.`,name:`logfire.browser.web_vital.cls`,unit:`1`},FCP:{boundaries:[500,1e3,1500,1800,2500,3e3,4e3,6e3],description:`First Contentful Paint duration recorded in browser sessions.`,name:`logfire.browser.web_vital.fcp`,unit:`ms`},INP:{boundaries:[50,100,150,200,300,500,800,1e3,2e3],description:`Interaction to Next Paint duration recorded in browser sessions.`,name:`logfire.browser.web_vital.inp`,unit:`ms`},LCP:{boundaries:[500,1e3,1500,2e3,2500,3e3,3500,4e3,5e3,8e3,1e4],description:`Largest Contentful Paint duration recorded in browser sessions.`,name:`logfire.browser.web_vital.lcp`,unit:`ms`},TTFB:{boundaries:[100,300,500,800,1200,1800,2500,4e3],description:`Time to First Byte duration recorded in browser sessions.`,name:`logfire.browser.web_vital.ttfb`,unit:`ms`}},n=new Set([`browser.session.id`,`logfire.page.url.full`,`logfire.page.url.path`,`session.id`,`url.full`,`web_vital.delta`,`web_vital.id`,`web_vital.value`]),r={exportIntervalMillis:6e4,exportTimeoutMillis:1e4};function i(e){return e===`CLS`||e===`FCP`||e===`INP`||e===`LCP`||e===`TTFB`}function a(e){return n.has(e)||e.startsWith(`web_vital.cls.`)||e.startsWith(`web_vital.fcp.`)||e.startsWith(`web_vital.inp.`)||e.startsWith(`web_vital.lcp.`)||e.startsWith(`web_vital.ttfb.`)}function o(e,t,n){if(!a(t)){if(typeof n==`string`||typeof n==`boolean`){e[t]=n;return}typeof n==`number`&&Number.isFinite(n)&&(e[t]=n)}}function s(e,t){if(t!==void 0)for(let[n,r]of Object.entries(t))o(e,n,r)}function c(e){let t={};return o(t,`web_vital.name`,e.name),o(t,`web_vital.rating`,e.rating),t}function l(e){let n=e.getMeter(`logfire-browser-web-vitals`);return{CLS:n.createHistogram(t.CLS.name,{advice:{explicitBucketBoundaries:t.CLS.boundaries},description:t.CLS.description,unit:t.CLS.unit}),FCP:n.createHistogram(t.FCP.name,{advice:{explicitBucketBoundaries:t.FCP.boundaries},description:t.FCP.description,unit:t.FCP.unit}),INP:n.createHistogram(t.INP.name,{advice:{explicitBucketBoundaries:t.INP.boundaries},description:t.INP.description,unit:t.INP.unit}),LCP:n.createHistogram(t.LCP.name,{advice:{explicitBucketBoundaries:t.LCP.boundaries},description:t.LCP.description,unit:t.LCP.unit}),TTFB:n.createHistogram(t.TTFB.name,{advice:{explicitBucketBoundaries:t.TTFB.boundaries},description:t.TTFB.description,unit:t.TTFB.unit})}}function u(t,n={}){let r=!0;return{record(a){if(!(!r||!i(a.name)))try{let e=c(a);s(e,n.defaultAttributes?.(a)),n.attributes!==!1&&s(e,n.attributes?.(a)),t[a.name].record(a.value,e)}catch(t){e.error(`logfire-browser: failed to record Web Vital metric`,t)}},shutdown(){r=!1}}}async function d(e,t){let[{MeterProvider:n,PeriodicExportingMetricReader:i},{OTLPMetricExporter:a}]=await Promise.all([import(`@opentelemetry/sdk-metrics`),import(`@opentelemetry/exporter-metrics-otlp-http`)]),o=e.metricExporterHeaders,s=new a({...e.metricExporterConfig,headers:o===void 0?void 0:async()=>o(),url:e.metricUrl}),c=new n({readers:[new i({...r,...e.metricReaderConfig,exporter:s}),...e.metricReaders??[]],resource:t}),d=l(c),f;return{createWebVitalsMetricRecorder(e){return u(d,e)},async forceFlush(){if(f!==void 0)return f;await c.forceFlush()},async shutdown(){return f??=c.shutdown(),f}}}export{d as startBrowserMetrics};
@@ -0,0 +1 @@
1
+ let e=require("@opentelemetry/api");const t={CLS:{boundaries:[.01,.05,.1,.15,.25,.5,1],description:`Cumulative Layout Shift score recorded in browser sessions.`,name:`logfire.browser.web_vital.cls`,unit:`1`},FCP:{boundaries:[500,1e3,1500,1800,2500,3e3,4e3,6e3],description:`First Contentful Paint duration recorded in browser sessions.`,name:`logfire.browser.web_vital.fcp`,unit:`ms`},INP:{boundaries:[50,100,150,200,300,500,800,1e3,2e3],description:`Interaction to Next Paint duration recorded in browser sessions.`,name:`logfire.browser.web_vital.inp`,unit:`ms`},LCP:{boundaries:[500,1e3,1500,2e3,2500,3e3,3500,4e3,5e3,8e3,1e4],description:`Largest Contentful Paint duration recorded in browser sessions.`,name:`logfire.browser.web_vital.lcp`,unit:`ms`},TTFB:{boundaries:[100,300,500,800,1200,1800,2500,4e3],description:`Time to First Byte duration recorded in browser sessions.`,name:`logfire.browser.web_vital.ttfb`,unit:`ms`}},n=new Set([`browser.session.id`,`logfire.page.url.full`,`logfire.page.url.path`,`session.id`,`url.full`,`web_vital.delta`,`web_vital.id`,`web_vital.value`]),r={exportIntervalMillis:6e4,exportTimeoutMillis:1e4};function i(e){return e===`CLS`||e===`FCP`||e===`INP`||e===`LCP`||e===`TTFB`}function a(e){return n.has(e)||e.startsWith(`web_vital.cls.`)||e.startsWith(`web_vital.fcp.`)||e.startsWith(`web_vital.inp.`)||e.startsWith(`web_vital.lcp.`)||e.startsWith(`web_vital.ttfb.`)}function o(e,t,n){if(!a(t)){if(typeof n==`string`||typeof n==`boolean`){e[t]=n;return}typeof n==`number`&&Number.isFinite(n)&&(e[t]=n)}}function s(e,t){if(t!==void 0)for(let[n,r]of Object.entries(t))o(e,n,r)}function c(e){let t={};return o(t,`web_vital.name`,e.name),o(t,`web_vital.rating`,e.rating),t}function l(e){let n=e.getMeter(`logfire-browser-web-vitals`);return{CLS:n.createHistogram(t.CLS.name,{advice:{explicitBucketBoundaries:t.CLS.boundaries},description:t.CLS.description,unit:t.CLS.unit}),FCP:n.createHistogram(t.FCP.name,{advice:{explicitBucketBoundaries:t.FCP.boundaries},description:t.FCP.description,unit:t.FCP.unit}),INP:n.createHistogram(t.INP.name,{advice:{explicitBucketBoundaries:t.INP.boundaries},description:t.INP.description,unit:t.INP.unit}),LCP:n.createHistogram(t.LCP.name,{advice:{explicitBucketBoundaries:t.LCP.boundaries},description:t.LCP.description,unit:t.LCP.unit}),TTFB:n.createHistogram(t.TTFB.name,{advice:{explicitBucketBoundaries:t.TTFB.boundaries},description:t.TTFB.description,unit:t.TTFB.unit})}}function u(t,n={}){let r=!0;return{record(a){if(!(!r||!i(a.name)))try{let e=c(a);s(e,n.defaultAttributes?.(a)),n.attributes!==!1&&s(e,n.attributes?.(a)),t[a.name].record(a.value,e)}catch(t){e.diag.error(`logfire-browser: failed to record Web Vital metric`,t)}},shutdown(){r=!1}}}async function d(e,t){let[{MeterProvider:n,PeriodicExportingMetricReader:i},{OTLPMetricExporter:a}]=await Promise.all([import(`@opentelemetry/sdk-metrics`),import(`@opentelemetry/exporter-metrics-otlp-http`)]),o=e.metricExporterHeaders,s=new a({...e.metricExporterConfig,headers:o===void 0?void 0:async()=>o(),url:e.metricUrl}),c=new n({readers:[new i({...r,...e.metricReaderConfig,exporter:s}),...e.metricReaders??[]],resource:t}),d=l(c),f;return{createWebVitalsMetricRecorder(e){return u(d,e)},async forceFlush(){if(f!==void 0)return f;await c.forceFlush()},async shutdown(){return f??=c.shutdown(),f}}}exports.startBrowserMetrics=d;
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});let e=require("@opentelemetry/api"),t=require("@opentelemetry/exporter-trace-otlp-http"),n=require("@opentelemetry/instrumentation"),r=require("@opentelemetry/resources"),i=require("@opentelemetry/sdk-trace-web"),a=require("@opentelemetry/semantic-conventions"),o=require("@opentelemetry/semantic-conventions/incubating"),s=require("logfire"),c=require("@opentelemetry/core");function l(){let e=globalThis;try{let t=(e.location??e.window?.location)?.href;return t===void 0||t===``?void 0:new URL(t)}catch{return}}var u=class{replayState;sessionManager;constructor(e,t){this.sessionManager=e,this.replayState=t}async forceFlush(){return Promise.resolve()}onEnd(e){}onStart(e,t){let n=this.sessionManager.touch();e.setAttribute(`session.id`,n.id),e.setAttribute(`browser.session.id`,n.id);let r=this.replayState?.getState();r!==void 0&&(e.setAttribute(`logfire.session_replay.active`,r.active),e.setAttribute(`logfire.session_replay.mode`,r.mode));let i=l();if(i===void 0)return;let a;try{a=this.sessionManager.getUrlAttributes(i)}catch{return}a?.full!==void 0&&e.setAttribute(`url.full`,a.full),a?.path!==void 0&&e.setAttribute(`url.path`,a.path)}async shutdown(){return Promise.resolve()}};const d={idleTimeoutMs:30*6e4,maxDurationMs:240*6e4,storageKey:`lf_browser_session`};function f(){try{return globalThis.sessionStorage??null}catch{return null}}function p(){let e=globalThis.crypto;if(typeof e?.randomUUID==`function`)return e.randomUUID();if(typeof e?.getRandomValues==`function`){let t=new Uint8Array(16);return e.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,`0`)).join(``)}return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}-${Math.random().toString(36).slice(2)}`}function m(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.id==`string`&&t.id.length>0&&typeof t.startedAt==`number`&&Number.isFinite(t.startedAt)&&typeof t.lastActivityAt==`number`&&Number.isFinite(t.lastActivityAt)}var h=class{generateId;idleTimeoutMs;maxDurationMs;now;storage;storageKey;urlAttributes;memorySession;constructor(e={}){this.generateId=e.generateId??p,this.idleTimeoutMs=e.idleTimeoutMs??d.idleTimeoutMs,this.maxDurationMs=e.maxDurationMs??d.maxDurationMs,this.now=e.now??Date.now,this.storage=e.storage===void 0?f():e.storage,this.storageKey=e.storageKey??d.storageKey,this.urlAttributes=e.urlAttributes}getSession(){return this.getSessionAt(this.now())}peekSessionId(){return this.memorySession?.id}touch(){let e=this.now(),t={...this.getSessionAt(e),lastActivityAt:e};return this.writeSession(t),t}reset(){return this.createSession(this.now())}getUrlAttributes(e){if(this.urlAttributes!==!1)return typeof this.urlAttributes==`function`?this.urlAttributes(e):{full:e.href,path:e.pathname}}createSession(e){let t={id:this.generateId(),lastActivityAt:e,startedAt:e};return this.writeSession(t),t}getSessionAt(e){let t=this.readSession();return t!==void 0&&!this.isExpired(t,e)?t:this.createSession(e)}isExpired(e,t){return t-e.lastActivityAt>this.idleTimeoutMs||t-e.startedAt>this.maxDurationMs}readSession(){if(this.storage!==null)try{let e=this.storage.getItem(this.storageKey);if(e!==null){let t=JSON.parse(e);if(m(t))return this.memorySession=t,t}}catch{return this.memorySession}return this.memorySession}writeSession(e){if(this.memorySession=e,this.storage!==null)try{this.storage.setItem(this.storageKey,JSON.stringify(e))}catch{}}};let g;function _(e){if(e===void 0||e===!1){g=void 0;return}let t=new h(e===!0?{}:e);return g=t,t}function v(){return g?.touch().id}function y(e){g===e&&(g=void 0)}var b=class{replay;setReplay(e){this.replay=e}clear(){this.replay=void 0}getState(){let e=this.replay?.mode;if(!(this.replay?.recording!==!0||e!==`full`&&e!==`buffer`))return{active:!0,mode:e}}};async function x(t,n,r,i){try{if(n.touch(),n.peekSessionId()===void 0)throw Error(`logfire-browser: sessionReplay requires an active browser session id`);let e=await t.load(),a=S(t,n,i),o=C(e.startSessionReplay(a),r);return o.recording&&(o.mode===`full`||o.mode===`buffer`)&&r.setReplay(o),o}catch(n){r.clear(),e.diag.error(`logfire-browser: failed to start session replay; install @pydantic/logfire-session-replay and verify sessionReplay config`,n),t.onError?.(n);return}}function S(e,t,n){let r={getSessionId:()=>t.peekSessionId(),ignoreUrlPatterns:[...w(e.replayUrl,n),...e.ignoreUrlPatterns??[]],redactUrlPatterns:e.redactUrlPatterns??[],replayUrl:e.replayUrl};return e.headers!==void 0&&(r.headers=e.headers),e.token!==void 0&&(r.token=e.token),e.sessionSampleRate!==void 0&&(r.sessionSampleRate=e.sessionSampleRate),e.onErrorSampleRate!==void 0&&(r.onErrorSampleRate=e.onErrorSampleRate),e.maskAllInputs!==void 0&&(r.maskAllInputs=e.maskAllInputs),e.maskTextSelector!==void 0&&(r.maskTextSelector=e.maskTextSelector),e.blockSelector!==void 0&&(r.blockSelector=e.blockSelector),e.flushIntervalMs!==void 0&&(r.flushIntervalMs=e.flushIntervalMs),e.maxBufferBytes!==void 0&&(r.maxBufferBytes=e.maxBufferBytes),e.distinctId!==void 0&&(r.distinctId=e.distinctId),e.getDistinctId!==void 0&&(r.getDistinctId=e.getDistinctId),e.captureConsole!==void 0&&(r.captureConsole=e.captureConsole),e.captureNetwork!==void 0&&(r.captureNetwork=e.captureNetwork),e.captureNavigation!==void 0&&(r.captureNavigation=e.captureNavigation),e.onError!==void 0&&(r.onError=e.onError),e.fetchImpl!==void 0&&(r.fetchImpl=e.fetchImpl),r}function C(e,t){let n;return{get mode(){return e.mode},get recording(){return e.recording},flush:async()=>e.flush(),getSessionId:()=>e.getSessionId(),stop:async()=>(n??=(async()=>{try{await e.stop()}finally{t.clear()}})(),n)}}function w(e,t){return[t.traceUrl,t.metricUrl,e].flatMap(e=>{let t=T(e);return t===void 0?[]:[t]})}function T(e){if(e===void 0||e.length===0)return;let t=e.replace(/\/+$/u,``);return RegExp(`^${E(t)}(?:[/?#]|$)`,`u`)}function E(e){return e.replace(/[.*+?^${}()|[\]\\]/gu,`\\$&`)}let D,O;function k(e){let t=!1;return{async shutdown(){return t?Promise.resolve():(t=!0,e?.shutdown(),O===e&&(O=void 0),Promise.resolve())}}}function A(e,t,n){if(typeof n==`string`||typeof n==`boolean`){e[t]=n;return}typeof n==`number`&&Number.isFinite(n)&&(e[t]=n)}function j(e={}){let t={};return e.reportAllChanges!==void 0&&(t.reportAllChanges=e.reportAllChanges),e.generateTarget!==void 0&&(t.generateTarget=e.generateTarget),t}function M(e={}){return{...j(e),includeProcessedEventEntries:e.includeProcessedEventEntries??!1}}function N(e){let t={};return A(t,`web_vital.name`,e.name),A(t,`web_vital.value`,e.value),A(t,`web_vital.delta`,e.delta),A(t,`web_vital.id`,e.id),A(t,`web_vital.rating`,e.rating),A(t,`web_vital.navigation_type`,e.navigationType),t}function P(e){let t=N(e);switch(e.name){case`LCP`:{let{attribution:n}=e;A(t,`web_vital.lcp.target`,n.target),A(t,`web_vital.lcp.element`,n.target),A(t,`web_vital.lcp.url`,n.url),A(t,`web_vital.lcp.time_to_first_byte`,n.timeToFirstByte),A(t,`web_vital.lcp.resource_load_delay`,n.resourceLoadDelay),A(t,`web_vital.lcp.resource_load_duration`,n.resourceLoadDuration),A(t,`web_vital.lcp.element_render_delay`,n.elementRenderDelay);break}case`INP`:{let{attribution:n}=e;A(t,`web_vital.inp.target`,n.interactionTarget),A(t,`web_vital.inp.interaction_type`,n.interactionType),A(t,`web_vital.inp.interaction_time`,n.interactionTime),A(t,`web_vital.inp.input_delay`,n.inputDelay),A(t,`web_vital.inp.processing_duration`,n.processingDuration),A(t,`web_vital.inp.presentation_delay`,n.presentationDelay),A(t,`web_vital.inp.load_state`,n.loadState);break}case`CLS`:{let{attribution:n}=e;A(t,`web_vital.cls.largest_shift_target`,n.largestShiftTarget),A(t,`web_vital.cls.largest_shift_time`,n.largestShiftTime),A(t,`web_vital.cls.largest_shift_value`,n.largestShiftValue),A(t,`web_vital.cls.load_state`,n.loadState);break}case`FCP`:{let{attribution:n}=e;A(t,`web_vital.fcp.time_to_first_byte`,n.timeToFirstByte),A(t,`web_vital.fcp.first_byte_to_fcp`,n.firstByteToFCP),A(t,`web_vital.fcp.load_state`,n.loadState);break}case`TTFB`:{let{attribution:n}=e;A(t,`web_vital.ttfb.waiting_duration`,n.waitingDuration),A(t,`web_vital.ttfb.cache_duration`,n.cacheDuration),A(t,`web_vital.ttfb.dns_duration`,n.dnsDuration),A(t,`web_vital.ttfb.connection_duration`,n.connectionDuration),A(t,`web_vital.ttfb.request_duration`,n.requestDuration);break}default:break}return t}function F(t){try{let n=e.trace.getTracer(`logfire-web-vitals`).startSpan(`web_vital.${t.name.toLowerCase()}`);try{n.setAttributes(P(t))}finally{n.end()}}catch(t){e.diag.error(`logfire-browser: failed to report Web Vital`,t)}}function I(t,n){if(n!==void 0)try{n.record(t)}catch(t){e.diag.error(`logfire-browser: failed to report Web Vital metric`,t)}}function L(e,t){F(e),I(e,t)}function R(e,t={}){let n=j(t),r=e=>{L(e,O)};e.onLCP(r,n),e.onINP(r,M(t)),e.onCLS(r,n),e.onFCP(r,n),e.onTTFB(r,n)}async function z(t={}){return t.metricRecorder!==void 0&&(O=t.metricRecorder),D??=import(`web-vitals/attribution`).then(e=>{R(e,t)}).catch(t=>{e.diag.error(`logfire-browser: failed to start Web Vitals reporting`,t)}),await D,k(t.metricRecorder)}const B=`target_xpath`,V={1:`trace`,5:`debug`,9:`info`,10:`notice`,13:`warning`,17:`error`,21:`fatal`},H={debug:`#E3E3E3`,error:`#EA4335`,fatal:`#EA4335`,info:`#9EC1FB`,notice:`#A5D490`,"on-debug":`#636262`,"on-error":`#FFEDE9`,"on-fatal":`#FFEDE9`,"on-info":`#063175`,"on-notice":`#222222`,"on-trace":`#636262`,"on-warning":`#613A0D`,trace:`#E3E3E3`,warning:`#EFB77A`};var U=class{export(e,t){this.sendSpans(e,t)}async forceFlush(){return Promise.resolve()}async shutdown(){return this.sendSpans([]),this.forceFlush()}exportInfo(e){return{attributes:e.attributes,duration:(0,c.hrTimeToMicroseconds)(e.duration),events:e.events,id:e.spanContext().spanId,instrumentationScope:e.instrumentationScope,kind:e.kind,links:e.links,name:e.name,parentSpanContext:e.parentSpanContext,resource:{attributes:e.resource.attributes},status:e.status,timestamp:(0,c.hrTimeToMicroseconds)(e.startTime),traceId:e.spanContext().traceId,traceState:e.spanContext().traceState?.serialize()}}sendSpans(e,t){for(let t of e){let e=V[t.attributes[`logfire.level_num`]]??`info`,{attributes:n,name:r,...i}=this.exportInfo(t);console.log(`%cLogfire %c${e}`,`background-color: #E520E9; color: #FFFFFF`,`background-color: ${H[`on-${e}`]}; color: ${H[e]}`,r,n,i)}t&&t({code:c.ExportResultCode.SUCCESS})}},W=class{console;wrapped;constructor(e,t){t&&(this.console=new i.SimpleSpanProcessor(new U)),this.wrapped=e}async forceFlush(){return await this.console?.forceFlush(),this.wrapped.forceFlush()}onEnd(e){this.console?.onEnd(e),this.wrapped.onEnd(e)}onStart(e,t){if(o.ATTR_HTTP_URL in e.attributes){let t=new URL(e.attributes[o.ATTR_HTTP_URL]);Reflect.set(e,`name`,`${e.name} ${t.pathname}`)}if(B in e.attributes){let t=String(e.attributes.event_type??`unknown`),n=String(e.attributes[B]??``);Reflect.set(e,`name`,`${t} ${n}`)}this.console?.onStart(e,t),this.wrapped.onStart(e,t)}async shutdown(){return await this.console?.shutdown(),this.wrapped.shutdown()}};function G(){return{}}function K(e){if(!(e===void 0||e===!1))return e===!0?{}:e}function q(e){if(!(e===void 0||e===!1)){if(e.metricUrl===``)throw Error(`logfire-browser: metrics.metricUrl must be a non-empty browser-safe metrics proxy URL`);return e}}function J(e){if(!(e?.metrics===void 0||e.metrics===!1))return e.metrics===!0?{}:e.metrics}function Y(e){if(!(e===void 0||e===!1))return e}function X(e,t){let n=K(e?.webVitals),r=t!==void 0;if(n===void 0&&!r)return e?.session;if(e?.session===!1)throw Error(r?`logfire-browser: sessionReplay requires browser session attributes; remove rum.session: false or disable sessionReplay`:`logfire-browser: rum.webVitals requires browser session attributes; remove rum.session: false or disable rum.webVitals`);return e?.session??!0}async function Z(e,t){return{...typeof e==`function`?await e():e??{},...t()}}function Q(c){c.diagLogLevel!==void 0&&e.diag.setLogger(new e.DiagConsoleLogger,c.diagLogLevel);let l=K(c.rum?.webVitals),d=Y(c.sessionReplay),f=q(c.metrics),p=J(l);if(p!==void 0&&f===void 0)throw Error(`logfire-browser: rum.webVitals.metrics requires top-level metrics.metricUrl`);let m=X(c.rum,d),h={errorFingerprinting:c.errorFingerprinting??!1};c.baggage!==void 0&&(h.baggage=c.baggage),c.jsonSchema!==void 0&&(h.jsonSchema=c.jsonSchema),c.minLevel!==void 0&&(h.minLevel=c.minLevel),c.scrubbing!==void 0&&(h.scrubbing=c.scrubbing),(0,s.configureLogfireApi)(h);let g=(0,r.resourceFromAttributes)(c.resourceAttributes??{}).merge((0,r.resourceFromAttributes)({[o.ATTR_BROWSER_LANGUAGE]:navigator.language,[a.ATTR_SERVICE_NAME]:c.serviceName??`logfire-browser`,[a.ATTR_SERVICE_VERSION]:c.serviceVersion??`0.0.1`,[a.ATTR_TELEMETRY_SDK_LANGUAGE]:a.TELEMETRY_SDK_LANGUAGE_VALUE_WEBJS,[a.ATTR_TELEMETRY_SDK_NAME]:`logfire-browser`,...c.environment!==void 0&&c.environment!==``?{[o.ATTR_DEPLOYMENT_ENVIRONMENT_NAME]:c.environment}:{},[a.ATTR_TELEMETRY_SDK_VERSION]:`0.0.0`,...navigator.userAgentData?{[o.ATTR_BROWSER_BRANDS]:navigator.userAgentData.brands.map(e=>`${e.brand} ${e.version}`),[o.ATTR_BROWSER_MOBILE]:navigator.userAgentData.mobile,[o.ATTR_BROWSER_PLATFORM]:navigator.userAgentData.platform}:{[a.ATTR_USER_AGENT_ORIGINAL]:navigator.userAgent}}));e.diag.info(`logfire-browser: starting`);let v=c.sampling?.head,S=v!==void 0&&v<1?new i.ParentBasedSampler({root:new i.TraceIdRatioBasedSampler(v)}):void 0,C=new W(new i.BatchSpanProcessor(new t.OTLPTraceExporter({...c.traceExporterConfig,headers:async()=>Z(c.traceExporterConfig?.headers,c.traceExporterHeaders??G),url:c.traceUrl}),c.batchSpanProcessorConfig),!!c.console);c.sampling?.tail&&(C=new s.TailSamplingProcessor(C,c.sampling.tail));let w=_(m),T=new b,E=[];w!==void 0&&E.push(new u(w,T)),E.push(...c.spanProcessors??[],C);let D=new i.WebTracerProvider({idGenerator:new s.ULIDGenerator,resource:g,...S?{sampler:S}:{},spanProcessors:E});D.register({contextManager:c.contextManager??new i.StackContextManager});let O=(0,n.registerInstrumentations)({instrumentations:c.instrumentations??[],tracerProvider:D}),k=d===void 0||w===void 0?void 0:x(d,w,T,{metricUrl:f?.metricUrl,traceUrl:c.traceUrl}),A=f===void 0?void 0:Promise.resolve().then(()=>require("./browserMetrics-sqpejR9C.cjs")).then(async({startBrowserMetrics:e})=>e(f,g)).catch(t=>{e.diag.error(`logfire-browser: failed to start browser metrics`,t)}),j=l===void 0?void 0:p===void 0?z(l).catch(t=>{e.diag.error(`logfire-browser: failed to start Web Vitals reporting`,t)}):(async()=>{let e=await A;if(e===void 0)throw Error(`logfire-browser: failed to start Web Vitals metrics because browser metrics transport did not start`);return z({...l,metricRecorder:e.createWebVitalsMetricRecorder(p)})})().catch(t=>{e.diag.error(`logfire-browser: failed to start Web Vitals reporting`,t)}),M;return()=>(M??=(async()=>{let t,n=(n,r)=>{let i=r instanceof Error?r:Error(String(r));t??=i,e.diag.error(`logfire-browser: ${n} failed during shutdown`,i)},r=async(e,t)=>{try{await t()}catch(t){n(e,t)}};if(e.diag.info(`logfire-browser: shutting down`),k!==void 0&&(T.clear(),await r(`session replay shutdown`,async()=>{await(await k)?.stop()})),await r(`instrumentation unregister`,O),j!==void 0&&await r(`web vitals shutdown`,async()=>{await(await j)?.shutdown()}),A!==void 0&&(await r(`metric provider force flush`,async()=>{await(await A)?.forceFlush()}),await r(`metric provider shutdown`,async()=>{await(await A)?.shutdown()})),await r(`force flush`,async()=>D.forceFlush()),await r(`tracer provider shutdown`,async()=>D.shutdown()),w!==void 0&&await r(`browser session cleanup`,()=>{y(w)}),t!==void 0)throw Error(t.message,{cause:t});e.diag.info(`logfire-browser: shut down complete`)})(),M)}const $={configure:Q,configureLogfireApi:s.configureLogfireApi,debug:s.debug,DiagLogLevel:e.DiagLogLevel,error:s.error,fatal:s.fatal,getBrowserSessionId:v,info:s.info,instrument:s.instrument,Level:s.Level,log:s.log,logfireApiConfig:s.logfireApiConfig,LogfireAttributeScrubber:s.LogfireAttributeScrubber,NoopAttributeScrubber:s.NoopAttributeScrubber,notice:s.notice,reportError:s.reportError,resolveBaseUrl:s.resolveBaseUrl,resolveSendToLogfire:s.resolveSendToLogfire,serializeAttributes:s.serializeAttributes,span:s.span,startPendingSpan:s.startPendingSpan,startSpan:s.startSpan,trace:s.trace,ULIDGenerator:s.ULIDGenerator,warning:s.warning,withSettings:s.withSettings,withTags:s.withTags};Object.defineProperty(exports,"DiagLogLevel",{enumerable:!0,get:function(){return e.DiagLogLevel}}),exports.configure=Q,exports.default=$,exports.getBrowserSessionId=v,Object.keys(s).forEach(function(e){e!=="default"&&!Object.prototype.hasOwnProperty.call(exports,e)&&Object.defineProperty(exports,e,{enumerable:!0,get:function(){return s[e]}})});
1
+ Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});let e=require("@opentelemetry/api"),t=require("@opentelemetry/exporter-trace-otlp-http"),n=require("@opentelemetry/instrumentation"),r=require("@opentelemetry/resources"),i=require("@opentelemetry/sdk-trace-web"),a=require("@opentelemetry/semantic-conventions"),o=require("@opentelemetry/semantic-conventions/incubating"),s=require("logfire"),c=require("@opentelemetry/core");function l(){let e=globalThis;try{let t=(e.location??e.window?.location)?.href;return t===void 0||t===``?void 0:new URL(t)}catch{return}}var ee=class{replayState;sessionManager;constructor(e,t){this.sessionManager=e,this.replayState=t}async forceFlush(){return Promise.resolve()}onEnd(e){}onStart(e,t){let n=this.sessionManager.touch();e.setAttribute(`session.id`,n.id),e.setAttribute(`browser.session.id`,n.id);let r;try{r=this.replayState?.getState()}catch{r=void 0}r!==void 0&&(e.setAttribute(`logfire.session_replay.active`,r.active),e.setAttribute(`logfire.session_replay.mode`,r.mode));let i=l();if(i===void 0)return;let a;try{a=this.sessionManager.getUrlAttributes(i)}catch{return}a?.full!==void 0&&e.setAttribute(`logfire.page.url.full`,a.full),a?.path!==void 0&&e.setAttribute(`logfire.page.url.path`,a.path)}async shutdown(){return Promise.resolve()}};const u={idleTimeoutMs:30*6e4,maxDurationMs:240*6e4,storageKey:`lf_browser_session`};function d(){try{return globalThis.sessionStorage??null}catch{return null}}function f(){let e=globalThis.crypto;if(typeof e?.randomUUID==`function`)return e.randomUUID();if(typeof e?.getRandomValues==`function`){let t=new Uint8Array(16);return e.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,`0`)).join(``)}return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}-${Math.random().toString(36).slice(2)}`}function p(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.id==`string`&&t.id.length>0&&typeof t.startedAt==`number`&&Number.isFinite(t.startedAt)&&typeof t.lastActivityAt==`number`&&Number.isFinite(t.lastActivityAt)}var m=class{generateId;idleTimeoutMs;maxDurationMs;now;storage;storageKey;urlAttributes;memorySession;pendingSession;persistenceTimer;constructor(e={}){this.generateId=e.generateId??f,this.idleTimeoutMs=e.idleTimeoutMs??u.idleTimeoutMs,this.maxDurationMs=e.maxDurationMs??u.maxDurationMs,this.now=e.now??Date.now,this.storage=e.storage===void 0?d():e.storage,this.storageKey=e.storageKey??u.storageKey,this.urlAttributes=e.urlAttributes}getSession(){return this.getSessionAt(this.now())}peekSessionId(){return this.memorySession?.id}touch(){let e=this.now(),t={...this.getSessionAt(e),lastActivityAt:e};return this.memorySession=t,this.scheduleWrite(t),t}reset(){return this.createSession(this.now())}flushPendingStorage(){this.persistenceTimer!==void 0&&(clearTimeout(this.persistenceTimer),this.persistenceTimer=void 0);let e=this.pendingSession;this.pendingSession=void 0,e!==void 0&&this.writeSession(e)}getUrlAttributes(e){if(this.urlAttributes!==!1)return typeof this.urlAttributes==`function`?this.urlAttributes(e):{full:`${e.origin}${e.pathname}`,path:e.pathname}}createSession(e){let t={id:this.generateId(),lastActivityAt:e,startedAt:e};return this.flushPendingStorage(),this.writeSession(t),t}getSessionAt(e){if(this.memorySession!==void 0&&!this.isExpired(this.memorySession,e))return this.memorySession;let t=this.readSession();return t!==void 0&&!this.isExpired(t,e)?t:this.createSession(e)}isExpired(e,t){return t-e.lastActivityAt>this.idleTimeoutMs||t-e.startedAt>this.maxDurationMs}readSession(){if(this.storage!==null)try{let e=this.storage.getItem(this.storageKey);if(e!==null){let t=JSON.parse(e);if(p(t))return this.memorySession=t,t}}catch{return this.memorySession}return this.memorySession}writeSession(e){if(this.memorySession=e,this.storage!==null)try{this.storage.setItem(this.storageKey,JSON.stringify(e))}catch{}}scheduleWrite(e){this.pendingSession=e,this.persistenceTimer===void 0&&(this.persistenceTimer=setTimeout(()=>{this.persistenceTimer=void 0;let e=this.pendingSession;this.pendingSession=void 0,e!==void 0&&this.writeSession(e)},1e3))}};let h;function te(e){if(h?.flushPendingStorage(),e===void 0||e===!1){h=void 0;return}let t=new m(e===!0?{}:e);return h=t,t}function g(){return h?.touch().id}function _(e){h===e&&(e.flushPendingStorage(),h=void 0)}function v(e){let t=new Map;for(let n of e)for(let e of b(n.url)){let r=w(n.kind,e);t.set(`${r.source}/${r.flags}`,r)}return[...t.values()]}function y(e){if(e.length===0)throw Error(`logfire-browser: sessionReplay.replayUrl must be a non-empty browser URL`);let t=new Set([x(),S()].filter(e=>e!==void 0));t.size===0&&t.add(`https://logfire.invalid/`);let n=[...t].map(t=>C(e,t));if(n.some(e=>e===void 0))throw Error(`logfire-browser: sessionReplay.replayUrl must be a valid browser URL`);if(n.some(e=>e?.pathname===`/`))throw Error(`logfire-browser: sessionReplay.replayUrl must use a non-root path`);if(n.some(e=>e?.search!==``||e.hash!==``))throw Error(`logfire-browser: sessionReplay.replayUrl must not contain a query or fragment`)}function ne(e){try{return y(e),!0}catch{return!1}}function b(e){let t=new Set([e]),n=C(e,x());n!==void 0&&t.add(n.href);let r=C(e,S());return r!==void 0&&t.add(r.href),[...t]}function x(){let e=Reflect.get(globalThis,`location`);if(typeof e!=`object`||!e)return;let t=Reflect.get(e,`href`);return typeof t==`string`?t:void 0}function S(){let e=Reflect.get(globalThis,`document`);if(typeof e!=`object`||!e)return;let t=Reflect.get(e,`baseURI`);return typeof t==`string`?t:void 0}function C(e,t){try{return t===void 0?new URL(e):new URL(e,t)}catch{return}}function w(e,t){return e===`exact`?T(t):E(t)}function T(e){let t=e.indexOf(`#`),n=t===-1?e:e.slice(0,t),r=n.indexOf(`?`);return RegExp(t===-1?r===-1?`^${D(n)}(?:[?#].*)?$`:`^${D(n)}(?:#.*)?$`:`^${D(e)}$`,`u`)}function E(e){let t=e===`/`?e:e.replace(/\/+$/u,``);return RegExp(`^${D(t)}/[^/?#]+(?:\\?[^#]*)?(?:#.*)?$`,`u`)}function D(e){return e.replace(/[.*+?^${}()|[\]\\]/gu,`\\$&`)}var re=class{replay;setReplay(e){this.replay=e}clear(){this.replay=void 0}getState(){let e=this.replay?.mode;if(!(this.replay?.recording!==!0||e!==`full`&&e!==`buffer`))return{active:!0,mode:e}}};async function ie(t,n,r,i){try{if(y(t.replayUrl),n.touch(),n.peekSessionId()===void 0)throw Error(`logfire-browser: sessionReplay requires an active browser session id`);let e=await t.load(),a=O(t,n,i),o=j(e.startSessionReplay(a),r,t.onError);return r.setReplay(o),o}catch(n){r.clear(),e.diag.error(`logfire-browser: failed to start session replay; install @pydantic/logfire-session-replay and verify sessionReplay config`,n),k(t.onError,n);return}}function O(e,t,n){let r={getSessionId:()=>t.peekSessionId(),ignoreUrlPatterns:[...v([{kind:`exact`,url:n.traceUrl},...n.metricUrl===void 0?[]:[{kind:`exact`,url:n.metricUrl}],{kind:`replay-base`,url:e.replayUrl}]),...e.ignoreUrlPatterns??[]],replayUrl:e.replayUrl};return e.headers!==void 0&&(r.headers=e.headers),e.token!==void 0&&(r.token=e.token),e.sessionSampleRate!==void 0&&(r.sessionSampleRate=e.sessionSampleRate),e.onErrorSampleRate!==void 0&&(r.onErrorSampleRate=e.onErrorSampleRate),e.maskAllText!==void 0&&(r.maskAllText=e.maskAllText),e.maskAllInputs!==void 0&&(r.maskAllInputs=e.maskAllInputs),e.maskTextSelector!==void 0&&(r.maskTextSelector=e.maskTextSelector),e.blockSelector!==void 0&&(r.blockSelector=e.blockSelector),e.flushIntervalMs!==void 0&&(r.flushIntervalMs=e.flushIntervalMs),e.maxBufferBytes!==void 0&&(r.maxBufferBytes=e.maxBufferBytes),e.distinctId!==void 0&&(r.distinctId=e.distinctId),e.getDistinctId!==void 0&&(r.getDistinctId=e.getDistinctId),e.captureConsole!==void 0&&(r.captureConsole=e.captureConsole),e.captureNetwork!==void 0&&(r.captureNetwork=e.captureNetwork),e.captureNavigation!==void 0&&(r.captureNavigation=e.captureNavigation),e.redactUrlPatterns!==void 0&&(r.redactUrlPatterns=e.redactUrlPatterns),e.onError!==void 0&&(r.onError=t=>{k(e.onError,t)}),e.fetchImpl!==void 0&&(r.fetchImpl=e.fetchImpl),r}function k(e,t){try{let n=e?.(t);A(n)&&Promise.resolve(n).catch(()=>void 0)}catch{}}function A(e){return typeof e==`object`&&!!e&&`then`in e&&typeof e.then==`function`}function j(e,t,n){let r;return{get mode(){try{return e.mode}catch(e){return k(n,e),`off`}},get recording(){try{return e.recording}catch(e){return k(n,e),!1}},flush:async()=>{try{await e.flush()}catch(e){k(n,e)}},stop:async()=>(r??=(async()=>{try{await e.stop()}catch(e){k(n,e)}finally{t.clear()}})(),r)}}let M,N,P,F,I,L;const R=new Set;function ae(e,t,n){let r=!1;return{async shutdown(){return r?Promise.resolve():(r=!0,n.active=!1,e?.shutdown(),N===e&&(N=void 0),P===t&&(P=void 0),F===n&&(F=void 0),Promise.resolve())}}}function z(e,t,n){if(typeof n==`string`||typeof n==`boolean`){e[t]=n;return}typeof n==`number`&&Number.isFinite(n)&&(e[t]=n)}function B(e={}){let t={};return e.reportAllChanges!==void 0&&(t.reportAllChanges=e.reportAllChanges),e.generateTarget!==void 0&&(t.generateTarget=e.generateTarget),t}function oe(e={}){return{...B(e),includeProcessedEventEntries:e.includeProcessedEventEntries??!1}}function se(e){let t={"logfire.span_type":`log`};return z(t,`web_vital.name`,e.name),z(t,`web_vital.value`,e.value),z(t,`web_vital.delta`,e.delta),z(t,`web_vital.id`,e.id),z(t,`web_vital.rating`,e.rating),z(t,`web_vital.navigation_type`,e.navigationType),t}function ce(e){let t=se(e);switch(e.name){case`LCP`:{let{attribution:n}=e;z(t,`web_vital.lcp.target`,n.target),z(t,`web_vital.lcp.element`,n.target),z(t,`web_vital.lcp.url`,n.url),z(t,`web_vital.lcp.time_to_first_byte`,n.timeToFirstByte),z(t,`web_vital.lcp.resource_load_delay`,n.resourceLoadDelay),z(t,`web_vital.lcp.resource_load_duration`,n.resourceLoadDuration),z(t,`web_vital.lcp.element_render_delay`,n.elementRenderDelay);break}case`INP`:{let{attribution:n}=e;z(t,`web_vital.inp.target`,n.interactionTarget),z(t,`web_vital.inp.interaction_type`,n.interactionType),z(t,`web_vital.inp.interaction_time`,n.interactionTime),z(t,`web_vital.inp.input_delay`,n.inputDelay),z(t,`web_vital.inp.processing_duration`,n.processingDuration),z(t,`web_vital.inp.presentation_delay`,n.presentationDelay),z(t,`web_vital.inp.load_state`,n.loadState);break}case`CLS`:{let{attribution:n}=e;z(t,`web_vital.cls.largest_shift_target`,n.largestShiftTarget),z(t,`web_vital.cls.largest_shift_time`,n.largestShiftTime),z(t,`web_vital.cls.largest_shift_value`,n.largestShiftValue),z(t,`web_vital.cls.load_state`,n.loadState);break}case`FCP`:{let{attribution:n}=e;z(t,`web_vital.fcp.time_to_first_byte`,n.timeToFirstByte),z(t,`web_vital.fcp.first_byte_to_fcp`,n.firstByteToFCP),z(t,`web_vital.fcp.load_state`,n.loadState);break}case`TTFB`:{let{attribution:n}=e;z(t,`web_vital.ttfb.waiting_duration`,n.waitingDuration),z(t,`web_vital.ttfb.cache_duration`,n.cacheDuration),z(t,`web_vital.ttfb.dns_duration`,n.dnsDuration),z(t,`web_vital.ttfb.connection_duration`,n.connectionDuration),z(t,`web_vital.ttfb.request_duration`,n.requestDuration);break}default:break}return t}function le(t,n){if(n===void 0){e.diag.error(`logfire-browser: failed to report Web Vital`,Error(`missing Web Vitals tracer`));return}try{let e=n.startSpan(`web_vital.${t.name.toLowerCase()}`);try{e.setAttributes(ce(t))}finally{e.end()}}catch(t){e.diag.error(`logfire-browser: failed to report Web Vital`,t)}}function ue(t,n){if(n!==void 0)try{n.record(t)}catch(t){e.diag.error(`logfire-browser: failed to report Web Vital metric`,t)}}function de(e,t,n){le(e,n),ue(e,t)}function fe(e,t){let n=L??=H(t),r=B(n),i=e=>{I===void 0||F?.active!==!0||de(e,N,P)},a=[[`LCP`,e.onLCP,r],[`INP`,e.onINP,oe(n)],[`CLS`,e.onCLS,r],[`FCP`,e.onFCP,r],[`TTFB`,e.onTTFB,r]];for(let[e,t,n]of a)R.has(e)||(t(i,n),R.add(e));I=n}async function V(t){let n={active:!0};t.metricRecorder!==void 0&&(N=t.metricRecorder),P=t.tracer,F=n;let r=H(t);if(M===void 0){let e=import(`web-vitals/attribution`).then(e=>{fe(e,t)}).catch(t=>{throw M===e&&(M=void 0),R.size===0&&(L=void 0),t});M=e}try{await M}catch(e){throw n.active=!1,t.metricRecorder?.shutdown(),N===t.metricRecorder&&(N=void 0),P===t.tracer&&(P=void 0),F===n&&(F=void 0),e}return I!==void 0&&!pe(I,r)&&e.diag.warn(`logfire-browser: Web Vitals observer options are fixed by the first successful startup; ignoring changed options`),ae(t.metricRecorder,t.tracer,n)}function H(e){return{generateTarget:e.generateTarget,includeProcessedEventEntries:e.includeProcessedEventEntries??!1,reportAllChanges:e.reportAllChanges}}function pe(e,t){return e.generateTarget===t.generateTarget&&e.includeProcessedEventEntries===t.includeProcessedEventEntries&&(e.reportAllChanges??!1)===(t.reportAllChanges??!1)}const U=`target_xpath`,me={1:`trace`,5:`debug`,9:`info`,10:`notice`,13:`warning`,17:`error`,21:`fatal`},W={debug:`#E3E3E3`,error:`#EA4335`,fatal:`#EA4335`,info:`#9EC1FB`,notice:`#A5D490`,"on-debug":`#636262`,"on-error":`#FFEDE9`,"on-fatal":`#FFEDE9`,"on-info":`#063175`,"on-notice":`#222222`,"on-trace":`#636262`,"on-warning":`#613A0D`,trace:`#E3E3E3`,warning:`#EFB77A`};var he=class{export(e,t){this.sendSpans(e,t)}async forceFlush(){return Promise.resolve()}async shutdown(){return this.sendSpans([]),this.forceFlush()}exportInfo(e){return{attributes:e.attributes,duration:(0,c.hrTimeToMicroseconds)(e.duration),events:e.events,id:e.spanContext().spanId,instrumentationScope:e.instrumentationScope,kind:e.kind,links:e.links,name:e.name,parentSpanContext:e.parentSpanContext,resource:{attributes:e.resource.attributes},status:e.status,timestamp:(0,c.hrTimeToMicroseconds)(e.startTime),traceId:e.spanContext().traceId,traceState:e.spanContext().traceState?.serialize()}}sendSpans(e,t){for(let t of e){let e=me[t.attributes[`logfire.level_num`]]??`info`,{attributes:n,name:r,...i}=this.exportInfo(t);console.log(`%cLogfire %c${e}`,`background-color: #E520E9; color: #FFFFFF`,`background-color: ${W[`on-${e}`]}; color: ${W[e]}`,r,n,i)}t&&t({code:c.ExportResultCode.SUCCESS})}},ge=class{console;wrapped;constructor(e,t){t&&(this.console=new i.SimpleSpanProcessor(new he)),this.wrapped=e}async forceFlush(){return await this.console?.forceFlush(),this.wrapped.forceFlush()}onEnd(e){this.console?.onEnd(e),this.wrapped.onEnd(e)}onStart(e,t){if(o.ATTR_HTTP_URL in e.attributes){let t=new URL(e.attributes[o.ATTR_HTTP_URL]);Reflect.set(e,`name`,`${e.name} ${t.pathname}`)}if(U in e.attributes){let t=String(e.attributes.event_type??`unknown`),n=String(e.attributes[U]??``);Reflect.set(e,`name`,`${t} ${n}`)}this.console?.onStart(e,t),this.wrapped.onStart(e,t)}async shutdown(){return await this.console?.shutdown(),this.wrapped.shutdown()}};const G=`logfire-browser: an OpenTelemetry context manager is already registered; omit contextManager to use the application-owned manager`;var _e=class{getCurrentProvider;constructor(e){this.getCurrentProvider=e}getTracer(e,t,n){return new ve(this.getCurrentProvider,e,t,n)}},ve=class{getCurrentProvider;name;options;version;constructor(e,t,n,r){this.getCurrentProvider=e,this.name=t,this.version=n,this.options=r}startSpan(t,n,r){return this.getDelegate()?.startSpan(t,n,r)??e.trace.wrapSpanContext(e.INVALID_SPAN_CONTEXT)}startActiveSpan(t,n,r,i){let a=this.getDelegate();if(a!==void 0)return typeof n==`function`?a.startActiveSpan(t,n):typeof r==`function`?a.startActiveSpan(t,n,r):a.startActiveSpan(t,n,r,i);let o=e.trace.wrapSpanContext(e.INVALID_SPAN_CONTEXT),s=typeof n==`function`?n:typeof r==`function`?r:i,c=typeof n==`function`||typeof r==`function`?e.context.active():r??e.context.active();return e.context.with(e.trace.setSpan(c,o),s,void 0,o)}getDelegate(){return this.getCurrentProvider()?.getTracer(this.name,this.version,this.options)}},ye=class{contextOwnership={status:`uninitialized`};generation={status:`idle`};propagationOwnership={status:`uninitialized`};traceOwnership={status:`uninitialized`};stableProvider=new _e(()=>this.getCurrentProvider());assertAvailable(){if(this.contextOwnership.status===`failed`)throw this.contextOwnership.error;if(this.generation.status===`failed`)throw Error(`logfire-browser: the previous cleanup failed; reload the page before configuring again`,{cause:this.generation.error});if(this.generation.status!==`idle`)throw Error(`logfire-browser: a configuration is already active; await its cleanup before configuring again`)}initializeGlobals(e){this.assertAvailable(),this.initializeContext(e),this.initializeTrace(),this.initializePropagation()}activate(e){this.assertAvailable();let t=Symbol(`logfire-browser-provider-generation`);return this.generation={provider:e,status:`active`,token:t},t}beginCleanup(e){this.generation.status===`active`&&this.generation.token===e&&(this.generation={delegateActive:!0,provider:this.generation.provider,status:`cleaning`,token:e})}deactivateDelegate(e){this.generation.status===`cleaning`&&this.generation.token===e&&(this.generation.delegateActive=!1)}settleCleanup(e,t){this.generation.status!==`cleaning`||this.generation.token!==e||(this.generation=t===void 0?{status:`idle`}:{error:t,status:`failed`,token:this.generation.token})}rollbackActivation(e,t){this.generation.status!==`active`||this.generation.token!==e||(this.generation=t===void 0?{status:`idle`}:{error:t,status:`failed`,token:e})}resetForTests(){this.generation={status:`idle`},this.contextOwnership={status:`uninitialized`},this.traceOwnership={status:`uninitialized`},this.propagationOwnership={status:`uninitialized`},K(()=>{e.context.disable()}),K(()=>{e.propagation.disable()}),K(()=>{e.trace.disable()})}getStateForTests(){return this.generation}getCurrentProvider(){if(this.generation.status===`active`||this.generation.status===`cleaning`&&this.generation.delegateActive)return this.generation.provider}initializeContext(t){if(this.contextOwnership.status===`failed`)throw this.contextOwnership.error;if(this.contextOwnership.status===`logfire`){if(t!==void 0&&t!==this.contextOwnership.contextManager)throw Error(`logfire-browser: contextManager cannot change after Logfire context initialization`);return}if(this.contextOwnership.status===`external`){if(t!==void 0)throw Error(G);return}let n=t??new i.StackContextManager;if(!e.context.setGlobalContextManager(n)){if(this.contextOwnership={status:`external`},t!==void 0)throw Error(G);return}try{n.enable(),this.contextOwnership={contextManager:n,status:`logfire`}}catch(t){try{e.context.disable(),this.contextOwnership={status:`uninitialized`}}catch(e){let n=Error(`logfire-browser: context manager initialization failed and could not be rolled back; reload the page before configuring again`,{cause:{enableError:t,rollbackError:e}});throw this.contextOwnership={error:n,status:`failed`},n}throw t}}initializeTrace(){this.traceOwnership.status===`uninitialized`&&(this.traceOwnership={status:e.trace.setGlobalTracerProvider(this.stableProvider)?`logfire`:`external`})}initializePropagation(){if(this.propagationOwnership.status!==`uninitialized`)return;let t=new c.CompositePropagator({propagators:[new c.W3CTraceContextPropagator,new c.W3CBaggagePropagator]});this.propagationOwnership={status:e.propagation.setGlobalPropagator(t)?`logfire`:`external`}}};function K(e){try{e()}catch{}}const q=new ye;function be(){q.assertAvailable()}function xe(e){q.initializeGlobals(e)}function Se(e){return q.activate(e)}function J(e){q.beginCleanup(e)}function Y(e){q.deactivateDelegate(e)}function X(e,t){q.settleCleanup(e,t)}function Ce(e,t,n){return q.stableProvider.getTracer(e,t,n)}function we(){return{}}function Z(e){if(!(e===void 0||e===!1))return e===!0?{}:e}function Te(e){if(!(e===void 0||e===!1)){if(e.metricUrl===``)throw Error(`logfire-browser: metrics.metricUrl must be a non-empty browser-safe metrics proxy URL`);return e}}function Ee(e){if(!(e?.metrics===void 0||e.metrics===!1))return e.metrics===!0?{}:e.metrics}function De(e){if(!(e===void 0||e===!1))return y(e.replayUrl),e}function Oe(e,t){let n=Z(e?.webVitals),r=t!==void 0;if(n===void 0&&!r)return e?.session;if(e?.session===!1)throw Error(r?`logfire-browser: sessionReplay requires browser session attributes; remove rum.session: false or disable sessionReplay`:`logfire-browser: rum.webVitals requires browser session attributes; remove rum.session: false or disable rum.webVitals`);return e?.session??!0}async function ke(e,t){return{...typeof e==`function`?await e():e??{},...t()}}function Ae(e){return Array.isArray(e)?e:[e]}function je(e,t){if(e===void 0||e===!1)return;let{enabled:n,...r}=e===!0?{}:e;if(n===!1)return;let i=v([{kind:`exact`,url:t.traceUrl},...t.metricUrl===void 0?[]:[{kind:`exact`,url:t.metricUrl}],...t.replayUrl===void 0?[]:[{kind:`replay-base`,url:t.replayUrl}]]),a=`@opentelemetry/instrumentation-fetch`,o=`@opentelemetry/instrumentation-xml-http-request`,s=r[a],c=r[o];return{...r,[a]:{...s,ignoreUrls:[...s?.ignoreUrls??[],...i]},[o]:{...c,ignoreUrls:[...c?.ignoreUrls??[],...i]}}}function Me(){}function Ne(t){let r=[],i=t.instrumentations??[],a=i.length===0?[[]]:i;for(let i of a){let a=[];try{a=Ae(typeof i==`function`?i():i),r.push((0,n.registerInstrumentations)({instrumentations:a,tracerProvider:t.tracerProvider}))}catch(t){Q(a),e.diag.error(`logfire-browser: failed to start configured browser instrumentation group`,t)}}let o=je(t.autoInstrumentations,t.telemetryUrls),s=o===void 0?void 0:import(`@opentelemetry/auto-instrumentations-web`).then(({getWebAutoInstrumentations:e})=>{let r=e(o);try{return(0,n.registerInstrumentations)({instrumentations:r,tracerProvider:t.tracerProvider})}catch(e){throw Q(r),e}}).catch(t=>(e.diag.error(`logfire-browser: failed to start browser auto-instrumentations`,t),Me)),c;return async()=>(c??=(async()=>{let e=await s,t=[...r,...e===void 0?[]:[e]],n;for(let e=t.length-1;e>=0;--e)try{t[e]?.()}catch(e){n??=e}if(n!==void 0)throw n instanceof Error?n:Error(`logfire-browser: instrumentation unregister failed`,{cause:n})})(),c)}function Q(t){for(let n=t.length-1;n>=0;--n)try{t[n]?.disable()}catch(t){e.diag.error(`logfire-browser: failed to disable browser instrumentation after registration failure`,t)}}function Pe(){return{baggage:s.logfireApiConfig.baggage,enableErrorFingerprinting:s.logfireApiConfig.enableErrorFingerprinting,jsonSchema:s.logfireApiConfig.jsonSchema,minLevel:s.logfireApiConfig.minLevel,scrubber:s.logfireApiConfig.scrubber,tracer:s.logfireApiConfig.tracer}}function Fe(e){s.logfireApiConfig.baggage=e.baggage,s.logfireApiConfig.enableErrorFingerprinting=e.enableErrorFingerprinting,s.logfireApiConfig.jsonSchema=e.jsonSchema,s.logfireApiConfig.minLevel=e.minLevel,s.logfireApiConfig.scrubber=e.scrubber,s.logfireApiConfig.tracer=e.tracer}function $(n){be();let c=Z(n.rum?.webVitals),l=De(n.sessionReplay),u=Te(n.metrics),d=Ee(c);if(d!==void 0&&u===void 0)throw Error(`logfire-browser: rum.webVitals.metrics requires top-level metrics.metricUrl`);let f=Oe(n.rum,l);xe(n.contextManager);let p=(0,r.resourceFromAttributes)(n.resourceAttributes??{}).merge((0,r.resourceFromAttributes)({[o.ATTR_BROWSER_LANGUAGE]:navigator.language,[a.ATTR_SERVICE_NAME]:n.serviceName??`logfire-browser`,[a.ATTR_SERVICE_VERSION]:n.serviceVersion??`0.0.1`,[a.ATTR_TELEMETRY_SDK_LANGUAGE]:a.TELEMETRY_SDK_LANGUAGE_VALUE_WEBJS,[a.ATTR_TELEMETRY_SDK_NAME]:`logfire-browser`,...n.environment!==void 0&&n.environment!==``?{[o.ATTR_DEPLOYMENT_ENVIRONMENT_NAME]:n.environment}:{},[a.ATTR_TELEMETRY_SDK_VERSION]:`1.0.0`,...navigator.userAgentData?{[o.ATTR_BROWSER_BRANDS]:navigator.userAgentData.brands.map(e=>`${e.brand} ${e.version}`),[o.ATTR_BROWSER_MOBILE]:navigator.userAgentData.mobile,[o.ATTR_BROWSER_PLATFORM]:navigator.userAgentData.platform}:{[a.ATTR_USER_AGENT_ORIGINAL]:navigator.userAgent}}));e.diag.info(`logfire-browser: starting`);let m=n.sampling?.head,h=m!==void 0&&m<1?new i.ParentBasedSampler({root:new i.TraceIdRatioBasedSampler(m)}):void 0,g=new ge(new i.BatchSpanProcessor(new t.OTLPTraceExporter({...n.traceExporterConfig,headers:async()=>ke(n.traceExporterConfig?.headers,n.traceExporterHeaders??we),url:n.traceUrl}),n.batchSpanProcessorConfig),!!n.console);n.sampling?.tail&&(g=new s.TailSamplingProcessor(g,n.sampling.tail));let v=te(f),y=new re,b=[];v!==void 0&&b.push(new ee(v,y)),b.push(...n.spanProcessors??[],g);let x;try{x=new i.WebTracerProvider({idGenerator:new s.ULIDGenerator,resource:p,...h?{sampler:h}:{},spanProcessors:b})}catch(e){throw v!==void 0&&_(v),e}let S=Pe(),C=Se(x);try{let t={errorFingerprinting:n.errorFingerprinting??!1};n.baggage!==void 0&&(t.baggage=n.baggage),n.jsonSchema!==void 0&&(t.jsonSchema=n.jsonSchema),n.minLevel!==void 0&&(t.minLevel=n.minLevel),n.scrubbing!==void 0&&(t.scrubbing=n.scrubbing),(0,s.configureLogfireApi)(t),n.diagLogLevel!==void 0&&e.diag.setLogger(new e.DiagConsoleLogger,n.diagLogLevel),s.logfireApiConfig.tracer=Ce(s.logfireApiConfig.otelScope)}catch(e){J(C),Y(C),Fe(S);let t;if(v!==void 0)try{_(v)}catch(e){t=e instanceof Error?e:Error(String(e))}throw x.shutdown().then(()=>{X(C,t)},e=>{X(C,t??(e instanceof Error?e:Error(String(e))))}),e}let w=Ne({autoInstrumentations:n.autoInstrumentations,instrumentations:n.instrumentations,telemetryUrls:{metricUrl:u?.metricUrl,replayUrl:l!==void 0&&ne(l.replayUrl)?l.replayUrl:void 0,traceUrl:n.traceUrl},tracerProvider:x}),T,E=l===void 0||v===void 0?void 0:ie(l,v,y,{metricUrl:u?.metricUrl,traceUrl:n.traceUrl}).then(e=>(T=e,e)),D=Promise.resolve(),O,k=!1,A=E===void 0?void 0:{get mode(){return k?`off`:T?.mode??`off`},get recording(){return k?!1:T?.recording??!1},flush(){if(k)return O??D;let e=D.then(async()=>{await(await E)?.flush()});return D=e,e},stop(){return O===void 0?(k=!0,y.clear(),O=D.then(async()=>{await(await E)?.stop()}),D=O,O):O}},j=u===void 0?void 0:Promise.resolve().then(()=>require("./browserMetrics-bhbn_Yb6.cjs")).then(async({startBrowserMetrics:e})=>e(u,p)).catch(t=>{e.diag.error(`logfire-browser: failed to start browser metrics`,t)}),M=c===void 0?void 0:d===void 0?V({...c,tracer:x.getTracer(`logfire-web-vitals`)}).catch(t=>{e.diag.error(`logfire-browser: failed to start Web Vitals reporting`,t)}):(async()=>{let t=await j;return t===void 0?(e.diag.warn(`logfire-browser: browser metrics did not start; continuing Web Vitals with span reporting only`),V({...c,tracer:x.getTracer(`logfire-web-vitals`)})):V({...c,metricRecorder:t.createWebVitalsMetricRecorder(d),tracer:x.getTracer(`logfire-web-vitals`)})})().catch(t=>{e.diag.error(`logfire-browser: failed to start Web Vitals reporting`,t)}),N,P=()=>N===void 0?(J(C),N=(async()=>{let t,n=(n,r)=>{let i=r instanceof Error?r:Error(String(r));t??=i,e.diag.error(`logfire-browser: ${n} failed during shutdown`,i)},r=async(e,t)=>{try{await t()}catch(t){n(e,t)}};e.diag.info(`logfire-browser: shutting down`),A!==void 0&&await r(`session replay shutdown`,async()=>A.stop()),await r(`instrumentation unregister`,w),M!==void 0&&await r(`web vitals shutdown`,async()=>{await(await M)?.shutdown()}),j!==void 0&&(await r(`metric provider force flush`,async()=>{await(await j)?.forceFlush()}),await r(`metric provider shutdown`,async()=>{await(await j)?.shutdown()})),Y(C),await r(`force flush`,async()=>x.forceFlush()),await r(`tracer provider shutdown`,async()=>x.shutdown()),v!==void 0&&await r(`browser session cleanup`,()=>{_(v)});let i=t===void 0?void 0:Error(t.message,{cause:t});if(X(C,i),i!==void 0)throw i;e.diag.info(`logfire-browser: shut down complete`)})(),N):N;return A!==void 0&&Object.defineProperty(P,"sessionReplay",{enumerable:!0,value:A}),P}const Ie={configure:$,configureLogfireApi:s.configureLogfireApi,debug:s.debug,DiagLogLevel:e.DiagLogLevel,error:s.error,fatal:s.fatal,getBrowserSessionId:g,info:s.info,instrument:s.instrument,Level:s.Level,log:s.log,logfireApiConfig:s.logfireApiConfig,LogfireAttributeScrubber:s.LogfireAttributeScrubber,NoopAttributeScrubber:s.NoopAttributeScrubber,notice:s.notice,reportError:s.reportError,resolveBaseUrl:s.resolveBaseUrl,resolveSendToLogfire:s.resolveSendToLogfire,serializeAttributes:s.serializeAttributes,span:s.span,startPendingSpan:s.startPendingSpan,startSpan:s.startSpan,trace:s.trace,ULIDGenerator:s.ULIDGenerator,warning:s.warning,withSettings:s.withSettings,withTags:s.withTags};Object.defineProperty(exports,"DiagLogLevel",{enumerable:!0,get:function(){return e.DiagLogLevel}}),exports.configure=$,exports.default=Ie,exports.getBrowserSessionId=g,Object.keys(s).forEach(function(e){e!=="default"&&!Object.prototype.hasOwnProperty.call(exports,e)&&Object.defineProperty(exports,e,{enumerable:!0,get:function(){return s[e]}})});
package/dist/index.d.cts CHANGED
@@ -3,6 +3,7 @@ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
3
3
  import { Instrumentation } from "@opentelemetry/instrumentation";
4
4
  import { BufferConfig, SpanProcessor } from "@opentelemetry/sdk-trace-web";
5
5
  import { BaggageOptions, JsonSchemaMode, Level, LogfireAttributeScrubber, MinLevel, NoopAttributeScrubber, SamplingOptions, ScrubbingOptions, ULIDGenerator, configureLogfireApi, debug, error, fatal, info, instrument, log, logfireApiConfig, notice, reportError, resolveBaseUrl, resolveSendToLogfire, serializeAttributes, span, startPendingSpan, startSpan, trace as trace$1, warning, withSettings, withTags } from "logfire";
6
+ import { InstrumentationConfigMap } from "@opentelemetry/auto-instrumentations-web";
6
7
  import { OTLPMetricExporterOptions } from "@opentelemetry/exporter-metrics-otlp-http";
7
8
  import { MetricReader, PeriodicExportingMetricReaderOptions } from "@opentelemetry/sdk-metrics";
8
9
  import { MetricWithAttribution } from "web-vitals/attribution";
@@ -73,7 +74,10 @@ interface BrowserSessionUrlAttributes {
73
74
  }
74
75
  interface BrowserSessionOptions {
75
76
  /**
76
- * Session inactivity timeout. Defaults to 30 minutes.
77
+ * Session inactivity timeout. Defaults to 30 minutes. Replay startup touches
78
+ * the session once before lazy loading; subsequent replay events only peek
79
+ * and do not refresh inactivity. Span starts are the ongoing automatic
80
+ * activity, and getBrowserSessionId() explicitly touches the session.
77
81
  */
78
82
  idleTimeoutMs?: number;
79
83
  /**
@@ -87,8 +91,9 @@ interface BrowserSessionOptions {
87
91
  storageKey?: string;
88
92
  /**
89
93
  * Controls URL attributes stamped on session/RUM spans. Defaults to emitting
90
- * `url.full = window.location.href` and `url.path = window.location.pathname`.
91
- * Set to false to suppress URL attributes, or return sanitized values.
94
+ * `logfire.page.url.full = window.location.origin + window.location.pathname`
95
+ * and `logfire.page.url.path = window.location.pathname`. Set to false to suppress URL
96
+ * attributes, or return custom values (including the raw URL if required).
92
97
  */
93
98
  urlAttributes?: false | ((url: URL) => BrowserSessionUrlAttributes);
94
99
  }
@@ -120,6 +125,7 @@ interface BrowserSessionReplayPackageConfig {
120
125
  getSessionId?: () => string | undefined;
121
126
  sessionSampleRate?: number;
122
127
  onErrorSampleRate?: number;
128
+ maskAllText?: boolean;
123
129
  maskAllInputs?: boolean;
124
130
  maskTextSelector?: string;
125
131
  blockSelector?: string;
@@ -167,6 +173,7 @@ interface BrowserSessionReplayOptions {
167
173
  token?: string | (() => MaybePromise<string>);
168
174
  sessionSampleRate?: number;
169
175
  onErrorSampleRate?: number;
176
+ maskAllText?: boolean;
170
177
  maskAllInputs?: boolean;
171
178
  maskTextSelector?: string;
172
179
  blockSelector?: string;
@@ -185,6 +192,20 @@ interface BrowserSessionReplayOptions {
185
192
  //#endregion
186
193
  //#region src/index.d.ts
187
194
  type TraceExporterConfig = NonNullable<typeof OTLPTraceExporter extends (new (config: infer T) => unknown) ? T : never>;
195
+ type BrowserInstrumentationInput = Instrumentation | Instrumentation[] | (() => Instrumentation | Instrumentation[]);
196
+ type AutoInstrumentationsConfig = InstrumentationConfigMap & {
197
+ enabled?: boolean;
198
+ };
199
+ interface BrowserSessionReplayHandle {
200
+ readonly mode: "full" | "buffer" | "off";
201
+ readonly recording: boolean;
202
+ flush(): Promise<void>;
203
+ stop(): Promise<void>;
204
+ }
205
+ interface BrowserConfigureHandle {
206
+ (): Promise<void>;
207
+ readonly sessionReplay?: BrowserSessionReplayHandle;
208
+ }
188
209
  interface LogfireConfigOptions {
189
210
  /**
190
211
  * The configuration of the batch span processor.
@@ -223,9 +244,16 @@ interface LogfireConfigOptions {
223
244
  */
224
245
  jsonSchema?: JsonSchemaMode;
225
246
  /**
226
- * The instrumentations to register - a common one [is the fetch instrumentation](https://www.npmjs.com/package/@opentelemetry/instrumentation-fetch).
247
+ * Lazily register OpenTelemetry browser auto-instrumentations after the
248
+ * Logfire browser provider and session span processor are ready. Disabled by
249
+ * default. Pass an object to configure `getWebAutoInstrumentations()`.
250
+ */
251
+ autoInstrumentations?: boolean | AutoInstrumentationsConfig;
252
+ /**
253
+ * The instrumentations to register. Pass factories when construction should
254
+ * happen after the Logfire browser provider is registered.
227
255
  */
228
- instrumentations?: (Instrumentation | Instrumentation[])[];
256
+ instrumentations?: BrowserInstrumentationInput[];
229
257
  /**
230
258
  * Minimum Logfire level to emit for manual log-like spans.
231
259
  *
@@ -299,7 +327,7 @@ interface LogfireConfigOptions {
299
327
  */
300
328
  traceUrl: string;
301
329
  }
302
- declare function configure(options: LogfireConfigOptions): () => Promise<void>;
330
+ declare function configure(options: LogfireConfigOptions): BrowserConfigureHandle;
303
331
  declare const defaultExport: {
304
332
  DiagLogLevel: typeof DiagLogLevel$1;
305
333
  Level: typeof Level;
@@ -330,4 +358,4 @@ declare const defaultExport: {
330
358
  withTags: typeof withTags;
331
359
  };
332
360
  //#endregion
333
- export { type BrowserMetricsOptions, type BrowserSessionOptions, type BrowserSessionReplayOptions, type BrowserSessionUrlAttributes, type BrowserWebVitalsMetricOptions, type BrowserWebVitalsOptions, DiagLogLevel, LogfireConfigOptions, type RUMOptions, configure, defaultExport as default, getBrowserSessionId };
361
+ export { AutoInstrumentationsConfig, BrowserConfigureHandle, BrowserInstrumentationInput, type BrowserMetricsOptions, type BrowserSessionOptions, BrowserSessionReplayHandle, type BrowserSessionReplayOptions, type BrowserSessionUrlAttributes, type BrowserWebVitalsMetricOptions, type BrowserWebVitalsOptions, DiagLogLevel, LogfireConfigOptions, type RUMOptions, configure, defaultExport as default, getBrowserSessionId };
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
3
3
  import { Instrumentation } from "@opentelemetry/instrumentation";
4
4
  import { BufferConfig, SpanProcessor } from "@opentelemetry/sdk-trace-web";
5
5
  import { BaggageOptions, JsonSchemaMode, Level, LogfireAttributeScrubber, MinLevel, NoopAttributeScrubber, SamplingOptions, ScrubbingOptions, ULIDGenerator, configureLogfireApi, debug, error, fatal, info, instrument, log, logfireApiConfig, notice, reportError, resolveBaseUrl, resolveSendToLogfire, serializeAttributes, span, startPendingSpan, startSpan, trace as trace$1, warning, withSettings, withTags } from "logfire";
6
+ import { InstrumentationConfigMap } from "@opentelemetry/auto-instrumentations-web";
6
7
  import { OTLPMetricExporterOptions } from "@opentelemetry/exporter-metrics-otlp-http";
7
8
  import { MetricReader, PeriodicExportingMetricReaderOptions } from "@opentelemetry/sdk-metrics";
8
9
  import { MetricWithAttribution } from "web-vitals/attribution";
@@ -73,7 +74,10 @@ interface BrowserSessionUrlAttributes {
73
74
  }
74
75
  interface BrowserSessionOptions {
75
76
  /**
76
- * Session inactivity timeout. Defaults to 30 minutes.
77
+ * Session inactivity timeout. Defaults to 30 minutes. Replay startup touches
78
+ * the session once before lazy loading; subsequent replay events only peek
79
+ * and do not refresh inactivity. Span starts are the ongoing automatic
80
+ * activity, and getBrowserSessionId() explicitly touches the session.
77
81
  */
78
82
  idleTimeoutMs?: number;
79
83
  /**
@@ -87,8 +91,9 @@ interface BrowserSessionOptions {
87
91
  storageKey?: string;
88
92
  /**
89
93
  * Controls URL attributes stamped on session/RUM spans. Defaults to emitting
90
- * `url.full = window.location.href` and `url.path = window.location.pathname`.
91
- * Set to false to suppress URL attributes, or return sanitized values.
94
+ * `logfire.page.url.full = window.location.origin + window.location.pathname`
95
+ * and `logfire.page.url.path = window.location.pathname`. Set to false to suppress URL
96
+ * attributes, or return custom values (including the raw URL if required).
92
97
  */
93
98
  urlAttributes?: false | ((url: URL) => BrowserSessionUrlAttributes);
94
99
  }
@@ -120,6 +125,7 @@ interface BrowserSessionReplayPackageConfig {
120
125
  getSessionId?: () => string | undefined;
121
126
  sessionSampleRate?: number;
122
127
  onErrorSampleRate?: number;
128
+ maskAllText?: boolean;
123
129
  maskAllInputs?: boolean;
124
130
  maskTextSelector?: string;
125
131
  blockSelector?: string;
@@ -167,6 +173,7 @@ interface BrowserSessionReplayOptions {
167
173
  token?: string | (() => MaybePromise<string>);
168
174
  sessionSampleRate?: number;
169
175
  onErrorSampleRate?: number;
176
+ maskAllText?: boolean;
170
177
  maskAllInputs?: boolean;
171
178
  maskTextSelector?: string;
172
179
  blockSelector?: string;
@@ -185,6 +192,20 @@ interface BrowserSessionReplayOptions {
185
192
  //#endregion
186
193
  //#region src/index.d.ts
187
194
  type TraceExporterConfig = NonNullable<typeof OTLPTraceExporter extends (new (config: infer T) => unknown) ? T : never>;
195
+ type BrowserInstrumentationInput = Instrumentation | Instrumentation[] | (() => Instrumentation | Instrumentation[]);
196
+ type AutoInstrumentationsConfig = InstrumentationConfigMap & {
197
+ enabled?: boolean;
198
+ };
199
+ interface BrowserSessionReplayHandle {
200
+ readonly mode: "full" | "buffer" | "off";
201
+ readonly recording: boolean;
202
+ flush(): Promise<void>;
203
+ stop(): Promise<void>;
204
+ }
205
+ interface BrowserConfigureHandle {
206
+ (): Promise<void>;
207
+ readonly sessionReplay?: BrowserSessionReplayHandle;
208
+ }
188
209
  interface LogfireConfigOptions {
189
210
  /**
190
211
  * The configuration of the batch span processor.
@@ -223,9 +244,16 @@ interface LogfireConfigOptions {
223
244
  */
224
245
  jsonSchema?: JsonSchemaMode;
225
246
  /**
226
- * The instrumentations to register - a common one [is the fetch instrumentation](https://www.npmjs.com/package/@opentelemetry/instrumentation-fetch).
247
+ * Lazily register OpenTelemetry browser auto-instrumentations after the
248
+ * Logfire browser provider and session span processor are ready. Disabled by
249
+ * default. Pass an object to configure `getWebAutoInstrumentations()`.
250
+ */
251
+ autoInstrumentations?: boolean | AutoInstrumentationsConfig;
252
+ /**
253
+ * The instrumentations to register. Pass factories when construction should
254
+ * happen after the Logfire browser provider is registered.
227
255
  */
228
- instrumentations?: (Instrumentation | Instrumentation[])[];
256
+ instrumentations?: BrowserInstrumentationInput[];
229
257
  /**
230
258
  * Minimum Logfire level to emit for manual log-like spans.
231
259
  *
@@ -299,7 +327,7 @@ interface LogfireConfigOptions {
299
327
  */
300
328
  traceUrl: string;
301
329
  }
302
- declare function configure(options: LogfireConfigOptions): () => Promise<void>;
330
+ declare function configure(options: LogfireConfigOptions): BrowserConfigureHandle;
303
331
  declare const defaultExport: {
304
332
  DiagLogLevel: typeof DiagLogLevel$1;
305
333
  Level: typeof Level;
@@ -330,4 +358,4 @@ declare const defaultExport: {
330
358
  withTags: typeof withTags;
331
359
  };
332
360
  //#endregion
333
- export { type BrowserMetricsOptions, type BrowserSessionOptions, type BrowserSessionReplayOptions, type BrowserSessionUrlAttributes, type BrowserWebVitalsMetricOptions, type BrowserWebVitalsOptions, DiagLogLevel, LogfireConfigOptions, type RUMOptions, configure, defaultExport as default, getBrowserSessionId };
361
+ export { AutoInstrumentationsConfig, BrowserConfigureHandle, BrowserInstrumentationInput, type BrowserMetricsOptions, type BrowserSessionOptions, BrowserSessionReplayHandle, type BrowserSessionReplayOptions, type BrowserSessionUrlAttributes, type BrowserWebVitalsMetricOptions, type BrowserWebVitalsOptions, DiagLogLevel, LogfireConfigOptions, type RUMOptions, configure, defaultExport as default, getBrowserSessionId };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{DiagConsoleLogger as e,DiagLogLevel as t,DiagLogLevel as n,diag as r,trace as i}from"@opentelemetry/api";import{OTLPTraceExporter as a}from"@opentelemetry/exporter-trace-otlp-http";import{registerInstrumentations as o}from"@opentelemetry/instrumentation";import{resourceFromAttributes as s}from"@opentelemetry/resources";import{BatchSpanProcessor as ee,ParentBasedSampler as te,SimpleSpanProcessor as c,StackContextManager as l,TraceIdRatioBasedSampler as ne,WebTracerProvider as re}from"@opentelemetry/sdk-trace-web";import{ATTR_SERVICE_NAME as ie,ATTR_SERVICE_VERSION as ae,ATTR_TELEMETRY_SDK_LANGUAGE as oe,ATTR_TELEMETRY_SDK_NAME as se,ATTR_TELEMETRY_SDK_VERSION as ce,ATTR_USER_AGENT_ORIGINAL as u,TELEMETRY_SDK_LANGUAGE_VALUE_WEBJS as d}from"@opentelemetry/semantic-conventions";import{ATTR_BROWSER_BRANDS as f,ATTR_BROWSER_LANGUAGE as le,ATTR_BROWSER_MOBILE as ue,ATTR_BROWSER_PLATFORM as de,ATTR_DEPLOYMENT_ENVIRONMENT_NAME as fe,ATTR_HTTP_URL as p}from"@opentelemetry/semantic-conventions/incubating";import{Level as m,LogfireAttributeScrubber as h,NoopAttributeScrubber as g,TailSamplingProcessor as pe,ULIDGenerator as _,configureLogfireApi as v,debug as y,error as b,fatal as x,info as S,instrument as C,log as w,logfireApiConfig as T,notice as E,reportError as D,resolveBaseUrl as O,resolveSendToLogfire as k,serializeAttributes as A,span as j,startPendingSpan as M,startSpan as N,trace as P,warning as F,withSettings as I,withTags as L}from"logfire";import{ExportResultCode as R,hrTimeToMicroseconds as z}from"@opentelemetry/core";export*from"logfire";function B(){let e=globalThis;try{let t=(e.location??e.window?.location)?.href;return t===void 0||t===``?void 0:new URL(t)}catch{return}}var me=class{replayState;sessionManager;constructor(e,t){this.sessionManager=e,this.replayState=t}async forceFlush(){return Promise.resolve()}onEnd(e){}onStart(e,t){let n=this.sessionManager.touch();e.setAttribute(`session.id`,n.id),e.setAttribute(`browser.session.id`,n.id);let r=this.replayState?.getState();r!==void 0&&(e.setAttribute(`logfire.session_replay.active`,r.active),e.setAttribute(`logfire.session_replay.mode`,r.mode));let i=B();if(i===void 0)return;let a;try{a=this.sessionManager.getUrlAttributes(i)}catch{return}a?.full!==void 0&&e.setAttribute(`url.full`,a.full),a?.path!==void 0&&e.setAttribute(`url.path`,a.path)}async shutdown(){return Promise.resolve()}};const V={idleTimeoutMs:30*6e4,maxDurationMs:240*6e4,storageKey:`lf_browser_session`};function he(){try{return globalThis.sessionStorage??null}catch{return null}}function ge(){let e=globalThis.crypto;if(typeof e?.randomUUID==`function`)return e.randomUUID();if(typeof e?.getRandomValues==`function`){let t=new Uint8Array(16);return e.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,`0`)).join(``)}return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}-${Math.random().toString(36).slice(2)}`}function _e(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.id==`string`&&t.id.length>0&&typeof t.startedAt==`number`&&Number.isFinite(t.startedAt)&&typeof t.lastActivityAt==`number`&&Number.isFinite(t.lastActivityAt)}var ve=class{generateId;idleTimeoutMs;maxDurationMs;now;storage;storageKey;urlAttributes;memorySession;constructor(e={}){this.generateId=e.generateId??ge,this.idleTimeoutMs=e.idleTimeoutMs??V.idleTimeoutMs,this.maxDurationMs=e.maxDurationMs??V.maxDurationMs,this.now=e.now??Date.now,this.storage=e.storage===void 0?he():e.storage,this.storageKey=e.storageKey??V.storageKey,this.urlAttributes=e.urlAttributes}getSession(){return this.getSessionAt(this.now())}peekSessionId(){return this.memorySession?.id}touch(){let e=this.now(),t={...this.getSessionAt(e),lastActivityAt:e};return this.writeSession(t),t}reset(){return this.createSession(this.now())}getUrlAttributes(e){if(this.urlAttributes!==!1)return typeof this.urlAttributes==`function`?this.urlAttributes(e):{full:e.href,path:e.pathname}}createSession(e){let t={id:this.generateId(),lastActivityAt:e,startedAt:e};return this.writeSession(t),t}getSessionAt(e){let t=this.readSession();return t!==void 0&&!this.isExpired(t,e)?t:this.createSession(e)}isExpired(e,t){return t-e.lastActivityAt>this.idleTimeoutMs||t-e.startedAt>this.maxDurationMs}readSession(){if(this.storage!==null)try{let e=this.storage.getItem(this.storageKey);if(e!==null){let t=JSON.parse(e);if(_e(t))return this.memorySession=t,t}}catch{return this.memorySession}return this.memorySession}writeSession(e){if(this.memorySession=e,this.storage!==null)try{this.storage.setItem(this.storageKey,JSON.stringify(e))}catch{}}};let H;function ye(e){if(e===void 0||e===!1){H=void 0;return}let t=new ve(e===!0?{}:e);return H=t,t}function U(){return H?.touch().id}function be(e){H===e&&(H=void 0)}var xe=class{replay;setReplay(e){this.replay=e}clear(){this.replay=void 0}getState(){let e=this.replay?.mode;if(!(this.replay?.recording!==!0||e!==`full`&&e!==`buffer`))return{active:!0,mode:e}}};async function Se(e,t,n,i){try{if(t.touch(),t.peekSessionId()===void 0)throw Error(`logfire-browser: sessionReplay requires an active browser session id`);let r=await e.load(),a=Ce(e,t,i),o=we(r.startSessionReplay(a),n);return o.recording&&(o.mode===`full`||o.mode===`buffer`)&&n.setReplay(o),o}catch(t){n.clear(),r.error(`logfire-browser: failed to start session replay; install @pydantic/logfire-session-replay and verify sessionReplay config`,t),e.onError?.(t);return}}function Ce(e,t,n){let r={getSessionId:()=>t.peekSessionId(),ignoreUrlPatterns:[...Te(e.replayUrl,n),...e.ignoreUrlPatterns??[]],redactUrlPatterns:e.redactUrlPatterns??[],replayUrl:e.replayUrl};return e.headers!==void 0&&(r.headers=e.headers),e.token!==void 0&&(r.token=e.token),e.sessionSampleRate!==void 0&&(r.sessionSampleRate=e.sessionSampleRate),e.onErrorSampleRate!==void 0&&(r.onErrorSampleRate=e.onErrorSampleRate),e.maskAllInputs!==void 0&&(r.maskAllInputs=e.maskAllInputs),e.maskTextSelector!==void 0&&(r.maskTextSelector=e.maskTextSelector),e.blockSelector!==void 0&&(r.blockSelector=e.blockSelector),e.flushIntervalMs!==void 0&&(r.flushIntervalMs=e.flushIntervalMs),e.maxBufferBytes!==void 0&&(r.maxBufferBytes=e.maxBufferBytes),e.distinctId!==void 0&&(r.distinctId=e.distinctId),e.getDistinctId!==void 0&&(r.getDistinctId=e.getDistinctId),e.captureConsole!==void 0&&(r.captureConsole=e.captureConsole),e.captureNetwork!==void 0&&(r.captureNetwork=e.captureNetwork),e.captureNavigation!==void 0&&(r.captureNavigation=e.captureNavigation),e.onError!==void 0&&(r.onError=e.onError),e.fetchImpl!==void 0&&(r.fetchImpl=e.fetchImpl),r}function we(e,t){let n;return{get mode(){return e.mode},get recording(){return e.recording},flush:async()=>e.flush(),getSessionId:()=>e.getSessionId(),stop:async()=>(n??=(async()=>{try{await e.stop()}finally{t.clear()}})(),n)}}function Te(e,t){return[t.traceUrl,t.metricUrl,e].flatMap(e=>{let t=Ee(e);return t===void 0?[]:[t]})}function Ee(e){if(e===void 0||e.length===0)return;let t=e.replace(/\/+$/u,``);return RegExp(`^${De(t)}(?:[/?#]|$)`,`u`)}function De(e){return e.replace(/[.*+?^${}()|[\]\\]/gu,`\\$&`)}let W,G;function Oe(e){let t=!1;return{async shutdown(){return t?Promise.resolve():(t=!0,e?.shutdown(),G===e&&(G=void 0),Promise.resolve())}}}function K(e,t,n){if(typeof n==`string`||typeof n==`boolean`){e[t]=n;return}typeof n==`number`&&Number.isFinite(n)&&(e[t]=n)}function q(e={}){let t={};return e.reportAllChanges!==void 0&&(t.reportAllChanges=e.reportAllChanges),e.generateTarget!==void 0&&(t.generateTarget=e.generateTarget),t}function ke(e={}){return{...q(e),includeProcessedEventEntries:e.includeProcessedEventEntries??!1}}function Ae(e){let t={};return K(t,`web_vital.name`,e.name),K(t,`web_vital.value`,e.value),K(t,`web_vital.delta`,e.delta),K(t,`web_vital.id`,e.id),K(t,`web_vital.rating`,e.rating),K(t,`web_vital.navigation_type`,e.navigationType),t}function je(e){let t=Ae(e);switch(e.name){case`LCP`:{let{attribution:n}=e;K(t,`web_vital.lcp.target`,n.target),K(t,`web_vital.lcp.element`,n.target),K(t,`web_vital.lcp.url`,n.url),K(t,`web_vital.lcp.time_to_first_byte`,n.timeToFirstByte),K(t,`web_vital.lcp.resource_load_delay`,n.resourceLoadDelay),K(t,`web_vital.lcp.resource_load_duration`,n.resourceLoadDuration),K(t,`web_vital.lcp.element_render_delay`,n.elementRenderDelay);break}case`INP`:{let{attribution:n}=e;K(t,`web_vital.inp.target`,n.interactionTarget),K(t,`web_vital.inp.interaction_type`,n.interactionType),K(t,`web_vital.inp.interaction_time`,n.interactionTime),K(t,`web_vital.inp.input_delay`,n.inputDelay),K(t,`web_vital.inp.processing_duration`,n.processingDuration),K(t,`web_vital.inp.presentation_delay`,n.presentationDelay),K(t,`web_vital.inp.load_state`,n.loadState);break}case`CLS`:{let{attribution:n}=e;K(t,`web_vital.cls.largest_shift_target`,n.largestShiftTarget),K(t,`web_vital.cls.largest_shift_time`,n.largestShiftTime),K(t,`web_vital.cls.largest_shift_value`,n.largestShiftValue),K(t,`web_vital.cls.load_state`,n.loadState);break}case`FCP`:{let{attribution:n}=e;K(t,`web_vital.fcp.time_to_first_byte`,n.timeToFirstByte),K(t,`web_vital.fcp.first_byte_to_fcp`,n.firstByteToFCP),K(t,`web_vital.fcp.load_state`,n.loadState);break}case`TTFB`:{let{attribution:n}=e;K(t,`web_vital.ttfb.waiting_duration`,n.waitingDuration),K(t,`web_vital.ttfb.cache_duration`,n.cacheDuration),K(t,`web_vital.ttfb.dns_duration`,n.dnsDuration),K(t,`web_vital.ttfb.connection_duration`,n.connectionDuration),K(t,`web_vital.ttfb.request_duration`,n.requestDuration);break}default:break}return t}function Me(e){try{let t=i.getTracer(`logfire-web-vitals`).startSpan(`web_vital.${e.name.toLowerCase()}`);try{t.setAttributes(je(e))}finally{t.end()}}catch(e){r.error(`logfire-browser: failed to report Web Vital`,e)}}function Ne(e,t){if(t!==void 0)try{t.record(e)}catch(e){r.error(`logfire-browser: failed to report Web Vital metric`,e)}}function Pe(e,t){Me(e),Ne(e,t)}function Fe(e,t={}){let n=q(t),r=e=>{Pe(e,G)};e.onLCP(r,n),e.onINP(r,ke(t)),e.onCLS(r,n),e.onFCP(r,n),e.onTTFB(r,n)}async function J(e={}){return e.metricRecorder!==void 0&&(G=e.metricRecorder),W??=import(`web-vitals/attribution`).then(t=>{Fe(t,e)}).catch(e=>{r.error(`logfire-browser: failed to start Web Vitals reporting`,e)}),await W,Oe(e.metricRecorder)}const Y=`target_xpath`,Ie={1:`trace`,5:`debug`,9:`info`,10:`notice`,13:`warning`,17:`error`,21:`fatal`},X={debug:`#E3E3E3`,error:`#EA4335`,fatal:`#EA4335`,info:`#9EC1FB`,notice:`#A5D490`,"on-debug":`#636262`,"on-error":`#FFEDE9`,"on-fatal":`#FFEDE9`,"on-info":`#063175`,"on-notice":`#222222`,"on-trace":`#636262`,"on-warning":`#613A0D`,trace:`#E3E3E3`,warning:`#EFB77A`};var Le=class{export(e,t){this.sendSpans(e,t)}async forceFlush(){return Promise.resolve()}async shutdown(){return this.sendSpans([]),this.forceFlush()}exportInfo(e){return{attributes:e.attributes,duration:z(e.duration),events:e.events,id:e.spanContext().spanId,instrumentationScope:e.instrumentationScope,kind:e.kind,links:e.links,name:e.name,parentSpanContext:e.parentSpanContext,resource:{attributes:e.resource.attributes},status:e.status,timestamp:z(e.startTime),traceId:e.spanContext().traceId,traceState:e.spanContext().traceState?.serialize()}}sendSpans(e,t){for(let t of e){let e=Ie[t.attributes[`logfire.level_num`]]??`info`,{attributes:n,name:r,...i}=this.exportInfo(t);console.log(`%cLogfire %c${e}`,`background-color: #E520E9; color: #FFFFFF`,`background-color: ${X[`on-${e}`]}; color: ${X[e]}`,r,n,i)}t&&t({code:R.SUCCESS})}},Re=class{console;wrapped;constructor(e,t){t&&(this.console=new c(new Le)),this.wrapped=e}async forceFlush(){return await this.console?.forceFlush(),this.wrapped.forceFlush()}onEnd(e){this.console?.onEnd(e),this.wrapped.onEnd(e)}onStart(e,t){if(p in e.attributes){let t=new URL(e.attributes[p]);Reflect.set(e,`name`,`${e.name} ${t.pathname}`)}if(Y in e.attributes){let t=String(e.attributes.event_type??`unknown`),n=String(e.attributes[Y]??``);Reflect.set(e,`name`,`${t} ${n}`)}this.console?.onStart(e,t),this.wrapped.onStart(e,t)}async shutdown(){return await this.console?.shutdown(),this.wrapped.shutdown()}};function ze(){return{}}function Z(e){if(!(e===void 0||e===!1))return e===!0?{}:e}function Be(e){if(!(e===void 0||e===!1)){if(e.metricUrl===``)throw Error(`logfire-browser: metrics.metricUrl must be a non-empty browser-safe metrics proxy URL`);return e}}function Ve(e){if(!(e?.metrics===void 0||e.metrics===!1))return e.metrics===!0?{}:e.metrics}function Q(e){if(!(e===void 0||e===!1))return e}function He(e,t){let n=Z(e?.webVitals),r=t!==void 0;if(n===void 0&&!r)return e?.session;if(e?.session===!1)throw Error(r?`logfire-browser: sessionReplay requires browser session attributes; remove rum.session: false or disable sessionReplay`:`logfire-browser: rum.webVitals requires browser session attributes; remove rum.session: false or disable rum.webVitals`);return e?.session??!0}async function Ue(e,t){return{...typeof e==`function`?await e():e??{},...t()}}function $(t){t.diagLogLevel!==void 0&&r.setLogger(new e,t.diagLogLevel);let n=Z(t.rum?.webVitals),i=Q(t.sessionReplay),c=Be(t.metrics),p=Ve(n);if(p!==void 0&&c===void 0)throw Error(`logfire-browser: rum.webVitals.metrics requires top-level metrics.metricUrl`);let m=He(t.rum,i),h={errorFingerprinting:t.errorFingerprinting??!1};t.baggage!==void 0&&(h.baggage=t.baggage),t.jsonSchema!==void 0&&(h.jsonSchema=t.jsonSchema),t.minLevel!==void 0&&(h.minLevel=t.minLevel),t.scrubbing!==void 0&&(h.scrubbing=t.scrubbing),v(h);let g=s(t.resourceAttributes??{}).merge(s({[le]:navigator.language,[ie]:t.serviceName??`logfire-browser`,[ae]:t.serviceVersion??`0.0.1`,[oe]:d,[se]:`logfire-browser`,...t.environment!==void 0&&t.environment!==``?{[fe]:t.environment}:{},[ce]:`0.0.0`,...navigator.userAgentData?{[f]:navigator.userAgentData.brands.map(e=>`${e.brand} ${e.version}`),[ue]:navigator.userAgentData.mobile,[de]:navigator.userAgentData.platform}:{[u]:navigator.userAgent}}));r.info(`logfire-browser: starting`);let y=t.sampling?.head,b=y!==void 0&&y<1?new te({root:new ne(y)}):void 0,x=new Re(new ee(new a({...t.traceExporterConfig,headers:async()=>Ue(t.traceExporterConfig?.headers,t.traceExporterHeaders??ze),url:t.traceUrl}),t.batchSpanProcessorConfig),!!t.console);t.sampling?.tail&&(x=new pe(x,t.sampling.tail));let S=ye(m),C=new xe,w=[];S!==void 0&&w.push(new me(S,C)),w.push(...t.spanProcessors??[],x);let T=new re({idGenerator:new _,resource:g,...b?{sampler:b}:{},spanProcessors:w});T.register({contextManager:t.contextManager??new l});let E=o({instrumentations:t.instrumentations??[],tracerProvider:T}),D=i===void 0||S===void 0?void 0:Se(i,S,C,{metricUrl:c?.metricUrl,traceUrl:t.traceUrl}),O=c===void 0?void 0:import(`./browserMetrics-Bx5fHWgu.js`).then(async({startBrowserMetrics:e})=>e(c,g)).catch(e=>{r.error(`logfire-browser: failed to start browser metrics`,e)}),k=n===void 0?void 0:p===void 0?J(n).catch(e=>{r.error(`logfire-browser: failed to start Web Vitals reporting`,e)}):(async()=>{let e=await O;if(e===void 0)throw Error(`logfire-browser: failed to start Web Vitals metrics because browser metrics transport did not start`);return J({...n,metricRecorder:e.createWebVitalsMetricRecorder(p)})})().catch(e=>{r.error(`logfire-browser: failed to start Web Vitals reporting`,e)}),A;return()=>(A??=(async()=>{let e,t=(t,n)=>{let i=n instanceof Error?n:Error(String(n));e??=i,r.error(`logfire-browser: ${t} failed during shutdown`,i)},n=async(e,n)=>{try{await n()}catch(n){t(e,n)}};if(r.info(`logfire-browser: shutting down`),D!==void 0&&(C.clear(),await n(`session replay shutdown`,async()=>{await(await D)?.stop()})),await n(`instrumentation unregister`,E),k!==void 0&&await n(`web vitals shutdown`,async()=>{await(await k)?.shutdown()}),O!==void 0&&(await n(`metric provider force flush`,async()=>{await(await O)?.forceFlush()}),await n(`metric provider shutdown`,async()=>{await(await O)?.shutdown()})),await n(`force flush`,async()=>T.forceFlush()),await n(`tracer provider shutdown`,async()=>T.shutdown()),S!==void 0&&await n(`browser session cleanup`,()=>{be(S)}),e!==void 0)throw Error(e.message,{cause:e});r.info(`logfire-browser: shut down complete`)})(),A)}const We={configure:$,configureLogfireApi:v,debug:y,DiagLogLevel:n,error:b,fatal:x,getBrowserSessionId:U,info:S,instrument:C,Level:m,log:w,logfireApiConfig:T,LogfireAttributeScrubber:h,NoopAttributeScrubber:g,notice:E,reportError:D,resolveBaseUrl:O,resolveSendToLogfire:k,serializeAttributes:A,span:j,startPendingSpan:M,startSpan:N,trace:P,ULIDGenerator:_,warning:F,withSettings:I,withTags:L};export{t as DiagLogLevel,$ as configure,We as default,U as getBrowserSessionId};
1
+ import{DiagConsoleLogger as e,DiagLogLevel as t,DiagLogLevel as n,INVALID_SPAN_CONTEXT as r,context as i,diag as a,propagation as o,trace as s}from"@opentelemetry/api";import{OTLPTraceExporter as c}from"@opentelemetry/exporter-trace-otlp-http";import{registerInstrumentations as l}from"@opentelemetry/instrumentation";import{resourceFromAttributes as u}from"@opentelemetry/resources";import{BatchSpanProcessor as ee,ParentBasedSampler as te,SimpleSpanProcessor as d,StackContextManager as f,TraceIdRatioBasedSampler as ne,WebTracerProvider as re}from"@opentelemetry/sdk-trace-web";import{ATTR_SERVICE_NAME as ie,ATTR_SERVICE_VERSION as ae,ATTR_TELEMETRY_SDK_LANGUAGE as oe,ATTR_TELEMETRY_SDK_NAME as se,ATTR_TELEMETRY_SDK_VERSION as ce,ATTR_USER_AGENT_ORIGINAL as le,TELEMETRY_SDK_LANGUAGE_VALUE_WEBJS as ue}from"@opentelemetry/semantic-conventions";import{ATTR_BROWSER_BRANDS as de,ATTR_BROWSER_LANGUAGE as fe,ATTR_BROWSER_MOBILE as pe,ATTR_BROWSER_PLATFORM as me,ATTR_DEPLOYMENT_ENVIRONMENT_NAME as he,ATTR_HTTP_URL as p}from"@opentelemetry/semantic-conventions/incubating";import{Level as m,LogfireAttributeScrubber as h,NoopAttributeScrubber as g,TailSamplingProcessor as ge,ULIDGenerator as _,configureLogfireApi as v,debug as y,error as _e,fatal as b,info as x,instrument as S,log as C,logfireApiConfig as w,notice as T,reportError as E,resolveBaseUrl as D,resolveSendToLogfire as O,serializeAttributes as k,span as A,startPendingSpan as j,startSpan as M,trace as ve,warning as ye,withSettings as be,withTags as xe}from"logfire";import{CompositePropagator as Se,ExportResultCode as Ce,W3CBaggagePropagator as we,W3CTraceContextPropagator as Te,hrTimeToMicroseconds as Ee}from"@opentelemetry/core";export*from"logfire";function De(){let e=globalThis;try{let t=(e.location??e.window?.location)?.href;return t===void 0||t===``?void 0:new URL(t)}catch{return}}var Oe=class{replayState;sessionManager;constructor(e,t){this.sessionManager=e,this.replayState=t}async forceFlush(){return Promise.resolve()}onEnd(e){}onStart(e,t){let n=this.sessionManager.touch();e.setAttribute(`session.id`,n.id),e.setAttribute(`browser.session.id`,n.id);let r;try{r=this.replayState?.getState()}catch{r=void 0}r!==void 0&&(e.setAttribute(`logfire.session_replay.active`,r.active),e.setAttribute(`logfire.session_replay.mode`,r.mode));let i=De();if(i===void 0)return;let a;try{a=this.sessionManager.getUrlAttributes(i)}catch{return}a?.full!==void 0&&e.setAttribute(`logfire.page.url.full`,a.full),a?.path!==void 0&&e.setAttribute(`logfire.page.url.path`,a.path)}async shutdown(){return Promise.resolve()}};const N={idleTimeoutMs:30*6e4,maxDurationMs:240*6e4,storageKey:`lf_browser_session`};function ke(){try{return globalThis.sessionStorage??null}catch{return null}}function Ae(){let e=globalThis.crypto;if(typeof e?.randomUUID==`function`)return e.randomUUID();if(typeof e?.getRandomValues==`function`){let t=new Uint8Array(16);return e.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,`0`)).join(``)}return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}-${Math.random().toString(36).slice(2)}`}function je(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.id==`string`&&t.id.length>0&&typeof t.startedAt==`number`&&Number.isFinite(t.startedAt)&&typeof t.lastActivityAt==`number`&&Number.isFinite(t.lastActivityAt)}var Me=class{generateId;idleTimeoutMs;maxDurationMs;now;storage;storageKey;urlAttributes;memorySession;pendingSession;persistenceTimer;constructor(e={}){this.generateId=e.generateId??Ae,this.idleTimeoutMs=e.idleTimeoutMs??N.idleTimeoutMs,this.maxDurationMs=e.maxDurationMs??N.maxDurationMs,this.now=e.now??Date.now,this.storage=e.storage===void 0?ke():e.storage,this.storageKey=e.storageKey??N.storageKey,this.urlAttributes=e.urlAttributes}getSession(){return this.getSessionAt(this.now())}peekSessionId(){return this.memorySession?.id}touch(){let e=this.now(),t={...this.getSessionAt(e),lastActivityAt:e};return this.memorySession=t,this.scheduleWrite(t),t}reset(){return this.createSession(this.now())}flushPendingStorage(){this.persistenceTimer!==void 0&&(clearTimeout(this.persistenceTimer),this.persistenceTimer=void 0);let e=this.pendingSession;this.pendingSession=void 0,e!==void 0&&this.writeSession(e)}getUrlAttributes(e){if(this.urlAttributes!==!1)return typeof this.urlAttributes==`function`?this.urlAttributes(e):{full:`${e.origin}${e.pathname}`,path:e.pathname}}createSession(e){let t={id:this.generateId(),lastActivityAt:e,startedAt:e};return this.flushPendingStorage(),this.writeSession(t),t}getSessionAt(e){if(this.memorySession!==void 0&&!this.isExpired(this.memorySession,e))return this.memorySession;let t=this.readSession();return t!==void 0&&!this.isExpired(t,e)?t:this.createSession(e)}isExpired(e,t){return t-e.lastActivityAt>this.idleTimeoutMs||t-e.startedAt>this.maxDurationMs}readSession(){if(this.storage!==null)try{let e=this.storage.getItem(this.storageKey);if(e!==null){let t=JSON.parse(e);if(je(t))return this.memorySession=t,t}}catch{return this.memorySession}return this.memorySession}writeSession(e){if(this.memorySession=e,this.storage!==null)try{this.storage.setItem(this.storageKey,JSON.stringify(e))}catch{}}scheduleWrite(e){this.pendingSession=e,this.persistenceTimer===void 0&&(this.persistenceTimer=setTimeout(()=>{this.persistenceTimer=void 0;let e=this.pendingSession;this.pendingSession=void 0,e!==void 0&&this.writeSession(e)},1e3))}};let P;function Ne(e){if(P?.flushPendingStorage(),e===void 0||e===!1){P=void 0;return}let t=new Me(e===!0?{}:e);return P=t,t}function Pe(){return P?.touch().id}function F(e){P===e&&(e.flushPendingStorage(),P=void 0)}function I(e){let t=new Map;for(let n of e)for(let e of Ie(n.url)){let r=Le(n.kind,e);t.set(`${r.source}/${r.flags}`,r)}return[...t.values()]}function L(e){if(e.length===0)throw Error(`logfire-browser: sessionReplay.replayUrl must be a non-empty browser URL`);let t=new Set([R(),z()].filter(e=>e!==void 0));t.size===0&&t.add(`https://logfire.invalid/`);let n=[...t].map(t=>B(e,t));if(n.some(e=>e===void 0))throw Error(`logfire-browser: sessionReplay.replayUrl must be a valid browser URL`);if(n.some(e=>e?.pathname===`/`))throw Error(`logfire-browser: sessionReplay.replayUrl must use a non-root path`);if(n.some(e=>e?.search!==``||e.hash!==``))throw Error(`logfire-browser: sessionReplay.replayUrl must not contain a query or fragment`)}function Fe(e){try{return L(e),!0}catch{return!1}}function Ie(e){let t=new Set([e]),n=B(e,R());n!==void 0&&t.add(n.href);let r=B(e,z());return r!==void 0&&t.add(r.href),[...t]}function R(){let e=Reflect.get(globalThis,`location`);if(typeof e!=`object`||!e)return;let t=Reflect.get(e,`href`);return typeof t==`string`?t:void 0}function z(){let e=Reflect.get(globalThis,`document`);if(typeof e!=`object`||!e)return;let t=Reflect.get(e,`baseURI`);return typeof t==`string`?t:void 0}function B(e,t){try{return t===void 0?new URL(e):new URL(e,t)}catch{return}}function Le(e,t){return e===`exact`?Re(t):ze(t)}function Re(e){let t=e.indexOf(`#`),n=t===-1?e:e.slice(0,t),r=n.indexOf(`?`);return RegExp(t===-1?r===-1?`^${V(n)}(?:[?#].*)?$`:`^${V(n)}(?:#.*)?$`:`^${V(e)}$`,`u`)}function ze(e){let t=e===`/`?e:e.replace(/\/+$/u,``);return RegExp(`^${V(t)}/[^/?#]+(?:\\?[^#]*)?(?:#.*)?$`,`u`)}function V(e){return e.replace(/[.*+?^${}()|[\]\\]/gu,`\\$&`)}var Be=class{replay;setReplay(e){this.replay=e}clear(){this.replay=void 0}getState(){let e=this.replay?.mode;if(!(this.replay?.recording!==!0||e!==`full`&&e!==`buffer`))return{active:!0,mode:e}}};async function Ve(e,t,n,r){try{if(L(e.replayUrl),t.touch(),t.peekSessionId()===void 0)throw Error(`logfire-browser: sessionReplay requires an active browser session id`);let i=await e.load(),a=He(e,t,r),o=We(i.startSessionReplay(a),n,e.onError);return n.setReplay(o),o}catch(t){n.clear(),a.error(`logfire-browser: failed to start session replay; install @pydantic/logfire-session-replay and verify sessionReplay config`,t),H(e.onError,t);return}}function He(e,t,n){let r={getSessionId:()=>t.peekSessionId(),ignoreUrlPatterns:[...I([{kind:`exact`,url:n.traceUrl},...n.metricUrl===void 0?[]:[{kind:`exact`,url:n.metricUrl}],{kind:`replay-base`,url:e.replayUrl}]),...e.ignoreUrlPatterns??[]],replayUrl:e.replayUrl};return e.headers!==void 0&&(r.headers=e.headers),e.token!==void 0&&(r.token=e.token),e.sessionSampleRate!==void 0&&(r.sessionSampleRate=e.sessionSampleRate),e.onErrorSampleRate!==void 0&&(r.onErrorSampleRate=e.onErrorSampleRate),e.maskAllText!==void 0&&(r.maskAllText=e.maskAllText),e.maskAllInputs!==void 0&&(r.maskAllInputs=e.maskAllInputs),e.maskTextSelector!==void 0&&(r.maskTextSelector=e.maskTextSelector),e.blockSelector!==void 0&&(r.blockSelector=e.blockSelector),e.flushIntervalMs!==void 0&&(r.flushIntervalMs=e.flushIntervalMs),e.maxBufferBytes!==void 0&&(r.maxBufferBytes=e.maxBufferBytes),e.distinctId!==void 0&&(r.distinctId=e.distinctId),e.getDistinctId!==void 0&&(r.getDistinctId=e.getDistinctId),e.captureConsole!==void 0&&(r.captureConsole=e.captureConsole),e.captureNetwork!==void 0&&(r.captureNetwork=e.captureNetwork),e.captureNavigation!==void 0&&(r.captureNavigation=e.captureNavigation),e.redactUrlPatterns!==void 0&&(r.redactUrlPatterns=e.redactUrlPatterns),e.onError!==void 0&&(r.onError=t=>{H(e.onError,t)}),e.fetchImpl!==void 0&&(r.fetchImpl=e.fetchImpl),r}function H(e,t){try{let n=e?.(t);Ue(n)&&Promise.resolve(n).catch(()=>void 0)}catch{}}function Ue(e){return typeof e==`object`&&!!e&&`then`in e&&typeof e.then==`function`}function We(e,t,n){let r;return{get mode(){try{return e.mode}catch(e){return H(n,e),`off`}},get recording(){try{return e.recording}catch(e){return H(n,e),!1}},flush:async()=>{try{await e.flush()}catch(e){H(n,e)}},stop:async()=>(r??=(async()=>{try{await e.stop()}catch(e){H(n,e)}finally{t.clear()}})(),r)}}let U,W,G,K,q,Ge;const J=new Set;function Ke(e,t,n){let r=!1;return{async shutdown(){return r?Promise.resolve():(r=!0,n.active=!1,e?.shutdown(),W===e&&(W=void 0),G===t&&(G=void 0),K===n&&(K=void 0),Promise.resolve())}}}function Y(e,t,n){if(typeof n==`string`||typeof n==`boolean`){e[t]=n;return}typeof n==`number`&&Number.isFinite(n)&&(e[t]=n)}function qe(e={}){let t={};return e.reportAllChanges!==void 0&&(t.reportAllChanges=e.reportAllChanges),e.generateTarget!==void 0&&(t.generateTarget=e.generateTarget),t}function Je(e={}){return{...qe(e),includeProcessedEventEntries:e.includeProcessedEventEntries??!1}}function Ye(e){let t={"logfire.span_type":`log`};return Y(t,`web_vital.name`,e.name),Y(t,`web_vital.value`,e.value),Y(t,`web_vital.delta`,e.delta),Y(t,`web_vital.id`,e.id),Y(t,`web_vital.rating`,e.rating),Y(t,`web_vital.navigation_type`,e.navigationType),t}function Xe(e){let t=Ye(e);switch(e.name){case`LCP`:{let{attribution:n}=e;Y(t,`web_vital.lcp.target`,n.target),Y(t,`web_vital.lcp.element`,n.target),Y(t,`web_vital.lcp.url`,n.url),Y(t,`web_vital.lcp.time_to_first_byte`,n.timeToFirstByte),Y(t,`web_vital.lcp.resource_load_delay`,n.resourceLoadDelay),Y(t,`web_vital.lcp.resource_load_duration`,n.resourceLoadDuration),Y(t,`web_vital.lcp.element_render_delay`,n.elementRenderDelay);break}case`INP`:{let{attribution:n}=e;Y(t,`web_vital.inp.target`,n.interactionTarget),Y(t,`web_vital.inp.interaction_type`,n.interactionType),Y(t,`web_vital.inp.interaction_time`,n.interactionTime),Y(t,`web_vital.inp.input_delay`,n.inputDelay),Y(t,`web_vital.inp.processing_duration`,n.processingDuration),Y(t,`web_vital.inp.presentation_delay`,n.presentationDelay),Y(t,`web_vital.inp.load_state`,n.loadState);break}case`CLS`:{let{attribution:n}=e;Y(t,`web_vital.cls.largest_shift_target`,n.largestShiftTarget),Y(t,`web_vital.cls.largest_shift_time`,n.largestShiftTime),Y(t,`web_vital.cls.largest_shift_value`,n.largestShiftValue),Y(t,`web_vital.cls.load_state`,n.loadState);break}case`FCP`:{let{attribution:n}=e;Y(t,`web_vital.fcp.time_to_first_byte`,n.timeToFirstByte),Y(t,`web_vital.fcp.first_byte_to_fcp`,n.firstByteToFCP),Y(t,`web_vital.fcp.load_state`,n.loadState);break}case`TTFB`:{let{attribution:n}=e;Y(t,`web_vital.ttfb.waiting_duration`,n.waitingDuration),Y(t,`web_vital.ttfb.cache_duration`,n.cacheDuration),Y(t,`web_vital.ttfb.dns_duration`,n.dnsDuration),Y(t,`web_vital.ttfb.connection_duration`,n.connectionDuration),Y(t,`web_vital.ttfb.request_duration`,n.requestDuration);break}default:break}return t}function Ze(e,t){if(t===void 0){a.error(`logfire-browser: failed to report Web Vital`,Error(`missing Web Vitals tracer`));return}try{let n=t.startSpan(`web_vital.${e.name.toLowerCase()}`);try{n.setAttributes(Xe(e))}finally{n.end()}}catch(e){a.error(`logfire-browser: failed to report Web Vital`,e)}}function Qe(e,t){if(t!==void 0)try{t.record(e)}catch(e){a.error(`logfire-browser: failed to report Web Vital metric`,e)}}function $e(e,t,n){Ze(e,n),Qe(e,t)}function et(e,t){let n=Ge??=tt(t),r=qe(n),i=e=>{q===void 0||K?.active!==!0||$e(e,W,G)},a=[[`LCP`,e.onLCP,r],[`INP`,e.onINP,Je(n)],[`CLS`,e.onCLS,r],[`FCP`,e.onFCP,r],[`TTFB`,e.onTTFB,r]];for(let[e,t,n]of a)J.has(e)||(t(i,n),J.add(e));q=n}async function X(e){let t={active:!0};e.metricRecorder!==void 0&&(W=e.metricRecorder),G=e.tracer,K=t;let n=tt(e);if(U===void 0){let t=import(`web-vitals/attribution`).then(t=>{et(t,e)}).catch(e=>{throw U===t&&(U=void 0),J.size===0&&(Ge=void 0),e});U=t}try{await U}catch(n){throw t.active=!1,e.metricRecorder?.shutdown(),W===e.metricRecorder&&(W=void 0),G===e.tracer&&(G=void 0),K===t&&(K=void 0),n}return q!==void 0&&!nt(q,n)&&a.warn(`logfire-browser: Web Vitals observer options are fixed by the first successful startup; ignoring changed options`),Ke(e.metricRecorder,e.tracer,t)}function tt(e){return{generateTarget:e.generateTarget,includeProcessedEventEntries:e.includeProcessedEventEntries??!1,reportAllChanges:e.reportAllChanges}}function nt(e,t){return e.generateTarget===t.generateTarget&&e.includeProcessedEventEntries===t.includeProcessedEventEntries&&(e.reportAllChanges??!1)===(t.reportAllChanges??!1)}const rt=`target_xpath`,it={1:`trace`,5:`debug`,9:`info`,10:`notice`,13:`warning`,17:`error`,21:`fatal`},at={debug:`#E3E3E3`,error:`#EA4335`,fatal:`#EA4335`,info:`#9EC1FB`,notice:`#A5D490`,"on-debug":`#636262`,"on-error":`#FFEDE9`,"on-fatal":`#FFEDE9`,"on-info":`#063175`,"on-notice":`#222222`,"on-trace":`#636262`,"on-warning":`#613A0D`,trace:`#E3E3E3`,warning:`#EFB77A`};var ot=class{export(e,t){this.sendSpans(e,t)}async forceFlush(){return Promise.resolve()}async shutdown(){return this.sendSpans([]),this.forceFlush()}exportInfo(e){return{attributes:e.attributes,duration:Ee(e.duration),events:e.events,id:e.spanContext().spanId,instrumentationScope:e.instrumentationScope,kind:e.kind,links:e.links,name:e.name,parentSpanContext:e.parentSpanContext,resource:{attributes:e.resource.attributes},status:e.status,timestamp:Ee(e.startTime),traceId:e.spanContext().traceId,traceState:e.spanContext().traceState?.serialize()}}sendSpans(e,t){for(let t of e){let e=it[t.attributes[`logfire.level_num`]]??`info`,{attributes:n,name:r,...i}=this.exportInfo(t);console.log(`%cLogfire %c${e}`,`background-color: #E520E9; color: #FFFFFF`,`background-color: ${at[`on-${e}`]}; color: ${at[e]}`,r,n,i)}t&&t({code:Ce.SUCCESS})}},st=class{console;wrapped;constructor(e,t){t&&(this.console=new d(new ot)),this.wrapped=e}async forceFlush(){return await this.console?.forceFlush(),this.wrapped.forceFlush()}onEnd(e){this.console?.onEnd(e),this.wrapped.onEnd(e)}onStart(e,t){if(p in e.attributes){let t=new URL(e.attributes[p]);Reflect.set(e,`name`,`${e.name} ${t.pathname}`)}if(rt in e.attributes){let t=String(e.attributes.event_type??`unknown`),n=String(e.attributes[rt]??``);Reflect.set(e,`name`,`${t} ${n}`)}this.console?.onStart(e,t),this.wrapped.onStart(e,t)}async shutdown(){return await this.console?.shutdown(),this.wrapped.shutdown()}};const ct=`logfire-browser: an OpenTelemetry context manager is already registered; omit contextManager to use the application-owned manager`;var lt=class{getCurrentProvider;constructor(e){this.getCurrentProvider=e}getTracer(e,t,n){return new ut(this.getCurrentProvider,e,t,n)}},ut=class{getCurrentProvider;name;options;version;constructor(e,t,n,r){this.getCurrentProvider=e,this.name=t,this.version=n,this.options=r}startSpan(e,t,n){return this.getDelegate()?.startSpan(e,t,n)??s.wrapSpanContext(r)}startActiveSpan(e,t,n,a){let o=this.getDelegate();if(o!==void 0)return typeof t==`function`?o.startActiveSpan(e,t):typeof n==`function`?o.startActiveSpan(e,t,n):o.startActiveSpan(e,t,n,a);let c=s.wrapSpanContext(r),l=typeof t==`function`?t:typeof n==`function`?n:a,u=typeof t==`function`||typeof n==`function`?i.active():n??i.active();return i.with(s.setSpan(u,c),l,void 0,c)}getDelegate(){return this.getCurrentProvider()?.getTracer(this.name,this.version,this.options)}},dt=class{contextOwnership={status:`uninitialized`};generation={status:`idle`};propagationOwnership={status:`uninitialized`};traceOwnership={status:`uninitialized`};stableProvider=new lt(()=>this.getCurrentProvider());assertAvailable(){if(this.contextOwnership.status===`failed`)throw this.contextOwnership.error;if(this.generation.status===`failed`)throw Error(`logfire-browser: the previous cleanup failed; reload the page before configuring again`,{cause:this.generation.error});if(this.generation.status!==`idle`)throw Error(`logfire-browser: a configuration is already active; await its cleanup before configuring again`)}initializeGlobals(e){this.assertAvailable(),this.initializeContext(e),this.initializeTrace(),this.initializePropagation()}activate(e){this.assertAvailable();let t=Symbol(`logfire-browser-provider-generation`);return this.generation={provider:e,status:`active`,token:t},t}beginCleanup(e){this.generation.status===`active`&&this.generation.token===e&&(this.generation={delegateActive:!0,provider:this.generation.provider,status:`cleaning`,token:e})}deactivateDelegate(e){this.generation.status===`cleaning`&&this.generation.token===e&&(this.generation.delegateActive=!1)}settleCleanup(e,t){this.generation.status!==`cleaning`||this.generation.token!==e||(this.generation=t===void 0?{status:`idle`}:{error:t,status:`failed`,token:this.generation.token})}rollbackActivation(e,t){this.generation.status!==`active`||this.generation.token!==e||(this.generation=t===void 0?{status:`idle`}:{error:t,status:`failed`,token:e})}resetForTests(){this.generation={status:`idle`},this.contextOwnership={status:`uninitialized`},this.traceOwnership={status:`uninitialized`},this.propagationOwnership={status:`uninitialized`},Z(()=>{i.disable()}),Z(()=>{o.disable()}),Z(()=>{s.disable()})}getStateForTests(){return this.generation}getCurrentProvider(){if(this.generation.status===`active`||this.generation.status===`cleaning`&&this.generation.delegateActive)return this.generation.provider}initializeContext(e){if(this.contextOwnership.status===`failed`)throw this.contextOwnership.error;if(this.contextOwnership.status===`logfire`){if(e!==void 0&&e!==this.contextOwnership.contextManager)throw Error(`logfire-browser: contextManager cannot change after Logfire context initialization`);return}if(this.contextOwnership.status===`external`){if(e!==void 0)throw Error(ct);return}let t=e??new f;if(!i.setGlobalContextManager(t)){if(this.contextOwnership={status:`external`},e!==void 0)throw Error(ct);return}try{t.enable(),this.contextOwnership={contextManager:t,status:`logfire`}}catch(e){try{i.disable(),this.contextOwnership={status:`uninitialized`}}catch(t){let n=Error(`logfire-browser: context manager initialization failed and could not be rolled back; reload the page before configuring again`,{cause:{enableError:e,rollbackError:t}});throw this.contextOwnership={error:n,status:`failed`},n}throw e}}initializeTrace(){this.traceOwnership.status===`uninitialized`&&(this.traceOwnership={status:s.setGlobalTracerProvider(this.stableProvider)?`logfire`:`external`})}initializePropagation(){if(this.propagationOwnership.status!==`uninitialized`)return;let e=new Se({propagators:[new Te,new we]});this.propagationOwnership={status:o.setGlobalPropagator(e)?`logfire`:`external`}}};function Z(e){try{e()}catch{}}const Q=new dt;function ft(){Q.assertAvailable()}function pt(e){Q.initializeGlobals(e)}function mt(e){return Q.activate(e)}function ht(e){Q.beginCleanup(e)}function gt(e){Q.deactivateDelegate(e)}function $(e,t){Q.settleCleanup(e,t)}function _t(e,t,n){return Q.stableProvider.getTracer(e,t,n)}function vt(){return{}}function yt(e){if(!(e===void 0||e===!1))return e===!0?{}:e}function bt(e){if(!(e===void 0||e===!1)){if(e.metricUrl===``)throw Error(`logfire-browser: metrics.metricUrl must be a non-empty browser-safe metrics proxy URL`);return e}}function xt(e){if(!(e?.metrics===void 0||e.metrics===!1))return e.metrics===!0?{}:e.metrics}function St(e){if(!(e===void 0||e===!1))return L(e.replayUrl),e}function Ct(e,t){let n=yt(e?.webVitals),r=t!==void 0;if(n===void 0&&!r)return e?.session;if(e?.session===!1)throw Error(r?`logfire-browser: sessionReplay requires browser session attributes; remove rum.session: false or disable sessionReplay`:`logfire-browser: rum.webVitals requires browser session attributes; remove rum.session: false or disable rum.webVitals`);return e?.session??!0}async function wt(e,t){return{...typeof e==`function`?await e():e??{},...t()}}function Tt(e){return Array.isArray(e)?e:[e]}function Et(e,t){if(e===void 0||e===!1)return;let{enabled:n,...r}=e===!0?{}:e;if(n===!1)return;let i=I([{kind:`exact`,url:t.traceUrl},...t.metricUrl===void 0?[]:[{kind:`exact`,url:t.metricUrl}],...t.replayUrl===void 0?[]:[{kind:`replay-base`,url:t.replayUrl}]]),a=`@opentelemetry/instrumentation-fetch`,o=`@opentelemetry/instrumentation-xml-http-request`,s=r[a],c=r[o];return{...r,[a]:{...s,ignoreUrls:[...s?.ignoreUrls??[],...i]},[o]:{...c,ignoreUrls:[...c?.ignoreUrls??[],...i]}}}function Dt(){}function Ot(e){let t=[],n=e.instrumentations??[],r=n.length===0?[[]]:n;for(let n of r){let r=[];try{r=Tt(typeof n==`function`?n():n),t.push(l({instrumentations:r,tracerProvider:e.tracerProvider}))}catch(e){kt(r),a.error(`logfire-browser: failed to start configured browser instrumentation group`,e)}}let i=Et(e.autoInstrumentations,e.telemetryUrls),o=i===void 0?void 0:import(`@opentelemetry/auto-instrumentations-web`).then(({getWebAutoInstrumentations:t})=>{let n=t(i);try{return l({instrumentations:n,tracerProvider:e.tracerProvider})}catch(e){throw kt(n),e}}).catch(e=>(a.error(`logfire-browser: failed to start browser auto-instrumentations`,e),Dt)),s;return async()=>(s??=(async()=>{let e=await o,n=[...t,...e===void 0?[]:[e]],r;for(let e=n.length-1;e>=0;--e)try{n[e]?.()}catch(e){r??=e}if(r!==void 0)throw r instanceof Error?r:Error(`logfire-browser: instrumentation unregister failed`,{cause:r})})(),s)}function kt(e){for(let t=e.length-1;t>=0;--t)try{e[t]?.disable()}catch(e){a.error(`logfire-browser: failed to disable browser instrumentation after registration failure`,e)}}function At(){return{baggage:w.baggage,enableErrorFingerprinting:w.enableErrorFingerprinting,jsonSchema:w.jsonSchema,minLevel:w.minLevel,scrubber:w.scrubber,tracer:w.tracer}}function jt(e){w.baggage=e.baggage,w.enableErrorFingerprinting=e.enableErrorFingerprinting,w.jsonSchema=e.jsonSchema,w.minLevel=e.minLevel,w.scrubber=e.scrubber,w.tracer=e.tracer}function Mt(t){ft();let n=yt(t.rum?.webVitals),r=St(t.sessionReplay),i=bt(t.metrics),o=xt(n);if(o!==void 0&&i===void 0)throw Error(`logfire-browser: rum.webVitals.metrics requires top-level metrics.metricUrl`);let s=Ct(t.rum,r);pt(t.contextManager);let l=u(t.resourceAttributes??{}).merge(u({[fe]:navigator.language,[ie]:t.serviceName??`logfire-browser`,[ae]:t.serviceVersion??`0.0.1`,[oe]:ue,[se]:`logfire-browser`,...t.environment!==void 0&&t.environment!==``?{[he]:t.environment}:{},[ce]:`1.0.0`,...navigator.userAgentData?{[de]:navigator.userAgentData.brands.map(e=>`${e.brand} ${e.version}`),[pe]:navigator.userAgentData.mobile,[me]:navigator.userAgentData.platform}:{[le]:navigator.userAgent}}));a.info(`logfire-browser: starting`);let d=t.sampling?.head,f=d!==void 0&&d<1?new te({root:new ne(d)}):void 0,p=new st(new ee(new c({...t.traceExporterConfig,headers:async()=>wt(t.traceExporterConfig?.headers,t.traceExporterHeaders??vt),url:t.traceUrl}),t.batchSpanProcessorConfig),!!t.console);t.sampling?.tail&&(p=new ge(p,t.sampling.tail));let m=Ne(s),h=new Be,g=[];m!==void 0&&g.push(new Oe(m,h)),g.push(...t.spanProcessors??[],p);let y;try{y=new re({idGenerator:new _,resource:l,...f?{sampler:f}:{},spanProcessors:g})}catch(e){throw m!==void 0&&F(m),e}let _e=At(),b=mt(y);try{let n={errorFingerprinting:t.errorFingerprinting??!1};t.baggage!==void 0&&(n.baggage=t.baggage),t.jsonSchema!==void 0&&(n.jsonSchema=t.jsonSchema),t.minLevel!==void 0&&(n.minLevel=t.minLevel),t.scrubbing!==void 0&&(n.scrubbing=t.scrubbing),v(n),t.diagLogLevel!==void 0&&a.setLogger(new e,t.diagLogLevel),w.tracer=_t(w.otelScope)}catch(e){ht(b),gt(b),jt(_e);let t;if(m!==void 0)try{F(m)}catch(e){t=e instanceof Error?e:Error(String(e))}throw y.shutdown().then(()=>{$(b,t)},e=>{$(b,t??(e instanceof Error?e:Error(String(e))))}),e}let x=Ot({autoInstrumentations:t.autoInstrumentations,instrumentations:t.instrumentations,telemetryUrls:{metricUrl:i?.metricUrl,replayUrl:r!==void 0&&Fe(r.replayUrl)?r.replayUrl:void 0,traceUrl:t.traceUrl},tracerProvider:y}),S,C=r===void 0||m===void 0?void 0:Ve(r,m,h,{metricUrl:i?.metricUrl,traceUrl:t.traceUrl}).then(e=>(S=e,e)),T=Promise.resolve(),E,D=!1,O=C===void 0?void 0:{get mode(){return D?`off`:S?.mode??`off`},get recording(){return D?!1:S?.recording??!1},flush(){if(D)return E??T;let e=T.then(async()=>{await(await C)?.flush()});return T=e,e},stop(){return E===void 0?(D=!0,h.clear(),E=T.then(async()=>{await(await C)?.stop()}),T=E,E):E}},k=i===void 0?void 0:import(`./browserMetrics-ClpXqdqf.js`).then(async({startBrowserMetrics:e})=>e(i,l)).catch(e=>{a.error(`logfire-browser: failed to start browser metrics`,e)}),A=n===void 0?void 0:o===void 0?X({...n,tracer:y.getTracer(`logfire-web-vitals`)}).catch(e=>{a.error(`logfire-browser: failed to start Web Vitals reporting`,e)}):(async()=>{let e=await k;return e===void 0?(a.warn(`logfire-browser: browser metrics did not start; continuing Web Vitals with span reporting only`),X({...n,tracer:y.getTracer(`logfire-web-vitals`)})):X({...n,metricRecorder:e.createWebVitalsMetricRecorder(o),tracer:y.getTracer(`logfire-web-vitals`)})})().catch(e=>{a.error(`logfire-browser: failed to start Web Vitals reporting`,e)}),j,M=()=>j===void 0?(ht(b),j=(async()=>{let e,t=(t,n)=>{let r=n instanceof Error?n:Error(String(n));e??=r,a.error(`logfire-browser: ${t} failed during shutdown`,r)},n=async(e,n)=>{try{await n()}catch(n){t(e,n)}};a.info(`logfire-browser: shutting down`),O!==void 0&&await n(`session replay shutdown`,async()=>O.stop()),await n(`instrumentation unregister`,x),A!==void 0&&await n(`web vitals shutdown`,async()=>{await(await A)?.shutdown()}),k!==void 0&&(await n(`metric provider force flush`,async()=>{await(await k)?.forceFlush()}),await n(`metric provider shutdown`,async()=>{await(await k)?.shutdown()})),gt(b),await n(`force flush`,async()=>y.forceFlush()),await n(`tracer provider shutdown`,async()=>y.shutdown()),m!==void 0&&await n(`browser session cleanup`,()=>{F(m)});let r=e===void 0?void 0:Error(e.message,{cause:e});if($(b,r),r!==void 0)throw r;a.info(`logfire-browser: shut down complete`)})(),j):j;return O!==void 0&&Object.defineProperty(M,"sessionReplay",{enumerable:!0,value:O}),M}const Nt={configure:Mt,configureLogfireApi:v,debug:y,DiagLogLevel:n,error:_e,fatal:b,getBrowserSessionId:Pe,info:x,instrument:S,Level:m,log:C,logfireApiConfig:w,LogfireAttributeScrubber:h,NoopAttributeScrubber:g,notice:T,reportError:E,resolveBaseUrl:D,resolveSendToLogfire:O,serializeAttributes:k,span:A,startPendingSpan:j,startSpan:M,trace:ve,ULIDGenerator:_,warning:ye,withSettings:be,withTags:xe};export{t as DiagLogLevel,Mt as configure,Nt as default,Pe as getBrowserSessionId};
package/package.json CHANGED
@@ -25,7 +25,7 @@
25
25
  "stats",
26
26
  "monitoring"
27
27
  ],
28
- "version": "0.17.0-alpha.1",
28
+ "version": "0.17.0",
29
29
  "type": "module",
30
30
  "main": "./dist/index.cjs",
31
31
  "module": "./dist/index.js",
@@ -44,6 +44,7 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "@opentelemetry/api": "^1.9.1",
47
+ "@opentelemetry/auto-instrumentations-web": ">=0.64.0 <0.100.0",
47
48
  "@opentelemetry/core": "^2.8.0",
48
49
  "@opentelemetry/exporter-metrics-otlp-http": ">=0.219.0 <0.300.0",
49
50
  "@opentelemetry/exporter-trace-otlp-http": ">=0.219.0 <0.300.0",
@@ -56,7 +57,7 @@
56
57
  "peerDependencies": {
57
58
  "@opentelemetry/sdk-trace-web": "^2.8.0",
58
59
  "@opentelemetry/semantic-conventions": "^1.41.1",
59
- "@pydantic/logfire-session-replay": "0.1.0-alpha.1"
60
+ "@pydantic/logfire-session-replay": "^0.1.0"
60
61
  },
61
62
  "peerDependenciesMeta": {
62
63
  "@pydantic/logfire-session-replay": {
@@ -64,10 +65,13 @@
64
65
  }
65
66
  },
66
67
  "devDependencies": {
68
+ "@opentelemetry/context-zone": "^2.8.0",
69
+ "@opentelemetry/instrumentation-fetch": ">=0.219.0 <0.300.0",
67
70
  "@opentelemetry/sdk-trace-web": "^2.8.0",
68
71
  "@opentelemetry/semantic-conventions": "^1.41.1",
69
72
  "user-agent-data-types": "^0.4.2",
70
- "@pydantic/logfire-session-replay": "0.1.0-alpha.1"
73
+ "zone.js": "^0.15.1",
74
+ "@pydantic/logfire-session-replay": "0.1.0"
71
75
  },
72
76
  "files": [
73
77
  "dist",
@@ -1 +0,0 @@
1
- import{diag as e}from"@opentelemetry/api";const t={CLS:{boundaries:[.01,.05,.1,.15,.25,.5,1],description:`Cumulative Layout Shift score recorded in browser sessions.`,name:`logfire.browser.web_vital.cls`,unit:`1`},FCP:{boundaries:[500,1e3,1500,1800,2500,3e3,4e3,6e3],description:`First Contentful Paint duration recorded in browser sessions.`,name:`logfire.browser.web_vital.fcp`,unit:`ms`},INP:{boundaries:[50,100,150,200,300,500,800,1e3,2e3],description:`Interaction to Next Paint duration recorded in browser sessions.`,name:`logfire.browser.web_vital.inp`,unit:`ms`},LCP:{boundaries:[500,1e3,1500,2e3,2500,3e3,3500,4e3,5e3,8e3,1e4],description:`Largest Contentful Paint duration recorded in browser sessions.`,name:`logfire.browser.web_vital.lcp`,unit:`ms`},TTFB:{boundaries:[100,300,500,800,1200,1800,2500,4e3],description:`Time to First Byte duration recorded in browser sessions.`,name:`logfire.browser.web_vital.ttfb`,unit:`ms`}},n=new Set([`browser.session.id`,`session.id`,`url.full`,`web_vital.delta`,`web_vital.id`,`web_vital.value`]),r={exportIntervalMillis:6e4,exportTimeoutMillis:1e4};function i(e){return e===`CLS`||e===`FCP`||e===`INP`||e===`LCP`||e===`TTFB`}function a(e){return n.has(e)||e.startsWith(`web_vital.cls.`)||e.startsWith(`web_vital.fcp.`)||e.startsWith(`web_vital.inp.`)||e.startsWith(`web_vital.lcp.`)||e.startsWith(`web_vital.ttfb.`)}function o(e,t,n){if(!a(t)){if(typeof n==`string`||typeof n==`boolean`){e[t]=n;return}typeof n==`number`&&Number.isFinite(n)&&(e[t]=n)}}function s(e,t){if(t!==void 0)for(let[n,r]of Object.entries(t))o(e,n,r)}function c(e){let t={};return o(t,`web_vital.name`,e.name),o(t,`web_vital.rating`,e.rating),t}function l(e){let n=e.getMeter(`logfire-browser-web-vitals`);return{CLS:n.createHistogram(t.CLS.name,{advice:{explicitBucketBoundaries:t.CLS.boundaries},description:t.CLS.description,unit:t.CLS.unit}),FCP:n.createHistogram(t.FCP.name,{advice:{explicitBucketBoundaries:t.FCP.boundaries},description:t.FCP.description,unit:t.FCP.unit}),INP:n.createHistogram(t.INP.name,{advice:{explicitBucketBoundaries:t.INP.boundaries},description:t.INP.description,unit:t.INP.unit}),LCP:n.createHistogram(t.LCP.name,{advice:{explicitBucketBoundaries:t.LCP.boundaries},description:t.LCP.description,unit:t.LCP.unit}),TTFB:n.createHistogram(t.TTFB.name,{advice:{explicitBucketBoundaries:t.TTFB.boundaries},description:t.TTFB.description,unit:t.TTFB.unit})}}function u(t,n={}){let r=!0;return{record(a){if(!(!r||!i(a.name)))try{let e=c(a);s(e,n.defaultAttributes?.(a)),n.attributes!==!1&&s(e,n.attributes?.(a)),t[a.name].record(a.value,e)}catch(t){e.error(`logfire-browser: failed to record Web Vital metric`,t)}},shutdown(){r=!1}}}async function d(e,t){let[{MeterProvider:n,PeriodicExportingMetricReader:i},{OTLPMetricExporter:a}]=await Promise.all([import(`@opentelemetry/sdk-metrics`),import(`@opentelemetry/exporter-metrics-otlp-http`)]),o=new a({...e.metricExporterConfig,headers:e.metricExporterHeaders===void 0?void 0:async()=>e.metricExporterHeaders?.()??{},url:e.metricUrl}),s=new n({readers:[new i({...r,...e.metricReaderConfig,exporter:o}),...e.metricReaders??[]],resource:t}),c=l(s),d;return{createWebVitalsMetricRecorder(e){return u(c,e)},async forceFlush(){if(d!==void 0)return d;await s.forceFlush()},async shutdown(){return d??=s.shutdown(),d}}}export{d as startBrowserMetrics};
@@ -1 +0,0 @@
1
- let e=require("@opentelemetry/api");const t={CLS:{boundaries:[.01,.05,.1,.15,.25,.5,1],description:`Cumulative Layout Shift score recorded in browser sessions.`,name:`logfire.browser.web_vital.cls`,unit:`1`},FCP:{boundaries:[500,1e3,1500,1800,2500,3e3,4e3,6e3],description:`First Contentful Paint duration recorded in browser sessions.`,name:`logfire.browser.web_vital.fcp`,unit:`ms`},INP:{boundaries:[50,100,150,200,300,500,800,1e3,2e3],description:`Interaction to Next Paint duration recorded in browser sessions.`,name:`logfire.browser.web_vital.inp`,unit:`ms`},LCP:{boundaries:[500,1e3,1500,2e3,2500,3e3,3500,4e3,5e3,8e3,1e4],description:`Largest Contentful Paint duration recorded in browser sessions.`,name:`logfire.browser.web_vital.lcp`,unit:`ms`},TTFB:{boundaries:[100,300,500,800,1200,1800,2500,4e3],description:`Time to First Byte duration recorded in browser sessions.`,name:`logfire.browser.web_vital.ttfb`,unit:`ms`}},n=new Set([`browser.session.id`,`session.id`,`url.full`,`web_vital.delta`,`web_vital.id`,`web_vital.value`]),r={exportIntervalMillis:6e4,exportTimeoutMillis:1e4};function i(e){return e===`CLS`||e===`FCP`||e===`INP`||e===`LCP`||e===`TTFB`}function a(e){return n.has(e)||e.startsWith(`web_vital.cls.`)||e.startsWith(`web_vital.fcp.`)||e.startsWith(`web_vital.inp.`)||e.startsWith(`web_vital.lcp.`)||e.startsWith(`web_vital.ttfb.`)}function o(e,t,n){if(!a(t)){if(typeof n==`string`||typeof n==`boolean`){e[t]=n;return}typeof n==`number`&&Number.isFinite(n)&&(e[t]=n)}}function s(e,t){if(t!==void 0)for(let[n,r]of Object.entries(t))o(e,n,r)}function c(e){let t={};return o(t,`web_vital.name`,e.name),o(t,`web_vital.rating`,e.rating),t}function l(e){let n=e.getMeter(`logfire-browser-web-vitals`);return{CLS:n.createHistogram(t.CLS.name,{advice:{explicitBucketBoundaries:t.CLS.boundaries},description:t.CLS.description,unit:t.CLS.unit}),FCP:n.createHistogram(t.FCP.name,{advice:{explicitBucketBoundaries:t.FCP.boundaries},description:t.FCP.description,unit:t.FCP.unit}),INP:n.createHistogram(t.INP.name,{advice:{explicitBucketBoundaries:t.INP.boundaries},description:t.INP.description,unit:t.INP.unit}),LCP:n.createHistogram(t.LCP.name,{advice:{explicitBucketBoundaries:t.LCP.boundaries},description:t.LCP.description,unit:t.LCP.unit}),TTFB:n.createHistogram(t.TTFB.name,{advice:{explicitBucketBoundaries:t.TTFB.boundaries},description:t.TTFB.description,unit:t.TTFB.unit})}}function u(t,n={}){let r=!0;return{record(a){if(!(!r||!i(a.name)))try{let e=c(a);s(e,n.defaultAttributes?.(a)),n.attributes!==!1&&s(e,n.attributes?.(a)),t[a.name].record(a.value,e)}catch(t){e.diag.error(`logfire-browser: failed to record Web Vital metric`,t)}},shutdown(){r=!1}}}async function d(e,t){let[{MeterProvider:n,PeriodicExportingMetricReader:i},{OTLPMetricExporter:a}]=await Promise.all([import(`@opentelemetry/sdk-metrics`),import(`@opentelemetry/exporter-metrics-otlp-http`)]),o=new a({...e.metricExporterConfig,headers:e.metricExporterHeaders===void 0?void 0:async()=>e.metricExporterHeaders?.()??{},url:e.metricUrl}),s=new n({readers:[new i({...r,...e.metricReaderConfig,exporter:o}),...e.metricReaders??[]],resource:t}),c=l(s),d;return{createWebVitalsMetricRecorder(e){return u(c,e)},async forceFlush(){if(d!==void 0)return d;await s.forceFlush()},async shutdown(){return d??=s.shutdown(),d}}}exports.startBrowserMetrics=d;