@interfere/react 12.0.5 → 12.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -0
- package/dist/actionable-DOmVf_ib.mjs +1 -0
- package/dist/activity-D18VXGTn.mjs +1 -0
- package/dist/{activity-BfYxFVcK.d.mts → activity-Duhfgvxt.d.mts} +1 -1
- package/dist/{api-DEVCOKkJ.d.mts → api-CMPV9rgU.d.mts} +1 -1
- package/dist/api-DXmjUMZE.mjs +1 -0
- package/dist/api.mjs +1 -1
- package/dist/bot-YLSbnCeg.mjs +1 -0
- package/dist/buffer-BRn_kSm-.mjs +1 -0
- package/dist/capture-BV2RlsYg.mjs +1 -0
- package/dist/capture-boundary-Cz0jO-y5.mjs +1 -0
- package/dist/chunking-Dvs3f50A.d.mts +39 -0
- package/dist/chunking-qZffPbyY.mjs +2 -0
- package/dist/compressor-host-BAz6860r.d.mts +9 -0
- package/dist/compressor-host-CrKngamF.mjs +1 -0
- package/dist/config-Bm8myQlS.mjs +1 -0
- package/dist/config-CBqqY1AV.d.mts +29 -0
- package/dist/config-DapTbKhs.mjs +1 -0
- package/dist/{config-Rm-ct4K1.d.mts → config-Dyc09HCZ.d.mts} +2 -1
- package/dist/consent-COUmLJLD.mjs +1 -0
- package/dist/console-patch-WNKoLE7U.mjs +1 -0
- package/dist/delivery-DehIJWRh.mjs +1 -0
- package/dist/device-6T3DYkLD.mjs +1 -0
- package/dist/device-DRK7hhLi.mjs +1 -0
- package/dist/device-metadata-Ffi__vup.mjs +1 -0
- package/dist/{dist-ByNfzdQp.mjs → dist-Bcb677YG.mjs} +2 -2
- package/dist/environment-CoEXhF1a.mjs +1 -0
- package/dist/environment-_LKcAXKG.d.mts +9 -0
- package/dist/error-boundary.d.mts +1 -1
- package/dist/error-boundary.mjs +1 -1
- package/dist/errors-BDmCWb5z.mjs +1 -0
- package/dist/event-capabilities-Dd0Hoaq2.mjs +1 -0
- package/dist/exporter-DjvOtWYJ.mjs +1 -0
- package/dist/exporter-logs-DS2AXWnV.mjs +1 -0
- package/dist/exporter-metrics-DZYqUo6_.mjs +1 -0
- package/dist/geo-D2wa9bGs.mjs +2 -0
- package/dist/global-DYq1Z4_H.mjs +1 -0
- package/dist/http-span-route-t2gig-KI.mjs +1 -0
- package/dist/hydration-BIp2cKhz.mjs +1 -0
- package/dist/index-DBsXraeJ.d.mts +4 -0
- package/dist/initial-navigation-YeK6UUHX.mjs +1 -0
- package/dist/{instrumentations-Bgm2EazU.d.mts → instrumentations-BuccMAMj.d.mts} +8 -1
- package/dist/instrumentations-CY8NcP_M.mjs +1 -0
- package/dist/internal/{activity.d.mts → activity/activity.d.mts} +1 -1
- package/dist/internal/activity/activity.mjs +1 -0
- package/dist/internal/browser-context.mjs +1 -1
- package/dist/internal/capture-boundary.d.mts +1 -1
- package/dist/internal/capture-boundary.mjs +1 -1
- package/dist/internal/capture.d.mts +1 -1
- package/dist/internal/capture.mjs +1 -1
- package/dist/internal/config.d.mts +2 -28
- package/dist/internal/config.mjs +1 -1
- package/dist/internal/consent.mjs +1 -1
- package/dist/internal/console-patch.mjs +1 -1
- package/dist/internal/device-metadata.d.mts +41 -0
- package/dist/internal/device-metadata.mjs +1 -0
- package/dist/internal/dom/actionable.d.mts +4 -13
- package/dist/internal/dom/actionable.mjs +1 -1
- package/dist/internal/dom/privacy.d.mts +2 -0
- package/dist/internal/dom/privacy.mjs +1 -0
- package/dist/internal/environment.d.mts +2 -0
- package/dist/internal/environment.mjs +1 -0
- package/dist/internal/event-capabilities.d.mts +3 -0
- package/dist/internal/event-capabilities.mjs +1 -0
- package/dist/internal/hydration.mjs +1 -1
- package/dist/internal/kernel-registry.d.mts +1 -1
- package/dist/internal/kernel-registry.mjs +1 -1
- package/dist/internal/kernel.d.mts +5 -3
- package/dist/internal/kernel.mjs +1 -1
- package/dist/internal/otel/exporter-logs.mjs +1 -1
- package/dist/internal/otel/exporter-metrics.mjs +1 -1
- package/dist/internal/otel/exporter.mjs +1 -1
- package/dist/internal/otel/http-span-route.mjs +1 -1
- package/dist/internal/otel/index.d.mts +3 -3
- package/dist/internal/otel/index.mjs +1 -1
- package/dist/internal/otel/initial-navigation.d.mts +1 -0
- package/dist/internal/otel/initial-navigation.mjs +1 -1
- package/dist/internal/otel/instrumentations.d.mts +1 -1
- package/dist/internal/otel/instrumentations.mjs +1 -1
- package/dist/internal/otel/navigation.mjs +1 -1
- package/dist/internal/otel/normalize-path.mjs +1 -1
- package/dist/internal/otel/page-scope-context-manager.mjs +1 -1
- package/dist/internal/otel/propagation.mjs +1 -1
- package/dist/internal/otel/provider.d.mts +1 -1
- package/dist/internal/otel/provider.mjs +1 -1
- package/dist/internal/otel/url-attrs.mjs +1 -1
- package/dist/internal/otel/web-vitals.mjs +1 -1
- package/dist/internal/{page-lifecycle.d.mts → page-lifecycle/page-lifecycle.d.mts} +1 -1
- package/dist/internal/page-lifecycle/page-lifecycle.mjs +1 -0
- package/dist/internal/plugins/plugin-runtime.d.mts +2 -0
- package/dist/internal/plugins/plugin-runtime.mjs +1 -0
- package/dist/internal/react-context.d.mts +1 -1
- package/dist/internal/react-context.mjs +1 -1
- package/dist/internal/server-digest.mjs +1 -1
- package/dist/internal/third-party-hosts.mjs +1 -1
- package/dist/internal/version.mjs +1 -1
- package/dist/internal/wrapper-singleton.d.mts +1 -1
- package/dist/internal/wrapper-singleton.mjs +1 -1
- package/dist/kernel-BD57JxiH.mjs +1 -0
- package/dist/kernel-registry-6f-3VCIy.mjs +1 -0
- package/dist/loader-BGwWwN2n.mjs +1 -0
- package/dist/log-D6Ht--tv.mjs +1 -0
- package/dist/navigation-DwkvuhFR.mjs +1 -0
- package/dist/normalize-path-BChqP8pA.mjs +1 -0
- package/dist/page-events-config-CiJvdAaJ.d.mts +12 -0
- package/dist/{internal/page-lifecycle.mjs → page-lifecycle-BhSFqjlK.mjs} +1 -1
- package/dist/page-scope-context-manager-DhArvVJ_.mjs +1 -0
- package/dist/plugin-runtime-CnFVGbJw.mjs +1 -0
- package/dist/plugins/device.d.mts +1 -1
- package/dist/plugins/device.mjs +1 -1
- package/dist/plugins/errors.d.mts +1 -1
- package/dist/plugins/errors.mjs +1 -1
- package/dist/plugins/lib/loader.d.mts +1 -1
- package/dist/plugins/lib/loader.mjs +1 -1
- package/dist/plugins/lib/types.d.mts +1 -1
- package/dist/plugins/logs.d.mts +1 -1
- package/dist/plugins/logs.mjs +1 -1
- package/dist/plugins/page-events-config.d.mts +2 -0
- package/dist/plugins/page-events-config.mjs +1 -0
- package/dist/plugins/page-events.d.mts +1 -1
- package/dist/plugins/rage-clicks.d.mts +1 -1
- package/dist/plugins/rage-clicks.mjs +1 -1
- package/dist/plugins/replay/buffer.d.mts +1 -1
- package/dist/plugins/replay/buffer.mjs +1 -1
- package/dist/plugins/replay/chunking.d.mts +2 -38
- package/dist/plugins/replay/chunking.mjs +1 -2
- package/dist/plugins/replay/compressor-host.d.mts +2 -8
- package/dist/plugins/replay/compressor-host.mjs +1 -1
- package/dist/plugins/replay/config.d.mts +1 -1
- package/dist/plugins/replay/config.mjs +1 -1
- package/dist/plugins/replay/delivery.d.mts +4 -4
- package/dist/plugins/replay/delivery.mjs +1 -1
- package/dist/plugins/replay/index.d.mts +1 -1
- package/dist/plugins/replay/index.mjs +1 -1
- package/dist/plugins/replay/recorder.d.mts +1 -1
- package/dist/plugins/replay/recorder.mjs +1 -1
- package/dist/plugins/replay/redact-urls.d.mts +6 -0
- package/dist/plugins/replay/redact-urls.mjs +1 -0
- package/dist/plugins/replay/sequence.mjs +1 -1
- package/dist/plugins/replay/upload.d.mts +1 -1
- package/dist/plugins/replay/upload.mjs +1 -1
- package/dist/privacy-CPKosXDP.d.mts +31 -0
- package/dist/privacy-CRuL0X8r.mjs +1 -0
- package/dist/propagation-DVcqCu_E.mjs +1 -0
- package/dist/{provider-DWgb6tn9.d.mts → provider-C68KiG80.d.mts} +55 -39
- package/dist/provider-NuAexTzU.mjs +1 -0
- package/dist/{provider-2LrbA-ld.d.mts → provider-VZtcX6ZS.d.mts} +4 -1
- package/dist/provider.d.mts +4 -3
- package/dist/provider.mjs +1 -1
- package/dist/react-context-c1uTUJfB.mjs +1 -0
- package/dist/react-error-handler.d.mts +1 -1
- package/dist/react-error-handler.mjs +1 -1
- package/dist/recorder-CM6Ae_0S.mjs +1 -0
- package/dist/redact-urls-CwFod9d4.mjs +1 -0
- package/dist/sequence-B4dYChb0.mjs +1 -0
- package/dist/server-digest-CzGdvjW1.mjs +1 -0
- package/dist/session-C30CtCVv.mjs +1 -0
- package/dist/session-retry-DJHvfDaO.mjs +1 -0
- package/dist/stringify-DvuHsAT4.mjs +1 -0
- package/dist/third-party-hosts-BoJNL3xG.mjs +1 -0
- package/dist/tracking/api.d.mts +1 -1
- package/dist/tracking/api.mjs +1 -1
- package/dist/tracking/device.mjs +1 -1
- package/dist/tracking/geo.mjs +1 -2
- package/dist/tracking/registration.fixture.d.mts +119 -109
- package/dist/tracking/registration.fixture.mjs +148 -26
- package/dist/tracking/session-retry.mjs +1 -1
- package/dist/tracking/session.mjs +1 -1
- package/dist/upload-BPaD3YcA.mjs +1 -0
- package/dist/url-attrs-BdcyE2n6.mjs +1 -0
- package/dist/util/bot.d.mts +1 -0
- package/dist/util/bot.mjs +1 -1
- package/dist/util/global.mjs +1 -1
- package/dist/util/log.mjs +1 -1
- package/dist/util/stringify.mjs +1 -1
- package/dist/{version-CsfyuVoF.mjs → version-BuN6IItu.mjs} +1 -1
- package/dist/web-vitals-CxXDUgpl.mjs +1 -0
- package/package.json +6 -6
- package/dist/index-DvFfO2V9.d.mts +0 -4
- package/dist/internal/activity.mjs +0 -1
- package/dist/internal/plugin-runtime.d.mts +0 -2
- package/dist/internal/plugin-runtime.mjs +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ROOT_CONTEXT,trace}from"@opentelemetry/api";import{ZoneContextManager}from"@opentelemetry/context-zone";var PageScopeContextManager=class extends ZoneContextManager{pageScope=ROOT_CONTEXT;pageSpans=new WeakSet;pageScopeSetAtMs=0;rotator=null;maxAgeMs=1/0;rotating=!1;setPageScope(ctx){this.pageScope=ctx,this.pageScopeSetAtMs=Date.now();let span=trace.getSpan(ctx);span&&this.pageSpans.add(span)}setRotation(rotator,maxAgeMs){this.rotator=rotator,this.maxAgeMs=maxAgeMs}active(){let ctx=super.active(),span=trace.getSpan(ctx);if(span&&!this.pageSpans.has(span))return ctx;if(this.pageScope!==ROOT_CONTEXT&&this.rotator&&!this.rotating&&Date.now()-this.pageScopeSetAtMs>this.maxAgeMs){this.rotating=!0;try{this.setPageScope(this.rotator(this.pageScope))}finally{this.rotating=!1}}if(ctx===ROOT_CONTEXT)return this.pageScope;let pageSpan=trace.getSpan(this.pageScope);return pageSpan?trace.setSpan(ctx,pageSpan):ctx}};export{PageScopeContextManager as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as createLogger}from"./log-D6Ht--tv.mjs";import{a as resolveGrantedConsent,i as isConsentAllowed,n as getPluginConsentCategory,r as hasConsentChanged}from"./consent-COUmLJLD.mjs";import{t as devicePlugin}from"./device-6T3DYkLD.mjs";import{t as errorsPlugin}from"./errors-BDmCWb5z.mjs";import{n as loadPlugin,r as resolveFeatures}from"./loader-BGwWwN2n.mjs";import{PLUGIN_MANIFEST}from"@interfere/types/sdk/plugins/manifest";const log=createLogger(`plugin-runtime`);var PluginRuntime=class{activeCleanups=new Map;activations=new Map;features=resolveFeatures();pluginConfigListeners=new Map;remoteConfig={};remoteConfigSettled=!1;consentState=null;configSettled=!1;replayConfig={};pageEventsConfig={};syncVersion=0;disposed=!1;context;hasInitialConsent;constructor(context,consent,remoteConfig={}){this.context=context,this.hasInitialConsent=consent!==void 0,this.consentState=consent===void 0?null:resolveGrantedConsent(consent),this.configSettled=this.hasInitialConsent,this.remoteConfig=remoteConfig}getConsent(){return this.consentState}getReplayConfig(){return this.replayConfig}isInteractionCaptureEnabled(){return this.pageEventsConfig.interactions!==!1}applyProviderConfig(overrides,consent){let pageEvents=overrides?.pageEvents,replay=overrides?.replay;this.features=resolveFeatures(overrides),this.pageEventsConfig=typeof pageEvents==`object`?pageEvents:{},this.replayConfig=typeof replay==`object`?replay:{},consent===void 0?this.hasInitialConsent||(this.consentState=null):this.consentState=resolveGrantedConsent(consent),this.configSettled=!0,this.sync()}setConsent(nextConsent){let nextState=resolveGrantedConsent(nextConsent);(!this.configSettled||hasConsentChanged(this.consentState,nextState))&&(this.consentState=nextState,this.configSettled=!0,this.sync())}resetConsent(){(!this.configSettled||hasConsentChanged(this.consentState,null))&&(this.consentState=null,this.configSettled=!0,this.sync())}applyRemoteConfig(config){this.remoteConfig=config,this.remoteConfigSettled=!0,this.emitPluginConfigState(),this.sync()}applyRemoteConfigDefaults(){this.remoteConfigSettled=!0,this.emitPluginConfigState(),this.sync()}start(){for(let[key,plugin]of[[`errors`,errorsPlugin],[`device`,devicePlugin]])if(this.shouldEnablePlugin(key)){let cleanup=plugin.setup(this.context);cleanup&&this.activeCleanups.set(key,cleanup)}this.sync()}async dispose(){this.disposed=!0,this.syncVersion+=1;for(let key of this.activeCleanups.keys())this.deactivate(key,`dispose`);await Promise.allSettled(this.activations.values())}shouldEnablePlugin(key){let category=getPluginConsentCategory(key);return category!==`necessary`&&!this.configSettled?!1:this.features[key]&&this.remoteConfig[key]!==!1&&isConsentAllowed(category,this.consentState)}getPluginConfigState(key){return this.remoteConfigSettled?this.remoteConfig[key]===!1?`disabled`:`enabled`:`pending`}subscribePluginConfigState(key,listener){let listeners=this.pluginConfigListeners.get(key)??new Set;return listeners.add(listener),this.pluginConfigListeners.set(key,listeners),(()=>{listeners.delete(listener),listeners.size===0&&this.pluginConfigListeners.delete(key)})}emitPluginConfigState(){for(let[key,listeners]of this.pluginConfigListeners){let state=this.getPluginConfigState(key);for(let listener of listeners)listener(state)}}teardownReason(key){let category=getPluginConsentCategory(key);return isConsentAllowed(category,this.consentState)?`disabled`:`consent-revoked`}deactivate(key,reason){let cleanup=this.activeCleanups.get(key);if(cleanup){try{cleanup(reason)}catch{log.warn(`cleanup failed for %s`,key)}this.activeCleanups.delete(key)}}async activate(key){if(this.activeCleanups.has(key)||!this.shouldEnablePlugin(key))return;let version=this.syncVersion,cleanup=await loadPlugin(key,this.context);if(cleanup){if(version!==this.syncVersion||!this.shouldEnablePlugin(key)){cleanup(this.teardownReason(key));return}this.activeCleanups.set(key,cleanup)}}sync(){if(!this.disposed){this.syncVersion+=1;for(let plugin of PLUGIN_MANIFEST){if(this.shouldEnablePlugin(plugin.name)){if(plugin.name===`errors`){if(!this.activeCleanups.has(`errors`)){let cleanup=errorsPlugin.setup(this.context);cleanup&&this.activeCleanups.set(`errors`,cleanup)}continue}let previous=this.activations.get(plugin.name);this.activations.set(plugin.name,(async()=>{await previous;try{await this.activate(plugin.name)}catch{log.warn(`non-critical plugin loading failed`)}})());continue}this.deactivate(plugin.name,this.teardownReason(plugin.name))}}}};export{PluginRuntime as t};
|
package/dist/plugins/device.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import{t as devicePlugin}from"../device-6T3DYkLD.mjs";export{devicePlugin as default};
|
package/dist/plugins/errors.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{t as errorsPlugin}from"../errors-BDmCWb5z.mjs";export{errorsPlugin as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as resolveFeatures, S as loadPlugin, b as LOADERS, x as PluginOverrides } from "../../provider-C68KiG80.mjs";
|
|
2
2
|
export { LOADERS, PluginOverrides, loadPlugin, resolveFeatures };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{n as loadPlugin,r as resolveFeatures,t as LOADERS}from"../../loader-BGwWwN2n.mjs";export{LOADERS,loadPlugin,resolveFeatures};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { D as
|
|
1
|
+
import { D as PluginContext, E as PluginConfigState, O as PluginTeardownReason, T as PluginCleanup, w as Plugin } from "../../provider-C68KiG80.mjs";
|
|
2
2
|
export { Plugin, PluginCleanup, PluginConfigState, PluginContext, PluginTeardownReason };
|
package/dist/plugins/logs.d.mts
CHANGED
package/dist/plugins/logs.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{activeKernel}from"../
|
|
1
|
+
import{t as activeKernel}from"../kernel-registry-6f-3VCIy.mjs";import{n as onConsoleCall}from"../console-patch-WNKoLE7U.mjs";import{t as safeStringify}from"../stringify-DvuHsAT4.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 @@
|
|
|
1
|
+
export{};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function distance(a,b){return Math.hypot(a.x-b.x,a.y-b.y)}function
|
|
1
|
+
import{n as describeActionable}from"../actionable-DOmVf_ib.mjs";import{omitUndefined}from"@interfere/helpers/omit-undefined";function distance(a,b){return Math.hypot(a.x-b.x,a.y-b.y)}function describeTarget(el,policy){if(!el)return{selector:`unknown`,text:``};let{id,label,privacy,tag,text=``}=describeActionable(el,policy),classes=privacy?[]:[...el.classList].slice(0,3);return{label,privacy,selector:id?`#${id}`:[tag,...classes].join(`.`),text}}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);if(!last)return;let target=describeTarget(last.target,ctx.privacyPolicy);ctx.getTracer(`@interfere/react/rage-clicks`).startSpan(`rage_click`,{attributes:omitUndefined({"ui.event_type":`rage_click`,"ui.rage_click.count":clustered.length,"ui.rage_click.selector":target.selector,"ui.rage_click.text":target.text,"ui.rage_click.time_window_ms":last.ts-anchor.ts,"ui.rage_click.x":last.x,"ui.rage_click.y":last.y,"ui.target.label":target.label,"ui.target.privacy":target.privacy})}).end(),clicks.length=0};return document.addEventListener(`click`,onClick,{capture:!0}),()=>{document.removeEventListener(`click`,onClick,{capture:!0})}}};export{rageClicksPlugin as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{t as createReplayBuffer}from"../../buffer-BRn_kSm-.mjs";export{createReplayBuffer};
|
|
@@ -1,38 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
bytes: number;
|
|
4
|
-
isActivity: boolean;
|
|
5
|
-
isFullSnapshot: boolean;
|
|
6
|
-
json: string;
|
|
7
|
-
ts: number;
|
|
8
|
-
}
|
|
9
|
-
export interface ReplayChunkPayload {
|
|
10
|
-
activityCount: number;
|
|
11
|
-
bodyJson: string;
|
|
12
|
-
eventCount: number;
|
|
13
|
-
firstTs: number | null;
|
|
14
|
-
hasFullSnapshot: boolean;
|
|
15
|
-
lastTs: number | null;
|
|
16
|
-
}
|
|
17
|
-
export interface SplitReplayEventsResult {
|
|
18
|
-
chunks: BufferedReplayEvent[][];
|
|
19
|
-
droppedEventBytes: number[];
|
|
20
|
-
}
|
|
21
|
-
export declare function classifyReplayEvent(event: unknown): {
|
|
22
|
-
isActivity: boolean;
|
|
23
|
-
isFullSnapshot: boolean;
|
|
24
|
-
};
|
|
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
|
+
import { a as splitReplayEvents, i as classifyReplayEvent, n as ReplayChunkPayload, o as toReplayChunkPayload, r as SplitReplayEventsResult, s as utf8ByteLength, t as BufferedReplayEvent } from "../../chunking-Dvs3f50A.mjs";
|
|
2
|
+
export { BufferedReplayEvent, ReplayChunkPayload, SplitReplayEventsResult, classifyReplayEvent, splitReplayEvents, toReplayChunkPayload, utf8ByteLength };
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
import{
|
|
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&¤tBytes+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
|
+
import{i as utf8ByteLength,n as splitReplayEvents,r as toReplayChunkPayload,t as classifyReplayEvent}from"../../chunking-qZffPbyY.mjs";export{classifyReplayEvent,splitReplayEvents,toReplayChunkPayload,utf8ByteLength};
|
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export interface Compressor {
|
|
4
|
-
readonly dispose: () => void;
|
|
5
|
-
readonly gzip: ((bytes: Uint8Array) => Promise<Uint8Array<ArrayBuffer>>) | null;
|
|
6
|
-
}
|
|
7
|
-
export declare function createCompressor(): Compressor;
|
|
8
|
-
//#endregion
|
|
1
|
+
import { n as createCompressor, t as Compressor } from "../../compressor-host-BAz6860r.mjs";
|
|
2
|
+
export { Compressor, createCompressor };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{t as createCompressor}from"../../compressor-host-CrKngamF.mjs";export{createCompressor};
|
|
@@ -1,2 +1,2 @@
|
|
|
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-
|
|
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-Dyc09HCZ.mjs";
|
|
2
2
|
export { INTERFERE_BLOCK_CLASS, INTERFERE_IGNORE_CLASS, INTERFERE_MASK_TEXT_CLASS, ReplayConfig, ReplayOption, ReplayRecordOptions, toRecordOptions };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import{i as toRecordOptions,n as INTERFERE_IGNORE_CLASS,r as INTERFERE_MASK_TEXT_CLASS,t as INTERFERE_BLOCK_CLASS}from"../../config-DapTbKhs.mjs";export{INTERFERE_BLOCK_CLASS,INTERFERE_IGNORE_CLASS,INTERFERE_MASK_TEXT_CLASS,toRecordOptions};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { resolveTargets } from "../../
|
|
3
|
-
import { ReplayChunkPayload } from "
|
|
4
|
-
import { Compressor } from "
|
|
1
|
+
import { D as PluginContext } from "../../provider-C68KiG80.mjs";
|
|
2
|
+
import { n as resolveTargets } from "../../config-CBqqY1AV.mjs";
|
|
3
|
+
import { n as ReplayChunkPayload } from "../../chunking-Dvs3f50A.mjs";
|
|
4
|
+
import { t as Compressor } from "../../compressor-host-BAz6860r.mjs";
|
|
5
5
|
//#region src/plugins/replay/delivery.d.ts
|
|
6
6
|
export type DeliverResult = "ok" | "retryable" | "fatal";
|
|
7
7
|
export interface ReplayChunkRef {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{t as deliverChunk}from"../../delivery-DehIJWRh.mjs";export{deliverChunk};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"../../
|
|
1
|
+
import{t as createLogger}from"../../log-D6Ht--tv.mjs";import{n as resolveTargets}from"../../config-Bm8myQlS.mjs";import{n as onPageShown,t as onPageHidden}from"../../page-lifecycle-BhSFqjlK.mjs";import{i as toRecordOptions}from"../../config-DapTbKhs.mjs";import{n as splitReplayEvents,r as toReplayChunkPayload}from"../../chunking-qZffPbyY.mjs";import{t as createReplayBuffer}from"../../buffer-BRn_kSm-.mjs";import{t as createCompressor}from"../../compressor-host-CrKngamF.mjs";import{t as deliverChunk}from"../../delivery-DehIJWRh.mjs";import{t as startReplayRecorder}from"../../recorder-CM6Ae_0S.mjs";import{t as redactReplayEvent}from"../../redact-urls-CwFod9d4.mjs";import{t as createSegmentSequence}from"../../sequence-B4dYChb0.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(),ctx.privacyPolicy);return(async()=>{if(recorder=await startReplayRecorder({onEvent:(event,isCheckout)=>{startup.signal.aborted||(isCheckout&&event.type===EventType.Meta&&flush(),redactReplayEvent(event,ctx.redactUrl),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 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{t as startReplayRecorder}from"../../recorder-CM6Ae_0S.mjs";export{startReplayRecorder};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { eventWithTime } from "@rrweb/types";
|
|
2
|
+
//#region src/plugins/replay/redact-urls.d.ts
|
|
3
|
+
type RedactUrl = (url: string) => string;
|
|
4
|
+
/** Rewrites URLs that rrweb records in page metadata and DOM attributes before the event leaves the browser. */
|
|
5
|
+
export declare function redactReplayEvent(event: eventWithTime, redactUrl: RedactUrl): void;
|
|
6
|
+
//#endregion
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as redactReplayEvent}from"../../redact-urls-CwFod9d4.mjs";export{redactReplayEvent};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import{t as createSegmentSequence}from"../../sequence-B4dYChb0.mjs";export{createSegmentSequence};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resolveTargets } from "../../
|
|
1
|
+
import { n as resolveTargets } from "../../config-CBqqY1AV.mjs";
|
|
2
2
|
//#region src/plugins/replay/upload.d.ts
|
|
3
3
|
export declare function uploadReplayChunk(target: ReturnType<typeof resolveTargets>["ingest"], sessionId: string, body: Uint8Array<ArrayBuffer>, headers: Record<string, string>): Promise<Response>;
|
|
4
4
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import{t as uploadReplayChunk}from"../../upload-BPaD3YcA.mjs";export{uploadReplayChunk};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { UrlRedactionOption } from "@interfere/types/sdk/url-redaction";
|
|
2
|
+
//#region src/internal/dom/privacy.d.ts
|
|
3
|
+
type PrivacyLevel = "blocked" | "masked" | "public";
|
|
4
|
+
/** What the SDK never records. Selectors apply to session replay and to click, submit and rage-click records from the first capture. */
|
|
5
|
+
interface PrivacyOptions {
|
|
6
|
+
/**
|
|
7
|
+
* CSS selector for elements recorded only as placeholders. Replay shows a
|
|
8
|
+
* same-size box; interaction records keep the event, tag and field label.
|
|
9
|
+
* Matches the element and everything inside it.
|
|
10
|
+
*/
|
|
11
|
+
blockSelector?: string;
|
|
12
|
+
/**
|
|
13
|
+
* CSS selector for elements whose text is masked in replay and omitted from
|
|
14
|
+
* interaction records. Matches the element and everything inside it.
|
|
15
|
+
*/
|
|
16
|
+
maskTextSelector?: string;
|
|
17
|
+
/** Query values and fragments to redact in recorded URLs. Defaults to built-in sensitive parameter names. */
|
|
18
|
+
urls?: UrlRedactionOption;
|
|
19
|
+
}
|
|
20
|
+
interface PrivacyPolicy {
|
|
21
|
+
readonly blockAll: boolean;
|
|
22
|
+
readonly blockSelector: string;
|
|
23
|
+
readonly maskSelector: string;
|
|
24
|
+
}
|
|
25
|
+
declare const DEFAULT_PRIVACY_POLICY: PrivacyPolicy;
|
|
26
|
+
declare function resolvePrivacyPolicy({ blockSelector, maskTextSelector }?: PrivacyOptions): PrivacyPolicy;
|
|
27
|
+
declare function privacyLevel(element: Element, policy: PrivacyPolicy): "blocked" | "masked" | "public";
|
|
28
|
+
declare function publicText(element: Element, policy: PrivacyPolicy): string;
|
|
29
|
+
declare function fieldLabel(element: Element, policy: PrivacyPolicy): string;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { fieldLabel as a, resolvePrivacyPolicy as c, PrivacyPolicy as i, PrivacyLevel as n, privacyLevel as o, PrivacyOptions as r, publicText as s, DEFAULT_PRIVACY_POLICY as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as createLogger}from"./log-D6Ht--tv.mjs";import{r as INTERFERE_MASK_TEXT_CLASS,t as INTERFERE_BLOCK_CLASS}from"./config-DapTbKhs.mjs";const log=createLogger(`privacy`),LABEL_ATTRIBUTE=`data-interfere-label`,FORM_FIELD_SELECTOR=`input, select, textarea`,DEFAULT_PRIVACY_POLICY={blockAll:!1,blockSelector:`.${INTERFERE_BLOCK_CLASS}`,maskSelector:`.${INTERFERE_MASK_TEXT_CLASS}`};function resolvePrivacyPolicy({blockSelector,maskTextSelector}={}){let policy={blockAll:!1,blockSelector:[DEFAULT_PRIVACY_POLICY.blockSelector,blockSelector].filter(Boolean).join(`, `),maskSelector:[DEFAULT_PRIVACY_POLICY.maskSelector,maskTextSelector].filter(Boolean).join(`, `)};try{return document.querySelector(`${policy.blockSelector}, ${policy.maskSelector}`),policy}catch{return log.warn(`invalid privacy selector; interaction details are blocked`),{...policy,blockAll:!0}}}function privacyLevel(element,policy){return policy.blockAll||element.closest(policy.blockSelector)?`blocked`:element.closest(policy.maskSelector)?`masked`:`public`}function publicText(element,policy){if(element.matches(FORM_FIELD_SELECTOR))return``;let hidden=`${policy.blockSelector}, ${policy.maskSelector}, ${FORM_FIELD_SELECTOR}`,walker=document.createTreeWalker(element,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT,{acceptNode(node){return node instanceof Element?node.matches(hidden)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_SKIP:NodeFilter.FILTER_ACCEPT}}),text=``;for(let node=walker.nextNode();node&&text.trimStart().length<120;node=walker.nextNode())text+=node.nodeValue??``;return text.trim().slice(0,120)}function labelElements(element){let labels=element instanceof HTMLButtonElement||element instanceof HTMLInputElement||element instanceof HTMLSelectElement||element instanceof HTMLTextAreaElement?[...element.labels??[]]:[];for(let id of element.getAttribute(`aria-labelledby`)?.split(/\s+/u)??[]){let labelledBy=id?element.ownerDocument.querySelector(`#${CSS.escape(id)}`):null;labelledBy&&labels.push(labelledBy)}return labels}function fieldLabel(element,policy){let explicit=element.closest(`[${LABEL_ATTRIBUTE}]`)?.getAttribute(LABEL_ATTRIBUTE)?.trim();return explicit?explicit.slice(0,120):labelElements(element).filter(label=>privacyLevel(label,policy)===`public`).map(label=>publicText(label,policy)).filter(Boolean).join(` `).slice(0,120)}export{resolvePrivacyPolicy as a,publicText as i,fieldLabel as n,privacyLevel as r,DEFAULT_PRIVACY_POLICY as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ROOT_CONTEXT,defaultTextMapGetter,trace}from"@opentelemetry/api";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{W3CBaggagePropagator,W3CTraceContextPropagator}from"@opentelemetry/core";import{TRACESTATE_FRESHNESS_KEY,isFreshnessStampExpired}from"@interfere/types/sdk/trace-freshness";const TRACESTATE_META=`tracestate`,BAGGAGE_META=`baggage`,W3C_PROPAGATOR=new W3CTraceContextPropagator,W3C_BAGGAGE_PROPAGATOR=new W3CBaggagePropagator;function readMeta(name){return typeof document>`u`?null:document.querySelector(`meta[name="${name}"]`)?.getAttribute(`content`)??null}function readTracestateMeta(){if(typeof document>`u`)return null;let contents=[...document.querySelectorAll(`meta[name="${TRACESTATE_META}"]`)].flatMap(el=>{let content=el.getAttribute(`content`);return content===null?[]:[content]});return contents.find(content=>RegExp(`(?:^|,)\\s*${TRACESTATE_FRESHNESS_KEY}=`,`u`).test(content))??contents.at(0)??null}function readPropagationFromDocument(){let traceparent=readMeta(`traceparent`);if(!traceparent)return null;let carrier=omitUndefined({traceparent,[TRACESTATE_META]:readTracestateMeta()||void 0,[BAGGAGE_META]:readMeta(BAGGAGE_META)||void 0}),withTrace=W3C_PROPAGATOR.extract(ROOT_CONTEXT,carrier,defaultTextMapGetter),extracted=W3C_BAGGAGE_PROPAGATOR.extract(withTrace,carrier,defaultTextMapGetter),spanCtx=trace.getSpanContext(extracted);return!spanCtx||spanCtx.traceId===`00000000000000000000000000000000`||!(spanCtx.traceFlags&1)||isStaleTraceparent(spanCtx.traceState?.get(TRACESTATE_FRESHNESS_KEY))?null:extracted}function isStaleTraceparent(freshnessStamp){return freshnessStamp?isFreshnessStampExpired(freshnessStamp,Date.now()):!1}export{readPropagationFromDocument as t};
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import { c as SessionResumeReason } from "./activity-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { n as
|
|
5
|
-
import { t as
|
|
6
|
-
import "./
|
|
1
|
+
import { c as SessionResumeReason } from "./activity-Duhfgvxt.mjs";
|
|
2
|
+
import { i as PrivacyPolicy, r as PrivacyOptions } from "./privacy-CPKosXDP.mjs";
|
|
3
|
+
import { a as ReplayOption, i as ReplayConfig } from "./config-Dyc09HCZ.mjs";
|
|
4
|
+
import { n as PageEventsOption } from "./page-events-config-CiJvdAaJ.mjs";
|
|
5
|
+
import { t as SessionTracker } from "./api-CMPV9rgU.mjs";
|
|
6
|
+
import { n as CaptureFailedRequestsOption, t as BundledInstrumentations } from "./instrumentations-BuccMAMj.mjs";
|
|
7
|
+
import { t as OtelProviderHandle } from "./provider-VZtcX6ZS.mjs";
|
|
8
|
+
import "./index-DBsXraeJ.mjs";
|
|
7
9
|
import { NonErrorException } from "@interfere/types/sdk/errors";
|
|
8
10
|
import { Tracer } from "@opentelemetry/api";
|
|
9
11
|
import { PropsWithChildren } from "react";
|
|
10
12
|
import { ConsentInput, ConsentState, PluginKey } from "@interfere/types/sdk/plugins/manifest";
|
|
11
13
|
import { RemotePluginConfig } from "@interfere/types/sdk/remote-config";
|
|
14
|
+
import { UrlRedactionPolicy } from "@interfere/types/sdk/url-redaction";
|
|
12
15
|
import { SessionId } from "@interfere/types/data/session";
|
|
13
16
|
import { MetricReader } from "@opentelemetry/sdk-metrics";
|
|
14
17
|
import { LogRecordProcessor, LoggerProvider } from "@opentelemetry/sdk-logs";
|
|
@@ -23,12 +26,14 @@ type PluginConfigState = "disabled" | "enabled" | "pending";
|
|
|
23
26
|
interface PluginContext {
|
|
24
27
|
getPluginConfigState: (key: PluginKey) => PluginConfigState;
|
|
25
28
|
getReplayConfig: () => ReplayConfig;
|
|
29
|
+
readonly privacyPolicy: PrivacyPolicy;
|
|
26
30
|
getSessionId: () => string;
|
|
27
31
|
getTracer: (name: string) => Tracer;
|
|
28
32
|
getWindowId: () => string;
|
|
29
33
|
onSessionPause: (handler: () => void) => () => void;
|
|
30
34
|
onSessionResume: (handler: (reason: SessionResumeReason) => void) => () => void;
|
|
31
35
|
recordException: (value: Error | NonErrorException, opts: RecordExceptionOpts) => void;
|
|
36
|
+
redactUrl: (url: string) => string;
|
|
32
37
|
startDeviceInfoCapture: () => PluginCleanup | null;
|
|
33
38
|
startPageEventsCapture: () => PluginCleanup | null;
|
|
34
39
|
subscribePluginConfigState: (key: PluginKey, listener: (state: PluginConfigState) => void) => () => void;
|
|
@@ -43,7 +48,8 @@ type PluginLoader = () => Promise<{
|
|
|
43
48
|
default: Plugin;
|
|
44
49
|
} | Plugin> | Plugin;
|
|
45
50
|
declare const LOADERS: Record<PluginKey, PluginLoader>;
|
|
46
|
-
type PluginOverrides = Partial<Record<Exclude<PluginKey, "replay">, boolean>> & {
|
|
51
|
+
type PluginOverrides = Partial<Record<Exclude<PluginKey, "pageEvents" | "replay">, boolean>> & {
|
|
52
|
+
pageEvents?: PageEventsOption;
|
|
47
53
|
replay?: ReplayOption;
|
|
48
54
|
};
|
|
49
55
|
declare function resolveFeatures(overrides?: PluginOverrides): {
|
|
@@ -56,10 +62,10 @@ declare function resolveFeatures(overrides?: PluginOverrides): {
|
|
|
56
62
|
};
|
|
57
63
|
declare function loadPlugin(key: PluginKey, context: PluginContext): Promise<PluginCleanup | null>;
|
|
58
64
|
//#endregion
|
|
59
|
-
//#region src/internal/plugin-runtime.d.ts
|
|
65
|
+
//#region src/internal/plugins/plugin-runtime.d.ts
|
|
60
66
|
declare class PluginRuntime {
|
|
61
67
|
private readonly activeCleanups;
|
|
62
|
-
private readonly
|
|
68
|
+
private readonly activations;
|
|
63
69
|
private features;
|
|
64
70
|
private readonly pluginConfigListeners;
|
|
65
71
|
private remoteConfig;
|
|
@@ -67,6 +73,7 @@ declare class PluginRuntime {
|
|
|
67
73
|
private consentState;
|
|
68
74
|
private configSettled;
|
|
69
75
|
private replayConfig;
|
|
76
|
+
private pageEventsConfig;
|
|
70
77
|
private syncVersion;
|
|
71
78
|
private disposed;
|
|
72
79
|
private readonly context;
|
|
@@ -74,6 +81,7 @@ declare class PluginRuntime {
|
|
|
74
81
|
constructor(context: PluginContext, consent?: ConsentInput, remoteConfig?: RemotePluginConfig);
|
|
75
82
|
getConsent(): ConsentState | null;
|
|
76
83
|
getReplayConfig(): ReplayConfig;
|
|
84
|
+
isInteractionCaptureEnabled(): boolean;
|
|
77
85
|
applyProviderConfig(overrides: PluginOverrides | undefined, consent: ConsentInput | undefined): void;
|
|
78
86
|
setConsent(nextConsent?: ConsentInput): void;
|
|
79
87
|
resetConsent(): void;
|
|
@@ -127,6 +135,14 @@ interface KernelOptions {
|
|
|
127
135
|
serviceName?: string;
|
|
128
136
|
/** Optional application namespace for grouping related services. */
|
|
129
137
|
serviceNamespace?: string;
|
|
138
|
+
/**
|
|
139
|
+
* What the SDK never records. `blockSelector` and `maskTextSelector` apply
|
|
140
|
+
* to session replay and to click, submit and rage-click records from the
|
|
141
|
+
* first capture; the `interfere-block` and `interfere-mask` classes always
|
|
142
|
+
* apply. `urls` controls query and fragment redaction; URL credentials are
|
|
143
|
+
* always redacted.
|
|
144
|
+
*/
|
|
145
|
+
privacy?: PrivacyOptions;
|
|
130
146
|
/**
|
|
131
147
|
* `false` skips the OTel module entirely — the bundler code-splits
|
|
132
148
|
* `internal/otel/*` out of this path so the error-only bundle never
|
|
@@ -143,6 +159,12 @@ interface KernelOptions {
|
|
|
143
159
|
* need to touch any of these — sensible defaults ship out of the box.
|
|
144
160
|
*/
|
|
145
161
|
interface TracingOptions {
|
|
162
|
+
/**
|
|
163
|
+
* Additional OpenTelemetry processors, in array order after built-in enrichment
|
|
164
|
+
* and before wrapper processors and export. Complete redaction synchronously
|
|
165
|
+
* in onEnd. The SDK owns forceFlush and shutdown for these instances.
|
|
166
|
+
*/
|
|
167
|
+
spanProcessors?: SpanProcessor[];
|
|
146
168
|
/**
|
|
147
169
|
* Backend hostnames that receive trace context and session baggage, e.g.
|
|
148
170
|
* `["api.example.com"]`. Same-origin requests always propagate. Entries
|
|
@@ -271,6 +293,9 @@ declare class Kernel implements PluginContext {
|
|
|
271
293
|
readonly identity: KernelIdentity;
|
|
272
294
|
readonly device: KernelDevice;
|
|
273
295
|
readonly session: KernelSession;
|
|
296
|
+
readonly privacyPolicy: PrivacyPolicy;
|
|
297
|
+
readonly urlRedaction: UrlRedactionPolicy;
|
|
298
|
+
readonly redactUrl: (url: string) => string;
|
|
274
299
|
private readonly seen;
|
|
275
300
|
private readonly initialNavigationSeen;
|
|
276
301
|
private runtime;
|
|
@@ -280,7 +305,7 @@ declare class Kernel implements PluginContext {
|
|
|
280
305
|
private deviceInfoCaptureEnabled;
|
|
281
306
|
private unsubscribePageHidden;
|
|
282
307
|
private readonly tracker;
|
|
283
|
-
constructor(tracker: SessionTracker);
|
|
308
|
+
constructor(tracker: SessionTracker, privacy?: PrivacyOptions);
|
|
284
309
|
/**
|
|
285
310
|
* Bound by `createKernel` immediately after construction.
|
|
286
311
|
*
|
|
@@ -295,6 +320,7 @@ declare class Kernel implements PluginContext {
|
|
|
295
320
|
onSessionResume(handler: (reason: SessionResumeReason) => void): () => void;
|
|
296
321
|
getPluginConfigState(key: PluginKey): "disabled" | "enabled" | "pending";
|
|
297
322
|
getReplayConfig(): ReplayConfig;
|
|
323
|
+
isInteractionCaptureEnabled(): boolean;
|
|
298
324
|
subscribePluginConfigState(key: PluginKey, listener: (state: PluginConfigState) => void): () => void;
|
|
299
325
|
getTracer(name: string): import("@opentelemetry/api").Tracer;
|
|
300
326
|
startPageEventsCapture(): (() => void) | null;
|
|
@@ -363,7 +389,6 @@ interface CreateKernelInput {
|
|
|
363
389
|
opts?: KernelInternalOptions;
|
|
364
390
|
}
|
|
365
391
|
declare function createKernel(input?: CreateKernelInput): Promise<Kernel>;
|
|
366
|
-
declare function isEnabledByEnvironment(): boolean;
|
|
367
392
|
/**
|
|
368
393
|
* Build-time-derived release slug. The build step
|
|
369
394
|
* (`@interfere/next/withInterfere`, `@interfere/vite/plugin`) takes the
|
|
@@ -426,22 +451,9 @@ interface InterfereProviderProps extends PropsWithChildren {
|
|
|
426
451
|
* consent, omitting this prop leaves every category allowed.
|
|
427
452
|
*/
|
|
428
453
|
consent?: ConsentInput | undefined;
|
|
429
|
-
/**
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
* `ErrorBoundary` / `error.tsx` of its own.
|
|
433
|
-
*
|
|
434
|
-
* The internal boundary is transparent: it captures the error and then
|
|
435
|
-
* re-throws so upstream boundaries (the customer's own, Next.js's
|
|
436
|
-
* `error.tsx` / `global-error.tsx`, or React's default unmount) keep full
|
|
437
|
-
* control of what the user sees. Safe to leave enabled.
|
|
438
|
-
*
|
|
439
|
-
* Pass `false` only if you explicitly don't want automatic capture of
|
|
440
|
-
* render-phase errors — for example, if you've already wired
|
|
441
|
-
* {@link reactErrorHandler} into `createRoot()`.
|
|
442
|
-
*
|
|
443
|
-
* @default true
|
|
444
|
-
*/
|
|
454
|
+
/** Reports render errors and rethrows to the host boundary. Defaults to true. */
|
|
455
|
+
captureRenderErrors?: boolean;
|
|
456
|
+
/** @deprecated Use captureRenderErrors, which takes precedence when both are set. */
|
|
445
457
|
errorBoundary?: boolean;
|
|
446
458
|
/**
|
|
447
459
|
* The active kernel from `init()`. Pass `null` (or omit on the server)
|
|
@@ -452,21 +464,25 @@ interface InterfereProviderProps extends PropsWithChildren {
|
|
|
452
464
|
kernel: Kernel | null;
|
|
453
465
|
/**
|
|
454
466
|
* Per-plugin overrides, merged over the manifest defaults. Generic plugins
|
|
455
|
-
* are booleans (e.g. `{
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
*
|
|
467
|
+
* are booleans (e.g. `{ rageClick: false }`). `pageEvents` also accepts
|
|
468
|
+
* `{ interactions: false }`, which keeps navigation, document-load and
|
|
469
|
+
* resource timing while dropping click and submit spans. `replay`
|
|
470
|
+
* additionally accepts a config object — `{ replay: { maskAllInputs: true } }`
|
|
471
|
+
* enables replay with that masking config; `{ replay: false }` disables it.
|
|
472
|
+
* Privacy classes are always applied, regardless of config:
|
|
473
|
+
* `interfere-block` elements are dropped and replay as a same-size
|
|
474
|
+
* placeholder, `interfere-mask` masks the text of an element and all its
|
|
475
|
+
* children, and `interfere-ignore` stops an element's input events from
|
|
476
|
+
* being recorded. `input[type="password"]` is masked by default; use
|
|
477
|
+
* `maskInputOptions`/`maskAllInputs` to mask other input values. Use
|
|
478
|
+
* `init()`'s `privacy` option for selectors that also govern click, submit
|
|
479
|
+
* and rage-click capture. `init()` no longer accepts plugin config; this is
|
|
480
|
+
* the only place it lives.
|
|
465
481
|
*/
|
|
466
482
|
plugins?: PluginOverrides | undefined;
|
|
467
483
|
}
|
|
468
|
-
declare function InterfereProvider({ kernel, children, consent, plugins, errorBoundary }: InterfereProviderProps): import("react").JSX.Element;
|
|
484
|
+
declare function InterfereProvider({ kernel, children, consent, plugins, captureRenderErrors, errorBoundary }: InterfereProviderProps): import("react").JSX.Element;
|
|
469
485
|
declare function useInterfere(): InterfereContextValue;
|
|
470
486
|
declare function useSession(): string | null;
|
|
471
487
|
//#endregion
|
|
472
|
-
export {
|
|
488
|
+
export { resolveFeatures as C, PluginContext as D, PluginConfigState as E, PluginTeardownReason as O, loadPlugin as S, PluginCleanup as T, createKernel as _, InterfereContextValue as a, LOADERS as b, KernelConsent as c, KernelInternalOptions as d, KernelOptions as f, buildSdkStack as g, TracingOptions as h, InterfereContext as i, KernelDevice as l, RecordExceptionOpts as m, useInterfere as n, NULL_CONTEXT_VALUE as o, KernelSession as p, useSession as r, Kernel as s, InterfereProvider as t, KernelIdentity as u, readReleaseSlugFromGlobals as v, Plugin as w, PluginOverrides as x, PluginRuntime as y };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as getStringGlobal}from"./global-DYq1Z4_H.mjs";import{n as SDK_NAME,r as SDK_VERSION}from"./version-BuN6IItu.mjs";import{i as createTraceExporter,n as createLogExporter,r as createMetricExporter}from"./exporter-DjvOtWYJ.mjs";import{t as PageScopeContextManager}from"./page-scope-context-manager-DhArvVJ_.mjs";import{context,propagation}from"@opentelemetry/api";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{ENVIRONMENT_GLOBAL}from"@interfere/types/sdk/injected-globals";import{createUrlRedactionSpanProcessor,resolveUrlRedaction}from"@interfere/types/sdk/url-redaction";import{CompositePropagator,W3CBaggagePropagator,W3CTraceContextPropagator}from"@opentelemetry/core";import{defaultServiceName,detectResources,resourceFromAttributes}from"@opentelemetry/resources";import{MeterProvider,PeriodicExportingMetricReader}from"@opentelemetry/sdk-metrics";import{WebTracerProvider}from"@opentelemetry/sdk-trace-web";import{resolveEnvironment}from"@interfere/types/sdk/runtime";import{browserDetector}from"@opentelemetry/opentelemetry-browser-detector";import{BatchLogRecordProcessor,LoggerProvider}from"@opentelemetry/sdk-logs";import{BatchSpanProcessor}from"@opentelemetry/sdk-trace-base";import{createSessionLogRecordProcessor,createSessionSpanProcessor}from"@opentelemetry/web-common";const ATTR_DEVICE_ID=`device.id`,BROWSER_BATCH_OPTIONS={exportTimeoutMillis:1e4,maxExportBatchSize:10,maxQueueSize:2048,scheduledDelayMillis:2e3};function createSessionBaggagePropagator(getSessionId){let propagator=new W3CBaggagePropagator;return{fields:()=>propagator.fields(),extract:(ctx,carrier,getter)=>propagator.extract(ctx,carrier,getter),inject:(ctx,carrier,setter)=>{let sessionId=getSessionId(),baggage=propagation.getBaggage(ctx)??propagation.createBaggage(),updated=sessionId?baggage.setEntry(`session.id`,{value:sessionId}):baggage.removeEntry(`session.id`);propagator.inject(propagation.setBaggage(ctx,updated),carrier,setter)}}}function createDeviceSpanProcessor(opts){return{forceFlush:async()=>Promise.resolve(),onEnd(){},onStart(span){let id=opts.getDeviceId();id&&span.setAttribute(ATTR_DEVICE_ID,id)},shutdown:async()=>Promise.resolve()}}function createDeviceLogRecordProcessor(opts){return{forceFlush:async()=>Promise.resolve(),onEmit(logRecord){let id=opts.getDeviceId();id&&logRecord.setAttribute(ATTR_DEVICE_ID,id)},shutdown:async()=>Promise.resolve()}}function stampGatedAttributes(target,opts){if(opts.isEnabled())for(let[key,value]of Object.entries(opts.attributes))value!==void 0&&target.setAttribute(key,value)}function createDeviceInfoSpanProcessor(opts){return{forceFlush:async()=>Promise.resolve(),onEnd(){},onStart:span=>{stampGatedAttributes(span,opts)},shutdown:async()=>Promise.resolve()}}function createDeviceInfoLogRecordProcessor(opts){return{forceFlush:async()=>Promise.resolve(),onEmit:logRecord=>{stampGatedAttributes(logRecord,opts)},shutdown:async()=>Promise.resolve()}}function buildOtelProvider(input){let environment=resolveEnvironment({explicit:getStringGlobal(ENVIRONMENT_GLOBAL),env:typeof process>`u`?{}:{INTERFERE_ENVIRONMENT:process.env.INTERFERE_ENVIRONMENT,NODE_ENV:process.env.NODE_ENV,VERCEL_ENV:process.env.VERCEL_ENV}}),resource=resourceFromAttributes(omitUndefined({"service.name":input.serviceName||defaultServiceName(),"service.namespace":input.serviceNamespace,"deployment.environment.name":environment,"telemetry.sdk.language":`webjs`,"interfere.sdk.name":SDK_NAME,"interfere.sdk.version":SDK_VERSION,"interfere.sdk.stack":input.sdkStack.join(`, `),"release.slug":input.releaseSlug||void 0})),deviceInfoAttributes=detectResources({detectors:[browserDetector]}).attributes,isDeviceInfoEnabled=input.isDeviceInfoEnabled??(()=>!1),traceExporter=createTraceExporter({clientOptions:input.clientOptions}),{getSessionId}=input,{getDeviceId}=input,spanProcessors=[createUrlRedactionSpanProcessor(input.urlRedaction??resolveUrlRedaction()),createSessionSpanProcessor({getSessionId}),createDeviceSpanProcessor({getDeviceId}),createDeviceInfoSpanProcessor({attributes:deviceInfoAttributes,isEnabled:isDeviceInfoEnabled}),...input.additionalSpanProcessors??[],new BatchSpanProcessor(traceExporter,BROWSER_BATCH_OPTIONS)],tracerProvider=new WebTracerProvider({resource,spanProcessors}),contextManager=new PageScopeContextManager;contextManager.enable(),context.setGlobalContextManager(contextManager)||contextManager.disable();let isShutdown=!1,getPropagationSessionId=input.getPropagationSessionId??getSessionId;propagation.fields().length===0&&propagation.setGlobalPropagator(new CompositePropagator({propagators:[new W3CTraceContextPropagator,createSessionBaggagePropagator(()=>isShutdown?null:getPropagationSessionId())]}));let metricExporter=createMetricExporter({clientOptions:input.clientOptions},{attributes:deviceInfoAttributes,isEnabled:isDeviceInfoEnabled}),metricReader=new PeriodicExportingMetricReader({exportIntervalMillis:3e4,exporter:metricExporter}),meterProvider=new MeterProvider({readers:[metricReader,...input.additionalMetricReaders??[]],resource}),logExporter=createLogExporter({clientOptions:input.clientOptions}),loggerProvider=new LoggerProvider({processors:[createSessionLogRecordProcessor({getSessionId}),createDeviceLogRecordProcessor({getDeviceId}),createDeviceInfoLogRecordProcessor({attributes:deviceInfoAttributes,isEnabled:isDeviceInfoEnabled}),new BatchLogRecordProcessor({exporter:logExporter,...BROWSER_BATCH_OPTIONS}),...input.additionalLogRecordProcessors??[]],resource});return{contextManager,flush:async()=>{await Promise.allSettled([tracerProvider.forceFlush(),metricReader.forceFlush(),loggerProvider.forceFlush()])},loggerProvider,meterProvider,metricReader,shutdown:async()=>{isShutdown=!0,await Promise.allSettled([tracerProvider.shutdown(),meterProvider.shutdown(),loggerProvider.shutdown()])},tracerProvider}}export{buildOtelProvider as t};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { t as PageScopeContextManager } from "./page-scope-context-manager-r92ZMJok.mjs";
|
|
2
2
|
import { InterfereClient } from "@interfere/javascript";
|
|
3
3
|
import { ReleaseSlug } from "@interfere/types/releases/slug";
|
|
4
|
+
import { UrlRedactionPolicy } from "@interfere/types/sdk/url-redaction";
|
|
4
5
|
import { SessionId } from "@interfere/types/data/session";
|
|
5
6
|
import { MeterProvider, MetricReader, PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
|
7
|
+
import { WebTracerProvider } from "@opentelemetry/sdk-trace-web";
|
|
6
8
|
import { LogRecordProcessor, LoggerProvider } from "@opentelemetry/sdk-logs";
|
|
7
9
|
import { SpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
8
|
-
import { WebTracerProvider } from "@opentelemetry/sdk-trace-web";
|
|
9
10
|
//#region src/internal/otel/provider.d.ts
|
|
10
11
|
interface OtelProviderInput {
|
|
11
12
|
/** @internal */
|
|
@@ -64,6 +65,8 @@ interface OtelProviderInput {
|
|
|
64
65
|
serviceName?: string;
|
|
65
66
|
/** Optional application namespace for grouping related services. */
|
|
66
67
|
serviceNamespace?: string;
|
|
68
|
+
/** URL redaction applied in `onEnding`, before customer processors and export. Defaults to built-in sensitive names. */
|
|
69
|
+
urlRedaction?: UrlRedactionPolicy;
|
|
67
70
|
}
|
|
68
71
|
interface OtelProviderHandle {
|
|
69
72
|
/**
|