@interfere/react 10.0.0 → 10.0.1-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/dist/api.d.mts.map +1 -1
  2. package/dist/api.mjs +1 -68
  3. package/dist/api.mjs.map +1 -1
  4. package/dist/error-boundary.d.mts +1 -2
  5. package/dist/error-boundary.d.mts.map +1 -1
  6. package/dist/error-boundary.mjs +1 -42
  7. package/dist/error-boundary.mjs.map +1 -1
  8. package/dist/internal/browser-context.d.mts.map +1 -1
  9. package/dist/internal/browser-context.mjs +1 -59
  10. package/dist/internal/browser-context.mjs.map +1 -1
  11. package/dist/internal/capture-boundary.d.mts +1 -2
  12. package/dist/internal/capture-boundary.d.mts.map +1 -1
  13. package/dist/internal/capture-boundary.mjs +1 -48
  14. package/dist/internal/capture-boundary.mjs.map +1 -1
  15. package/dist/internal/capture.mjs +1 -27
  16. package/dist/internal/capture.mjs.map +1 -1
  17. package/dist/internal/config.d.mts +3 -1
  18. package/dist/internal/config.d.mts.map +1 -1
  19. package/dist/internal/config.mjs +1 -33
  20. package/dist/internal/config.mjs.map +1 -1
  21. package/dist/internal/consent.d.mts.map +1 -1
  22. package/dist/internal/consent.mjs +1 -27
  23. package/dist/internal/consent.mjs.map +1 -1
  24. package/dist/internal/console-patch.d.mts.map +1 -1
  25. package/dist/internal/console-patch.mjs +1 -62
  26. package/dist/internal/console-patch.mjs.map +1 -1
  27. package/dist/internal/dom/actionable.d.mts.map +1 -1
  28. package/dist/internal/dom/actionable.mjs +1 -62
  29. package/dist/internal/dom/actionable.mjs.map +1 -1
  30. package/dist/internal/kernel-registry.d.mts.map +1 -1
  31. package/dist/internal/kernel-registry.mjs +1 -31
  32. package/dist/internal/kernel-registry.mjs.map +1 -1
  33. package/dist/internal/kernel.d.mts.map +1 -1
  34. package/dist/internal/kernel.mjs +1 -322
  35. package/dist/internal/kernel.mjs.map +1 -1
  36. package/dist/internal/otel/exporter.d.mts +4 -12
  37. package/dist/internal/otel/exporter.d.mts.map +1 -1
  38. package/dist/internal/otel/exporter.mjs +1 -212
  39. package/dist/internal/otel/exporter.mjs.map +1 -1
  40. package/dist/internal/otel/index.mjs +1 -6
  41. package/dist/internal/otel/instrumentations.d.mts.map +1 -1
  42. package/dist/internal/otel/instrumentations.mjs +1 -150
  43. package/dist/internal/otel/instrumentations.mjs.map +1 -1
  44. package/dist/internal/otel/page-scope-context-manager.d.mts.map +1 -1
  45. package/dist/internal/otel/page-scope-context-manager.mjs +1 -36
  46. package/dist/internal/otel/page-scope-context-manager.mjs.map +1 -1
  47. package/dist/internal/otel/propagation.d.mts.map +1 -1
  48. package/dist/internal/otel/propagation.mjs +1 -40
  49. package/dist/internal/otel/propagation.mjs.map +1 -1
  50. package/dist/internal/otel/provider.d.mts +1 -2
  51. package/dist/internal/otel/provider.d.mts.map +1 -1
  52. package/dist/internal/otel/provider.mjs +1 -151
  53. package/dist/internal/otel/provider.mjs.map +1 -1
  54. package/dist/internal/otel/web-vitals.d.mts.map +1 -1
  55. package/dist/internal/otel/web-vitals.mjs +1 -162
  56. package/dist/internal/otel/web-vitals.mjs.map +1 -1
  57. package/dist/internal/page-lifecycle.d.mts.map +1 -1
  58. package/dist/internal/page-lifecycle.mjs +1 -33
  59. package/dist/internal/page-lifecycle.mjs.map +1 -1
  60. package/dist/internal/plugin-runtime.mjs +1 -101
  61. package/dist/internal/plugin-runtime.mjs.map +1 -1
  62. package/dist/internal/react-context.d.mts +1 -2
  63. package/dist/internal/react-context.d.mts.map +1 -1
  64. package/dist/internal/react-context.mjs +1 -34
  65. package/dist/internal/react-context.mjs.map +1 -1
  66. package/dist/internal/sw.d.mts.map +1 -1
  67. package/dist/internal/sw.mjs +1 -37
  68. package/dist/internal/sw.mjs.map +1 -1
  69. package/dist/internal/version.mjs +1 -7
  70. package/dist/internal/version.mjs.map +1 -1
  71. package/dist/internal/wrapper-singleton.d.mts.map +1 -1
  72. package/dist/internal/wrapper-singleton.mjs +1 -73
  73. package/dist/internal/wrapper-singleton.mjs.map +1 -1
  74. package/dist/package.mjs +1 -5
  75. package/dist/plugins/errors.d.mts.map +1 -1
  76. package/dist/plugins/errors.mjs +1 -84
  77. package/dist/plugins/errors.mjs.map +1 -1
  78. package/dist/plugins/lib/loader.mjs +1 -34
  79. package/dist/plugins/lib/loader.mjs.map +1 -1
  80. package/dist/plugins/lib/types.d.mts.map +1 -1
  81. package/dist/plugins/lib/types.mjs +1 -1
  82. package/dist/plugins/logs.d.mts.map +1 -1
  83. package/dist/plugins/logs.mjs +1 -53
  84. package/dist/plugins/logs.mjs.map +1 -1
  85. package/dist/plugins/rage-clicks.d.mts.map +1 -1
  86. package/dist/plugins/rage-clicks.mjs +1 -55
  87. package/dist/plugins/rage-clicks.mjs.map +1 -1
  88. package/dist/plugins/replay.d.mts.map +1 -1
  89. package/dist/plugins/replay.mjs +1 -101
  90. package/dist/plugins/replay.mjs.map +1 -1
  91. package/dist/provider.d.mts.map +1 -1
  92. package/dist/provider.mjs +1 -31
  93. package/dist/provider.mjs.map +1 -1
  94. package/dist/react-error-handler.d.mts.map +1 -1
  95. package/dist/react-error-handler.mjs +1 -62
  96. package/dist/react-error-handler.mjs.map +1 -1
  97. package/dist/tracking/api.d.mts.map +1 -1
  98. package/dist/tracking/api.mjs +1 -152
  99. package/dist/tracking/api.mjs.map +1 -1
  100. package/dist/tracking/device.d.mts.map +1 -1
  101. package/dist/tracking/device.mjs +1 -104
  102. package/dist/tracking/device.mjs.map +1 -1
  103. package/dist/tracking/geo.d.mts.map +1 -1
  104. package/dist/tracking/geo.mjs +2 -48
  105. package/dist/tracking/geo.mjs.map +1 -1
  106. package/dist/tracking/session.d.mts.map +1 -1
  107. package/dist/tracking/session.mjs +1 -75
  108. package/dist/tracking/session.mjs.map +1 -1
  109. package/dist/util/bot.d.mts.map +1 -1
  110. package/dist/util/bot.mjs +1 -14
  111. package/dist/util/bot.mjs.map +1 -1
  112. package/dist/util/global.d.mts.map +1 -1
  113. package/dist/util/global.mjs +1 -12
  114. package/dist/util/global.mjs.map +1 -1
  115. package/dist/util/log.d.mts.map +1 -1
  116. package/dist/util/log.mjs +1 -44
  117. package/dist/util/log.mjs.map +1 -1
  118. package/dist/util/stringify.d.mts.map +1 -1
  119. package/dist/util/stringify.mjs +1 -16
  120. package/dist/util/stringify.mjs.map +1 -1
  121. package/package.json +34 -33
@@ -1,150 +1 @@
1
- import { describeActionable, isActionable } from "../dom/actionable.mjs";
2
- import { registerInstrumentations } from "@opentelemetry/instrumentation";
3
- import { BrowserNavigationInstrumentation, defaultSanitizeUrl } from "@opentelemetry/instrumentation-browser-navigation";
4
- import { DocumentLoadInstrumentation } from "@opentelemetry/instrumentation-document-load";
5
- import { FetchInstrumentation } from "@opentelemetry/instrumentation-fetch";
6
- import { LongTaskInstrumentation } from "@opentelemetry/instrumentation-long-task";
7
- import { UserInteractionInstrumentation } from "@opentelemetry/instrumentation-user-interaction";
8
- import { XMLHttpRequestInstrumentation } from "@opentelemetry/instrumentation-xml-http-request";
9
- //#region src/internal/otel/instrumentations.ts
10
- const ATTR_HTTP_ROUTE = "http.route";
11
- const ATTR_URL_FULL = "url.full";
12
- const ATTR_URL_PATH = "url.path";
13
- /**
14
- * Mirrors the `semconvStabilityOptIn` constant from the internal
15
- * `observability/browser/rum.ts`. Pins the HTTP attribute set to the
16
- * stable-namespace conventions (`url.path`, `server.address`, …) so
17
- * dashboards that filter on those keys aren't broken by minor
18
- * upgrades of the instrumentation packages.
19
- */
20
- const SEMCONV_STABILITY_OPT_IN = "http,database,messaging,gen_ai_latest_experimental";
21
- /**
22
- * Hosts/paths whose CLIENT fetch spans we never want to emit: they
23
- * always become 1-span orphan traces (no traceparent propagation to
24
- * 3rd-party origins) and clutter live tail. Conservative, customer-
25
- * generic list — common analytics / ads / auth / replay vendors that
26
- * many apps use. Customer-specific noise (Statsig CDNs, our own
27
- * BetterStack, etc.) belongs in the customer's own `ignoreUrls` config,
28
- * not hardcoded into a public SDK.
29
- */
30
- const THIRD_PARTY_IGNORE = [
31
- /(?:^|\/\/)clerk\./,
32
- /\.clerk\./,
33
- /\.sentry\./,
34
- /\.intercom\./,
35
- /\.posthog\./,
36
- /\.googletagmanager\.com/,
37
- /\.google-analytics\.com/,
38
- /\.googleapis\.com/,
39
- /\.doubleclick\.net/,
40
- /\.facebook\.com/,
41
- /\.fbcdn\.net/,
42
- /\.analytics\.google\.com/,
43
- /px\.ads\.linkedin\.com/,
44
- /[?&]_rsc=/
45
- ];
46
- const NEVER_MATCH = /^$/;
47
- const ESCAPE_RE = /[.*+?^${}()|[\]\\]/g;
48
- function sameOriginPattern() {
49
- if (typeof window === "undefined") return NEVER_MATCH;
50
- const { protocol, host } = window.location;
51
- return new RegExp(`^${protocol}//${host.replace(ESCAPE_RE, "\\$&")}`);
52
- }
53
- function stampInteractionAttrs(eventType, element, span) {
54
- const desc = describeActionable(element);
55
- span.setAttribute("ui.event_type", eventType);
56
- span.setAttribute("ui.target.tag", desc.tag);
57
- if (desc.id) span.setAttribute("ui.target.id", desc.id);
58
- if (desc.name) span.setAttribute("ui.target.name", desc.name);
59
- if (desc.role) span.setAttribute("ui.target.role", desc.role);
60
- if (desc.ariaLabel) span.setAttribute("ui.target.aria_label", desc.ariaLabel);
61
- if (desc.text) span.setAttribute("ui.target.text", desc.text);
62
- }
63
- function stampUrlAttrs(span, resolveRoute) {
64
- if (typeof window === "undefined") return;
65
- const pathname = window.location.pathname;
66
- const route = resolveRoute?.(pathname);
67
- span.setAttribute(ATTR_URL_PATH, route ?? pathname);
68
- span.setAttribute(ATTR_URL_FULL, window.location.href);
69
- if (route) span.setAttribute(ATTR_HTTP_ROUTE, route);
70
- }
71
- /**
72
- * Registers every browser auto-instrumentation against the kernel's
73
- * private provider. Every instrumentation is enriched with the same
74
- * route-template-aware URL attributes so dashboards can slice fetch /
75
- * interaction / long-task / resource-load by `http.route` without
76
- * cardinality blow-up from raw pathnames.
77
- *
78
- * Returns a disposer that unregisters everything; called by
79
- * `kernel.dispose()`.
80
- */
81
- function registerBundledInstrumentations(input) {
82
- const { tracerProvider, ignoreUrls, propagateContextUrls = [] } = input;
83
- const resolveRoute = input.resolveRoute;
84
- const origin = sameOriginPattern();
85
- const fetchIgnore = [...ignoreUrls, ...THIRD_PARTY_IGNORE];
86
- return registerInstrumentations({
87
- tracerProvider,
88
- instrumentations: [
89
- new FetchInstrumentation({
90
- propagateTraceHeaderCorsUrls: [origin, ...propagateContextUrls],
91
- ignoreUrls: fetchIgnore,
92
- semconvStabilityOptIn: SEMCONV_STABILITY_OPT_IN,
93
- measureRequestSize: true,
94
- applyCustomAttributesOnSpan: (span, request) => {
95
- const url = request instanceof Request ? request.url : request?.toString();
96
- if (typeof url !== "string") return;
97
- try {
98
- const parsed = new URL(url);
99
- span.setAttribute(ATTR_URL_PATH, parsed.pathname);
100
- if (origin.test(url) || propagateContextUrls.some((re) => re instanceof RegExp ? re.test(url) : url.includes(re))) {
101
- const method = (request instanceof Request ? request.method : void 0) ?? "GET";
102
- const route = resolveRoute?.(parsed.pathname);
103
- if (route) span.setAttribute(ATTR_HTTP_ROUTE, route);
104
- span.updateName(`${method} ${route ?? parsed.pathname}`);
105
- }
106
- } catch {
107
- return;
108
- }
109
- }
110
- }),
111
- new XMLHttpRequestInstrumentation({
112
- propagateTraceHeaderCorsUrls: [origin, ...propagateContextUrls],
113
- ignoreUrls: fetchIgnore,
114
- semconvStabilityOptIn: SEMCONV_STABILITY_OPT_IN
115
- }),
116
- new DocumentLoadInstrumentation({
117
- semconvStabilityOptIn: SEMCONV_STABILITY_OPT_IN,
118
- applyCustomAttributesOnSpan: { resourceFetch: (span, entry) => {
119
- const name = entry?.name;
120
- if (typeof name !== "string") return;
121
- try {
122
- const url = new URL(name);
123
- const isCrossOrigin = typeof window !== "undefined" && url.origin !== window.location.origin;
124
- span.updateName(isCrossOrigin ? `resource: ${url.host}${url.pathname}` : `resource: ${url.pathname}`);
125
- span.setAttribute(ATTR_URL_FULL, name);
126
- span.setAttribute(ATTR_URL_PATH, url.pathname);
127
- span.setAttribute("server.address", url.host);
128
- } catch {}
129
- } }
130
- }),
131
- new BrowserNavigationInstrumentation({ sanitizeUrl: defaultSanitizeUrl }),
132
- new UserInteractionInstrumentation({
133
- eventNames: ["click", "submit"],
134
- shouldPreventSpanCreation: (eventType, element, span) => {
135
- if (eventType === "click" && !isActionable(element)) return true;
136
- stampInteractionAttrs(eventType, element, span);
137
- stampUrlAttrs(span, resolveRoute);
138
- return false;
139
- }
140
- }),
141
- new LongTaskInstrumentation({ observerCallback: (span, info) => {
142
- stampUrlAttrs(span, resolveRoute);
143
- const containerType = info.longtaskEntry.attribution[0]?.containerType;
144
- if (containerType) span.setAttribute("longtask.container_type", containerType);
145
- } })
146
- ]
147
- });
148
- }
149
- //#endregion
150
- export { registerBundledInstrumentations };
1
+ import{describeActionable,isActionable}from"../dom/actionable.mjs";import{registerInstrumentations}from"@opentelemetry/instrumentation";import{BrowserNavigationInstrumentation,defaultSanitizeUrl}from"@opentelemetry/instrumentation-browser-navigation";import{DocumentLoadInstrumentation}from"@opentelemetry/instrumentation-document-load";import{FetchInstrumentation}from"@opentelemetry/instrumentation-fetch";import{LongTaskInstrumentation}from"@opentelemetry/instrumentation-long-task";import{UserInteractionInstrumentation}from"@opentelemetry/instrumentation-user-interaction";import{XMLHttpRequestInstrumentation}from"@opentelemetry/instrumentation-xml-http-request";const ATTR_HTTP_ROUTE=`http.route`,ATTR_URL_FULL=`url.full`,ATTR_URL_PATH=`url.path`,SEMCONV_STABILITY_OPT_IN=`http,database,messaging,gen_ai_latest_experimental`,THIRD_PARTY_IGNORE=[/(?:^|\/\/)clerk\./,/\.clerk\./,/\.sentry\./,/\.intercom\./,/\.posthog\./,/\.googletagmanager\.com/,/\.google-analytics\.com/,/\.googleapis\.com/,/\.doubleclick\.net/,/\.facebook\.com/,/\.fbcdn\.net/,/\.analytics\.google\.com/,/px\.ads\.linkedin\.com/,/[?&]_rsc=/],NEVER_MATCH=/^$/,ESCAPE_RE=/[.*+?^${}()|[\]\\]/g;function sameOriginPattern(){if(typeof window>`u`)return NEVER_MATCH;let{protocol,host}=window.location;return RegExp(`^${protocol}//${host.replace(ESCAPE_RE,`\\$&`)}`)}function stampInteractionAttrs(eventType,element,span){let desc=describeActionable(element);span.setAttribute(`ui.event_type`,eventType),span.setAttribute(`ui.target.tag`,desc.tag),desc.id&&span.setAttribute(`ui.target.id`,desc.id),desc.name&&span.setAttribute(`ui.target.name`,desc.name),desc.role&&span.setAttribute(`ui.target.role`,desc.role),desc.ariaLabel&&span.setAttribute(`ui.target.aria_label`,desc.ariaLabel),desc.text&&span.setAttribute(`ui.target.text`,desc.text)}function stampUrlAttrs(span,resolveRoute){if(typeof window>`u`)return;let pathname=window.location.pathname,route=resolveRoute?.(pathname);span.setAttribute(ATTR_URL_PATH,route??pathname),span.setAttribute(ATTR_URL_FULL,window.location.href),route&&span.setAttribute(ATTR_HTTP_ROUTE,route)}function registerBundledInstrumentations(input){let{tracerProvider,ignoreUrls,propagateContextUrls=[]}=input,resolveRoute=input.resolveRoute,origin=sameOriginPattern(),fetchIgnore=[...ignoreUrls,...THIRD_PARTY_IGNORE];return registerInstrumentations({tracerProvider,instrumentations:[new FetchInstrumentation({propagateTraceHeaderCorsUrls:[origin,...propagateContextUrls],ignoreUrls:fetchIgnore,semconvStabilityOptIn:SEMCONV_STABILITY_OPT_IN,measureRequestSize:!0,applyCustomAttributesOnSpan:(span,request)=>{let url=request instanceof Request?request.url:request?.toString();if(typeof url==`string`)try{let parsed=new URL(url);if(span.setAttribute(ATTR_URL_PATH,parsed.pathname),origin.test(url)||propagateContextUrls.some(re=>re instanceof RegExp?re.test(url):url.includes(re))){let method=(request instanceof Request?request.method:void 0)??`GET`,route=resolveRoute?.(parsed.pathname);route&&span.setAttribute(ATTR_HTTP_ROUTE,route),span.updateName(`${method} ${route??parsed.pathname}`)}}catch{return}}}),new XMLHttpRequestInstrumentation({propagateTraceHeaderCorsUrls:[origin,...propagateContextUrls],ignoreUrls:fetchIgnore,semconvStabilityOptIn:SEMCONV_STABILITY_OPT_IN}),new DocumentLoadInstrumentation({semconvStabilityOptIn:SEMCONV_STABILITY_OPT_IN,applyCustomAttributesOnSpan:{resourceFetch:(span,entry)=>{let name=entry?.name;if(typeof name==`string`)try{let url=new URL(name),isCrossOrigin=typeof window<`u`&&url.origin!==window.location.origin;span.updateName(isCrossOrigin?`resource: ${url.host}${url.pathname}`:`resource: ${url.pathname}`),span.setAttribute(ATTR_URL_FULL,name),span.setAttribute(ATTR_URL_PATH,url.pathname),span.setAttribute(`server.address`,url.host)}catch{}}}}),new BrowserNavigationInstrumentation({sanitizeUrl:defaultSanitizeUrl}),new UserInteractionInstrumentation({eventNames:[`click`,`submit`],shouldPreventSpanCreation:(eventType,element,span)=>eventType===`click`&&!isActionable(element)?!0:(stampInteractionAttrs(eventType,element,span),stampUrlAttrs(span,resolveRoute),!1)}),new LongTaskInstrumentation({observerCallback:(span,info)=>{stampUrlAttrs(span,resolveRoute);let containerType=info.longtaskEntry.attribution[0]?.containerType;containerType&&span.setAttribute(`longtask.container_type`,containerType)}})]})}export{registerBundledInstrumentations};
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentations.mjs","names":[],"sources":["../../../src/internal/otel/instrumentations.ts"],"sourcesContent":["import type { Span } from \"@opentelemetry/api\";\nimport { registerInstrumentations } from \"@opentelemetry/instrumentation\";\nimport {\n BrowserNavigationInstrumentation,\n defaultSanitizeUrl,\n} from \"@opentelemetry/instrumentation-browser-navigation\";\nimport { DocumentLoadInstrumentation } from \"@opentelemetry/instrumentation-document-load\";\nimport { FetchInstrumentation } from \"@opentelemetry/instrumentation-fetch\";\nimport {\n LongTaskInstrumentation,\n type ObserverCallbackInformation,\n} from \"@opentelemetry/instrumentation-long-task\";\nimport { UserInteractionInstrumentation } from \"@opentelemetry/instrumentation-user-interaction\";\nimport { XMLHttpRequestInstrumentation } from \"@opentelemetry/instrumentation-xml-http-request\";\nimport type { WebTracerProvider } from \"@opentelemetry/sdk-trace-web\";\n\nimport { describeActionable, isActionable } from \"../dom/actionable.js\";\n\nconst ATTR_HTTP_ROUTE = \"http.route\" as const;\nconst ATTR_URL_FULL = \"url.full\" as const;\nconst ATTR_URL_PATH = \"url.path\" as const;\n\n/**\n * Mirrors the `semconvStabilityOptIn` constant from the internal\n * `observability/browser/rum.ts`. Pins the HTTP attribute set to the\n * stable-namespace conventions (`url.path`, `server.address`, …) so\n * dashboards that filter on those keys aren't broken by minor\n * upgrades of the instrumentation packages.\n */\nconst SEMCONV_STABILITY_OPT_IN =\n \"http,database,messaging,gen_ai_latest_experimental\";\n\n/**\n * Hosts/paths whose CLIENT fetch spans we never want to emit: they\n * always become 1-span orphan traces (no traceparent propagation to\n * 3rd-party origins) and clutter live tail. Conservative, customer-\n * generic list — common analytics / ads / auth / replay vendors that\n * many apps use. Customer-specific noise (Statsig CDNs, our own\n * BetterStack, etc.) belongs in the customer's own `ignoreUrls` config,\n * not hardcoded into a public SDK.\n */\nconst THIRD_PARTY_IGNORE: RegExp[] = [\n /(?:^|\\/\\/)clerk\\./,\n /\\.clerk\\./,\n /\\.sentry\\./,\n /\\.intercom\\./,\n /\\.posthog\\./,\n /\\.googletagmanager\\.com/,\n /\\.google-analytics\\.com/,\n /\\.googleapis\\.com/,\n /\\.doubleclick\\.net/,\n /\\.facebook\\.com/,\n /\\.fbcdn\\.net/,\n /\\.analytics\\.google\\.com/,\n /px\\.ads\\.linkedin\\.com/,\n /[?&]_rsc=/,\n];\n\nconst NEVER_MATCH = /^$/;\nconst ESCAPE_RE = /[.*+?^${}()|[\\]\\\\]/g;\n\nfunction sameOriginPattern(): RegExp {\n if (typeof window === \"undefined\") {\n return NEVER_MATCH;\n }\n const { protocol, host } = window.location;\n return new RegExp(`^${protocol}//${host.replace(ESCAPE_RE, \"\\\\$&\")}`);\n}\n\nfunction stampInteractionAttrs(\n eventType: string,\n element: HTMLElement,\n span: Span\n): void {\n const desc = describeActionable(element);\n span.setAttribute(\"ui.event_type\", eventType);\n span.setAttribute(\"ui.target.tag\", desc.tag);\n if (desc.id) {\n span.setAttribute(\"ui.target.id\", desc.id);\n }\n if (desc.name) {\n span.setAttribute(\"ui.target.name\", desc.name);\n }\n if (desc.role) {\n span.setAttribute(\"ui.target.role\", desc.role);\n }\n if (desc.ariaLabel) {\n span.setAttribute(\"ui.target.aria_label\", desc.ariaLabel);\n }\n // Truncated visible label — useful for triage without exfiltrating\n // full DOM contents. Only meaningful on the direct target.\n if (desc.text) {\n span.setAttribute(\"ui.target.text\", desc.text);\n }\n}\n\nfunction stampUrlAttrs(\n span: Span,\n resolveRoute: ((pathname: string) => string | undefined) | undefined\n): void {\n if (typeof window === \"undefined\") {\n return;\n }\n const pathname = window.location.pathname;\n const route = resolveRoute?.(pathname);\n span.setAttribute(ATTR_URL_PATH, route ?? pathname);\n span.setAttribute(ATTR_URL_FULL, window.location.href);\n if (route) {\n span.setAttribute(ATTR_HTTP_ROUTE, route);\n }\n}\n\nexport interface InstrumentationsInput {\n /**\n * URLs the SDK exempts from `fetch` and `XHR` instrumentation —\n * typically our own ingest/OTLP endpoints, so the SDK doesn't trace\n * its own export requests in an infinite loop. Combined with the\n * `THIRD_PARTY_IGNORE` defaults and the customer's `ignoreUrls`.\n */\n ignoreUrls: (string | RegExp)[];\n /**\n * Customer-supplied URL patterns the fetch + XHR instrumentations\n * inject `traceparent` + `baggage` headers on. Same-origin requests\n * always propagate.\n */\n propagateContextUrls?: (string | RegExp)[];\n /**\n * Pathname → low-cardinality route template (e.g. `/blog/[slug]`).\n * Drives span renaming + `url.path` / `http.route` attrs across\n * fetch, document-load, user-interaction, and long-task.\n */\n resolveRoute?: (pathname: string) => string | undefined;\n /**\n * The kernel's private provider — instrumentations register against\n * it, not the global one, so customer OTel setups stay untouched.\n */\n tracerProvider: WebTracerProvider;\n}\n\n/**\n * Registers every browser auto-instrumentation against the kernel's\n * private provider. Every instrumentation is enriched with the same\n * route-template-aware URL attributes so dashboards can slice fetch /\n * interaction / long-task / resource-load by `http.route` without\n * cardinality blow-up from raw pathnames.\n *\n * Returns a disposer that unregisters everything; called by\n * `kernel.dispose()`.\n */\nexport function registerBundledInstrumentations(\n input: InstrumentationsInput\n): () => void {\n const { tracerProvider, ignoreUrls, propagateContextUrls = [] } = input;\n const resolveRoute = input.resolveRoute;\n const origin = sameOriginPattern();\n const fetchIgnore = [...ignoreUrls, ...THIRD_PARTY_IGNORE];\n\n return registerInstrumentations({\n tracerProvider,\n instrumentations: [\n new FetchInstrumentation({\n propagateTraceHeaderCorsUrls: [origin, ...propagateContextUrls],\n ignoreUrls: fetchIgnore,\n semconvStabilityOptIn: SEMCONV_STABILITY_OPT_IN,\n measureRequestSize: true,\n applyCustomAttributesOnSpan: (\n span: Span,\n request: Request | RequestInit\n ) => {\n const url =\n request instanceof Request ? request.url : request?.toString();\n if (typeof url !== \"string\") {\n return;\n }\n try {\n const parsed = new URL(url);\n span.setAttribute(ATTR_URL_PATH, parsed.pathname);\n const isTracked =\n origin.test(url) ||\n propagateContextUrls.some((re) =>\n re instanceof RegExp ? re.test(url) : url.includes(re)\n );\n if (isTracked) {\n const method =\n (request instanceof Request ? request.method : undefined) ??\n \"GET\";\n const route = resolveRoute?.(parsed.pathname);\n if (route) {\n span.setAttribute(ATTR_HTTP_ROUTE, route);\n }\n span.updateName(`${method} ${route ?? parsed.pathname}`);\n }\n } catch {\n return;\n }\n },\n }),\n new XMLHttpRequestInstrumentation({\n propagateTraceHeaderCorsUrls: [origin, ...propagateContextUrls],\n ignoreUrls: fetchIgnore,\n semconvStabilityOptIn: SEMCONV_STABILITY_OPT_IN,\n }),\n new DocumentLoadInstrumentation({\n semconvStabilityOptIn: SEMCONV_STABILITY_OPT_IN,\n // Default `resourceFetch` span name is the literal string\n // `\"resourceFetch\"` for every entry — useless when a single\n // page load emits 30 of them. Replace with the pathname (or\n // origin+path for cross-origin) so the waterfall is scannable.\n applyCustomAttributesOnSpan: {\n resourceFetch: (span, entry) => {\n const name = entry?.name;\n if (typeof name !== \"string\") {\n return;\n }\n try {\n const url = new URL(name);\n const isCrossOrigin =\n typeof window !== \"undefined\" &&\n url.origin !== window.location.origin;\n span.updateName(\n isCrossOrigin\n ? `resource: ${url.host}${url.pathname}`\n : `resource: ${url.pathname}`\n );\n span.setAttribute(ATTR_URL_FULL, name);\n span.setAttribute(ATTR_URL_PATH, url.pathname);\n span.setAttribute(\"server.address\", url.host);\n } catch {\n // Malformed/relative URL — leave the default name and\n // let the entry's own attributes carry whatever info\n // the SDK already stamped.\n }\n },\n },\n }),\n // `BrowserNavigationInstrumentation` emits a `browser.navigation`\n // log record per hard navigation (page load) and soft navigation\n // (history.pushState, hash change, back/forward). The default\n // sanitizer redacts credentials in the URL and common sensitive\n // query params (`token`, `api_key`, `secret`, …) before emit.\n new BrowserNavigationInstrumentation({\n sanitizeUrl: defaultSanitizeUrl,\n }),\n new UserInteractionInstrumentation({\n eventNames: [\"click\", \"submit\"],\n // Despite the name, `shouldPreventSpanCreation` is also the\n // hook for *enriching* spans (return falsy → create the span;\n // the callback may set attributes on the way through). We use\n // it as both: stamp a stable target descriptor for\n // dashboarding, then suppress spans on elements that aren't\n // actionable (scroll containers, body clicks, etc.).\n shouldPreventSpanCreation: (eventType, element, span) => {\n if (eventType === \"click\" && !isActionable(element)) {\n return true;\n }\n stampInteractionAttrs(eventType, element, span);\n stampUrlAttrs(span, resolveRoute);\n return false;\n },\n }),\n // Long-task spans default to a generic `longtask` name with\n // attribution embedded as attributes — but no page context.\n // Empty `url.path` makes it impossible to triage which routes\n // are jank-heavy. Stamp it in the observer callback so\n // dashboards can slice by route.\n new LongTaskInstrumentation({\n observerCallback: (span, info: ObserverCallbackInformation) => {\n stampUrlAttrs(span, resolveRoute);\n // PerformanceLongTaskTiming attribution[0].containerType is\n // the surface that hosted the offending task. Most are\n // `\"window\"` (main frame); the few that aren't (`\"iframe\"`,\n // `\"embed\"`, `\"object\"`) are the actionable ones — surface\n // them as a top-level attr instead of leaving them buried\n // in `longtask.attribution.container_type`.\n const containerType =\n info.longtaskEntry.attribution[0]?.containerType;\n if (containerType) {\n span.setAttribute(\"longtask.container_type\", containerType);\n }\n },\n }),\n ],\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"instrumentations.mjs","names":[],"sources":["../../../src/internal/otel/instrumentations.ts"],"sourcesContent":["import type { Span } from \"@opentelemetry/api\";\nimport { registerInstrumentations } from \"@opentelemetry/instrumentation\";\nimport {\n BrowserNavigationInstrumentation,\n defaultSanitizeUrl,\n} from \"@opentelemetry/instrumentation-browser-navigation\";\nimport { DocumentLoadInstrumentation } from \"@opentelemetry/instrumentation-document-load\";\nimport { FetchInstrumentation } from \"@opentelemetry/instrumentation-fetch\";\nimport {\n LongTaskInstrumentation,\n type ObserverCallbackInformation,\n} from \"@opentelemetry/instrumentation-long-task\";\nimport { UserInteractionInstrumentation } from \"@opentelemetry/instrumentation-user-interaction\";\nimport { XMLHttpRequestInstrumentation } from \"@opentelemetry/instrumentation-xml-http-request\";\nimport type { WebTracerProvider } from \"@opentelemetry/sdk-trace-web\";\n\nimport { describeActionable, isActionable } from \"../dom/actionable.js\";\n\nconst ATTR_HTTP_ROUTE = \"http.route\" as const;\nconst ATTR_URL_FULL = \"url.full\" as const;\nconst ATTR_URL_PATH = \"url.path\" as const;\n\n/**\n * Mirrors the `semconvStabilityOptIn` constant from the internal\n * `observability/browser/rum.ts`. Pins the HTTP attribute set to the\n * stable-namespace conventions (`url.path`, `server.address`, …) so\n * dashboards that filter on those keys aren't broken by minor\n * upgrades of the instrumentation packages.\n */\nconst SEMCONV_STABILITY_OPT_IN =\n \"http,database,messaging,gen_ai_latest_experimental\";\n\n/**\n * Hosts/paths whose CLIENT fetch spans we never want to emit: they\n * always become 1-span orphan traces (no traceparent propagation to\n * 3rd-party origins) and clutter live tail. Conservative, customer-\n * generic list — common analytics / ads / auth / replay vendors that\n * many apps use. Customer-specific noise (feature-flag CDNs, our own\n * BetterStack, etc.) belongs in the customer's own `ignoreUrls` config,\n * not hardcoded into a public SDK.\n */\nconst THIRD_PARTY_IGNORE: RegExp[] = [\n /(?:^|\\/\\/)clerk\\./,\n /\\.clerk\\./,\n /\\.sentry\\./,\n /\\.intercom\\./,\n /\\.posthog\\./,\n /\\.googletagmanager\\.com/,\n /\\.google-analytics\\.com/,\n /\\.googleapis\\.com/,\n /\\.doubleclick\\.net/,\n /\\.facebook\\.com/,\n /\\.fbcdn\\.net/,\n /\\.analytics\\.google\\.com/,\n /px\\.ads\\.linkedin\\.com/,\n /[?&]_rsc=/,\n];\n\nconst NEVER_MATCH = /^$/;\nconst ESCAPE_RE = /[.*+?^${}()|[\\]\\\\]/g;\n\nfunction sameOriginPattern(): RegExp {\n if (typeof window === \"undefined\") {\n return NEVER_MATCH;\n }\n const { protocol, host } = window.location;\n return new RegExp(`^${protocol}//${host.replace(ESCAPE_RE, \"\\\\$&\")}`);\n}\n\nfunction stampInteractionAttrs(\n eventType: string,\n element: HTMLElement,\n span: Span\n): void {\n const desc = describeActionable(element);\n span.setAttribute(\"ui.event_type\", eventType);\n span.setAttribute(\"ui.target.tag\", desc.tag);\n if (desc.id) {\n span.setAttribute(\"ui.target.id\", desc.id);\n }\n if (desc.name) {\n span.setAttribute(\"ui.target.name\", desc.name);\n }\n if (desc.role) {\n span.setAttribute(\"ui.target.role\", desc.role);\n }\n if (desc.ariaLabel) {\n span.setAttribute(\"ui.target.aria_label\", desc.ariaLabel);\n }\n // Truncated visible label — useful for triage without exfiltrating\n // full DOM contents. Only meaningful on the direct target.\n if (desc.text) {\n span.setAttribute(\"ui.target.text\", desc.text);\n }\n}\n\nfunction stampUrlAttrs(\n span: Span,\n resolveRoute: ((pathname: string) => string | undefined) | undefined\n): void {\n if (typeof window === \"undefined\") {\n return;\n }\n const pathname = window.location.pathname;\n const route = resolveRoute?.(pathname);\n span.setAttribute(ATTR_URL_PATH, route ?? pathname);\n span.setAttribute(ATTR_URL_FULL, window.location.href);\n if (route) {\n span.setAttribute(ATTR_HTTP_ROUTE, route);\n }\n}\n\nexport interface InstrumentationsInput {\n /**\n * URLs the SDK exempts from `fetch` and `XHR` instrumentation —\n * typically our own ingest/OTLP endpoints, so the SDK doesn't trace\n * its own export requests in an infinite loop. Combined with the\n * `THIRD_PARTY_IGNORE` defaults and the customer's `ignoreUrls`.\n */\n ignoreUrls: (string | RegExp)[];\n /**\n * Customer-supplied URL patterns the fetch + XHR instrumentations\n * inject `traceparent` + `baggage` headers on. Same-origin requests\n * always propagate.\n */\n propagateContextUrls?: (string | RegExp)[];\n /**\n * Pathname → low-cardinality route template (e.g. `/blog/[slug]`).\n * Drives span renaming + `url.path` / `http.route` attrs across\n * fetch, document-load, user-interaction, and long-task.\n */\n resolveRoute?: (pathname: string) => string | undefined;\n /**\n * The kernel's private provider — instrumentations register against\n * it, not the global one, so customer OTel setups stay untouched.\n */\n tracerProvider: WebTracerProvider;\n}\n\n/**\n * Registers every browser auto-instrumentation against the kernel's\n * private provider. Every instrumentation is enriched with the same\n * route-template-aware URL attributes so dashboards can slice fetch /\n * interaction / long-task / resource-load by `http.route` without\n * cardinality blow-up from raw pathnames.\n *\n * Returns a disposer that unregisters everything; called by\n * `kernel.dispose()`.\n */\nexport function registerBundledInstrumentations(\n input: InstrumentationsInput\n): () => void {\n const { tracerProvider, ignoreUrls, propagateContextUrls = [] } = input;\n const resolveRoute = input.resolveRoute;\n const origin = sameOriginPattern();\n const fetchIgnore = [...ignoreUrls, ...THIRD_PARTY_IGNORE];\n\n return registerInstrumentations({\n tracerProvider,\n instrumentations: [\n new FetchInstrumentation({\n propagateTraceHeaderCorsUrls: [origin, ...propagateContextUrls],\n ignoreUrls: fetchIgnore,\n semconvStabilityOptIn: SEMCONV_STABILITY_OPT_IN,\n measureRequestSize: true,\n applyCustomAttributesOnSpan: (\n span: Span,\n request: Request | RequestInit\n ) => {\n const url =\n request instanceof Request ? request.url : request?.toString();\n if (typeof url !== \"string\") {\n return;\n }\n try {\n const parsed = new URL(url);\n span.setAttribute(ATTR_URL_PATH, parsed.pathname);\n const isTracked =\n origin.test(url) ||\n propagateContextUrls.some((re) =>\n re instanceof RegExp ? re.test(url) : url.includes(re)\n );\n if (isTracked) {\n const method =\n (request instanceof Request ? request.method : undefined) ??\n \"GET\";\n const route = resolveRoute?.(parsed.pathname);\n if (route) {\n span.setAttribute(ATTR_HTTP_ROUTE, route);\n }\n span.updateName(`${method} ${route ?? parsed.pathname}`);\n }\n } catch {\n return;\n }\n },\n }),\n new XMLHttpRequestInstrumentation({\n propagateTraceHeaderCorsUrls: [origin, ...propagateContextUrls],\n ignoreUrls: fetchIgnore,\n semconvStabilityOptIn: SEMCONV_STABILITY_OPT_IN,\n }),\n new DocumentLoadInstrumentation({\n semconvStabilityOptIn: SEMCONV_STABILITY_OPT_IN,\n // Default `resourceFetch` span name is the literal string\n // `\"resourceFetch\"` for every entry — useless when a single\n // page load emits 30 of them. Replace with the pathname (or\n // origin+path for cross-origin) so the waterfall is scannable.\n applyCustomAttributesOnSpan: {\n resourceFetch: (span, entry) => {\n const name = entry?.name;\n if (typeof name !== \"string\") {\n return;\n }\n try {\n const url = new URL(name);\n const isCrossOrigin =\n typeof window !== \"undefined\" &&\n url.origin !== window.location.origin;\n span.updateName(\n isCrossOrigin\n ? `resource: ${url.host}${url.pathname}`\n : `resource: ${url.pathname}`\n );\n span.setAttribute(ATTR_URL_FULL, name);\n span.setAttribute(ATTR_URL_PATH, url.pathname);\n span.setAttribute(\"server.address\", url.host);\n } catch {\n // Malformed/relative URL — leave the default name and\n // let the entry's own attributes carry whatever info\n // the SDK already stamped.\n }\n },\n },\n }),\n // `BrowserNavigationInstrumentation` emits a `browser.navigation`\n // log record per hard navigation (page load) and soft navigation\n // (history.pushState, hash change, back/forward). The default\n // sanitizer redacts credentials in the URL and common sensitive\n // query params (`token`, `api_key`, `secret`, …) before emit.\n new BrowserNavigationInstrumentation({\n sanitizeUrl: defaultSanitizeUrl,\n }),\n new UserInteractionInstrumentation({\n eventNames: [\"click\", \"submit\"],\n // Despite the name, `shouldPreventSpanCreation` is also the\n // hook for *enriching* spans (return falsy → create the span;\n // the callback may set attributes on the way through). We use\n // it as both: stamp a stable target descriptor for\n // dashboarding, then suppress spans on elements that aren't\n // actionable (scroll containers, body clicks, etc.).\n shouldPreventSpanCreation: (eventType, element, span) => {\n if (eventType === \"click\" && !isActionable(element)) {\n return true;\n }\n stampInteractionAttrs(eventType, element, span);\n stampUrlAttrs(span, resolveRoute);\n return false;\n },\n }),\n // Long-task spans default to a generic `longtask` name with\n // attribution embedded as attributes — but no page context.\n // Empty `url.path` makes it impossible to triage which routes\n // are jank-heavy. Stamp it in the observer callback so\n // dashboards can slice by route.\n new LongTaskInstrumentation({\n observerCallback: (span, info: ObserverCallbackInformation) => {\n stampUrlAttrs(span, resolveRoute);\n // PerformanceLongTaskTiming attribution[0].containerType is\n // the surface that hosted the offending task. Most are\n // `\"window\"` (main frame); the few that aren't (`\"iframe\"`,\n // `\"embed\"`, `\"object\"`) are the actionable ones — surface\n // them as a top-level attr instead of leaving them buried\n // in `longtask.attribution.container_type`.\n const containerType =\n info.longtaskEntry.attribution[0]?.containerType;\n if (containerType) {\n span.setAttribute(\"longtask.container_type\", containerType);\n }\n },\n }),\n ],\n });\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"page-scope-context-manager.d.mts","names":[],"sources":["../../../src/internal/otel/page-scope-context-manager.ts"],"mappings":";;;;;;AAyBA;;;;;;;;;;;;;;;;;;;cAAa,uBAAA,SAAgC,kBAAA;EAAA,QACnC,SAAA;EAER,YAAA,CAAa,GAAA,EAAK,OAAA;EAIT,MAAA,CAAA,GAAU,OAAA;AAAA"}
1
+ {"version":3,"file":"page-scope-context-manager.d.mts","names":[],"sources":["../../../src/internal/otel/page-scope-context-manager.ts"],"mappings":";;;;;;AAyBA;;;;;;;;;;;;;;;;AAO4B;;;cAPf,uBAAA,SAAgC,kBAAA;EAAA,QACnC,SAAA;EAER,YAAA,CAAa,GAAA,EAAK,OAAA;EAIT,MAAA,CAAA,GAAU,OAAA;AAAA"}
@@ -1,36 +1 @@
1
- import { ROOT_CONTEXT } from "@opentelemetry/api";
2
- import { ZoneContextManager } from "@opentelemetry/context-zone";
3
- //#region src/internal/otel/page-scope-context-manager.ts
4
- /**
5
- * `ZoneContextManager` returns `ROOT_CONTEXT` whenever `context.active()` is
6
- * called outside a zone the manager itself created — which in practice is
7
- * most of the time:
8
- *
9
- * - app code calling `fetch(...)` from a `useEffect`
10
- * - `PerformanceObserver` callbacks (long-task, paint timing, …)
11
- * - top-level await / module init code
12
- * - listeners attached before the SDK booted
13
- *
14
- * Spans created from those code paths default to "no parent" → root, which
15
- * is why a single page load produces N disjoint traces (one per
16
- * instrumentation) instead of one waterfall.
17
- *
18
- * This subclass adds a single fallback: if the underlying zone lookup yields
19
- * `ROOT_CONTEXT`, return the page-scope context instead. The page-scope
20
- * context is built once at SDK init from the `<meta name="traceparent">`
21
- * tag emitted by the SSR layout. If the meta tag is absent the page scope
22
- * stays at `ROOT_CONTEXT` and the manager behaves like a stock
23
- * `ZoneContextManager`.
24
- */
25
- var PageScopeContextManager = class extends ZoneContextManager {
26
- pageScope = ROOT_CONTEXT;
27
- setPageScope(ctx) {
28
- this.pageScope = ctx;
29
- }
30
- active() {
31
- const ctx = super.active();
32
- return ctx === ROOT_CONTEXT ? this.pageScope : ctx;
33
- }
34
- };
35
- //#endregion
36
- export { PageScopeContextManager };
1
+ import{ROOT_CONTEXT}from"@opentelemetry/api";import{ZoneContextManager}from"@opentelemetry/context-zone";var PageScopeContextManager=class extends ZoneContextManager{pageScope=ROOT_CONTEXT;setPageScope(ctx){this.pageScope=ctx}active(){let ctx=super.active();return ctx===ROOT_CONTEXT?this.pageScope:ctx}};export{PageScopeContextManager};
@@ -1 +1 @@
1
- {"version":3,"file":"page-scope-context-manager.mjs","names":[],"sources":["../../../src/internal/otel/page-scope-context-manager.ts"],"sourcesContent":["import type { Context } from \"@opentelemetry/api\";\nimport { ROOT_CONTEXT } from \"@opentelemetry/api\";\nimport { ZoneContextManager } from \"@opentelemetry/context-zone\";\n\n/**\n * `ZoneContextManager` returns `ROOT_CONTEXT` whenever `context.active()` is\n * called outside a zone the manager itself created — which in practice is\n * most of the time:\n *\n * - app code calling `fetch(...)` from a `useEffect`\n * - `PerformanceObserver` callbacks (long-task, paint timing, …)\n * - top-level await / module init code\n * - listeners attached before the SDK booted\n *\n * Spans created from those code paths default to \"no parent\" → root, which\n * is why a single page load produces N disjoint traces (one per\n * instrumentation) instead of one waterfall.\n *\n * This subclass adds a single fallback: if the underlying zone lookup yields\n * `ROOT_CONTEXT`, return the page-scope context instead. The page-scope\n * context is built once at SDK init from the `<meta name=\"traceparent\">`\n * tag emitted by the SSR layout. If the meta tag is absent the page scope\n * stays at `ROOT_CONTEXT` and the manager behaves like a stock\n * `ZoneContextManager`.\n */\nexport class PageScopeContextManager extends ZoneContextManager {\n private pageScope: Context = ROOT_CONTEXT;\n\n setPageScope(ctx: Context): void {\n this.pageScope = ctx;\n }\n\n override active(): Context {\n const ctx = super.active();\n return ctx === ROOT_CONTEXT ? this.pageScope : ctx;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAyBA,IAAa,0BAAb,cAA6C,mBAAmB;CAC9D,YAA6B;CAE7B,aAAa,KAAoB;EAC/B,KAAK,YAAY;;CAGnB,SAA2B;EACzB,MAAM,MAAM,MAAM,QAAQ;EAC1B,OAAO,QAAQ,eAAe,KAAK,YAAY"}
1
+ {"version":3,"file":"page-scope-context-manager.mjs","names":[],"sources":["../../../src/internal/otel/page-scope-context-manager.ts"],"sourcesContent":["import type { Context } from \"@opentelemetry/api\";\nimport { ROOT_CONTEXT } from \"@opentelemetry/api\";\nimport { ZoneContextManager } from \"@opentelemetry/context-zone\";\n\n/**\n * `ZoneContextManager` returns `ROOT_CONTEXT` whenever `context.active()` is\n * called outside a zone the manager itself created — which in practice is\n * most of the time:\n *\n * - app code calling `fetch(...)` from a `useEffect`\n * - `PerformanceObserver` callbacks (long-task, paint timing, …)\n * - top-level await / module init code\n * - listeners attached before the SDK booted\n *\n * Spans created from those code paths default to \"no parent\" → root, which\n * is why a single page load produces N disjoint traces (one per\n * instrumentation) instead of one waterfall.\n *\n * This subclass adds a single fallback: if the underlying zone lookup yields\n * `ROOT_CONTEXT`, return the page-scope context instead. The page-scope\n * context is built once at SDK init from the `<meta name=\"traceparent\">`\n * tag emitted by the SSR layout. If the meta tag is absent the page scope\n * stays at `ROOT_CONTEXT` and the manager behaves like a stock\n * `ZoneContextManager`.\n */\nexport class PageScopeContextManager extends ZoneContextManager {\n private pageScope: Context = ROOT_CONTEXT;\n\n setPageScope(ctx: Context): void {\n this.pageScope = ctx;\n }\n\n override active(): Context {\n const ctx = super.active();\n return ctx === ROOT_CONTEXT ? this.pageScope : ctx;\n }\n}\n"],"mappings":"yGAyBA,IAAa,wBAAb,cAA6C,kBAAmB,CAC9D,UAA6B,aAE7B,aAAa,IAAoB,CAC/B,KAAK,UAAY,GACnB,CAEA,QAA2B,CACzB,IAAM,IAAM,MAAM,OAAO,EACzB,OAAO,MAAQ,aAAe,KAAK,UAAY,GACjD,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"propagation.d.mts","names":[],"sources":["../../../src/internal/otel/propagation.ts"],"mappings":";;;;;AAuCA;;;;;;;;;;;;;iBAAgB,2BAAA,CAAA,GAA+B,OAAA"}
1
+ {"version":3,"file":"propagation.d.mts","names":[],"sources":["../../../src/internal/otel/propagation.ts"],"mappings":";;;;;AAuCA;;;;AAAsD;;;;;;;;;iBAAtC,2BAAA,CAAA,GAA+B,OAAO"}
@@ -1,40 +1 @@
1
- import { ROOT_CONTEXT, defaultTextMapGetter, trace } from "@opentelemetry/api";
2
- import { W3CTraceContextPropagator } from "@opentelemetry/core";
3
- //#region src/internal/otel/propagation.ts
4
- const TRACEPARENT_META = "traceparent";
5
- const TRACESTATE_META = "tracestate";
6
- const INVALID_TRACE_ID = "00000000000000000000000000000000";
7
- const TRACE_FLAGS_SAMPLED = 1;
8
- const W3C_PROPAGATOR = new W3CTraceContextPropagator();
9
- function readMeta(name) {
10
- if (typeof document === "undefined") return null;
11
- return document.querySelector(`meta[name="${name}"]`)?.getAttribute("content") ?? null;
12
- }
13
- /**
14
- * Reads the W3C `traceparent` (and optional `tracestate`) meta tag from the
15
- * document head and extracts an OTel `Context`. SSR renderers (Next, Vite,
16
- * …) inject the server-side request span's context so the client SDK can
17
- * stitch its spans onto the same trace.
18
- *
19
- * Returns `null` when:
20
- * - called server-side (no `document`)
21
- * - no `traceparent` meta tag is present
22
- * - the extracted context has an invalid trace id
23
- * - the `sampled` flag is unset — the browser doesn't honor the bit when
24
- * creating child spans, so an unsampled parent would orphan every
25
- * browser span under a trace with no recorded server segments. Drop
26
- * instead so spans fall back to a fresh root.
27
- */
28
- function readPropagationFromDocument() {
29
- const traceparent = readMeta(TRACEPARENT_META);
30
- if (!traceparent) return null;
31
- const carrier = { traceparent };
32
- const tracestate = readMeta(TRACESTATE_META);
33
- if (tracestate) carrier[TRACESTATE_META] = tracestate;
34
- const extracted = W3C_PROPAGATOR.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter);
35
- const spanCtx = trace.getSpanContext(extracted);
36
- if (!spanCtx || spanCtx.traceId === INVALID_TRACE_ID || (spanCtx.traceFlags & TRACE_FLAGS_SAMPLED) === 0) return null;
37
- return extracted;
38
- }
39
- //#endregion
40
- export { readPropagationFromDocument };
1
+ import{ROOT_CONTEXT,defaultTextMapGetter,trace}from"@opentelemetry/api";import{W3CTraceContextPropagator}from"@opentelemetry/core";const TRACESTATE_META=`tracestate`,W3C_PROPAGATOR=new W3CTraceContextPropagator;function readMeta(name){return typeof document>`u`?null:document.querySelector(`meta[name="${name}"]`)?.getAttribute(`content`)??null}function readPropagationFromDocument(){let traceparent=readMeta(`traceparent`);if(!traceparent)return null;let carrier={traceparent},tracestate=readMeta(TRACESTATE_META);tracestate&&(carrier[TRACESTATE_META]=tracestate);let extracted=W3C_PROPAGATOR.extract(ROOT_CONTEXT,carrier,defaultTextMapGetter),spanCtx=trace.getSpanContext(extracted);return!spanCtx||spanCtx.traceId===`00000000000000000000000000000000`||!(spanCtx.traceFlags&1)?null:extracted}export{readPropagationFromDocument};
@@ -1 +1 @@
1
- {"version":3,"file":"propagation.mjs","names":[],"sources":["../../../src/internal/otel/propagation.ts"],"sourcesContent":["import {\n type Context,\n defaultTextMapGetter,\n ROOT_CONTEXT,\n trace,\n} from \"@opentelemetry/api\";\nimport { W3CTraceContextPropagator } from \"@opentelemetry/core\";\n\nconst TRACEPARENT_META = \"traceparent\";\nconst TRACESTATE_META = \"tracestate\";\nconst INVALID_TRACE_ID = \"00000000000000000000000000000000\";\nconst TRACE_FLAGS_SAMPLED = 0x1;\n// Local instance — extraction must not depend on whether the customer (or\n// our own bootstrap) set a global propagator.\nconst W3C_PROPAGATOR = new W3CTraceContextPropagator();\n\nfunction readMeta(name: string): string | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n const el = document.querySelector(`meta[name=\"${name}\"]`);\n return el?.getAttribute(\"content\") ?? null;\n}\n\n/**\n * Reads the W3C `traceparent` (and optional `tracestate`) meta tag from the\n * document head and extracts an OTel `Context`. SSR renderers (Next, Vite,\n * …) inject the server-side request span's context so the client SDK can\n * stitch its spans onto the same trace.\n *\n * Returns `null` when:\n * - called server-side (no `document`)\n * - no `traceparent` meta tag is present\n * - the extracted context has an invalid trace id\n * - the `sampled` flag is unset — the browser doesn't honor the bit when\n * creating child spans, so an unsampled parent would orphan every\n * browser span under a trace with no recorded server segments. Drop\n * instead so spans fall back to a fresh root.\n */\nexport function readPropagationFromDocument(): Context | null {\n const traceparent = readMeta(TRACEPARENT_META);\n if (!traceparent) {\n return null;\n }\n\n const carrier: Record<string, string> = { traceparent };\n const tracestate = readMeta(TRACESTATE_META);\n if (tracestate) {\n carrier[TRACESTATE_META] = tracestate;\n }\n\n const extracted = W3C_PROPAGATOR.extract(\n ROOT_CONTEXT,\n carrier,\n defaultTextMapGetter\n );\n const spanCtx = trace.getSpanContext(extracted);\n // octet of flag bits per the W3C trace-context spec; bit 0 is the sampled\n // bit. Bitwise AND is the canonical extraction.\n if (\n !spanCtx ||\n spanCtx.traceId === INVALID_TRACE_ID ||\n // biome-ignore lint/suspicious/noBitwiseOperators: traceFlags is a single\n (spanCtx.traceFlags & TRACE_FLAGS_SAMPLED) === 0\n ) {\n return null;\n }\n return extracted;\n}\n"],"mappings":";;;AAQA,MAAM,mBAAmB;AACzB,MAAM,kBAAkB;AACxB,MAAM,mBAAmB;AACzB,MAAM,sBAAsB;AAG5B,MAAM,iBAAiB,IAAI,2BAA2B;AAEtD,SAAS,SAAS,MAA6B;CAC7C,IAAI,OAAO,aAAa,aACtB,OAAO;CAGT,OADW,SAAS,cAAc,cAAc,KAAK,IAC5C,EAAE,aAAa,UAAU,IAAI;;;;;;;;;;;;;;;;;AAkBxC,SAAgB,8BAA8C;CAC5D,MAAM,cAAc,SAAS,iBAAiB;CAC9C,IAAI,CAAC,aACH,OAAO;CAGT,MAAM,UAAkC,EAAE,aAAa;CACvD,MAAM,aAAa,SAAS,gBAAgB;CAC5C,IAAI,YACF,QAAQ,mBAAmB;CAG7B,MAAM,YAAY,eAAe,QAC/B,cACA,SACA,qBACD;CACD,MAAM,UAAU,MAAM,eAAe,UAAU;CAG/C,IACE,CAAC,WACD,QAAQ,YAAY,qBAEnB,QAAQ,aAAa,yBAAyB,GAE/C,OAAO;CAET,OAAO"}
1
+ {"version":3,"file":"propagation.mjs","names":[],"sources":["../../../src/internal/otel/propagation.ts"],"sourcesContent":["import {\n type Context,\n defaultTextMapGetter,\n ROOT_CONTEXT,\n trace,\n} from \"@opentelemetry/api\";\nimport { W3CTraceContextPropagator } from \"@opentelemetry/core\";\n\nconst TRACEPARENT_META = \"traceparent\";\nconst TRACESTATE_META = \"tracestate\";\nconst INVALID_TRACE_ID = \"00000000000000000000000000000000\";\nconst TRACE_FLAGS_SAMPLED = 0x1;\n// Local instance — extraction must not depend on whether the customer (or\n// our own bootstrap) set a global propagator.\nconst W3C_PROPAGATOR = new W3CTraceContextPropagator();\n\nfunction readMeta(name: string): string | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n const el = document.querySelector(`meta[name=\"${name}\"]`);\n return el?.getAttribute(\"content\") ?? null;\n}\n\n/**\n * Reads the W3C `traceparent` (and optional `tracestate`) meta tag from the\n * document head and extracts an OTel `Context`. SSR renderers (Next, Vite,\n * …) inject the server-side request span's context so the client SDK can\n * stitch its spans onto the same trace.\n *\n * Returns `null` when:\n * - called server-side (no `document`)\n * - no `traceparent` meta tag is present\n * - the extracted context has an invalid trace id\n * - the `sampled` flag is unset — the browser doesn't honor the bit when\n * creating child spans, so an unsampled parent would orphan every\n * browser span under a trace with no recorded server segments. Drop\n * instead so spans fall back to a fresh root.\n */\nexport function readPropagationFromDocument(): Context | null {\n const traceparent = readMeta(TRACEPARENT_META);\n if (!traceparent) {\n return null;\n }\n\n const carrier: Record<string, string> = { traceparent };\n const tracestate = readMeta(TRACESTATE_META);\n if (tracestate) {\n carrier[TRACESTATE_META] = tracestate;\n }\n\n const extracted = W3C_PROPAGATOR.extract(\n ROOT_CONTEXT,\n carrier,\n defaultTextMapGetter\n );\n const spanCtx = trace.getSpanContext(extracted);\n // octet of flag bits per the W3C trace-context spec; bit 0 is the sampled\n // bit. Bitwise AND is the canonical extraction.\n if (\n !spanCtx ||\n spanCtx.traceId === INVALID_TRACE_ID ||\n // biome-ignore lint/suspicious/noBitwiseOperators: traceFlags is a single\n (spanCtx.traceFlags & TRACE_FLAGS_SAMPLED) === 0\n ) {\n return null;\n }\n return extracted;\n}\n"],"mappings":"mIAQA,MACM,gBAAkB,aAKlB,eAAiB,IAAI,0BAE3B,SAAS,SAAS,KAA6B,CAK7C,OAJI,OAAO,SAAa,IACf,KAEE,SAAS,cAAc,cAAc,KAAK,GAC7C,GAAG,aAAa,SAAS,GAAK,IACxC,CAiBA,SAAgB,6BAA8C,CAC5D,IAAM,YAAc,SAAS,aAAgB,EAC7C,GAAI,CAAC,YACH,OAAO,KAGT,IAAM,QAAkC,CAAE,WAAY,EAChD,WAAa,SAAS,eAAe,EACvC,aACF,QAAQ,iBAAmB,YAG7B,IAAM,UAAY,eAAe,QAC/B,aACA,QACA,oBACF,EACM,QAAU,MAAM,eAAe,SAAS,EAW9C,MAPE,CAAC,SACD,QAAQ,UAAY,oCAAA,EAEnB,QAAQ,WAAa,GAEf,KAEF,SACT"}
@@ -40,8 +40,7 @@ interface OtelProviderInput {
40
40
  /**
41
41
  * Auth + content headers for OTLP exports. Sourced from the kernel's
42
42
  * already-resolved ingest target so the OTLP path inherits the same
43
- * `x-interfere-pub-token` (or proxy-mode auth) the rest of the SDK
44
- * uses — no separate auth knob.
43
+ * transport metadata the rest of the SDK uses — no separate auth knob.
45
44
  */
46
45
  authHeaders: Headers;
47
46
  /** OTLP base URL — the opaque sink path is appended by the exporters. */
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.mts","names":[],"sources":["../../../src/internal/otel/provider.ts"],"mappings":";;;;;;;;;UA0GiB,iBAAA;;AAAjB;;;;;;;;;EAWE,6BAAA,GAAgC,kBAAA;EA+CP;;;;;;;;;;EApCzB,uBAAA,GAA0B,YAAA;EAkC1B;;;;;;EA3BA,wBAAA,GAA2B,aAAA;EAwChB;AAGb;;;;;EApCE,WAAA,EAAa,OAAA;EA8CE;EA5Cf,YAAA;EA+CY;;;;;;;;;EArCZ,QAAA;EAkCA;;;;;;;EA1BA,YAAA,QAAoB,SAAA;EA8Ba;EA5BjC,WAAA,GAAc,WAAA;EAuCA;;;;;EAjCd,QAAA;EAmCC;;;;EA9BD,WAAA;AAAA;AAAA,UAGe,kBAAA;;;;;;EAMf,cAAA,EAAgB,uBAAA;;EAEhB,KAAA,IAAS,OAAA;EACT,cAAA,EAAgB,cAAA;EAChB,aAAA,EAAe,aAAA;EACf,YAAA,EAAc,YAAA;;EAEd,QAAA,IAAY,OAAA;EACZ,cAAA,EAAgB,iBAAA;AAAA;;;;;;;;;iBAWF,iBAAA,CACd,KAAA,EAAO,iBAAA,GACN,kBAAA"}
1
+ {"version":3,"file":"provider.d.mts","names":[],"sources":["../../../src/internal/otel/provider.ts"],"mappings":";;;;;;;;;UA0GiB,iBAAA;;AAAjB;;;;;;;;;EAWE,6BAAA,GAAgC,kBAAA;EA8CP;;;;;;;;;;EAnCzB,uBAAA,GAA0B,YAAA;EAiC1B;;;;;;EA1BA,wBAAA,GAA2B,aAAA;EAuChB;AAGb;;;;EApCE,WAAA,EAAa,OAAA;EA6CG;EA3ChB,YAAA;EA6Cc;;;;;;;;;EAnCd,QAAA;EAiCgB;;;;;;;EAzBhB,YAAA,QAAoB,SAAA;EA8BJ;EA5BhB,WAAA,GAAc,WAAA;EA4BmB;AAWnC;;;;EAjCE,QAAA;EAkCA;;;AACmB;EA9BnB,WAAA;AAAA;AAAA,UAGe,kBAAA;;;;;;EAMf,cAAA,EAAgB,uBAAA;;EAEhB,KAAA,IAAS,OAAA;EACT,cAAA,EAAgB,cAAA;EAChB,aAAA,EAAe,aAAA;EACf,YAAA,EAAc,YAAA;;EAEd,QAAA,IAAY,OAAA;EACZ,cAAA,EAAgB,iBAAA;AAAA;;;;;;;;;iBAWF,iBAAA,CACd,KAAA,EAAO,iBAAA,GACN,kBAAkB"}
@@ -1,151 +1 @@
1
- import { SDK_NAME, SDK_VERSION } from "../version.mjs";
2
- import { createBeaconLogExporter, createBeaconMetricExporter, createBeaconTraceExporter } from "./exporter.mjs";
3
- import { PageScopeContextManager } from "./page-scope-context-manager.mjs";
4
- import { propagation } from "@opentelemetry/api";
5
- import { CompositePropagator, W3CBaggagePropagator, W3CTraceContextPropagator } from "@opentelemetry/core";
6
- import { MeterProvider, PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
7
- import { normalizeEnv } from "@interfere/types/sdk/runtime";
8
- import { browserDetector } from "@opentelemetry/opentelemetry-browser-detector";
9
- import { detectResources, resourceFromAttributes } from "@opentelemetry/resources";
10
- import { BatchLogRecordProcessor, LoggerProvider } from "@opentelemetry/sdk-logs";
11
- import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
12
- import { WebTracerProvider } from "@opentelemetry/sdk-trace-web";
13
- import { createSessionLogRecordProcessor, createSessionSpanProcessor } from "@opentelemetry/web-common";
14
- //#region src/internal/otel/provider.ts
15
- const SERVICE_NAMESPACE = "interfere";
16
- const ATTR_SERVICE_NAME = "service.name";
17
- const ATTR_SERVICE_NAMESPACE = "service.namespace";
18
- const ATTR_DEPLOYMENT_ENVIRONMENT_NAME = "deployment.environment.name";
19
- const ATTR_TELEMETRY_SDK_LANGUAGE = "telemetry.sdk.language";
20
- const ATTR_RELEASE_SLUG = "release.slug";
21
- const ATTR_INTERFERE_SDK_STACK = "interfere.sdk.stack";
22
- const ATTR_INTERFERE_SDK_NAME = "interfere.sdk.name";
23
- const ATTR_INTERFERE_SDK_VERSION = "interfere.sdk.version";
24
- const ATTR_DEVICE_ID = "device.id";
25
- const DEFAULT_SERVICE_NAME = "interfere-sdk";
26
- /**
27
- * Tuned for `navigator.sendBeacon`'s per-call payload ceiling.
28
- *
29
- * The browser primary exporters dispatch every export via beacon
30
- * (see `BeaconTraceExporter` / `BeaconLogExporter` /
31
- * `BeaconMetricExporter` in `exporter.ts`) — sendBeacon is the only
32
- * browser transport that reliably commits a request the page is also
33
- * tearing down. It's not free though: most browsers cap each beacon
34
- * payload at 64KiB (Chrome / Firefox) and reject anything larger
35
- * with a `false` return from `navigator.sendBeacon` — at which point
36
- * the BSP just drops the batch (no retry: the SW backstop intercepts
37
- * 5xx / network failures, not user-agent rejections).
38
- *
39
- * The numbers below keep payloads comfortably under that ceiling,
40
- * even on jank-heavy pages (production data on 2026-05-11 saw 831
41
- * `longtask` spans piled up on a single page-hide, observed via the
42
- * BetterStack dual-write) where a 100-span batch would already top
43
- * 100KiB:
44
- *
45
- * - `maxExportBatchSize: 10` — caps each beacon at ~10–20KiB,
46
- * leaving headroom for span attribute bloat without flirting
47
- * with the per-call ceiling.
48
- * - `maxQueueSize: 50` — caps the worst-case unload payload at
49
- * ~50–100KiB; the BSP drains across 5 beacons when forced-
50
- * flushed on `visibilitychange→hidden`, all of which queue
51
- * synchronously inside the user agent.
52
- * - `scheduledDelayMillis: 2000` — quieter pages keep less in
53
- * buffer at any moment, so a hidden→visible→hidden bounce
54
- * doesn't accumulate 5s of telemetry waiting to ship.
55
- * - `exportTimeoutMillis: 10_000` — unchanged. Beacon dispatches
56
- * are essentially synchronous (the user agent enqueues into its
57
- * own send loop), so the timeout is mostly defensive against
58
- * pathological `JsonTraceSerializer.serializeRequest` calls.
59
- */
60
- const BROWSER_BATCH_OPTIONS = {
61
- maxQueueSize: 50,
62
- maxExportBatchSize: 10,
63
- scheduledDelayMillis: 2e3,
64
- exportTimeoutMillis: 1e4
65
- };
66
- /**
67
- * Constructs the SDK's **private** OTel providers — never registers globally
68
- * via `provider.register()` or `trace.setGlobalTracerProvider()`. Customers
69
- * with their own OTel setup (DataDog, Vercel, etc.) cohabit cleanly.
70
- *
71
- * Splitting this out from `Kernel` keeps the OTel module lazy-loadable so
72
- * the error-only bundle path (no tracing) never imports the OTel SDK.
73
- */
74
- function buildOtelProvider(input) {
75
- const environment = normalizeEnv(typeof process === "undefined" ? void 0 : process.env["NODE_ENV"]) ?? "unknown";
76
- const baseResource = resourceFromAttributes({
77
- [ATTR_SERVICE_NAME]: input.serviceName ?? DEFAULT_SERVICE_NAME,
78
- [ATTR_SERVICE_NAMESPACE]: SERVICE_NAMESPACE,
79
- [ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: environment,
80
- [ATTR_TELEMETRY_SDK_LANGUAGE]: "webjs",
81
- [ATTR_INTERFERE_SDK_NAME]: SDK_NAME,
82
- [ATTR_INTERFERE_SDK_VERSION]: SDK_VERSION,
83
- [ATTR_INTERFERE_SDK_STACK]: input.sdkStack.join(", "),
84
- ...input.releaseSlug ? { [ATTR_RELEASE_SLUG]: input.releaseSlug } : {},
85
- ...input.deviceId ? { [ATTR_DEVICE_ID]: input.deviceId } : {}
86
- });
87
- const detected = detectResources({ detectors: [browserDetector] });
88
- const resource = baseResource.merge(detected);
89
- const traceExporter = createBeaconTraceExporter({
90
- collectorUrl: input.collectorUrl,
91
- authHeaders: input.authHeaders
92
- });
93
- const getSessionId = input.getSessionId;
94
- const tracerProvider = new WebTracerProvider({
95
- resource,
96
- spanProcessors: [
97
- createSessionSpanProcessor({ getSessionId }),
98
- new BatchSpanProcessor(traceExporter, BROWSER_BATCH_OPTIONS),
99
- ...input.additionalSpanProcessors ?? []
100
- ]
101
- });
102
- const contextManager = new PageScopeContextManager();
103
- tracerProvider.register({ contextManager });
104
- if (propagation.fields().length === 0) propagation.setGlobalPropagator(new CompositePropagator({ propagators: [new W3CTraceContextPropagator(), new W3CBaggagePropagator()] }));
105
- const metricReader = new PeriodicExportingMetricReader({
106
- exporter: createBeaconMetricExporter({
107
- collectorUrl: input.collectorUrl,
108
- authHeaders: input.authHeaders
109
- }),
110
- exportIntervalMillis: 3e4
111
- });
112
- const meterProvider = new MeterProvider({
113
- resource,
114
- readers: [metricReader, ...input.additionalMetricReaders ?? []]
115
- });
116
- const logExporter = createBeaconLogExporter({
117
- collectorUrl: input.collectorUrl,
118
- authHeaders: input.authHeaders
119
- });
120
- const loggerProvider = new LoggerProvider({
121
- resource,
122
- processors: [
123
- createSessionLogRecordProcessor({ getSessionId }),
124
- new BatchLogRecordProcessor(logExporter, BROWSER_BATCH_OPTIONS),
125
- ...input.additionalLogRecordProcessors ?? []
126
- ]
127
- });
128
- return {
129
- contextManager,
130
- tracerProvider,
131
- meterProvider,
132
- metricReader,
133
- loggerProvider,
134
- flush: async () => {
135
- await Promise.all([
136
- tracerProvider.forceFlush(),
137
- metricReader.forceFlush(),
138
- loggerProvider.forceFlush()
139
- ]);
140
- },
141
- shutdown: async () => {
142
- await Promise.all([
143
- tracerProvider.shutdown(),
144
- meterProvider.shutdown(),
145
- loggerProvider.shutdown()
146
- ]);
147
- }
148
- };
149
- }
150
- //#endregion
151
- export { buildOtelProvider };
1
+ import{SDK_NAME,SDK_VERSION}from"../version.mjs";import{createBeaconLogExporter,createBeaconMetricExporter,createBeaconTraceExporter}from"./exporter.mjs";import{PageScopeContextManager}from"./page-scope-context-manager.mjs";import{propagation}from"@opentelemetry/api";import{CompositePropagator,W3CBaggagePropagator,W3CTraceContextPropagator}from"@opentelemetry/core";import{MeterProvider,PeriodicExportingMetricReader}from"@opentelemetry/sdk-metrics";import{normalizeEnv}from"@interfere/types/sdk/runtime";import{browserDetector}from"@opentelemetry/opentelemetry-browser-detector";import{detectResources,resourceFromAttributes}from"@opentelemetry/resources";import{BatchLogRecordProcessor,LoggerProvider}from"@opentelemetry/sdk-logs";import{BatchSpanProcessor}from"@opentelemetry/sdk-trace-base";import{WebTracerProvider}from"@opentelemetry/sdk-trace-web";import{createSessionLogRecordProcessor,createSessionSpanProcessor}from"@opentelemetry/web-common";const BROWSER_BATCH_OPTIONS={maxQueueSize:50,maxExportBatchSize:10,scheduledDelayMillis:2e3,exportTimeoutMillis:1e4};function buildOtelProvider(input){let environment=normalizeEnv(typeof process>`u`?void 0:process.env.NODE_ENV)??`unknown`,baseResource=resourceFromAttributes({"service.name":input.serviceName??`interfere-sdk`,"service.namespace":`interfere`,"deployment.environment.name":environment,"telemetry.sdk.language":`webjs`,"interfere.sdk.name":SDK_NAME,"interfere.sdk.version":SDK_VERSION,"interfere.sdk.stack":input.sdkStack.join(`, `),...input.releaseSlug?{"release.slug":input.releaseSlug}:{},...input.deviceId?{"device.id":input.deviceId}:{}}),detected=detectResources({detectors:[browserDetector]}),resource=baseResource.merge(detected),traceExporter=createBeaconTraceExporter({collectorUrl:input.collectorUrl,authHeaders:input.authHeaders}),getSessionId=input.getSessionId,tracerProvider=new WebTracerProvider({resource,spanProcessors:[createSessionSpanProcessor({getSessionId}),new BatchSpanProcessor(traceExporter,BROWSER_BATCH_OPTIONS),...input.additionalSpanProcessors??[]]}),contextManager=new PageScopeContextManager;tracerProvider.register({contextManager}),propagation.fields().length===0&&propagation.setGlobalPropagator(new CompositePropagator({propagators:[new W3CTraceContextPropagator,new W3CBaggagePropagator]}));let metricReader=new PeriodicExportingMetricReader({exporter:createBeaconMetricExporter({collectorUrl:input.collectorUrl,authHeaders:input.authHeaders}),exportIntervalMillis:3e4}),meterProvider=new MeterProvider({resource,readers:[metricReader,...input.additionalMetricReaders??[]]}),logExporter=createBeaconLogExporter({collectorUrl:input.collectorUrl,authHeaders:input.authHeaders}),loggerProvider=new LoggerProvider({resource,processors:[createSessionLogRecordProcessor({getSessionId}),new BatchLogRecordProcessor(logExporter,BROWSER_BATCH_OPTIONS),...input.additionalLogRecordProcessors??[]]});return{contextManager,tracerProvider,meterProvider,metricReader,loggerProvider,flush:async()=>{await Promise.all([tracerProvider.forceFlush(),metricReader.forceFlush(),loggerProvider.forceFlush()])},shutdown:async()=>{await Promise.all([tracerProvider.shutdown(),meterProvider.shutdown(),loggerProvider.shutdown()])}}}export{buildOtelProvider};
@@ -1 +1 @@
1
- {"version":3,"file":"provider.mjs","names":[],"sources":["../../../src/internal/otel/provider.ts"],"sourcesContent":["import type { SessionId } from \"@interfere/types/data/session\";\nimport type { ReleaseSlug } from \"@interfere/types/releases/slug\";\nimport { normalizeEnv } from \"@interfere/types/sdk/runtime\";\n\nimport { propagation } from \"@opentelemetry/api\";\nimport {\n CompositePropagator,\n W3CBaggagePropagator,\n W3CTraceContextPropagator,\n} from \"@opentelemetry/core\";\nimport { browserDetector } from \"@opentelemetry/opentelemetry-browser-detector\";\nimport {\n detectResources,\n resourceFromAttributes,\n} from \"@opentelemetry/resources\";\nimport {\n BatchLogRecordProcessor,\n LoggerProvider,\n type LogRecordProcessor,\n} from \"@opentelemetry/sdk-logs\";\nimport {\n MeterProvider,\n type MetricReader,\n PeriodicExportingMetricReader,\n} from \"@opentelemetry/sdk-metrics\";\nimport {\n BatchSpanProcessor,\n type SpanProcessor,\n} from \"@opentelemetry/sdk-trace-base\";\nimport { WebTracerProvider } from \"@opentelemetry/sdk-trace-web\";\nimport {\n createSessionLogRecordProcessor,\n createSessionSpanProcessor,\n} from \"@opentelemetry/web-common\";\n\nimport { SDK_NAME, SDK_VERSION } from \"../version.js\";\nimport {\n createBeaconLogExporter,\n createBeaconMetricExporter,\n createBeaconTraceExporter,\n} from \"./exporter.js\";\nimport { PageScopeContextManager } from \"./page-scope-context-manager.js\";\n\nconst SERVICE_NAMESPACE = \"interfere\";\n\n// Inlined wire keys — matches the pattern in\n// `@interfere/observability/browser/rum` (semconv keeps shifting these\n// between minor versions, but the wire keys themselves are stable).\nconst ATTR_SERVICE_NAME = \"service.name\" as const;\nconst ATTR_SERVICE_NAMESPACE = \"service.namespace\" as const;\nconst ATTR_DEPLOYMENT_ENVIRONMENT_NAME = \"deployment.environment.name\" as const;\nconst ATTR_TELEMETRY_SDK_LANGUAGE = \"telemetry.sdk.language\" as const;\nconst ATTR_RELEASE_SLUG = \"release.slug\" as const;\nconst ATTR_INTERFERE_SDK_STACK = \"interfere.sdk.stack\" as const;\nconst ATTR_INTERFERE_SDK_NAME = \"interfere.sdk.name\" as const;\nconst ATTR_INTERFERE_SDK_VERSION = \"interfere.sdk.version\" as const;\n// OTel semconv-canonical name for a stable per-device identifier.\n// Stamped as a *resource* attribute (not per-span) because it's stable\n// for the lifetime of the page; sessions rotate, devices don't. The\n// collector reads this off `context.resourceAttributes[\"device.id\"]`\n// and projects it into `spans.deviceId`.\nconst ATTR_DEVICE_ID = \"device.id\" as const;\n\nconst DEFAULT_SERVICE_NAME = \"interfere-sdk\";\n\n/**\n * Tuned for `navigator.sendBeacon`'s per-call payload ceiling.\n *\n * The browser primary exporters dispatch every export via beacon\n * (see `BeaconTraceExporter` / `BeaconLogExporter` /\n * `BeaconMetricExporter` in `exporter.ts`) — sendBeacon is the only\n * browser transport that reliably commits a request the page is also\n * tearing down. It's not free though: most browsers cap each beacon\n * payload at 64KiB (Chrome / Firefox) and reject anything larger\n * with a `false` return from `navigator.sendBeacon` — at which point\n * the BSP just drops the batch (no retry: the SW backstop intercepts\n * 5xx / network failures, not user-agent rejections).\n *\n * The numbers below keep payloads comfortably under that ceiling,\n * even on jank-heavy pages (production data on 2026-05-11 saw 831\n * `longtask` spans piled up on a single page-hide, observed via the\n * BetterStack dual-write) where a 100-span batch would already top\n * 100KiB:\n *\n * - `maxExportBatchSize: 10` — caps each beacon at ~10–20KiB,\n * leaving headroom for span attribute bloat without flirting\n * with the per-call ceiling.\n * - `maxQueueSize: 50` — caps the worst-case unload payload at\n * ~50–100KiB; the BSP drains across 5 beacons when forced-\n * flushed on `visibilitychange→hidden`, all of which queue\n * synchronously inside the user agent.\n * - `scheduledDelayMillis: 2000` — quieter pages keep less in\n * buffer at any moment, so a hidden→visible→hidden bounce\n * doesn't accumulate 5s of telemetry waiting to ship.\n * - `exportTimeoutMillis: 10_000` — unchanged. Beacon dispatches\n * are essentially synchronous (the user agent enqueues into its\n * own send loop), so the timeout is mostly defensive against\n * pathological `JsonTraceSerializer.serializeRequest` calls.\n */\nconst BROWSER_BATCH_OPTIONS = {\n maxQueueSize: 50,\n maxExportBatchSize: 10,\n scheduledDelayMillis: 2000,\n exportTimeoutMillis: 10_000,\n} as const;\n\nexport interface OtelProviderInput {\n /**\n * @internal\n *\n * Extra log-record processors fanned into the LoggerProvider's\n * processor list at construction. Used by `@interfere/observability`\n * for internal-only dual-write to BetterStack — keeps a parallel\n * destination's queue/exporter independent of the SDK's own.\n * Customers don't get a fan-out hook on the SDK surface; this is a\n * private bridge for our own dogfood apps.\n */\n additionalLogRecordProcessors?: LogRecordProcessor[];\n /**\n * @internal\n *\n * Extra metric readers fanned into the MeterProvider's reader list\n * at construction. Used by `@interfere/observability` for internal-\n * only dual-write of web vitals histograms (`web_vitals.{ttfb,fcp,\n * lcp,inp,cls}`) to the BetterStack-fronting OTel collector. Each\n * reader owns its own queue + exporter so a 5xx / network outage on\n * the parallel destination backs off only its own batch.\n */\n additionalMetricReaders?: MetricReader[];\n /**\n * @internal\n *\n * Extra span processors fanned into the WebTracerProvider's processor\n * list at construction. See `additionalLogRecordProcessors`.\n */\n additionalSpanProcessors?: SpanProcessor[];\n /**\n * Auth + content headers for OTLP exports. Sourced from the kernel's\n * already-resolved ingest target so the OTLP path inherits the same\n * `x-interfere-pub-token` (or proxy-mode auth) the rest of the SDK\n * uses — no separate auth knob.\n */\n authHeaders: Headers;\n /** OTLP base URL — the opaque sink path is appended by the exporters. */\n collectorUrl: string;\n /**\n * Stable per-device identifier from `DeviceManager`. Resolved from\n * localStorage / cookie at kernel boot, so it's synchronously\n * available before the providers are constructed. Stamped as the\n * OTel-semconv `device.id` resource attribute so every span / log /\n * metric carries it without per-record re-stamping. Optional —\n * tests and SSR boot paths that build the provider before the\n * device manager has run pass `null`.\n */\n deviceId?: string | null | undefined;\n /**\n * Returns the kernel's current session id. Wired into per-span /\n * per-log session processors so a mid-page session rotation (30-min\n * idle expiry, manual reset) lands on subsequent spans without the\n * kernel having to rebuild the providers. Returns `null` before the\n * `SessionTracker` has bootstrapped.\n */\n getSessionId: () => SessionId | null;\n /** Optional release slug — top-level `release.slug` attr (Phase 6 wire identity). */\n releaseSlug?: ReleaseSlug | null | undefined;\n /**\n * Producer chain for the `interfere.sdk.stack` resource attribute —\n * e.g. `[\"@interfere/next@10.0.0\", \"@interfere/react@10.0.0\"]`.\n * Wrapper-injected; the kernel just forwards.\n */\n sdkStack: string[];\n /**\n * Override the OTel `service.name` resource attribute. Defaults to\n * `\"interfere-sdk\"`.\n */\n serviceName?: string;\n}\n\nexport interface OtelProviderHandle {\n /**\n * Page-scope context manager. The kernel calls `setPageScope(ctx)` after\n * extracting the SSR `traceparent` meta tag so spans without a more\n * specific zone descend from the server-side parent.\n */\n contextManager: PageScopeContextManager;\n /** Force-flush all three providers — call from kernel.flush() / on visibility hidden. */\n flush(): Promise<void>;\n loggerProvider: LoggerProvider;\n meterProvider: MeterProvider;\n metricReader: MetricReader;\n /** Tear down all three providers — called from kernel.dispose(). */\n shutdown(): Promise<void>;\n tracerProvider: WebTracerProvider;\n}\n\n/**\n * Constructs the SDK's **private** OTel providers — never registers globally\n * via `provider.register()` or `trace.setGlobalTracerProvider()`. Customers\n * with their own OTel setup (DataDog, Vercel, etc.) cohabit cleanly.\n *\n * Splitting this out from `Kernel` keeps the OTel module lazy-loadable so\n * the error-only bundle path (no tracing) never imports the OTel SDK.\n */\nexport function buildOtelProvider(\n input: OtelProviderInput\n): OtelProviderHandle {\n // Static service identity merged with detected browser attrs\n // (`browser.brands`, `browser.platform`, `browser.mobile`,\n // `browser.language`, `browser.user_agent`). The browser detector\n // reads UA Client Hints synchronously via `navigator.userAgentData`\n // low-entropy properties, so this stays sync — async would race\n // `DocumentLoadInstrumentation` and consistently miss page-load.\n const environment =\n normalizeEnv(\n typeof process === \"undefined\" ? undefined : process.env[\"NODE_ENV\"]\n ) ?? \"unknown\";\n\n const baseResource = resourceFromAttributes({\n [ATTR_SERVICE_NAME]: input.serviceName ?? DEFAULT_SERVICE_NAME,\n [ATTR_SERVICE_NAMESPACE]: SERVICE_NAMESPACE,\n [ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: environment,\n [ATTR_TELEMETRY_SDK_LANGUAGE]: \"webjs\",\n [ATTR_INTERFERE_SDK_NAME]: SDK_NAME,\n [ATTR_INTERFERE_SDK_VERSION]: SDK_VERSION,\n [ATTR_INTERFERE_SDK_STACK]: input.sdkStack.join(\", \"),\n ...(input.releaseSlug ? { [ATTR_RELEASE_SLUG]: input.releaseSlug } : {}),\n ...(input.deviceId ? { [ATTR_DEVICE_ID]: input.deviceId } : {}),\n });\n const detected = detectResources({ detectors: [browserDetector] });\n const resource = baseResource.merge(detected);\n\n const traceExporter = createBeaconTraceExporter({\n collectorUrl: input.collectorUrl,\n authHeaders: input.authHeaders,\n });\n\n // The web-common session processor expects `() => string | null`,\n // matching our `KernelSession.getId` shape.\n const getSessionId = input.getSessionId;\n\n const spanProcessors: SpanProcessor[] = [\n // Stamps `session.id` per-span, re-reading on every export. A\n // mid-page session rotation (30-min idle, manual reset) lands on\n // subsequent spans without rebuilding the provider. Resource-level\n // `session.id` would freeze at boot.\n createSessionSpanProcessor({ getSessionId }),\n // Exception attribute defaults (`interfere.exception.{mechanism,\n // handled,kind}`) are no longer stamped here — third-party\n // auto-instrumentations bypass our kernel anyway, so the SDK\n // can't reliably tell what to default. Server-side enrichment\n // (`enrichment/lib/normalize-atom.ts`) is the single chokepoint\n // every exception event flows through, so the defaults live\n // there now and the SDK ships less code.\n new BatchSpanProcessor(traceExporter, BROWSER_BATCH_OPTIONS),\n // Internal-only fan-out (BetterStack dual-write for `interfere/homepage`\n // + `interfere/dashboard`). Each extra processor owns its own queue +\n // exporter, so a 5xx / network outage on the parallel destination\n // backs off only its own batch — the primary collector pipeline keeps\n // draining unaffected.\n ...(input.additionalSpanProcessors ?? []),\n ];\n\n const tracerProvider = new WebTracerProvider({ resource, spanProcessors });\n\n // `PageScopeContextManager` keeps the active context alive across\n // microtasks/promise chains/setTimeout, AND falls back to the page-scope\n // context (the SSR `traceparent`) for code paths that fire outside any\n // zone the manager itself created. The kernel populates the page scope\n // by calling `contextManager.setPageScope(ctx)` after extracting the\n // meta tag.\n //\n // `register({ contextManager })` does call `setGlobalContextManager`\n // internally — that's unavoidable; OTel exposes exactly one global\n // context manager. Customers with their own OTel provider boot last and\n // win. We accept the trade-off for correctness: the alternative\n // (separate per-provider context manager) is not supported by OTel.\n const contextManager = new PageScopeContextManager();\n tracerProvider.register({ contextManager });\n\n // Composed W3C trace context + baggage propagator. `FetchInstrumentation`\n // injects both `traceparent` and `baggage` on outgoing requests so\n // backend Elysia plugins can pick `interfere.*` baggage entries off\n // the request and stamp them on server spans. Only set the global if\n // no propagator is currently registered (`fields()` is `[]` for the\n // noop). Customers who installed their own propagator (B3, composite,\n // …) are preserved. Reading the SSR meta tag uses a local instance,\n // not the global, so our extract path is independent.\n if (propagation.fields().length === 0) {\n propagation.setGlobalPropagator(\n new CompositePropagator({\n propagators: [\n new W3CTraceContextPropagator(),\n new W3CBaggagePropagator(),\n ],\n })\n );\n }\n\n const metricExporter = createBeaconMetricExporter({\n collectorUrl: input.collectorUrl,\n authHeaders: input.authHeaders,\n });\n\n const metricReader = new PeriodicExportingMetricReader({\n exporter: metricExporter,\n exportIntervalMillis: 30_000,\n });\n\n const meterProvider = new MeterProvider({\n resource,\n readers: [metricReader, ...(input.additionalMetricReaders ?? [])],\n });\n\n // Logs path. The `plugins/logs.ts` plugin patches `console.*` and emits\n // a `LogRecord` per call (errorsPlugin still owns Error-bearing console\n // calls — the class boundary is checked there). LoggerProvider is\n // private; the kernel exposes `recordLog` so callers don't have to\n // touch the OTel logs API directly.\n const logExporter = createBeaconLogExporter({\n collectorUrl: input.collectorUrl,\n authHeaders: input.authHeaders,\n });\n const loggerProvider = new LoggerProvider({\n resource,\n processors: [\n // Mirrors the SessionSpanProcessor for traces — every log record\n // (including `BrowserNavigationInstrumentation`'s navigation\n // events) carries the same `session.id` as the spans emitted\n // around it, so trace ↔ log correlation by session is trivial.\n createSessionLogRecordProcessor({ getSessionId }),\n new BatchLogRecordProcessor(logExporter, BROWSER_BATCH_OPTIONS),\n ...(input.additionalLogRecordProcessors ?? []),\n ],\n });\n\n return {\n contextManager,\n tracerProvider,\n meterProvider,\n metricReader,\n loggerProvider,\n flush: async () => {\n await Promise.all([\n tracerProvider.forceFlush(),\n metricReader.forceFlush(),\n loggerProvider.forceFlush(),\n ]);\n },\n shutdown: async () => {\n await Promise.all([\n tracerProvider.shutdown(),\n meterProvider.shutdown(),\n loggerProvider.shutdown(),\n ]);\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;AA2CA,MAAM,oBAAoB;AAK1B,MAAM,oBAAoB;AAC1B,MAAM,yBAAyB;AAC/B,MAAM,mCAAmC;AACzC,MAAM,8BAA8B;AACpC,MAAM,oBAAoB;AAC1B,MAAM,2BAA2B;AACjC,MAAM,0BAA0B;AAChC,MAAM,6BAA6B;AAMnC,MAAM,iBAAiB;AAEvB,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoC7B,MAAM,wBAAwB;CAC5B,cAAc;CACd,oBAAoB;CACpB,sBAAsB;CACtB,qBAAqB;CACtB;;;;;;;;;AAmGD,SAAgB,kBACd,OACoB;CAOpB,MAAM,cACJ,aACE,OAAO,YAAY,cAAc,KAAA,IAAY,QAAQ,IAAI,YAC1D,IAAI;CAEP,MAAM,eAAe,uBAAuB;GACzC,oBAAoB,MAAM,eAAe;GACzC,yBAAyB;GACzB,mCAAmC;GACnC,8BAA8B;GAC9B,0BAA0B;GAC1B,6BAA6B;GAC7B,2BAA2B,MAAM,SAAS,KAAK,KAAK;EACrD,GAAI,MAAM,cAAc,GAAG,oBAAoB,MAAM,aAAa,GAAG,EAAE;EACvE,GAAI,MAAM,WAAW,GAAG,iBAAiB,MAAM,UAAU,GAAG,EAAE;EAC/D,CAAC;CACF,MAAM,WAAW,gBAAgB,EAAE,WAAW,CAAC,gBAAgB,EAAE,CAAC;CAClE,MAAM,WAAW,aAAa,MAAM,SAAS;CAE7C,MAAM,gBAAgB,0BAA0B;EAC9C,cAAc,MAAM;EACpB,aAAa,MAAM;EACpB,CAAC;CAIF,MAAM,eAAe,MAAM;CAwB3B,MAAM,iBAAiB,IAAI,kBAAkB;EAAE;EAAU,gBAAA;GAjBvD,2BAA2B,EAAE,cAAc,CAAC;GAQ5C,IAAI,mBAAmB,eAAe,sBAAsB;GAM5D,GAAI,MAAM,4BAA4B,EAAE;GAG6B;EAAE,CAAC;CAc1E,MAAM,iBAAiB,IAAI,yBAAyB;CACpD,eAAe,SAAS,EAAE,gBAAgB,CAAC;CAU3C,IAAI,YAAY,QAAQ,CAAC,WAAW,GAClC,YAAY,oBACV,IAAI,oBAAoB,EACtB,aAAa,CACX,IAAI,2BAA2B,EAC/B,IAAI,sBAAsB,CAC3B,EACF,CAAC,CACH;CAQH,MAAM,eAAe,IAAI,8BAA8B;EACrD,UANqB,2BAA2B;GAChD,cAAc,MAAM;GACpB,aAAa,MAAM;GACpB,CAGyB;EACxB,sBAAsB;EACvB,CAAC;CAEF,MAAM,gBAAgB,IAAI,cAAc;EACtC;EACA,SAAS,CAAC,cAAc,GAAI,MAAM,2BAA2B,EAAE,CAAE;EAClE,CAAC;CAOF,MAAM,cAAc,wBAAwB;EAC1C,cAAc,MAAM;EACpB,aAAa,MAAM;EACpB,CAAC;CACF,MAAM,iBAAiB,IAAI,eAAe;EACxC;EACA,YAAY;GAKV,gCAAgC,EAAE,cAAc,CAAC;GACjD,IAAI,wBAAwB,aAAa,sBAAsB;GAC/D,GAAI,MAAM,iCAAiC,EAAE;GAC9C;EACF,CAAC;CAEF,OAAO;EACL;EACA;EACA;EACA;EACA;EACA,OAAO,YAAY;GACjB,MAAM,QAAQ,IAAI;IAChB,eAAe,YAAY;IAC3B,aAAa,YAAY;IACzB,eAAe,YAAY;IAC5B,CAAC;;EAEJ,UAAU,YAAY;GACpB,MAAM,QAAQ,IAAI;IAChB,eAAe,UAAU;IACzB,cAAc,UAAU;IACxB,eAAe,UAAU;IAC1B,CAAC;;EAEL"}
1
+ {"version":3,"file":"provider.mjs","names":[],"sources":["../../../src/internal/otel/provider.ts"],"sourcesContent":["import type { SessionId } from \"@interfere/types/data/session\";\nimport type { ReleaseSlug } from \"@interfere/types/releases/slug\";\nimport { normalizeEnv } from \"@interfere/types/sdk/runtime\";\n\nimport { propagation } from \"@opentelemetry/api\";\nimport {\n CompositePropagator,\n W3CBaggagePropagator,\n W3CTraceContextPropagator,\n} from \"@opentelemetry/core\";\nimport { browserDetector } from \"@opentelemetry/opentelemetry-browser-detector\";\nimport {\n detectResources,\n resourceFromAttributes,\n} from \"@opentelemetry/resources\";\nimport {\n BatchLogRecordProcessor,\n LoggerProvider,\n type LogRecordProcessor,\n} from \"@opentelemetry/sdk-logs\";\nimport {\n MeterProvider,\n type MetricReader,\n PeriodicExportingMetricReader,\n} from \"@opentelemetry/sdk-metrics\";\nimport {\n BatchSpanProcessor,\n type SpanProcessor,\n} from \"@opentelemetry/sdk-trace-base\";\nimport { WebTracerProvider } from \"@opentelemetry/sdk-trace-web\";\nimport {\n createSessionLogRecordProcessor,\n createSessionSpanProcessor,\n} from \"@opentelemetry/web-common\";\n\nimport { SDK_NAME, SDK_VERSION } from \"../version.js\";\nimport {\n createBeaconLogExporter,\n createBeaconMetricExporter,\n createBeaconTraceExporter,\n} from \"./exporter.js\";\nimport { PageScopeContextManager } from \"./page-scope-context-manager.js\";\n\nconst SERVICE_NAMESPACE = \"interfere\";\n\n// Inlined wire keys — matches the pattern in\n// `@interfere/observability/browser/rum` (semconv keeps shifting these\n// between minor versions, but the wire keys themselves are stable).\nconst ATTR_SERVICE_NAME = \"service.name\" as const;\nconst ATTR_SERVICE_NAMESPACE = \"service.namespace\" as const;\nconst ATTR_DEPLOYMENT_ENVIRONMENT_NAME = \"deployment.environment.name\" as const;\nconst ATTR_TELEMETRY_SDK_LANGUAGE = \"telemetry.sdk.language\" as const;\nconst ATTR_RELEASE_SLUG = \"release.slug\" as const;\nconst ATTR_INTERFERE_SDK_STACK = \"interfere.sdk.stack\" as const;\nconst ATTR_INTERFERE_SDK_NAME = \"interfere.sdk.name\" as const;\nconst ATTR_INTERFERE_SDK_VERSION = \"interfere.sdk.version\" as const;\n// OTel semconv-canonical name for a stable per-device identifier.\n// Stamped as a *resource* attribute (not per-span) because it's stable\n// for the lifetime of the page; sessions rotate, devices don't. The\n// collector reads this off `context.resourceAttributes[\"device.id\"]`\n// and projects it into `spans.deviceId`.\nconst ATTR_DEVICE_ID = \"device.id\" as const;\n\nconst DEFAULT_SERVICE_NAME = \"interfere-sdk\";\n\n/**\n * Tuned for `navigator.sendBeacon`'s per-call payload ceiling.\n *\n * The browser primary exporters dispatch every export via beacon\n * (see `BeaconTraceExporter` / `BeaconLogExporter` /\n * `BeaconMetricExporter` in `exporter.ts`) — sendBeacon is the only\n * browser transport that reliably commits a request the page is also\n * tearing down. It's not free though: most browsers cap each beacon\n * payload at 64KiB (Chrome / Firefox) and reject anything larger\n * with a `false` return from `navigator.sendBeacon` — at which point\n * the BSP just drops the batch (no retry: the SW backstop intercepts\n * 5xx / network failures, not user-agent rejections).\n *\n * The numbers below keep payloads comfortably under that ceiling,\n * even on jank-heavy pages (production data on 2026-05-11 saw 831\n * `longtask` spans piled up on a single page-hide, observed via the\n * BetterStack dual-write) where a 100-span batch would already top\n * 100KiB:\n *\n * - `maxExportBatchSize: 10` — caps each beacon at ~10–20KiB,\n * leaving headroom for span attribute bloat without flirting\n * with the per-call ceiling.\n * - `maxQueueSize: 50` — caps the worst-case unload payload at\n * ~50–100KiB; the BSP drains across 5 beacons when forced-\n * flushed on `visibilitychange→hidden`, all of which queue\n * synchronously inside the user agent.\n * - `scheduledDelayMillis: 2000` — quieter pages keep less in\n * buffer at any moment, so a hidden→visible→hidden bounce\n * doesn't accumulate 5s of telemetry waiting to ship.\n * - `exportTimeoutMillis: 10_000` — unchanged. Beacon dispatches\n * are essentially synchronous (the user agent enqueues into its\n * own send loop), so the timeout is mostly defensive against\n * pathological `JsonTraceSerializer.serializeRequest` calls.\n */\nconst BROWSER_BATCH_OPTIONS = {\n maxQueueSize: 50,\n maxExportBatchSize: 10,\n scheduledDelayMillis: 2000,\n exportTimeoutMillis: 10_000,\n} as const;\n\nexport interface OtelProviderInput {\n /**\n * @internal\n *\n * Extra log-record processors fanned into the LoggerProvider's\n * processor list at construction. Used by `@interfere/observability`\n * for internal-only dual-write to BetterStack — keeps a parallel\n * destination's queue/exporter independent of the SDK's own.\n * Customers don't get a fan-out hook on the SDK surface; this is a\n * private bridge for our own dogfood apps.\n */\n additionalLogRecordProcessors?: LogRecordProcessor[];\n /**\n * @internal\n *\n * Extra metric readers fanned into the MeterProvider's reader list\n * at construction. Used by `@interfere/observability` for internal-\n * only dual-write of web vitals histograms (`web_vitals.{ttfb,fcp,\n * lcp,inp,cls}`) to the BetterStack-fronting OTel collector. Each\n * reader owns its own queue + exporter so a 5xx / network outage on\n * the parallel destination backs off only its own batch.\n */\n additionalMetricReaders?: MetricReader[];\n /**\n * @internal\n *\n * Extra span processors fanned into the WebTracerProvider's processor\n * list at construction. See `additionalLogRecordProcessors`.\n */\n additionalSpanProcessors?: SpanProcessor[];\n /**\n * Auth + content headers for OTLP exports. Sourced from the kernel's\n * already-resolved ingest target so the OTLP path inherits the same\n * transport metadata the rest of the SDK uses — no separate auth knob.\n */\n authHeaders: Headers;\n /** OTLP base URL — the opaque sink path is appended by the exporters. */\n collectorUrl: string;\n /**\n * Stable per-device identifier from `DeviceManager`. Resolved from\n * localStorage / cookie at kernel boot, so it's synchronously\n * available before the providers are constructed. Stamped as the\n * OTel-semconv `device.id` resource attribute so every span / log /\n * metric carries it without per-record re-stamping. Optional —\n * tests and SSR boot paths that build the provider before the\n * device manager has run pass `null`.\n */\n deviceId?: string | null | undefined;\n /**\n * Returns the kernel's current session id. Wired into per-span /\n * per-log session processors so a mid-page session rotation (30-min\n * idle expiry, manual reset) lands on subsequent spans without the\n * kernel having to rebuild the providers. Returns `null` before the\n * `SessionTracker` has bootstrapped.\n */\n getSessionId: () => SessionId | null;\n /** Optional release slug — top-level `release.slug` attr (Phase 6 wire identity). */\n releaseSlug?: ReleaseSlug | null | undefined;\n /**\n * Producer chain for the `interfere.sdk.stack` resource attribute —\n * e.g. `[\"@interfere/next@10.0.0\", \"@interfere/react@10.0.0\"]`.\n * Wrapper-injected; the kernel just forwards.\n */\n sdkStack: string[];\n /**\n * Override the OTel `service.name` resource attribute. Defaults to\n * `\"interfere-sdk\"`.\n */\n serviceName?: string;\n}\n\nexport interface OtelProviderHandle {\n /**\n * Page-scope context manager. The kernel calls `setPageScope(ctx)` after\n * extracting the SSR `traceparent` meta tag so spans without a more\n * specific zone descend from the server-side parent.\n */\n contextManager: PageScopeContextManager;\n /** Force-flush all three providers — call from kernel.flush() / on visibility hidden. */\n flush(): Promise<void>;\n loggerProvider: LoggerProvider;\n meterProvider: MeterProvider;\n metricReader: MetricReader;\n /** Tear down all three providers — called from kernel.dispose(). */\n shutdown(): Promise<void>;\n tracerProvider: WebTracerProvider;\n}\n\n/**\n * Constructs the SDK's **private** OTel providers — never registers globally\n * via `provider.register()` or `trace.setGlobalTracerProvider()`. Customers\n * with their own OTel setup (DataDog, Vercel, etc.) cohabit cleanly.\n *\n * Splitting this out from `Kernel` keeps the OTel module lazy-loadable so\n * the error-only bundle path (no tracing) never imports the OTel SDK.\n */\nexport function buildOtelProvider(\n input: OtelProviderInput\n): OtelProviderHandle {\n // Static service identity merged with detected browser attrs\n // (`browser.brands`, `browser.platform`, `browser.mobile`,\n // `browser.language`, `browser.user_agent`). The browser detector\n // reads UA Client Hints synchronously via `navigator.userAgentData`\n // low-entropy properties, so this stays sync — async would race\n // `DocumentLoadInstrumentation` and consistently miss page-load.\n const environment =\n normalizeEnv(\n typeof process === \"undefined\" ? undefined : process.env[\"NODE_ENV\"]\n ) ?? \"unknown\";\n\n const baseResource = resourceFromAttributes({\n [ATTR_SERVICE_NAME]: input.serviceName ?? DEFAULT_SERVICE_NAME,\n [ATTR_SERVICE_NAMESPACE]: SERVICE_NAMESPACE,\n [ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: environment,\n [ATTR_TELEMETRY_SDK_LANGUAGE]: \"webjs\",\n [ATTR_INTERFERE_SDK_NAME]: SDK_NAME,\n [ATTR_INTERFERE_SDK_VERSION]: SDK_VERSION,\n [ATTR_INTERFERE_SDK_STACK]: input.sdkStack.join(\", \"),\n ...(input.releaseSlug ? { [ATTR_RELEASE_SLUG]: input.releaseSlug } : {}),\n ...(input.deviceId ? { [ATTR_DEVICE_ID]: input.deviceId } : {}),\n });\n const detected = detectResources({ detectors: [browserDetector] });\n const resource = baseResource.merge(detected);\n\n const traceExporter = createBeaconTraceExporter({\n collectorUrl: input.collectorUrl,\n authHeaders: input.authHeaders,\n });\n\n // The web-common session processor expects `() => string | null`,\n // matching our `KernelSession.getId` shape.\n const getSessionId = input.getSessionId;\n\n const spanProcessors: SpanProcessor[] = [\n // Stamps `session.id` per-span, re-reading on every export. A\n // mid-page session rotation (30-min idle, manual reset) lands on\n // subsequent spans without rebuilding the provider. Resource-level\n // `session.id` would freeze at boot.\n createSessionSpanProcessor({ getSessionId }),\n // Exception attribute defaults (`interfere.exception.{mechanism,\n // handled,kind}`) are no longer stamped here — third-party\n // auto-instrumentations bypass our kernel anyway, so the SDK\n // can't reliably tell what to default. Server-side enrichment\n // (`enrichment/lib/normalize-atom.ts`) is the single chokepoint\n // every exception event flows through, so the defaults live\n // there now and the SDK ships less code.\n new BatchSpanProcessor(traceExporter, BROWSER_BATCH_OPTIONS),\n // Internal-only fan-out (BetterStack dual-write for `interfere/homepage`\n // + `interfere/dashboard`). Each extra processor owns its own queue +\n // exporter, so a 5xx / network outage on the parallel destination\n // backs off only its own batch — the primary collector pipeline keeps\n // draining unaffected.\n ...(input.additionalSpanProcessors ?? []),\n ];\n\n const tracerProvider = new WebTracerProvider({ resource, spanProcessors });\n\n // `PageScopeContextManager` keeps the active context alive across\n // microtasks/promise chains/setTimeout, AND falls back to the page-scope\n // context (the SSR `traceparent`) for code paths that fire outside any\n // zone the manager itself created. The kernel populates the page scope\n // by calling `contextManager.setPageScope(ctx)` after extracting the\n // meta tag.\n //\n // `register({ contextManager })` does call `setGlobalContextManager`\n // internally — that's unavoidable; OTel exposes exactly one global\n // context manager. Customers with their own OTel provider boot last and\n // win. We accept the trade-off for correctness: the alternative\n // (separate per-provider context manager) is not supported by OTel.\n const contextManager = new PageScopeContextManager();\n tracerProvider.register({ contextManager });\n\n // Composed W3C trace context + baggage propagator. `FetchInstrumentation`\n // injects both `traceparent` and `baggage` on outgoing requests so\n // backend Elysia plugins can pick `interfere.*` baggage entries off\n // the request and stamp them on server spans. Only set the global if\n // no propagator is currently registered (`fields()` is `[]` for the\n // noop). Customers who installed their own propagator (B3, composite,\n // …) are preserved. Reading the SSR meta tag uses a local instance,\n // not the global, so our extract path is independent.\n if (propagation.fields().length === 0) {\n propagation.setGlobalPropagator(\n new CompositePropagator({\n propagators: [\n new W3CTraceContextPropagator(),\n new W3CBaggagePropagator(),\n ],\n })\n );\n }\n\n const metricExporter = createBeaconMetricExporter({\n collectorUrl: input.collectorUrl,\n authHeaders: input.authHeaders,\n });\n\n const metricReader = new PeriodicExportingMetricReader({\n exporter: metricExporter,\n exportIntervalMillis: 30_000,\n });\n\n const meterProvider = new MeterProvider({\n resource,\n readers: [metricReader, ...(input.additionalMetricReaders ?? [])],\n });\n\n // Logs path. The `plugins/logs.ts` plugin patches `console.*` and emits\n // a `LogRecord` per call (errorsPlugin still owns Error-bearing console\n // calls — the class boundary is checked there). LoggerProvider is\n // private; the kernel exposes `recordLog` so callers don't have to\n // touch the OTel logs API directly.\n const logExporter = createBeaconLogExporter({\n collectorUrl: input.collectorUrl,\n authHeaders: input.authHeaders,\n });\n const loggerProvider = new LoggerProvider({\n resource,\n processors: [\n // Mirrors the SessionSpanProcessor for traces — every log record\n // (including `BrowserNavigationInstrumentation`'s navigation\n // events) carries the same `session.id` as the spans emitted\n // around it, so trace ↔ log correlation by session is trivial.\n createSessionLogRecordProcessor({ getSessionId }),\n new BatchLogRecordProcessor(logExporter, BROWSER_BATCH_OPTIONS),\n ...(input.additionalLogRecordProcessors ?? []),\n ],\n });\n\n return {\n contextManager,\n tracerProvider,\n meterProvider,\n metricReader,\n loggerProvider,\n flush: async () => {\n await Promise.all([\n tracerProvider.forceFlush(),\n metricReader.forceFlush(),\n loggerProvider.forceFlush(),\n ]);\n },\n shutdown: async () => {\n await Promise.all([\n tracerProvider.shutdown(),\n meterProvider.shutdown(),\n loggerProvider.shutdown(),\n ]);\n },\n };\n}\n"],"mappings":"27BA2CA,MAwDM,sBAAwB,CAC5B,aAAc,GACd,mBAAoB,GACpB,qBAAsB,IACtB,oBAAqB,GACvB,EAkGA,SAAgB,kBACd,MACoB,CAOpB,IAAM,YACJ,aACE,OAAO,QAAY,IAAc,IAAA,GAAY,QAAQ,IAAI,QAC3D,GAAK,UAED,aAAe,uBAAuB,CACzC,eAAoB,MAAM,aAAe,gBACzC,oBAAyB,YACzB,8BAAmC,YACnC,yBAA8B,QAC9B,qBAA0B,SAC1B,wBAA6B,YAC7B,sBAA2B,MAAM,SAAS,KAAK,IAAI,EACpD,GAAI,MAAM,YAAc,CAAG,eAAoB,MAAM,WAAY,EAAI,CAAC,EACtE,GAAI,MAAM,SAAW,CAAG,YAAiB,MAAM,QAAS,EAAI,CAAC,CAC/D,CAAC,EACK,SAAW,gBAAgB,CAAE,UAAW,CAAC,eAAe,CAAE,CAAC,EAC3D,SAAW,aAAa,MAAM,QAAQ,EAEtC,cAAgB,0BAA0B,CAC9C,aAAc,MAAM,aACpB,YAAa,MAAM,WACrB,CAAC,EAIK,aAAe,MAAM,aAwBrB,eAAiB,IAAI,kBAAkB,CAAE,SAAU,eAAA,CAjBvD,2BAA2B,CAAE,YAAa,CAAC,EAQ3C,IAAI,mBAAmB,cAAe,qBAAqB,EAM3D,GAAI,MAAM,0BAA4B,CAAC,CAG6B,CAAE,CAAC,EAcnE,eAAiB,IAAI,wBAC3B,eAAe,SAAS,CAAE,cAAe,CAAC,EAUtC,YAAY,OAAO,EAAE,SAAW,GAClC,YAAY,oBACV,IAAI,oBAAoB,CACtB,YAAa,CACX,IAAI,0BACJ,IAAI,oBACN,CACF,CAAC,CACH,EAQF,IAAM,aAAe,IAAI,8BAA8B,CACrD,SANqB,2BAA2B,CAChD,aAAc,MAAM,aACpB,YAAa,MAAM,WACrB,CAGyB,EACvB,qBAAsB,GACxB,CAAC,EAEK,cAAgB,IAAI,cAAc,CACtC,SACA,QAAS,CAAC,aAAc,GAAI,MAAM,yBAA2B,CAAC,CAAE,CAClE,CAAC,EAOK,YAAc,wBAAwB,CAC1C,aAAc,MAAM,aACpB,YAAa,MAAM,WACrB,CAAC,EACK,eAAiB,IAAI,eAAe,CACxC,SACA,WAAY,CAKV,gCAAgC,CAAE,YAAa,CAAC,EAChD,IAAI,wBAAwB,YAAa,qBAAqB,EAC9D,GAAI,MAAM,+BAAiC,CAAC,CAC9C,CACF,CAAC,EAED,MAAO,CACL,eACA,eACA,cACA,aACA,eACA,MAAO,SAAY,CACjB,MAAM,QAAQ,IAAI,CAChB,eAAe,WAAW,EAC1B,aAAa,WAAW,EACxB,eAAe,WAAW,CAC5B,CAAC,CACH,EACA,SAAU,SAAY,CACpB,MAAM,QAAQ,IAAI,CAChB,eAAe,SAAS,EACxB,cAAc,SAAS,EACvB,eAAe,SAAS,CAC1B,CAAC,CACH,CACF,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"web-vitals.d.mts","names":[],"sources":["../../../src/internal/otel/web-vitals.ts"],"mappings":";;;UAmBiB,cAAA;;AAAjB;;;;EAME,KAAA,QAAa,OAAA;EAAA;EAEb,KAAA,EAAO,KAAA;EAAA;;;;;EAMP,YAAA,IAAgB,QAAA;AAAA;;;;;;;;;;;;;;iBAgBF,gBAAA,CAAiB,KAAA,EAAO,cAAA"}
1
+ {"version":3,"file":"web-vitals.d.mts","names":[],"sources":["../../../src/internal/otel/web-vitals.ts"],"mappings":";;;UAmBiB,cAAA;;AAAjB;;;;EAME,KAAA,QAAa,OAAA;EAAA;EAEb,KAAA,EAAO,KAAK;EAAL;;;;AAMyB;EAAhC,YAAA,IAAgB,QAAA;AAAA;;;AAgBoC;;;;;;;;;;;iBAAtC,gBAAA,CAAiB,KAAqB,EAAd,cAAc"}