@interfere/react 11.1.1 → 12.0.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 (136) hide show
  1. package/README.md +4 -4
  2. package/dist/activity-BfYxFVcK.d.mts +36 -0
  3. package/dist/api-wpS4xoMY.d.mts +70 -0
  4. package/dist/api.d.mts +8 -7
  5. package/dist/api.mjs +1 -1
  6. package/dist/config-Rm-ct4K1.d.mts +12 -0
  7. package/dist/device-vFtWy12y.d.mts +35 -0
  8. package/dist/error-boundary.d.mts +7 -7
  9. package/dist/error-boundary.mjs +1 -1
  10. package/dist/exporter-logs-CeGwMiMo.d.mts +51 -0
  11. package/dist/geo-PDfIZY4L.d.mts +16 -0
  12. package/dist/index-CatPKbtv.d.mts +4 -0
  13. package/dist/instrumentations-Bgm2EazU.d.mts +91 -0
  14. package/dist/internal/activity.d.mts +1 -35
  15. package/dist/internal/activity.mjs +1 -1
  16. package/dist/internal/browser-context.d.mts +44 -4
  17. package/dist/internal/browser-context.mjs +1 -1
  18. package/dist/internal/capture-boundary.d.mts +6 -5
  19. package/dist/internal/capture-boundary.mjs +1 -1
  20. package/dist/internal/capture.d.mts +3 -4
  21. package/dist/internal/capture.mjs +1 -1
  22. package/dist/internal/config.d.mts +26 -27
  23. package/dist/internal/config.mjs +1 -1
  24. package/dist/internal/consent.d.mts +16 -8
  25. package/dist/internal/console-patch.d.mts +6 -7
  26. package/dist/internal/console-patch.mjs +1 -1
  27. package/dist/internal/dom/actionable.d.mts +5 -7
  28. package/dist/internal/dom/actionable.mjs +1 -1
  29. package/dist/internal/hydration.d.mts +2 -3
  30. package/dist/internal/kernel-registry.d.mts +5 -6
  31. package/dist/internal/kernel.d.mts +2 -292
  32. package/dist/internal/kernel.mjs +1 -1
  33. package/dist/internal/otel/exporter-logs.d.mts +1 -12
  34. package/dist/internal/otel/exporter-logs.mjs +1 -1
  35. package/dist/internal/otel/exporter-metrics.d.mts +2 -14
  36. package/dist/internal/otel/exporter-metrics.mjs +1 -1
  37. package/dist/internal/otel/exporter.d.mts +2 -29
  38. package/dist/internal/otel/exporter.mjs +1 -1
  39. package/dist/internal/otel/http-span-route.d.mts +4 -0
  40. package/dist/internal/otel/http-span-route.mjs +1 -0
  41. package/dist/internal/otel/index.d.mts +7 -5
  42. package/dist/internal/otel/index.mjs +1 -1
  43. package/dist/internal/otel/initial-navigation.d.mts +3 -4
  44. package/dist/internal/otel/initial-navigation.mjs +1 -1
  45. package/dist/internal/otel/instrumentations.d.mts +2 -89
  46. package/dist/internal/otel/instrumentations.mjs +1 -1
  47. package/dist/internal/otel/navigation.d.mts +2 -0
  48. package/dist/internal/otel/navigation.mjs +1 -0
  49. package/dist/internal/otel/normalize-path.d.mts +9 -0
  50. package/dist/internal/otel/normalize-path.mjs +1 -0
  51. package/dist/internal/otel/page-scope-context-manager.d.mts +2 -31
  52. package/dist/internal/otel/page-scope-context-manager.mjs +1 -1
  53. package/dist/internal/otel/propagation.d.mts +1 -19
  54. package/dist/internal/otel/propagation.mjs +1 -1
  55. package/dist/internal/otel/provider.d.mts +1 -86
  56. package/dist/internal/otel/provider.mjs +1 -1
  57. package/dist/internal/otel/url-attrs.d.mts +7 -0
  58. package/dist/internal/otel/url-attrs.mjs +1 -0
  59. package/dist/internal/otel/web-vitals.d.mts +1 -33
  60. package/dist/internal/otel/web-vitals.mjs +1 -1
  61. package/dist/internal/page-lifecycle.d.mts +4 -5
  62. package/dist/internal/page-lifecycle.mjs +1 -1
  63. package/dist/internal/plugin-runtime.d.mts +1 -38
  64. package/dist/internal/plugin-runtime.mjs +1 -1
  65. package/dist/internal/react-context.d.mts +1 -43
  66. package/dist/internal/react-context.mjs +1 -1
  67. package/dist/internal/server-digest.d.mts +4 -3
  68. package/dist/internal/server-digest.mjs +1 -1
  69. package/dist/internal/sw-queue.d.mts +4 -5
  70. package/dist/internal/sw-queue.mjs +1 -1
  71. package/dist/internal/third-party-hosts.d.mts +2 -3
  72. package/dist/internal/third-party-hosts.mjs +1 -1
  73. package/dist/internal/version.d.mts +4 -5
  74. package/dist/internal/version.mjs +1 -1
  75. package/dist/internal/wrapper-singleton.d.mts +5 -6
  76. package/dist/internal/wrapper-singleton.mjs +1 -1
  77. package/dist/navigation-CkiV6lJY.d.mts +54 -0
  78. package/dist/page-scope-context-manager-r92ZMJok.d.mts +17 -0
  79. package/dist/plugins/device.d.mts +5 -0
  80. package/dist/plugins/device.mjs +1 -0
  81. package/dist/plugins/errors.d.mts +1 -1
  82. package/dist/plugins/errors.mjs +1 -1
  83. package/dist/plugins/lib/loader.d.mts +2 -11
  84. package/dist/plugins/lib/loader.mjs +1 -1
  85. package/dist/plugins/lib/types.d.mts +2 -24
  86. package/dist/plugins/logs.d.mts +1 -1
  87. package/dist/plugins/logs.mjs +1 -1
  88. package/dist/plugins/page-events.d.mts +5 -0
  89. package/dist/plugins/page-events.mjs +1 -0
  90. package/dist/plugins/rage-clicks.d.mts +1 -1
  91. package/dist/plugins/rage-clicks.mjs +1 -1
  92. package/dist/plugins/replay/buffer.d.mts +9 -6
  93. package/dist/plugins/replay/buffer.mjs +1 -1
  94. package/dist/plugins/replay/chunking.d.mts +18 -9
  95. package/dist/plugins/replay/chunking.mjs +1 -1
  96. package/dist/plugins/replay/compressor-host.d.mts +3 -4
  97. package/dist/plugins/replay/compressor-host.mjs +1 -1
  98. package/dist/plugins/replay/config.d.mts +1 -11
  99. package/dist/plugins/replay/config.mjs +1 -1
  100. package/dist/plugins/replay/delivery.d.mts +8 -9
  101. package/dist/plugins/replay/delivery.mjs +1 -1
  102. package/dist/plugins/replay/index.d.mts +1 -1
  103. package/dist/plugins/replay/index.mjs +1 -1
  104. package/dist/plugins/replay/recorder.d.mts +12 -6
  105. package/dist/plugins/replay/recorder.mjs +1 -1
  106. package/dist/plugins/replay/sequence.d.mts +5 -4
  107. package/dist/plugins/replay/sequence.mjs +1 -1
  108. package/dist/plugins/replay/upload.d.mts +4 -0
  109. package/dist/plugins/replay/upload.mjs +1 -0
  110. package/dist/propagation-CssinKCy.d.mts +26 -0
  111. package/dist/provider-50LbJ4Tl.d.mts +466 -0
  112. package/dist/provider-Cp6noibq.d.mts +101 -0
  113. package/dist/provider.d.mts +2 -58
  114. package/dist/provider.mjs +1 -1
  115. package/dist/react-error-handler.d.mts +9 -11
  116. package/dist/react-error-handler.mjs +1 -1
  117. package/dist/rrweb-CE6GKCEq.mjs +150 -0
  118. package/dist/tracking/api.d.mts +1 -54
  119. package/dist/tracking/api.mjs +1 -1
  120. package/dist/tracking/device.d.mts +1 -32
  121. package/dist/tracking/device.mjs +1 -1
  122. package/dist/tracking/geo.d.mts +1 -13
  123. package/dist/tracking/geo.mjs +1 -1
  124. package/dist/tracking/session.d.mts +6 -7
  125. package/dist/tracking/session.mjs +1 -1
  126. package/dist/util/bot.d.mts +2 -3
  127. package/dist/util/bot.mjs +1 -1
  128. package/dist/util/global.d.mts +4 -10
  129. package/dist/util/global.mjs +1 -1
  130. package/dist/util/log.d.mts +11 -7
  131. package/dist/util/log.mjs +1 -1
  132. package/dist/util/stringify.d.mts +2 -3
  133. package/dist/version-BniHrwLD.mjs +1 -0
  134. package/dist/web-vitals-x8y70B5x.d.mts +34 -0
  135. package/package.json +67 -48
  136. package/dist/package.mjs +0 -1
@@ -1 +1 @@
1
- const THIRD_PARTY_IGNORE=[/(?:^|\/\/)clerk\./u,/\.clerk\./u,/\.sentry\./u,/\.intercom\./u,/\.posthog\./u,/\.googletagmanager\.com/u,/\.google-analytics\.com/u,/\.googleapis\.com/u,/\.doubleclick\.net/u,/\.facebook\.com/u,/\.fbcdn\.net/u,/\.analytics\.google\.com/u,/px\.ads\.linkedin\.com/u,/[?&]_rsc=/u];export{THIRD_PARTY_IGNORE};
1
+ const THIRD_PARTY_IGNORE=[/(?:^|\/\/)clerk\./u,/\.clerk\./u,/\.sentry\./u,/\.intercom\./u,/\.posthog\./u,/\.googletagmanager\.com/u,/\.google-analytics\.com/u,/\.googleapis\.com/u,/\.doubleclick\.net/u,/\.facebook\.com/u,/\.fbcdn\.net/u,/\.analytics\.google\.com/u,/px\.ads\.linkedin\.com/u,/\/__nextjs_/u];export{THIRD_PARTY_IGNORE};
@@ -1,6 +1,5 @@
1
1
  //#region src/internal/version.d.ts
2
- declare const SDK_NAME: string;
3
- declare const SDK_VERSION: string;
4
- declare const PRODUCER_VERSION: string;
5
- //#endregion
6
- export { PRODUCER_VERSION, SDK_NAME, SDK_VERSION };
2
+ export declare const SDK_NAME: string;
3
+ export declare const SDK_VERSION: string;
4
+ export declare const PRODUCER_VERSION: string;
5
+ //#endregion
@@ -1 +1 @@
1
- import{name,version}from"../package.mjs";const SDK_NAME=name,SDK_VERSION=version,PRODUCER_VERSION=`${SDK_NAME}@${SDK_VERSION}`;export{PRODUCER_VERSION,SDK_NAME,SDK_VERSION};
1
+ import{n as SDK_NAME,r as SDK_VERSION,t as PRODUCER_VERSION}from"../version-BniHrwLD.mjs";export{PRODUCER_VERSION,SDK_NAME,SDK_VERSION};
@@ -1,8 +1,8 @@
1
- import { Kernel, KernelOptions } from "./kernel.mjs";
1
+ import { f as KernelOptions, s as Kernel } from "../provider-50LbJ4Tl.mjs";
2
2
  import { ConsentState } from "@interfere/types/sdk/plugins/manifest";
3
3
  import { IdentifyParams } from "@interfere/types/sdk/identify";
4
4
  //#region src/internal/wrapper-singleton.d.ts
5
- interface WrapperSingleton {
5
+ export interface WrapperSingleton {
6
6
  close: () => Promise<void>;
7
7
  consent: {
8
8
  get: () => ConsentState | null;
@@ -18,7 +18,7 @@ interface WrapperSingleton {
18
18
  init: (opts?: KernelOptions) => Promise<Kernel | null>;
19
19
  subscribeToKernel: (listener: () => void) => () => void;
20
20
  }
21
- interface WrapperSingletonInput {
21
+ export interface WrapperSingletonInput {
22
22
  /**
23
23
  * Surfaced in the "kernel not initialized" error so the message points
24
24
  * customers at the right entry file (e.g. "instrumentation-client" /
@@ -42,6 +42,5 @@ interface WrapperSingletonInput {
42
42
  * kernel is per-wrapper, not per-process. (Microfrontends can run two
43
43
  * different wrappers on the same page; each gets its own kernel.)
44
44
  */
45
- declare function createWrapperSingleton(input: WrapperSingletonInput): WrapperSingleton;
46
- //#endregion
47
- export { WrapperSingleton, WrapperSingletonInput, createWrapperSingleton };
45
+ export declare function createWrapperSingleton(input: WrapperSingletonInput): WrapperSingleton;
46
+ //#endregion
@@ -1 +1 @@
1
- import{registerKernel,unregisterKernel}from"./kernel-registry.mjs";import{createKernel,isEnabledByEnvironment}from"./kernel.mjs";import{isBotUserAgent}from"../util/bot.mjs";function createWrapperSingleton(input){let kernel=null,pending=null,listeners=new Set;function emit(){for(let listener of listeners)listener()}async function initKernel(internalOpts){try{let k=await createKernel({opts:internalOpts});return kernel=k,k&&registerKernel(k),emit(),k}finally{pending=null}}return{init(opts={}){return kernel?Promise.resolve(kernel):pending||(!(opts.enabled??isEnabledByEnvironment())||isBotUserAgent()?Promise.resolve(null):(pending=initKernel({...opts,_wrapperVersions:[input.producerVersion]}),pending))},getKernel(){if(!kernel)throw Error(`Interfere SDK not initialized. Call init() from your ${input.initEntryName} entrypoint.`);return kernel},getKernelOrNull(){return kernel},async close(){if(!kernel)return;let previous=kernel;await previous.dispose(),kernel=null,unregisterKernel(previous),emit()},subscribeToKernel(listener){return listeners.add(listener),()=>{listeners.delete(listener)}},consent:{get:()=>kernel?.consent.get()??null,set:value=>kernel?.consent.set(value)},identity:{clear:()=>kernel?.identity.clear(),get:()=>kernel?.identity.get()??null,set:params=>kernel?.identity.set(params)??Promise.resolve()}}}export{createWrapperSingleton};
1
+ import{registerKernel,unregisterKernel}from"./kernel-registry.mjs";import{isForceEnableActive}from"./config.mjs";import{createKernel,isEnabledByEnvironment}from"./kernel.mjs";import{isBotUserAgent}from"../util/bot.mjs";function createWrapperSingleton(input){let kernel=null,pending=null,listeners=new Set;function emit(){for(let listener of listeners)listener()}async function initKernel(internalOpts){try{let k=await createKernel({opts:internalOpts});return kernel=k,registerKernel(k),emit(),k}finally{pending=null}}return{async close(){if(!kernel)return;let previous=kernel;await previous.dispose(),kernel=null,unregisterKernel(previous),emit()},consent:{get:()=>kernel?.consent.get()??null,set:value=>kernel?.consent.set(value)},getKernel(){if(!kernel)throw Error(`Interfere SDK not initialized. Call init() from your ${input.initEntryName} entrypoint.`);return kernel},getKernelOrNull(){return kernel},identity:{clear:()=>kernel?.identity.clear(),get:()=>kernel?.identity.get()??null,set:async params=>kernel?.identity.set(params)??Promise.resolve()},async init(opts={}){return kernel||pending||(!(opts.enabled??isEnabledByEnvironment())||!isForceEnableActive()&&isBotUserAgent()?null:(pending=initKernel({...opts,_wrapperVersions:[input.producerVersion]}),pending))},subscribeToKernel(listener){return listeners.add(listener),(()=>{listeners.delete(listener)})}}}export{createWrapperSingleton};
@@ -0,0 +1,54 @@
1
+ import { Context, Tracer } from "@opentelemetry/api";
2
+ //#region src/internal/otel/navigation.d.ts
3
+ /**
4
+ * A parked tab accretes spans onto its page scope for as long as the
5
+ * scope lives; without a ceiling one trace was observed holding 4,251
6
+ * spans across 19.5 hours. Rotated traces link back to their
7
+ * predecessor, so the session story survives the cut.
8
+ */
9
+ declare const PAGE_SCOPE_MAX_AGE_MS: number;
10
+ interface NavigationScopeInput {
11
+ resolveRoute?: ((pathname: string) => string | undefined) | undefined;
12
+ setPageScope: (ctx: Context) => void;
13
+ tracer: Tracer;
14
+ }
15
+ interface ScopeSpanInput {
16
+ resolveRoute?: ((pathname: string) => string | undefined) | undefined;
17
+ tracer: Tracer;
18
+ }
19
+ /**
20
+ * Client-side page scope for the initial page view, used when no SSR
21
+ * `<meta name="traceparent">` exists (SPA surfaces, static pages, cached
22
+ * HTML the freshness guard refused). Without it, every observation made
23
+ * before the first soft navigation — long tasks, clicks, fetches — falls
24
+ * back to `ROOT_CONTEXT` and becomes its own single-span trace.
25
+ */
26
+ declare function seedPageScope(input: ScopeSpanInput): Context;
27
+ /**
28
+ * Rotator for {@link PageScopeContextManager.setRotation}: starts a fresh
29
+ * `navigation` root (trigger `max_age`) linked to the expiring scope's
30
+ * span, so a tab parked on one route all day produces a chain of bounded
31
+ * traces instead of one unbounded one.
32
+ */
33
+ declare function createPageScopeRotator(input: ScopeSpanInput): (previous: Context) => Context;
34
+ /**
35
+ * Refreshes the page-scope context on SPA navigations so each page view
36
+ * gets its own bounded trace.
37
+ *
38
+ * The initial page scope comes from the SSR `<meta name="traceparent">`
39
+ * tag, read once at SDK init. Frameworks never update that tag on soft
40
+ * navigation, so without this every span from page 2..N of a session
41
+ * would keep stitching onto page 1's server trace. On each real URL
42
+ * change (history push/replace or popstate; hash-only changes excluded)
43
+ * this starts a zero-duration `navigation` root span and re-anchors the
44
+ * page scope to it — the server render of the *next* page still joins
45
+ * the *previous* page's trace via the propagated router fetch, which is
46
+ * causally where it belongs.
47
+ *
48
+ * Deliberately not consent-gated: it shapes trace topology the same way
49
+ * the SSR meta tag does, and records only the URL attrs every other
50
+ * span already carries.
51
+ */
52
+ declare function installNavigationScope(input: NavigationScopeInput): () => void;
53
+ //#endregion
54
+ export { seedPageScope as a, installNavigationScope as i, PAGE_SCOPE_MAX_AGE_MS as n, createPageScopeRotator as r, NavigationScopeInput as t };
@@ -0,0 +1,17 @@
1
+ import { Context } from "@opentelemetry/api";
2
+ import { ZoneContextManager } from "@opentelemetry/context-zone";
3
+ //#region src/internal/otel/page-scope-context-manager.d.ts
4
+ type PageScopeRotator = (previous: Context) => Context;
5
+ declare class PageScopeContextManager extends ZoneContextManager {
6
+ private pageScope;
7
+ private readonly pageSpans;
8
+ private pageScopeSetAtMs;
9
+ private rotator;
10
+ private maxAgeMs;
11
+ private rotating;
12
+ setPageScope(ctx: Context): void;
13
+ setRotation(rotator: PageScopeRotator, maxAgeMs: number): void;
14
+ active(): Context;
15
+ }
16
+ //#endregion
17
+ export { PageScopeRotator as n, PageScopeContextManager as t };
@@ -0,0 +1,5 @@
1
+ import { T as Plugin } from "../provider-50LbJ4Tl.mjs";
2
+ //#region src/plugins/device.d.ts
3
+ declare const devicePlugin: Plugin;
4
+ //#endregion
5
+ export { devicePlugin as default };
@@ -0,0 +1 @@
1
+ const devicePlugin={name:`device`,setup(ctx){return ctx.startDeviceInfoCapture()??void 0}};export{devicePlugin as default};
@@ -1,4 +1,4 @@
1
- import { Plugin } from "./lib/types.mjs";
1
+ import { T as Plugin } from "../provider-50LbJ4Tl.mjs";
2
2
  //#region src/plugins/errors.d.ts
3
3
  declare const errorsPlugin: Plugin;
4
4
  //#endregion
@@ -1 +1 @@
1
- import{hasServerDigest}from"../internal/server-digest.mjs";import{onConsoleCall}from"../internal/console-patch.mjs";import{THIRD_PARTY_IGNORE}from"../internal/third-party-hosts.mjs";import{MECHANISM_TYPE,isNonErrorException,toException}from"@interfere/types/sdk/errors";function capture(ctx,opts){ctx.recordException(opts.error,{mechanism:opts.mechanism,...opts.fallbackFrame&&!isNonErrorException(opts.error)?{fallbackFrames:[opts.fallbackFrame]}:{}})}function findErrorArg(args){return args.find(arg=>arg instanceof Error)??null}function resourceError(target){return target instanceof HTMLImageElement||target instanceof HTMLScriptElement?target.src?{tag:target.localName,url:target.src}:null:target instanceof HTMLLinkElement&&target.href?{tag:target.localName,url:target.href}:null}function isIgnoredResourceUrl(url){return THIRD_PARTY_IGNORE.some(pattern=>pattern.test(url))}function createResourceGate(){let seen=new Set,windowStart=0,windowCount=0;return url=>{if(seen.has(url))return!1;let now=Date.now();return now-windowStart>6e4&&(windowStart=now,windowCount=0),windowCount>=20?!1:(seen.size>=100&&seen.clear(),seen.add(url),windowCount+=1,!0)}}const errorsPlugin={name:`errors`,setup(ctx){let originalOnError=globalThis.onerror,originalStackTraceLimit=Error.stackTraceLimit;Error.stackTraceLimit<50&&(Error.stackTraceLimit=50),globalThis.onerror=(msg,source,line,col,error)=>{if(error instanceof Error&&!hasServerDigest(error)){let fallbackFrame=typeof source==`string`?{id:`fallback-0`,file:source,...typeof line==`number`?{line}:{},...typeof col==`number`?{column:col}:{}}:null;capture(ctx,{error,mechanism:{type:MECHANISM_TYPE.browser.onerror,handled:!1},...fallbackFrame?{fallbackFrame}:{}})}return typeof originalOnError==`function`&&originalOnError.call(globalThis,msg,source,line,col,error)};let onUnhandledRejection=event=>{hasServerDigest(event.reason)||capture(ctx,{error:toException(event.reason),mechanism:{type:MECHANISM_TYPE.browser.onunhandledrejection,handled:!1,...event.reason instanceof Error?{}:{synthetic:!0}}})},seenCspReports=new Set,onSecurityPolicyViolation=event=>{let key=`${event.violatedDirective}|${event.blockedURI}`;seenCspReports.has(key)||seenCspReports.size>=5||(seenCspReports.add(key),capture(ctx,{error:{kind:`non-error`,type:`SecurityPolicyViolation`,value:`CSP ${event.violatedDirective} blocked ${event.blockedURI||`inline`}`,serialized:{violatedDirective:event.violatedDirective,blockedURI:event.blockedURI,sourceFile:event.sourceFile,lineNumber:event.lineNumber,columnNumber:event.columnNumber,disposition:event.disposition}},mechanism:{type:MECHANISM_TYPE.browser.securityPolicyViolation,handled:!1}}))},resourceGate=createResourceGate(),onResourceError=event=>{let resource=resourceError(event.target);!resource||isIgnoredResourceUrl(resource.url)||!resourceGate(resource.url)||capture(ctx,{error:{kind:`non-error`,type:`ResourceLoadError`,value:`Failed to load ${resource.tag}: ${resource.url}`,serialized:{url:resource.url}},mechanism:{type:MECHANISM_TYPE.browser.resourceError,handled:!1}})},supportsEventTarget=typeof globalThis.addEventListener==`function`&&typeof globalThis.removeEventListener==`function`;supportsEventTarget&&(globalThis.addEventListener(`unhandledrejection`,onUnhandledRejection),globalThis.addEventListener(`securitypolicyviolation`,onSecurityPolicyViolation),globalThis.addEventListener(`error`,onResourceError,!0));let unsubscribeConsole=onConsoleCall((level,args)=>{if(level!==`error`)return;let error=findErrorArg(args);error&&!hasServerDigest(error)&&capture(ctx,{error,mechanism:{type:MECHANISM_TYPE.browser.consoleError,handled:!0}})});return()=>{Error.stackTraceLimit=originalStackTraceLimit,globalThis.onerror=originalOnError,supportsEventTarget&&(globalThis.removeEventListener(`unhandledrejection`,onUnhandledRejection),globalThis.removeEventListener(`securitypolicyviolation`,onSecurityPolicyViolation),globalThis.removeEventListener(`error`,onResourceError,!0)),unsubscribeConsole()}}};export{errorsPlugin as default};
1
+ import{hasServerDigest}from"../internal/server-digest.mjs";import{onConsoleCall}from"../internal/console-patch.mjs";import{THIRD_PARTY_IGNORE}from"../internal/third-party-hosts.mjs";import{MECHANISM_TYPE,isNonErrorException,toException}from"@interfere/types/sdk/errors";import{omitUndefined}from"@interfere/helpers/omit-undefined";function capture(ctx,opts){ctx.recordException(opts.error,omitUndefined({mechanism:opts.mechanism,fallbackFrames:opts.fallbackFrame&&!isNonErrorException(opts.error)?[opts.fallbackFrame]:void 0}))}function findErrorArg(args){return args.find(arg=>arg instanceof Error)??null}function resourceError(target){return target instanceof HTMLImageElement||target instanceof HTMLScriptElement?target.src?{tag:target.localName,url:target.src}:null:target instanceof HTMLLinkElement&&target.href?{tag:target.localName,url:target.href}:null}function isIgnoredResourceUrl(url){return THIRD_PARTY_IGNORE.some(pattern=>pattern.test(url))}function createResourceGate(){let seen=new Set,windowStart=0,windowCount=0;return(url=>{if(seen.has(url))return!1;let now=Date.now();return now-windowStart>6e4&&(windowStart=now,windowCount=0),windowCount>=20?!1:(seen.size>=100&&seen.clear(),seen.add(url),windowCount+=1,!0)})}function createRepeatGate(){let counts=new Map,windowStart=0;return(key=>{let now=Date.now();now-windowStart>6e4&&(windowStart=now,counts.clear());let count=counts.get(key)??0;return count>=5?!1:(counts.size>=100&&counts.clear(),counts.set(key,count+1),!0)})}const errorsPlugin={name:`errors`,setup(ctx){let originalOnError=globalThis.onerror,originalStackTraceLimit=Error.stackTraceLimit;Error.stackTraceLimit<50&&(Error.stackTraceLimit=50);let repeatGate=createRepeatGate();globalThis.onerror=(msg,source,line,col,error)=>{if(error instanceof Error&&!hasServerDigest(error)&&repeatGate(`${typeof msg==`string`?msg:msg.type}|${String(source)}|${String(line)}|${String(col)}`)){let fallbackFrame=typeof source==`string`?omitUndefined({file:source,id:`fallback-0`,line:typeof line==`number`?line:void 0,column:typeof col==`number`?col:void 0}):null;capture(ctx,omitUndefined({error,mechanism:{handled:!1,type:MECHANISM_TYPE.browser.onerror},fallbackFrame:fallbackFrame??void 0}))}return typeof originalOnError==`function`&&originalOnError.call(globalThis,msg,source,line,col,error)};let onUnhandledRejection=event=>{hasServerDigest(event.reason)||capture(ctx,{error:toException(event.reason),mechanism:omitUndefined({handled:!1,type:MECHANISM_TYPE.browser.onunhandledrejection,synthetic:event.reason instanceof Error?void 0:!0})})},cspReportsByDisposition={enforce:new Set,report:new Set},onSecurityPolicyViolation=event=>{let seenCspReports=cspReportsByDisposition[event.disposition],key=`${event.violatedDirective}|${event.blockedURI}`;seenCspReports.has(key)||seenCspReports.size>=5||(seenCspReports.add(key),capture(ctx,{error:{kind:`non-error`,serialized:{blockedURI:event.blockedURI,columnNumber:event.columnNumber,disposition:event.disposition,lineNumber:event.lineNumber,sourceFile:event.sourceFile,violatedDirective:event.violatedDirective},type:`SecurityPolicyViolation`,value:event.disposition===`report`?`CSP ${event.violatedDirective} reported ${event.blockedURI||`inline`} (report-only)`:`CSP ${event.violatedDirective} blocked ${event.blockedURI||`inline`}`},mechanism:{handled:event.disposition===`report`,type:MECHANISM_TYPE.browser.securityPolicyViolation}}))},resourceGate=createResourceGate(),onResourceError=event=>{let resource=resourceError(event.target);resource&&!isIgnoredResourceUrl(resource.url)&&resourceGate(resource.url)&&capture(ctx,{error:{kind:`non-error`,serialized:{url:resource.url},type:`ResourceLoadError`,value:`Failed to load ${resource.tag}: ${resource.url}`},mechanism:{handled:!1,type:MECHANISM_TYPE.browser.resourceError}})},supportsEventTarget=typeof globalThis.addEventListener==`function`&&typeof globalThis.removeEventListener==`function`;supportsEventTarget&&(globalThis.addEventListener(`unhandledrejection`,onUnhandledRejection),globalThis.addEventListener(`securitypolicyviolation`,onSecurityPolicyViolation),globalThis.addEventListener(`error`,onResourceError,!0));let unsubscribeConsole=onConsoleCall((level,args)=>{if(level!==`error`)return;let error=findErrorArg(args);error&&!hasServerDigest(error)&&capture(ctx,{error,mechanism:{handled:!0,type:MECHANISM_TYPE.browser.consoleError}})});return()=>{Error.stackTraceLimit=originalStackTraceLimit,globalThis.onerror=originalOnError,supportsEventTarget&&(globalThis.removeEventListener(`unhandledrejection`,onUnhandledRejection),globalThis.removeEventListener(`securitypolicyviolation`,onSecurityPolicyViolation),globalThis.removeEventListener(`error`,onResourceError,!0)),unsubscribeConsole()}}};export{errorsPlugin as default};
@@ -1,11 +1,2 @@
1
- import { ReplayOption } from "../replay/config.mjs";
2
- import { PluginCleanup, PluginContext } from "./types.mjs";
3
- import { PluginKey } from "@interfere/types/sdk/plugins/manifest";
4
- //#region src/plugins/lib/loader.d.ts
5
- type PluginOverrides = Partial<Record<Exclude<PluginKey, "replay">, boolean>> & {
6
- replay?: ReplayOption;
7
- };
8
- declare function resolveFeatures(overrides?: PluginOverrides): Record<PluginKey, boolean>;
9
- declare function loadPlugin(key: PluginKey, context: PluginContext): Promise<PluginCleanup | null>;
10
- //#endregion
11
- export { PluginOverrides, loadPlugin, resolveFeatures };
1
+ import { C as loadPlugin, S as PluginOverrides, w as resolveFeatures, x as LOADERS } from "../../provider-50LbJ4Tl.mjs";
2
+ export { LOADERS, PluginOverrides, loadPlugin, resolveFeatures };
@@ -1 +1 @@
1
- import{createLogger}from"../../util/log.mjs";import{PLUGIN_MANIFEST}from"@interfere/types/sdk/plugins/manifest";const log=createLogger(`plugins`),LOADERS={errors:()=>import(`../errors.mjs`),logs:()=>import(`../logs.mjs`),rageClick:()=>import(`../rage-clicks.mjs`),replay:()=>import(`../replay/index.mjs`)},DEFAULTS=Object.fromEntries(PLUGIN_MANIFEST.map(p=>[p.name,p.defaultEnabled]));function resolveFeatures(overrides){if(!overrides)return{...DEFAULTS};let{replay,...rest}=overrides;return{...DEFAULTS,...rest,replay:replay===void 0?DEFAULTS.replay:replay!==!1}}function resolvePlugin(mod){return`default`in mod&&typeof mod.default.setup==`function`?mod.default:mod}async function loadPlugin(key,context){let loader=LOADERS[key];if(!loader)return null;try{let cleanup=resolvePlugin(await loader()).setup(context);return log.debug(`loaded %s`,key),typeof cleanup==`function`?cleanup:null}catch{return log.error(`failed to load plugin %s`,key),null}}export{loadPlugin,resolveFeatures};
1
+ import{createLogger}from"../../util/log.mjs";import errorsPlugin from"../errors.mjs";import{PLUGIN_MANIFEST}from"@interfere/types/sdk/plugins/manifest";const log=createLogger(`plugins`),LOADERS={device:async()=>import(`../device.mjs`),errors:()=>errorsPlugin,logs:async()=>import(`../logs.mjs`),pageEvents:async()=>import(`../page-events.mjs`),rageClick:async()=>import(`../rage-clicks.mjs`),replay:async()=>import(`../replay/index.mjs`)},DEFAULTS=Object.fromEntries(PLUGIN_MANIFEST.map(p=>[p.name,p.defaultEnabled]));function resolveFeatures(overrides){if(!overrides)return{...DEFAULTS};let{replay,...rest}=overrides;return{...DEFAULTS,...rest,replay:replay===void 0?DEFAULTS.replay:replay!==!1}}function resolvePlugin(mod){return`default`in mod?mod.default:mod}async function loadPlugin(key,context){let loader=LOADERS[key];if(loader===void 0)return null;try{let cleanup=resolvePlugin(await loader()).setup(context);return log.debug(`loaded %s`,key),cleanup??null}catch{return log.error(`failed to load plugin %s`,key),null}}export{LOADERS,loadPlugin,resolveFeatures};
@@ -1,24 +1,2 @@
1
- import { ReplayConfig } from "../replay/config.mjs";
2
- import { SessionResumeReason } from "../../internal/activity.mjs";
3
- import { RecordExceptionOpts } from "../../internal/kernel.mjs";
4
- import { NonErrorException } from "@interfere/types/sdk/errors";
5
- import { PluginKey } from "@interfere/types/sdk/plugins/manifest";
6
- //#region src/plugins/lib/types.d.ts
7
- type PluginCleanup = () => void;
8
- type PluginConfigState = "disabled" | "enabled" | "pending";
9
- interface PluginContext {
10
- getPluginConfigState: (key: PluginKey) => PluginConfigState;
11
- getReplayConfig: () => ReplayConfig;
12
- getSessionId: () => string;
13
- getWindowId: () => string;
14
- onSessionPause: (handler: () => void) => () => void;
15
- onSessionResume: (handler: (reason: SessionResumeReason) => void) => () => void;
16
- recordException: (value: Error | NonErrorException, opts: RecordExceptionOpts) => void;
17
- subscribePluginConfigState: (key: PluginKey, listener: (state: PluginConfigState) => void) => () => void;
18
- }
19
- interface Plugin {
20
- readonly name: string;
21
- setup: (ctx: PluginContext) => PluginCleanup | undefined;
22
- }
23
- //#endregion
24
- export { Plugin, PluginCleanup, PluginConfigState, PluginContext };
1
+ import { D as PluginConfigState, E as PluginCleanup, O as PluginContext, T as Plugin, k as PluginTeardownReason } from "../../provider-50LbJ4Tl.mjs";
2
+ export { Plugin, PluginCleanup, PluginConfigState, PluginContext, PluginTeardownReason };
@@ -1,4 +1,4 @@
1
- import { Plugin } from "./lib/types.mjs";
1
+ import { T as Plugin } from "../provider-50LbJ4Tl.mjs";
2
2
  //#region src/plugins/logs.d.ts
3
3
  /**
4
4
  * Subscribes to the central console patch so string-only console calls
@@ -1 +1 @@
1
- import{activeKernel}from"../internal/kernel-registry.mjs";import{onConsoleCall}from"../internal/console-patch.mjs";import{safeStringify}from"../util/stringify.mjs";import{SeverityNumber}from"@opentelemetry/api-logs";const LEVEL_TO_SEVERITY={debug:{number:SeverityNumber.DEBUG,text:`DEBUG`},info:{number:SeverityNumber.INFO,text:`INFO`},log:{number:SeverityNumber.INFO,text:`INFO`},warn:{number:SeverityNumber.WARN,text:`WARN`},error:{number:SeverityNumber.ERROR,text:`ERROR`}},logsPlugin={name:`logs`,setup(){return onConsoleCall((level,args)=>{if(args.some(a=>a instanceof Error))return;let kernel=activeKernel();if(!kernel)return;let sev=LEVEL_TO_SEVERITY[level];kernel.recordLog({severityText:sev.text,severityNumber:sev.number,body:args.length===1?safeStringify(args[0]):args.map(safeStringify).join(` `),attributes:{"console.level":level}})})}};export{logsPlugin as default};
1
+ import{activeKernel}from"../internal/kernel-registry.mjs";import{onConsoleCall}from"../internal/console-patch.mjs";import{safeStringify}from"../util/stringify.mjs";import{SeverityNumber}from"@opentelemetry/api-logs";const LEVEL_TO_SEVERITY={debug:{number:SeverityNumber.DEBUG,text:`DEBUG`},error:{number:SeverityNumber.ERROR,text:`ERROR`},info:{number:SeverityNumber.INFO,text:`INFO`},log:{number:SeverityNumber.INFO,text:`INFO`},warn:{number:SeverityNumber.WARN,text:`WARN`}},logsPlugin={name:`logs`,setup(){return onConsoleCall((level,args)=>{if(args.some(a=>a instanceof Error))return;let kernel=activeKernel();if(!kernel)return;let sev=LEVEL_TO_SEVERITY[level];kernel.recordLog({attributes:{"console.level":level},body:args.length===1?safeStringify(args[0]):args.map(element=>safeStringify(element)).join(` `),severityNumber:sev.number,severityText:sev.text})})}};export{logsPlugin as default};
@@ -0,0 +1,5 @@
1
+ import { T as Plugin } from "../provider-50LbJ4Tl.mjs";
2
+ //#region src/plugins/page-events.d.ts
3
+ declare const pageEventsPlugin: Plugin;
4
+ //#endregion
5
+ export { pageEventsPlugin as default };
@@ -0,0 +1 @@
1
+ const pageEventsPlugin={name:`pageEvents`,setup(ctx){return ctx.startPageEventsCapture()??void 0}};export{pageEventsPlugin as default};
@@ -1,4 +1,4 @@
1
- import { Plugin } from "./lib/types.mjs";
1
+ import { T as Plugin } from "../provider-50LbJ4Tl.mjs";
2
2
  //#region src/plugins/rage-clicks.d.ts
3
3
  declare const rageClicksPlugin: Plugin;
4
4
  //#endregion
@@ -1 +1 @@
1
- import{trace}from"@opentelemetry/api";function distance(a,b){return Math.hypot(a.x-b.x,a.y-b.y)}function selectorFor(el){if(!el)return`unknown`;if(el.id)return`#${el.id}`;let classes=[...el.classList].slice(0,3).join(`.`),tag=el.tagName.toLowerCase();return classes?`${tag}.${classes}`:tag}const rageClicksPlugin={name:`rage-clicks`,setup(){let clicks=[],onClick=event=>{let now=Date.now();for(clicks.push({x:event.clientX,y:event.clientY,ts:now,target:event.target instanceof Element?event.target:null});clicks.length>0&&now-(clicks[0]?.ts??0)>800;)clicks.shift();if(clicks.length<3)return;let[anchor]=clicks;if(!anchor)return;let clustered=clicks.filter(c=>distance(anchor,c)<=30);if(clustered.length<3)return;let last=clustered.at(-1);last&&(trace.getTracer(`@interfere/react/rage-clicks`).startSpan(`rage_click`,{attributes:{"ui.event_type":`rage_click`,"ui.rage_click.count":clustered.length,"ui.rage_click.time_window_ms":last.ts-anchor.ts,"ui.rage_click.selector":selectorFor(last.target),"ui.rage_click.text":last.target?.textContent?.trim().slice(0,120)??``,"ui.rage_click.x":last.x,"ui.rage_click.y":last.y}}).end(),clicks.length=0)};return document.addEventListener(`click`,onClick,{capture:!0}),()=>{document.removeEventListener(`click`,onClick,{capture:!0})}}};export{rageClicksPlugin as default};
1
+ function distance(a,b){return Math.hypot(a.x-b.x,a.y-b.y)}function selectorFor(el){if(!el)return`unknown`;if(el.id)return`#${el.id}`;let classes=[...el.classList].slice(0,3).join(`.`),tag=el.tagName.toLowerCase();return classes?`${tag}.${classes}`:tag}const rageClicksPlugin={name:`rage-clicks`,setup(ctx){let clicks=[],onClick=event=>{let now=Date.now();for(clicks.push({target:event.target instanceof Element?event.target:null,ts:now,x:event.clientX,y:event.clientY});clicks.length>0&&now-(clicks[0]?.ts??0)>800;)clicks.shift();if(clicks.length<3)return;let[anchor]=clicks;if(!anchor)return;let clustered=clicks.filter(c=>distance(anchor,c)<=30);if(clustered.length<3)return;let last=clustered.at(-1);last&&(ctx.getTracer(`@interfere/react/rage-clicks`).startSpan(`rage_click`,{attributes:{"ui.event_type":`rage_click`,"ui.rage_click.count":clustered.length,"ui.rage_click.selector":selectorFor(last.target),"ui.rage_click.text":last.target?.textContent.trim().slice(0,120)??``,"ui.rage_click.time_window_ms":last.ts-anchor.ts,"ui.rage_click.x":last.x,"ui.rage_click.y":last.y}}).end(),clicks.length=0)};return document.addEventListener(`click`,onClick,{capture:!0}),()=>{document.removeEventListener(`click`,onClick,{capture:!0})}}};export{rageClicksPlugin as default};
@@ -1,12 +1,15 @@
1
1
  import { BufferedReplayEvent } from "./chunking.mjs";
2
+ import { eventWithTime } from "@rrweb/types";
2
3
  //#region src/plugins/replay/buffer.d.ts
3
- interface ReplayBuffer {
4
+ export interface ReplayBuffer {
4
5
  drain: () => BufferedReplayEvent[];
5
- push: (event: unknown) => void;
6
+ push: (event: eventWithTime) => void;
6
7
  }
7
- declare function createReplayBuffer(opts: {
8
+ export declare function createReplayBuffer(opts: {
8
9
  onSoftLimit: () => void;
9
10
  softLimitBytes: number;
10
- }): ReplayBuffer;
11
- //#endregion
12
- export { ReplayBuffer, createReplayBuffer };
11
+ }): {
12
+ drain(): BufferedReplayEvent[];
13
+ push(event: eventWithTime): void;
14
+ };
15
+ //#endregion
@@ -1 +1 @@
1
- import{classifyReplayEvent,utf8ByteLength}from"./chunking.mjs";function createReplayBuffer(opts){let entries=[],totalBytes=0;return{push(event){let json=JSON.stringify(event),bytes=utf8ByteLength(json),{isActivity,isFullSnapshot}=classifyReplayEvent(event);entries.push({json,ts:Date.now(),bytes,isActivity,isFullSnapshot}),totalBytes+=bytes,totalBytes>=opts.softLimitBytes&&opts.onSoftLimit()},drain(){let drained=entries;return entries=[],totalBytes=0,drained}}}export{createReplayBuffer};
1
+ import{classifyReplayEvent,utf8ByteLength}from"./chunking.mjs";function createReplayBuffer(opts){let entries=[],totalBytes=0;return{drain(){let drained=entries;return entries=[],totalBytes=0,drained},push(event){let json=JSON.stringify(event),bytes=utf8ByteLength(json),{isActivity,isFullSnapshot}=classifyReplayEvent(event);entries.push({json,ts:Date.now(),bytes,isActivity,isFullSnapshot}),totalBytes+=bytes,totalBytes>=opts.softLimitBytes&&opts.onSoftLimit()}}}export{createReplayBuffer};
@@ -1,12 +1,12 @@
1
1
  //#region src/plugins/replay/chunking.d.ts
2
- interface BufferedReplayEvent {
2
+ export interface BufferedReplayEvent {
3
3
  bytes: number;
4
4
  isActivity: boolean;
5
5
  isFullSnapshot: boolean;
6
6
  json: string;
7
7
  ts: number;
8
8
  }
9
- interface ReplayChunkPayload {
9
+ export interface ReplayChunkPayload {
10
10
  activityCount: number;
11
11
  bodyJson: string;
12
12
  eventCount: number;
@@ -14,16 +14,25 @@ interface ReplayChunkPayload {
14
14
  hasFullSnapshot: boolean;
15
15
  lastTs: number | null;
16
16
  }
17
- interface SplitReplayEventsResult {
17
+ export interface SplitReplayEventsResult {
18
18
  chunks: BufferedReplayEvent[][];
19
19
  droppedEventBytes: number[];
20
20
  }
21
- declare function classifyReplayEvent(event: unknown): {
21
+ export declare function classifyReplayEvent(event: unknown): {
22
22
  isActivity: boolean;
23
23
  isFullSnapshot: boolean;
24
24
  };
25
- declare function toReplayChunkPayload(group: BufferedReplayEvent[]): ReplayChunkPayload;
26
- declare function splitReplayEvents(buffered: BufferedReplayEvent[]): SplitReplayEventsResult;
27
- declare function utf8ByteLength(value: string): number;
28
- //#endregion
29
- export { BufferedReplayEvent, ReplayChunkPayload, SplitReplayEventsResult, classifyReplayEvent, splitReplayEvents, toReplayChunkPayload, utf8ByteLength };
25
+ export declare function toReplayChunkPayload(group: BufferedReplayEvent[]): {
26
+ activityCount: number;
27
+ bodyJson: string;
28
+ eventCount: number;
29
+ firstTs: number | null;
30
+ hasFullSnapshot: boolean;
31
+ lastTs: number | null;
32
+ };
33
+ export declare function splitReplayEvents(buffered: BufferedReplayEvent[]): {
34
+ chunks: BufferedReplayEvent[][];
35
+ droppedEventBytes: number[];
36
+ };
37
+ export declare function utf8ByteLength(value: string): number;
38
+ //#endregion
@@ -1,2 +1,2 @@
1
- import{EventType,IncrementalSource}from"@rrweb/types";const textEncoder=new TextEncoder,ACTIVITY_SOURCES=new Set([IncrementalSource.MouseMove,IncrementalSource.MouseInteraction,IncrementalSource.Scroll,IncrementalSource.Input,IncrementalSource.TouchMove,IncrementalSource.Drag,IncrementalSource.Selection]);function classifyReplayEvent(event){let typed=event;if(!typed||typeof typed.type!=`number`)return{isActivity:!1,isFullSnapshot:!1};if(typed.type===EventType.FullSnapshot)return{isActivity:!1,isFullSnapshot:!0};if(typed.type===EventType.IncrementalSnapshot&&typed.data){let{source}=typed.data;if(source!==void 0&&ACTIVITY_SOURCES.has(source))return{isActivity:!0,isFullSnapshot:!1}}return{isActivity:!1,isFullSnapshot:!1}}function countActivityEvents(group){let count=0;for(let entry of group)entry.isActivity&&(count+=1);return count}function toReplayChunkPayload(group){let parts=[],hasFullSnapshot=!1;for(let entry of group)parts.push(entry.json),entry.isFullSnapshot&&(hasFullSnapshot=!0);let firstTs=group[0]?.ts??null;return{activityCount:countActivityEvents(group),bodyJson:parts.length>0?`${parts.join(`
1
+ import{EventType,IncrementalSource}from"@rrweb/types";const textEncoder=new TextEncoder,ACTIVITY_SOURCES=new Set([IncrementalSource.MouseMove,IncrementalSource.MouseInteraction,IncrementalSource.Scroll,IncrementalSource.Input,IncrementalSource.TouchMove,IncrementalSource.Drag,IncrementalSource.Selection]);function classifyReplayEvent(event){if(typeof event!=`object`||!event||!(`type`in event)||typeof event.type!=`number`)return{isActivity:!1,isFullSnapshot:!1};if(event.type===EventType.FullSnapshot)return{isActivity:!1,isFullSnapshot:!0};if(event.type===EventType.IncrementalSnapshot&&`data`in event&&event.data!==null&&typeof event.data==`object`&&`source`in event.data){let{source}=event.data;if(typeof source==`number`&&ACTIVITY_SOURCES.has(source))return{isActivity:!0,isFullSnapshot:!1}}return{isActivity:!1,isFullSnapshot:!1}}function countActivityEvents(group){let count=0;for(let entry of group)entry.isActivity&&(count+=1);return count}function toReplayChunkPayload(group){let parts=[],hasFullSnapshot=!1;for(let entry of group)parts.push(entry.json),entry.isFullSnapshot&&(hasFullSnapshot=!0);let firstTs=group[0]?.ts??null;return{activityCount:countActivityEvents(group),bodyJson:parts.length>0?`${parts.join(`
2
2
  `)}\n`:``,eventCount:group.length,firstTs,hasFullSnapshot,lastTs:group.at(-1)?.ts??null}}function splitReplayEvents(buffered){let chunks=[],droppedEventBytes=[],current=[],currentBytes=0;for(let entry of buffered){let singleEventBodyBytes=entry.bytes+1;if(singleEventBodyBytes>8388608){droppedEventBytes.push(singleEventBodyBytes);continue}current.length>0&&currentBytes+singleEventBodyBytes>6291456&&(chunks.push(current),current=[],currentBytes=0),currentBytes+=singleEventBodyBytes,current.push(entry)}return current.length>0&&chunks.push(current),{chunks,droppedEventBytes}}function utf8ByteLength(value){return textEncoder.encode(value).length}export{classifyReplayEvent,splitReplayEvents,toReplayChunkPayload,utf8ByteLength};
@@ -1,9 +1,8 @@
1
1
  //#region src/plugins/replay/compressor-host.d.ts
2
2
  /** `gzip` is `null` when compression is unavailable — callers must POST the chunk uncompressed. */
3
- interface Compressor {
3
+ export interface Compressor {
4
4
  readonly dispose: () => void;
5
5
  readonly gzip: ((bytes: Uint8Array) => Promise<Uint8Array<ArrayBuffer>>) | null;
6
6
  }
7
- declare function createCompressor(): Compressor;
8
- //#endregion
9
- export { Compressor, createCompressor };
7
+ export declare function createCompressor(): Compressor;
8
+ //#endregion
@@ -1 +1 @@
1
- import{createLogger}from"../../util/log.mjs";const log=createLogger(`replay/compressor`),FAIL_OPEN={gzip:null,dispose:()=>void 0},gzip=async bytes=>{let cs=new CompressionStream(`gzip`),compressed=new Response(cs.readable).arrayBuffer(),writer=cs.writable.getWriter();return await writer.write(new Uint8Array(bytes)),await writer.close(),new Uint8Array(await compressed)};function createCompressor(){return typeof CompressionStream>`u`?(log.warn(`CompressionStream unavailable; replay chunks will POST uncompressed`),FAIL_OPEN):{gzip,dispose:()=>void 0}}export{createCompressor};
1
+ import{createLogger}from"../../util/log.mjs";const log=createLogger(`replay/compressor`),FAIL_OPEN={dispose:()=>void 0,gzip:null},gzip=async bytes=>{let cs=new CompressionStream(`gzip`),compressed=new Response(cs.readable).arrayBuffer(),writer=cs.writable.getWriter();return await writer.write(new Uint8Array(bytes)),await writer.close(),new Uint8Array(await compressed)};function createCompressor(){return typeof CompressionStream>`u`?(log.warn(`CompressionStream unavailable; replay chunks will POST uncompressed`),FAIL_OPEN):{dispose:()=>void 0,gzip}}export{createCompressor};
@@ -1,12 +1,2 @@
1
- import { SetRequired } from "@interfere/helpers/set-required";
2
- import { recordOptions } from "rrweb";
3
- //#region src/plugins/replay/config.d.ts
4
- declare const INTERFERE_MASK_TEXT_CLASS = "interfere-mask";
5
- declare const INTERFERE_BLOCK_CLASS = "interfere-block";
6
- declare const INTERFERE_IGNORE_CLASS = "interfere-ignore";
7
- type ReplayConfig = Pick<recordOptions<unknown>, "blockClass" | "blockSelector" | "ignoreClass" | "ignoreSelector" | "maskAllInputs" | "maskInputFn" | "maskInputOptions" | "maskTextClass" | "maskTextFn" | "maskTextSelector" | "recordCanvas">;
8
- type ReplayOption = boolean | ReplayConfig;
9
- type ReplayRecordOptions = SetRequired<ReplayConfig, "maskTextClass" | "blockClass" | "ignoreClass">;
10
- declare function toRecordOptions(config: ReplayConfig): ReplayRecordOptions;
11
- //#endregion
1
+ import { a as ReplayOption, i as ReplayConfig, n as INTERFERE_IGNORE_CLASS, o as ReplayRecordOptions, r as INTERFERE_MASK_TEXT_CLASS, s as toRecordOptions, t as INTERFERE_BLOCK_CLASS } from "../../config-Rm-ct4K1.mjs";
12
2
  export { INTERFERE_BLOCK_CLASS, INTERFERE_IGNORE_CLASS, INTERFERE_MASK_TEXT_CLASS, ReplayConfig, ReplayOption, ReplayRecordOptions, toRecordOptions };
@@ -1 +1 @@
1
- const INTERFERE_MASK_TEXT_CLASS=`interfere-mask`,INTERFERE_BLOCK_CLASS=`interfere-block`,INTERFERE_IGNORE_CLASS=`interfere-ignore`;function toRecordOptions(config){return{...config,maskTextClass:INTERFERE_MASK_TEXT_CLASS,blockClass:INTERFERE_BLOCK_CLASS,ignoreClass:INTERFERE_IGNORE_CLASS}}export{INTERFERE_BLOCK_CLASS,INTERFERE_IGNORE_CLASS,INTERFERE_MASK_TEXT_CLASS,toRecordOptions};
1
+ const INTERFERE_MASK_TEXT_CLASS=`interfere-mask`,INTERFERE_BLOCK_CLASS=`interfere-block`,INTERFERE_IGNORE_CLASS=`interfere-ignore`;function toRecordOptions(config){return{...config,blockClass:INTERFERE_BLOCK_CLASS,ignoreClass:INTERFERE_IGNORE_CLASS,maskTextClass:INTERFERE_MASK_TEXT_CLASS}}export{INTERFERE_BLOCK_CLASS,INTERFERE_IGNORE_CLASS,INTERFERE_MASK_TEXT_CLASS,toRecordOptions};
@@ -1,21 +1,20 @@
1
- import { PluginContext } from "../lib/types.mjs";
1
+ import { O as PluginContext } from "../../provider-50LbJ4Tl.mjs";
2
+ import { resolveTargets } from "../../internal/config.mjs";
2
3
  import { ReplayChunkPayload } from "./chunking.mjs";
3
4
  import { Compressor } from "./compressor-host.mjs";
4
5
  //#region src/plugins/replay/delivery.d.ts
5
- type DeliverResult = "ok" | "retryable" | "fatal";
6
- interface ReplayChunkRef {
6
+ export type DeliverResult = "ok" | "retryable" | "fatal";
7
+ export interface ReplayChunkRef {
7
8
  segmentId: number;
8
9
  windowId: string;
9
10
  }
10
- interface DeliverInput {
11
- authHeaders: Record<string, string>;
11
+ export interface DeliverInput {
12
+ target: ReturnType<typeof resolveTargets>["ingest"];
12
13
  chunk: ReplayChunkRef;
13
14
  compressor: Compressor;
14
15
  ctx: PluginContext;
15
16
  payload: ReplayChunkPayload;
16
17
  skipCompression: boolean;
17
- uploadBaseUrl: string;
18
18
  }
19
- declare function deliverChunk({ ctx, chunk, uploadBaseUrl, authHeaders, compressor, payload, skipCompression }: DeliverInput): Promise<DeliverResult>;
20
- //#endregion
21
- export { DeliverInput, DeliverResult, ReplayChunkRef, deliverChunk };
19
+ export declare function deliverChunk({ ctx, chunk, target, compressor, payload, skipCompression }: DeliverInput): Promise<"fatal" | "ok" | "retryable">;
20
+ //#endregion
@@ -1 +1 @@
1
- import{createLogger}from"../../util/log.mjs";import{appendPathBeforeQuery}from"../../internal/config.mjs";import{trace}from"@opentelemetry/api";const log=createLogger(`replay`),textEncoder=new TextEncoder;async function prepareBody(compressor,rawBytes){if(!compressor.gzip)return{body:rawBytes,encoding:null};try{return{body:await compressor.gzip(rawBytes),encoding:`gzip`}}catch(error){return log.warn(`gzip failed for chunk; sending uncompressed: %o`,error),{body:rawBytes,encoding:null}}}function encodeReplayMeta(chunk,payload){return btoa(JSON.stringify({windowId:chunk.windowId,segmentId:chunk.segmentId,firstTs:payload.firstTs,lastTs:payload.lastTs,eventCount:payload.eventCount,hasFullSnapshot:payload.hasFullSnapshot,activityCount:payload.activityCount}))}async function deliverChunk({ctx,chunk,uploadBaseUrl,authHeaders,compressor,payload,skipCompression}){let sessionId=ctx.getSessionId();if(!sessionId)return`ok`;let rawBytes=textEncoder.encode(payload.bodyJson),uncompressedBytes=rawBytes.byteLength,prepared=skipCompression?{body:rawBytes,encoding:null}:await prepareBody(compressor,rawBytes),headers={...authHeaders,"content-type":`application/json`,"x-replay-meta":encodeReplayMeta(chunk,payload),...prepared.encoding===`gzip`?{"content-encoding":`gzip`}:{}},res;try{res=await fetch(appendPathBeforeQuery(uploadBaseUrl,`/v2/replay/upload/${encodeURIComponent(sessionId)}`),{method:`POST`,headers,credentials:`omit`,body:prepared.body})}catch(error){return log.warn(`replay chunk upload failed: %o`,error),`retryable`}if(!res.ok)return log.warn(`replay chunk upload rejected (%d)`,res.status),res.status>=400&&res.status<500?`fatal`:`retryable`;let objectKey=await res.json().catch(()=>({}));return trace.getTracer(`@interfere/react/replay`).startSpan(`replay.chunk`,{attributes:{...objectKey.objectKey?{"replay.chunk.uri":objectKey.objectKey}:{},"replay.chunk.size_bytes":uncompressedBytes,...prepared.encoding===`gzip`?{"replay.chunk.compressed_bytes":prepared.body.byteLength}:{},"replay.chunk.event_count":payload.eventCount,...payload.firstTs===null?{}:{"replay.chunk.first_event_ts":payload.firstTs},...payload.lastTs===null?{}:{"replay.chunk.last_event_ts":payload.lastTs}}}).end(),`ok`}export{deliverChunk};
1
+ import{createLogger}from"../../util/log.mjs";import{uploadReplayChunk}from"./upload.mjs";import{trace}from"@opentelemetry/api";import{omitUndefined}from"@interfere/helpers/omit-undefined";const log=createLogger(`replay`),textEncoder=new TextEncoder;async function prepareBody(compressor,rawBytes){if(!compressor.gzip)return{body:rawBytes,encoding:null};try{return{body:await compressor.gzip(rawBytes),encoding:`gzip`}}catch(error){return log.warn(`gzip failed for chunk; sending uncompressed: %o`,error),{body:rawBytes,encoding:null}}}function encodeReplayMeta(chunk,payload){return btoa(JSON.stringify({activityCount:payload.activityCount,eventCount:payload.eventCount,firstTs:payload.firstTs,hasFullSnapshot:payload.hasFullSnapshot,lastTs:payload.lastTs,segmentId:chunk.segmentId,windowId:chunk.windowId}))}async function deliverChunk({ctx,chunk,target,compressor,payload,skipCompression}){let sessionId=ctx.getSessionId();if(!sessionId)return`ok`;let rawBytes=textEncoder.encode(payload.bodyJson),uncompressedBytes=rawBytes.byteLength,prepared=skipCompression?{body:rawBytes,encoding:null}:await prepareBody(compressor,rawBytes),headers={"x-replay-meta":encodeReplayMeta(chunk,payload)};prepared.encoding===`gzip`&&(headers[`content-encoding`]=`gzip`);let response;try{let upload=await uploadReplayChunk(target,sessionId,prepared.body,headers);if(!upload.ok)return await upload.body?.cancel(),upload.status>=400&&upload.status<500?`fatal`:`retryable`;response=await upload.json()}catch(error){return log.warn(`replay chunk upload failed: %o`,error),`retryable`}let objectKey=typeof response==`object`&&response&&`objectKey`in response&&typeof response.objectKey==`string`?response.objectKey:null,attributes=omitUndefined({"replay.chunk.size_bytes":uncompressedBytes,"replay.chunk.event_count":payload.eventCount,"replay.chunk.uri":objectKey||void 0,"replay.chunk.compressed_bytes":prepared.encoding===`gzip`?prepared.body.byteLength:void 0,"replay.chunk.first_event_ts":payload.firstTs??void 0,"replay.chunk.last_event_ts":payload.lastTs??void 0});return trace.getTracer(`@interfere/react/replay`).startSpan(`replay.chunk`,{attributes}).end(),`ok`}export{deliverChunk};
@@ -1,4 +1,4 @@
1
- import { Plugin } from "../lib/types.mjs";
1
+ import { T as Plugin } from "../../provider-50LbJ4Tl.mjs";
2
2
  //#region src/plugins/replay/index.d.ts
3
3
  declare const replayPlugin: Plugin;
4
4
  //#endregion
@@ -1 +1 @@
1
- import{createLogger}from"../../util/log.mjs";import{onPageHidden,onPageShown}from"../../internal/page-lifecycle.mjs";import{resolveTargets}from"../../internal/config.mjs";import{splitReplayEvents,toReplayChunkPayload}from"./chunking.mjs";import{createReplayBuffer}from"./buffer.mjs";import{createCompressor}from"./compressor-host.mjs";import{toRecordOptions}from"./config.mjs";import{deliverChunk}from"./delivery.mjs";import{startReplayRecorder}from"./recorder.mjs";import{createSegmentSequence}from"./sequence.mjs";const log=createLogger(`replay`),replayPlugin={name:`replay`,setup(ctx){let targets=resolveTargets(),uploadBaseUrl=targets.collectorBaseUrl,authHeaders=Object.fromEntries(targets.ingest.headers.entries()),recorder=null,flushTimer=null,unsubscribeConfig=null,unsubscribeHidden=null,unsubscribeShown=null,unsubscribePause=null,unsubscribeResume=null,isPaused=!1,compressor=createCompressor(),windowId=ctx.getWindowId(),sequence=createSegmentSequence(windowId),consecutiveFailures=0,halted=!1;function halt(){halted||(halted=!0,flushTimer&&=(clearInterval(flushTimer),null),recorder?.stop(),recorder=null)}function handleResult(result){if(result===`ok`){consecutiveFailures=0;return}if(result===`fatal`){log.warn(`replay halted: upload rejected`),halt();return}consecutiveFailures+=1,consecutiveFailures>=3&&(log.warn(`replay halted after %d consecutive upload failures`,consecutiveFailures),halt())}let buffer=createReplayBuffer({softLimitBytes:4194304,onSoftLimit:flush});function flush(opts){if(halted||ctx.getPluginConfigState(`replay`)!==`enabled`)return;let drained=buffer.drain();if(drained.length===0)return;let{chunks,droppedEventBytes}=splitReplayEvents(drained);for(let bytes of droppedEventBytes)log.warn(`dropping replay event of ~%d bytes: too large to upload`,bytes);for(let group of chunks)sendChunk(toReplayChunkPayload(group),opts?.skipCompression??!1)}async function sendChunk(payload,skipCompression){try{handleResult(await deliverChunk({ctx,chunk:{windowId,segmentId:sequence.take()},uploadBaseUrl,authHeaders,compressor,payload,skipCompression}))}catch(error){log.warn(`replay chunk dropped: %o`,error),handleResult(`retryable`)}}let pauseSending=unload=>{isPaused||(isPaused=!0,flush(unload?{skipCompression:!0}:void 0))},resumeSending=()=>{isPaused&&(isPaused=!1,recorder?.takeFullSnapshot())},recordOptions=toRecordOptions(ctx.getReplayConfig());return(async()=>{recorder=await startReplayRecorder(event=>{isPaused||buffer.push(event)},recordOptions),recorder&&(unsubscribeConfig=ctx.subscribePluginConfigState(`replay`,state=>{state===`enabled`&&flush()}),flushTimer=setInterval(flush,1e4),unsubscribeHidden=onPageHidden(()=>pauseSending(!0)),unsubscribeShown=onPageShown(resumeSending),unsubscribePause=ctx.onSessionPause(()=>pauseSending(!1)),unsubscribeResume=ctx.onSessionResume(resumeSending),log.debug(`recording started`))})(),()=>{flush(),recorder?.stop(),flushTimer&&clearInterval(flushTimer),unsubscribeConfig?.(),unsubscribeHidden?.(),unsubscribeShown?.(),unsubscribePause?.(),unsubscribeResume?.(),compressor.dispose()}}};export{replayPlugin as default};
1
+ import{createLogger}from"../../util/log.mjs";import{onPageHidden,onPageShown}from"../../internal/page-lifecycle.mjs";import{resolveTargets}from"../../internal/config.mjs";import{splitReplayEvents,toReplayChunkPayload}from"./chunking.mjs";import{createReplayBuffer}from"./buffer.mjs";import{createCompressor}from"./compressor-host.mjs";import{toRecordOptions}from"./config.mjs";import{deliverChunk}from"./delivery.mjs";import{startReplayRecorder}from"./recorder.mjs";import{createSegmentSequence}from"./sequence.mjs";import{EventType}from"@rrweb/types";const log=createLogger(`replay`),replayPlugin={name:`replay`,setup(ctx){let targets=resolveTargets(),recorder=null,flushTimer=null,unsubscribeConfig=null,unsubscribeHidden=null,unsubscribeShown=null,unsubscribePause=null,unsubscribeResume=null,isPaused=!1,startup=new AbortController,compressor=createCompressor(),windowId=ctx.getWindowId(),sequence=createSegmentSequence(windowId),consecutiveFailures=0,recorderFaults=0,halted=!1;function halt(){halted||(halted=!0,startup.abort(),flushTimer&&=(clearInterval(flushTimer),null),recorder?.stop(),recorder=null)}function handleResult(result){if(result===`ok`){consecutiveFailures=0;return}if(result===`fatal`){log.warn(`replay halted: upload rejected`),halt();return}consecutiveFailures+=1,consecutiveFailures>=3&&(log.warn(`replay halted after %d consecutive upload failures`,consecutiveFailures),halt())}function handleRecorderFault(error){recorderFaults+=1,!(recorderFaults>10)&&(log.warn(`recorder fault: %s`,error instanceof Error?error.constructor.name:`UnknownError`),recorderFaults===10&&(log.warn(`replay halted after %d recorder faults`,10),flush(),halt()))}let buffer=createReplayBuffer({onSoftLimit:flush,softLimitBytes:4194304});function flush(opts){if(halted||ctx.getPluginConfigState(`replay`)!==`enabled`)return;let drained=buffer.drain();if(drained.length===0)return;let{chunks,droppedEventBytes}=splitReplayEvents(drained);for(let bytes of droppedEventBytes)log.warn(`dropping replay event of ~%d bytes: too large to upload`,bytes);for(let group of chunks)sendChunk(toReplayChunkPayload(group),opts?.skipCompression??!1)}async function sendChunk(payload,skipCompression){try{handleResult(await deliverChunk({target:targets.ingest,chunk:{segmentId:sequence.take(),windowId},compressor,ctx,payload,skipCompression}))}catch(error){log.warn(`replay chunk dropped: %s`,error instanceof Error?error.constructor.name:`UnknownError`),handleResult(`retryable`)}}let pauseRecording=unload=>{isPaused||(isPaused=!0,recorder?.stop(),flush(unload?{skipCompression:!0}:void 0))},resumeRecording=()=>{isPaused&&(isPaused=!1,recorder?.start())},recordOptions=toRecordOptions(ctx.getReplayConfig());return(async()=>{if(recorder=await startReplayRecorder({onEvent:(event,isCheckout)=>{startup.signal.aborted||(isCheckout&&event.type===EventType.Meta&&flush(),buffer.push(event))},onFault:handleRecorderFault,recordOptions,signal:startup.signal}),startup.signal.aborted){recorder?.stop(),recorder=null;return}recorder&&(unsubscribeConfig=ctx.subscribePluginConfigState(`replay`,state=>{state===`enabled`&&flush()}),flushTimer=setInterval(flush,1e4),unsubscribeHidden=onPageHidden(()=>{pauseRecording(!0)}),unsubscribeShown=onPageShown(resumeRecording),unsubscribePause=ctx.onSessionPause(()=>{pauseRecording(!1)}),unsubscribeResume=ctx.onSessionResume(resumeRecording),log.debug(`recording started`))})().catch(error=>{log.warn(`replay initialization failed: %s`,error instanceof Error?error.constructor.name:`UnknownError`),halt()}),reason=>{reason===`consent-revoked`?(buffer.drain(),log.debug(`replay buffer discarded: consent revoked`)):flush(),startup.abort(),recorder?.stop(),flushTimer&&clearInterval(flushTimer),unsubscribeConfig?.(),unsubscribeHidden?.(),unsubscribeShown?.(),unsubscribePause?.(),unsubscribeResume?.(),compressor.dispose()}}};export{replayPlugin as default};
@@ -1,9 +1,15 @@
1
- import { ReplayRecordOptions } from "./config.mjs";
1
+ import { o as ReplayRecordOptions } from "../../config-Rm-ct4K1.mjs";
2
+ import { eventWithTime } from "@rrweb/types";
2
3
  //#region src/plugins/replay/recorder.d.ts
3
- interface ReplayRecorder {
4
+ export interface ReplayRecorder {
5
+ start: () => boolean;
4
6
  stop: () => void;
5
- takeFullSnapshot: () => void;
6
7
  }
7
- declare function startReplayRecorder(onEvent: (event: unknown) => void, maskingOptions: ReplayRecordOptions): Promise<ReplayRecorder | null>;
8
- //#endregion
9
- export { ReplayRecorder, startReplayRecorder };
8
+ export interface StartReplayRecorderOptions {
9
+ onEvent: (event: eventWithTime, isCheckout?: boolean) => void;
10
+ onFault: (error: unknown) => void;
11
+ recordOptions: ReplayRecordOptions;
12
+ signal?: AbortSignal;
13
+ }
14
+ export declare function startReplayRecorder({ onEvent, onFault, recordOptions, signal }: StartReplayRecorderOptions): Promise<ReplayRecorder | null>;
15
+ //#endregion
@@ -1 +1 @@
1
- import{createLogger}from"../../util/log.mjs";const log=createLogger(`replay`);async function startReplayRecorder(onEvent,maskingOptions){try{let rrweb=await import(`rrweb`),stop=rrweb.record({emit:onEvent,recordAfter:`load`,inlineStylesheet:!0,slimDOMOptions:`all`,checkoutEveryNms:6e4,sampling:{mousemove:50,scroll:150,media:800},...maskingOptions})??null;return{stop:()=>{stop?.()},takeFullSnapshot:()=>{try{rrweb.record.takeFullSnapshot?.(!0)}catch(error){log.warn(`takeFullSnapshot failed: %o`,error)}}}}catch{return log.error(`rrweb failed to load, replay disabled`),null}}export{startReplayRecorder};
1
+ import{createLogger}from"../../util/log.mjs";const log=createLogger(`replay`);async function startReplayRecorder({onEvent,onFault,recordOptions,signal}){let record;try{({record}=await import(`../../rrweb-CE6GKCEq.mjs`))}catch{return log.error(`rrweb failed to load, replay disabled`),null}if(signal?.aborted)return null;let stopRecording,recorder={start:()=>(stopRecording??=record({emit:onEvent,recordAfter:`load`,inlineStylesheet:!0,slimDOMOptions:`all`,checkoutEveryNms:6e4,sampling:{media:800,mousemove:50,scroll:150},...recordOptions,errorHandler:error=>(onFault(error),!0)}),stopRecording!==void 0),stop:()=>{stopRecording?.(),stopRecording=void 0}};return recorder.start()?recorder:(log.error(`rrweb failed to start, replay disabled`),null)}export{startReplayRecorder};
@@ -1,7 +1,8 @@
1
1
  //#region src/plugins/replay/sequence.d.ts
2
- interface SegmentSequence {
2
+ export interface SegmentSequence {
3
3
  take: () => number;
4
4
  }
5
- declare function createSegmentSequence(windowId: string): SegmentSequence;
6
- //#endregion
7
- export { SegmentSequence, createSegmentSequence };
5
+ export declare function createSegmentSequence(windowId: string): {
6
+ take(): number;
7
+ };
8
+ //#endregion
@@ -1 +1 @@
1
- function sessionStore(){try{let store=globalThis.sessionStorage,probe=`__interfere_replay_seq_probe__`;return store.setItem(probe,`1`),store.removeItem(probe),store}catch{return null}}function createSegmentSequence(windowId){let key=`interfere:replay_seq:${windowId}`,store=sessionStore(),stored=store?.getItem(key),next=stored?Number(stored):0;return(!Number.isInteger(next)||next<0)&&(next=0),{take(){let seq=next;return next+=1,store?.setItem(key,String(next)),seq}}}export{createSegmentSequence};
1
+ function sessionStore(){try{let store=globalThis.sessionStorage,probe=`__interfere_replay_seq_probe__`;return store.setItem(probe,`1`),store.removeItem(probe),store}catch{return null}}function createSegmentSequence(windowId){let key=`interfere:replay_seq:${windowId}`,store=sessionStore(),stored=store?.getItem(key),next=stored?Number(stored):0;return(!Number.isInteger(next)||next<0)&&(next=0),{take(){let persisted=Number(store?.getItem(key));Number.isSafeInteger(persisted)&&persisted>next&&(next=persisted);let seq=next;return next+=1,store?.setItem(key,String(next)),seq}}}export{createSegmentSequence};
@@ -0,0 +1,4 @@
1
+ import { resolveTargets } from "../../internal/config.mjs";
2
+ //#region src/plugins/replay/upload.d.ts
3
+ export declare function uploadReplayChunk(target: ReturnType<typeof resolveTargets>["ingest"], sessionId: string, body: Uint8Array<ArrayBuffer>, headers: Record<string, string>): Promise<Response>;
4
+ //#endregion
@@ -0,0 +1 @@
1
+ async function uploadReplayChunk(target,sessionId,body,headers){let requestHeaders=new Headers(target.headers);target.publicKeyHeader&&requestHeaders.set(`x-interfere-public-key`,target.publicKeyHeader.apiKey);for(let[name,value]of Object.entries(headers))requestHeaders.set(name,value);return requestHeaders.set(`content-type`,`application/octet-stream`),fetch(new URL(`/v3/replay/upload/${encodeURIComponent(sessionId)}`,target.baseUrl),{method:`POST`,credentials:`omit`,headers:requestHeaders,body:new Blob([body]),signal:AbortSignal.timeout(target.timeoutInSeconds*1e3)})}export{uploadReplayChunk};
@@ -0,0 +1,26 @@
1
+ //#region src/internal/otel/propagation.d.ts
2
+ /**
3
+ * Reads the W3C `traceparent` (and optional `tracestate` / `baggage`) meta
4
+ * tags from the document head and extracts an OTel `Context`. SSR renderers (Next, Vite,
5
+ * …) inject the server-side request span's context so the client SDK can
6
+ * stitch its spans onto the same trace.
7
+ *
8
+ * Returns `null` when:
9
+ * - called server-side (no `document`)
10
+ * - no `traceparent` meta tag is present
11
+ * - the extracted context has an invalid trace id
12
+ * - the `sampled` flag is unset — the browser doesn't honor the bit when
13
+ * creating child spans, so an unsampled parent would orphan every
14
+ * browser span under a trace with no recorded server segments. Drop
15
+ * instead so spans fall back to a fresh root.
16
+ * - the server stamped a `tracestate` freshness timestamp
17
+ * (`interfere=<unix seconds>`) and it is older than two minutes —
18
+ * cached HTML (ISR revalidation, CDN full-page caches) serves one
19
+ * render's traceparent to every visitor in the cache window, which
20
+ * would pile all of their sessions onto a single stale trace. A
21
+ * missing or malformed stamp is accepted for compatibility with
22
+ * servers that don't emit one.
23
+ */
24
+ declare function readPropagationFromDocument(): import("@opentelemetry/api").Context | null;
25
+ //#endregion
26
+ export { readPropagationFromDocument as t };