@interfere/react 12.2.0 → 12.3.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/dist/delivery-BXEtTvnO.mjs +1 -0
- package/dist/exporter-CcNtHR8L.mjs +1 -0
- package/dist/{exporter-logs-CeGwMiMo.d.mts → exporter-logs-DMr5-1Yi.d.mts} +1 -1
- package/dist/internal/kernel.mjs +1 -1
- package/dist/internal/otel/exporter-logs.d.mts +1 -1
- package/dist/internal/otel/exporter-metrics.d.mts +1 -1
- package/dist/internal/otel/exporter.d.mts +1 -1
- package/dist/internal/otel/exporter.mjs +1 -1
- package/dist/internal/otel/index.mjs +1 -1
- package/dist/internal/otel/provider.mjs +1 -1
- package/dist/internal/version.mjs +1 -1
- package/dist/internal/wrapper-singleton.mjs +1 -1
- package/dist/{kernel-D52QMtA9.mjs → kernel-B0Q_aRde.mjs} +1 -1
- package/dist/plugins/replay/index.mjs +1 -1
- package/dist/plugins/replay/upload/delivery.d.mts +2 -2
- package/dist/plugins/replay/upload/delivery.mjs +1 -1
- package/dist/{provider-BMoWBbsK.mjs → provider-DYb87tIb.mjs} +1 -1
- package/dist/{version-CSFECZRw.mjs → version-CU2o2z22.mjs} +1 -1
- package/package.json +2 -2
- package/dist/delivery-_q1bkaIt.mjs +0 -1
- package/dist/exporter-D6Ld-TFZ.mjs +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as createLogger}from"./log-D6Ht--tv.mjs";import{t as reserveKeepaliveBody}from"./keepalive-budget-DeafGnVZ.mjs";import{t as gzipForUnload}from"./unload-gzip-WX9FyWPs.mjs";import{t as uploadReplayChunk}from"./upload-BIh8Q5UQ.mjs";import{omitUndefined}from"@interfere/helpers/omit-undefined";const log=createLogger(`replay`),REPLAY_TRACER_NAME=`@interfere/react/replay`,textEncoder=new TextEncoder,FATAL_STATUSES=new Set([401,403,413]);function classifyRejection(status){return status===409?`skipped`:FATAL_STATUSES.has(status)?`fatal`:`retryable`}async function prepareBody(compressor,rawBytes){if(!compressor.gzip)return{body:rawBytes,encoding:null,release:null};try{return{body:await compressor.gzip(rawBytes),encoding:`gzip`,release:null}}catch(error){return log.warn(`gzip failed for chunk; sending uncompressed: %o`,error),{body:rawBytes,encoding:null,release:null}}}function prepareUnloadBody(rawBytes){let rawRelease=reserveKeepaliveBody(rawBytes.byteLength);if(rawRelease)return{body:rawBytes,encoding:null,release:rawRelease};let compressed=gzipForUnload(rawBytes);return compressed?{body:compressed,encoding:`gzip`,release:reserveKeepaliveBody(compressed.byteLength)}:{body:rawBytes,encoding:null,release: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,unload}){let sessionId=ctx.getSessionId();if(!sessionId)return`ok`;let rawBytes=textEncoder.encode(payload.bodyJson),uncompressedBytes=rawBytes.byteLength,prepared=unload?prepareUnloadBody(rawBytes):await prepareBody(compressor,rawBytes),headers={"x-replay-meta":encodeReplayMeta(chunk,payload)};prepared.encoding===`gzip`&&(headers[`content-encoding`]=`gzip`);let keepalive=prepared.release!==null,response;try{let upload=await uploadReplayChunk(target,sessionId,prepared.body,headers,{keepalive});if(!upload.ok)return await upload.body?.cancel(),classifyRejection(upload.status);response=await upload.json()}catch(error){return log.warn(`replay chunk upload failed: %o`,error),`retryable`}finally{prepared.release?.()}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,"replay.chunk.unload":unload||void 0,"replay.chunk.keepalive":unload?keepalive:void 0});return ctx.getTracer(REPLAY_TRACER_NAME).startSpan(`replay.chunk`,{attributes}).end(),`ok`}export{deliverChunk as n,REPLAY_TRACER_NAME as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as reserveKeepaliveBody}from"./keepalive-budget-DeafGnVZ.mjs";import{t as PRODUCER_VERSION}from"./version-CU2o2z22.mjs";import{t as IngestLogExporter}from"./exporter-logs-DS2AXWnV.mjs";import{t as IngestMetricExporter}from"./exporter-metrics-DZYqUo6_.mjs";import{toError}from"@interfere/types/sdk/errors";import{InterfereClient,InterfereError}from"@interfere/javascript";import{TELEMETRY_EXPORT_TIMEOUT_MS,retryTelemetry}from"@interfere/helpers/retry-telemetry";import{ExportResultCode}from"@opentelemetry/core";import{JsonTraceSerializer}from"@opentelemetry/otlp-transformer";import{z}from"zod";const INGEST_IGNORE_RE=/\/drain\/v1\/(?:traces|logs|metrics)(?:\?|$)/u,AUTH_INVALID_HALT_COOLDOWN_MS=3e5,HALT_MESSAGES={release_not_found:`ingest halted: the ingest endpoint does not recognize this build's release`,public_key_rejected:`ingest paused: the ingest endpoint rejected this page's public key`};let haltReason=null,authHaltExpiresAt=0,consecutiveAuthRejections=0;function resetIngestHalt(){haltReason=null,authHaltExpiresAt=0,consecutiveAuthRejections=0}function currentHaltReason(){return haltReason===`public_key_rejected`&&Date.now()>=authHaltExpiresAt&&(haltReason=null,consecutiveAuthRejections=2),haltReason}function isIngestHalted(){return currentHaltReason()!==null}const textEncoder=new TextEncoder;function detectUnacceptableExport(error){if(currentHaltReason()!==null||error.statusCode!==422&&error.statusCode!==401)return;let body=error.body;if(typeof body==`object`&&body&&`code`in body){if(error.statusCode===422&&body.code===`RELEASE_NOT_FOUND`){haltReason=`release_not_found`,console.warn(`[interfere] the ingest endpoint does not recognize this build's release. Telemetry export is disabled for this page load. Check that source-map upload and finalization succeeded and that build and runtime use the same surface key.`);return}if(error.statusCode===401&&body.code===`AUTH_PK_INVALID`){if(consecutiveAuthRejections+=1,consecutiveAuthRejections<3)return;haltReason=`public_key_rejected`,authHaltExpiresAt=Date.now()+AUTH_INVALID_HALT_COOLDOWN_MS,console.warn(`[interfere] the ingest endpoint rejected this page's public key ${consecutiveAuthRejections} times in a row — telemetry export is paused for ${AUTH_INVALID_HALT_COOLDOWN_MS/6e4} minutes, then retried once. Check that INTERFERE_PUBLIC_KEY matches an active surface; a deleted surface's key stays rejected until the page is rebuilt with the new key.`)}}}function makeSender(input,signal){let client=new InterfereClient({...input.clientOptions,maxRetries:0,timeoutInSeconds:TELEMETRY_EXPORT_TIMEOUT_MS/1e3,fetch:Object.assign(async(url,init)=>{let body=init?.body,bytes=typeof body==`string`?textEncoder.encode(body).byteLength:0,release=reserveKeepaliveBody(bytes);try{return await retryTelemetry(async abortSignal=>globalThis.fetch(url,{...init,credentials:`omit`,keepalive:release!==null,signal:abortSignal}),init?.signal)}finally{release?.()}},globalThis.fetch)});return((payload,resultCallback)=>{if(!payload||payload.byteLength===0){resultCallback({code:ExportResultCode.SUCCESS});return}let reason=currentHaltReason();if(reason!==null){resultCallback({code:ExportResultCode.FAILED,error:Error(HALT_MESSAGES[reason])});return}(async()=>{try{let body=z.record(z.string(),z.unknown()).parse(JSON.parse(new TextDecoder().decode(payload)));await client.drain.otlpExport({signal,body},{headers:{"x-interfere-producer-version":PRODUCER_VERSION}}),consecutiveAuthRejections=0,resultCallback({code:ExportResultCode.SUCCESS})}catch(error){error instanceof InterfereError&&detectUnacceptableExport(error),resultCallback({code:ExportResultCode.FAILED,error:toError(error)})}})()})}var IngestTraceExporter=class{send;constructor(send){this.send=send}export(spans,resultCallback){if(spans.length===0){resultCallback({code:ExportResultCode.SUCCESS});return}this.send(JsonTraceSerializer.serializeRequest(spans),resultCallback)}async shutdown(){return Promise.resolve()}async forceFlush(){return Promise.resolve()}};function createTraceExporter(input){return new IngestTraceExporter(makeSender(input,`traces`))}function createMetricExporter(input,gatedResourceAttributes){return new IngestMetricExporter(makeSender(input,`metrics`),gatedResourceAttributes)}function createLogExporter(input){return new IngestLogExporter(makeSender(input,`logs`))}export{isIngestHalted as a,createTraceExporter as i,createLogExporter as n,resetIngestHalt as o,createMetricExporter as r,INGEST_IGNORE_RE as t};
|
|
@@ -25,7 +25,7 @@ type SignalSender = (payload: Uint8Array | undefined, resultCallback: (result: E
|
|
|
25
25
|
interface ExporterCommon {
|
|
26
26
|
clientOptions: InterfereClient.Options;
|
|
27
27
|
}
|
|
28
|
-
/** Test-only reset
|
|
28
|
+
/** Test-only reset of the ingest halt state. */
|
|
29
29
|
declare function resetIngestHalt(): void;
|
|
30
30
|
declare function isIngestHalted(): boolean;
|
|
31
31
|
declare class IngestTraceExporter implements SpanExporter {
|
package/dist/internal/kernel.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as isEnabledByEnvironment}from"../environment-CoEXhF1a.mjs";import{i as readReleaseSlugFromGlobals,n as buildSdkStack,r as createKernel,t as Kernel}from"../kernel-
|
|
1
|
+
import{t as isEnabledByEnvironment}from"../environment-CoEXhF1a.mjs";import{i as readReleaseSlugFromGlobals,n as buildSdkStack,r as createKernel,t as Kernel}from"../kernel-B0Q_aRde.mjs";export{Kernel,buildSdkStack,createKernel,isEnabledByEnvironment,readReleaseSlugFromGlobals};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as IngestLogExporter } from "../../exporter-logs-
|
|
1
|
+
import { t as IngestLogExporter } from "../../exporter-logs-DMr5-1Yi.mjs";
|
|
2
2
|
export { IngestLogExporter };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { l as GatedResourceAttributes, u as IngestMetricExporter } from "../../exporter-logs-
|
|
1
|
+
import { l as GatedResourceAttributes, u as IngestMetricExporter } from "../../exporter-logs-DMr5-1Yi.mjs";
|
|
2
2
|
export { GatedResourceAttributes, IngestMetricExporter };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as createMetricExporter, c as resetIngestHalt, i as createLogExporter, n as INGEST_IGNORE_RE, o as createTraceExporter, r as SignalSender, s as isIngestHalted } from "../../exporter-logs-
|
|
1
|
+
import { a as createMetricExporter, c as resetIngestHalt, i as createLogExporter, n as INGEST_IGNORE_RE, o as createTraceExporter, r as SignalSender, s as isIngestHalted } from "../../exporter-logs-DMr5-1Yi.mjs";
|
|
2
2
|
export { INGEST_IGNORE_RE, SignalSender, createLogExporter, createMetricExporter, createTraceExporter, isIngestHalted, resetIngestHalt };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as isIngestHalted,i as createTraceExporter,n as createLogExporter,o as resetIngestHalt,r as createMetricExporter,t as INGEST_IGNORE_RE}from"../../exporter-
|
|
1
|
+
import{a as isIngestHalted,i as createTraceExporter,n as createLogExporter,o as resetIngestHalt,r as createMetricExporter,t as INGEST_IGNORE_RE}from"../../exporter-CcNtHR8L.mjs";export{INGEST_IGNORE_RE,createLogExporter,createMetricExporter,createTraceExporter,isIngestHalted,resetIngestHalt};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as registerBundledInstrumentations}from"../../instrumentations-CY8NcP_M.mjs";import{i as seedPageScope,n as createPageScopeRotator,r as installNavigationScope,t as PAGE_SCOPE_MAX_AGE_MS}from"../../navigation-DwkvuhFR.mjs";import{t as readPropagationFromDocument}from"../../propagation-DVcqCu_E.mjs";import{t as buildOtelProvider}from"../../provider-
|
|
1
|
+
import{t as registerBundledInstrumentations}from"../../instrumentations-CY8NcP_M.mjs";import{i as seedPageScope,n as createPageScopeRotator,r as installNavigationScope,t as PAGE_SCOPE_MAX_AGE_MS}from"../../navigation-DwkvuhFR.mjs";import{t as readPropagationFromDocument}from"../../propagation-DVcqCu_E.mjs";import{t as buildOtelProvider}from"../../provider-DYb87tIb.mjs";import{t as captureWebVitals}from"../../web-vitals-CxXDUgpl.mjs";export{PAGE_SCOPE_MAX_AGE_MS,buildOtelProvider,captureWebVitals,createPageScopeRotator,installNavigationScope,readPropagationFromDocument,registerBundledInstrumentations,seedPageScope};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as buildOtelProvider}from"../../provider-
|
|
1
|
+
import{t as buildOtelProvider}from"../../provider-DYb87tIb.mjs";export{buildOtelProvider};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as SDK_NAME,r as SDK_VERSION,t as PRODUCER_VERSION}from"../version-
|
|
1
|
+
import{n as SDK_NAME,r as SDK_VERSION,t as PRODUCER_VERSION}from"../version-CU2o2z22.mjs";export{PRODUCER_VERSION,SDK_NAME,SDK_VERSION};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as createLogger}from"../log-D6Ht--tv.mjs";import{n as registerKernel,r as unregisterKernel}from"../kernel-registry-6f-3VCIy.mjs";import{n as isForceEnableActive,t as hasPublicKey}from"../config-VOyDjqS7.mjs";import{t as isEnabledByEnvironment}from"../environment-CoEXhF1a.mjs";import{r as createKernel}from"../kernel-
|
|
1
|
+
import{t as createLogger}from"../log-D6Ht--tv.mjs";import{n as registerKernel,r as unregisterKernel}from"../kernel-registry-6f-3VCIy.mjs";import{n as isForceEnableActive,t as hasPublicKey}from"../config-VOyDjqS7.mjs";import{t as isEnabledByEnvironment}from"../environment-CoEXhF1a.mjs";import{r as createKernel}from"../kernel-B0Q_aRde.mjs";import{n as isBotUserAgent}from"../bot-YLSbnCeg.mjs";const log=createLogger(`init`);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:hasPublicKey()?(pending=initKernel({...opts,_wrapperVersions:[input.producerVersion]}),pending):(log.warn(`No public key is configured, so the SDK is disabled. Set INTERFERE_PUBLIC_KEY (VITE_INTERFERE_PUBLIC_KEY for Vite) on builds that should send telemetry.`),null))},subscribeToKernel(listener){return listeners.add(listener),(()=>{listeners.delete(listener)})}}}export{createWrapperSingleton};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as createLogger}from"./log-D6Ht--tv.mjs";import{r as onPageUnloading,t as onPageHidden}from"./page-lifecycle-DTWqGlz2.mjs";import{t as SessionTracker}from"./api-BUYnj5MA.mjs";import{n as getStringGlobal,t as getGlobal}from"./global-DYq1Z4_H.mjs";import{i as setIngestHost,r as resolveTargets}from"./config-VOyDjqS7.mjs";import{a as resolvePrivacyPolicy}from"./privacy-CRuL0X8r.mjs";import{t as PRODUCER_VERSION}from"./version-CSFECZRw.mjs";import{t as INGEST_IGNORE_RE}from"./exporter-D6Ld-TFZ.mjs";import{t as recordInitialNavigation}from"./initial-navigation-YeK6UUHX.mjs";import{n as recordExceptionOnSpan,r as startExceptionSpan,t as buildExceptionEventAttrs}from"./exception-span-B74fhBQb.mjs";import{t as PluginRuntime}from"./plugin-runtime-B1oFO16q.mjs";import{isNonErrorException,shouldDropBrowserExtensionNoise,shouldDropUnresolvableStack}from"@interfere/types/sdk/errors";import{trace}from"@opentelemetry/api";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{InterfereClient}from"@interfere/javascript";import{releaseSlugSchema}from"@interfere/types/releases/slug";import{FORCE_ENABLE_GLOBAL,RELEASE_SLUG_GLOBAL,SDK_STACK_GLOBAL}from"@interfere/types/sdk/injected-globals";import{readBakedPlugins,remoteConfigInputSchema}from"@interfere/types/sdk/remote-config";import{SERVICE_NAME_GLOBAL}from"@interfere/types/sdk/service-name";import{redactUrl,resolveUrlRedaction}from"@interfere/types/sdk/url-redaction";const log=createLogger(`kernel`),REPLAY_UPLOAD_RE=/\/v3\/replay\/upload\//u;function buildSdkStack(wrapperVersions){return[...wrapperVersions??[],PRODUCER_VERSION]}var Kernel=class{consent;identity;device;session;privacyPolicy;urlRedaction;redactUrl=url=>redactUrl(url,this.urlRedaction);seen=new WeakSet;initialNavigationSeen=new Set;runtime=null;otel=null;otelDispose=null;otelControls=null;deviceInfoCaptureEnabled=!1;unsubscribePageHidden=null;unsubscribePageUnloading=null;tracker;constructor(tracker,privacy={}){this.tracker=tracker,this.privacyPolicy=resolvePrivacyPolicy(privacy),this.urlRedaction=resolveUrlRedaction(privacy.urls),this.consent={get:()=>this.requireRuntime().getConsent(),set:value=>{let runtime=this.requireRuntime();value===void 0?runtime.resetConsent():runtime.setConsent(value)}},this.identity={clear:()=>{this.tracker.reset()},get:()=>this.tracker.getIdentity(),set:async params=>this.tracker.identify(params)},this.device={getDeviceId:()=>this.tracker.getDeviceId(),getFpHash:()=>this.tracker.getFpHash()},this.session={getId:()=>this.tracker.sessionId(),getWindowId:()=>this.tracker.windowId()},this.unsubscribePageHidden=onPageHidden(()=>{this.flush().catch(()=>{})}),this.unsubscribePageUnloading=onPageUnloading(()=>{this.flush().catch(()=>{})})}attachRuntime(runtime){this.runtime=runtime}requireRuntime(){if(!this.runtime)throw Error(`Kernel runtime not attached. createKernel must call attachRuntime before any consent/dispose path runs.`);return this.runtime}getSessionId(){return this.tracker.sessionId()??``}getWindowId(){return this.tracker.windowId()??``}onSessionPause(handler){return this.tracker.onSessionPause(handler)}onSessionResume(handler){return this.tracker.onSessionResume(handler)}getPluginConfigState(key){return this.requireRuntime().getPluginConfigState(key)}getReplayConfig(){return this.requireRuntime().getReplayConfig()}isInteractionCaptureEnabled(){return this.requireRuntime().isInteractionCaptureEnabled()}subscribePluginConfigState(key,listener){return this.requireRuntime().subscribePluginConfigState(key,listener)}getTracer(name){return this.otel?.tracerProvider.getTracer(name)??trace.getTracer(name)}startPageEventsCapture(){let{otelControls:controls,otel}=this;return!controls||!otel?null:(controls.setPageEventsEnabled(!0),this.recordInitialNavigation(otel.loggerProvider),(()=>{controls.setPageEventsEnabled(!1)}))}startDeviceInfoCapture(){return this.tracker.startDeviceIdentity(),this.deviceInfoCaptureEnabled=!0,(reason=>{this.deviceInfoCaptureEnabled=!1,reason===`consent-revoked`&&this.tracker.discardDeviceIdentity()})}isDeviceInfoCaptureEnabled(){return this.deviceInfoCaptureEnabled}recordException(value,opts){if(!isNonErrorException(value)){if(this.seen.has(value))return;this.seen.add(value)}if(!isNonErrorException(value)){let stacks=[],current=value;for(let depth=0;current&&depth<5;depth+=1)current.stack&&stacks.push(current.stack),current=current.cause instanceof Error?current.cause:void 0;if(shouldDropBrowserExtensionNoise(stacks)||shouldDropUnresolvableStack(stacks))return}let attrs=buildExceptionEventAttrs(value,opts),active=trace.getActiveSpan();if(active?.isRecording()){recordExceptionOnSpan(active,value,attrs,opts.mechanism.handled);return}let tracer=this.otel?.tracerProvider.getTracer(`@interfere/react/exception`);if(!tracer)return;let span=startExceptionSpan(tracer,value);recordExceptionOnSpan(span,value,attrs,opts.mechanism.handled),span.end()}recordLog(input){this.otel&&this.otel.loggerProvider.getLogger(`@interfere/react`).emit(omitUndefined({body:input.body,severityNumber:input.severityNumber,severityText:input.severityText,attributes:input.attributes}))}recordInitialNavigation(loggerProvider){recordInitialNavigation({getSessionId:()=>this.session.getId(),getWindowId:()=>this.session.getWindowId(),loggerProvider,redactUrl:this.redactUrl,seen:this.initialNavigationSeen})}async flush(){this.otel&&await this.otel.flush()}attachOtel(handle,dispose,controls){this.otel=handle,this.otelDispose=dispose,this.otelControls=controls??null}syncProviderConfig(config){this.requireRuntime().applyProviderConfig(config.plugins,config.consent)}async dispose(){this.unsubscribePageHidden?.(),this.unsubscribePageHidden=null,this.unsubscribePageUnloading?.(),this.unsubscribePageUnloading=null,this.runtime&&await this.runtime.dispose(),this.tracker.dispose(),this.otelDispose?.(),this.otelDispose=null,this.otel&&=(await this.otel.shutdown(),null)}};async function createKernel(input={}){let{opts={}}=input,fetcher=opts.fetch??globalThis.fetch.bind(globalThis),remotePlugins=await resolveRemotePlugins(opts,fetcher),targets=resolveTargets(opts.apiHost);log.info(`ingest: %s`,targets.ingest.baseUrl),getGlobal(FORCE_ENABLE_GLOBAL)&&log.warn(`FORCE_ENABLE is active. Events will be dropped by production ingest. This should only be set during local development.`);let tracker=new SessionTracker({fetcher,target:targets.ingest});opts._wrapperVersions?.length&&Object.assign(globalThis,{[SDK_STACK_GLOBAL]:opts._wrapperVersions});let kernel=new Kernel(tracker,opts.privacy),runtime=new PluginRuntime(kernel,opts.consent,remotePlugins??{});if(kernel.attachRuntime(runtime),tracker.start(),runtime.start(),opts.tracing!==!1){let resolvedTracing={...typeof opts.tracing==`object`?opts.tracing:void 0},serviceName=opts.serviceName||getStringGlobal(SERVICE_NAME_GLOBAL);serviceName&&(resolvedTracing.serviceName=serviceName),opts.serviceNamespace!==void 0&&(resolvedTracing.serviceNamespace=opts.serviceNamespace),opts._internalAdditionalSpanProcessors&&(resolvedTracing.additionalSpanProcessors=opts._internalAdditionalSpanProcessors),opts._internalAdditionalLogRecordProcessors&&(resolvedTracing.additionalLogRecordProcessors=opts._internalAdditionalLogRecordProcessors),opts._internalAdditionalMetricReaders&&(resolvedTracing.additionalMetricReaders=opts._internalAdditionalMetricReaders),await wireOtel(kernel,targets,opts._wrapperVersions,resolvedTracing)}return remotePlugins?runtime.applyRemoteConfig(remotePlugins):runtime.applyRemoteConfigDefaults(),kernel}async function resolveRemotePlugins(opts,fetcher){let baked=readBakedPlugins();if(baked)return baked;let remoteConfig=await fetchRemoteConfig(resolveTargets(opts.apiHost).config,fetcher);return remoteConfig?.ingestUrl&&setIngestHost(remoteConfig.ingestUrl),remoteConfig?.plugins??null}async function wireOtel(kernel,targets,wrapperVersions,tracing){let{buildOtelProvider,captureWebVitals,createPageScopeRotator,installNavigationScope,PAGE_SCOPE_MAX_AGE_MS,readPropagationFromDocument,registerBundledInstrumentations,seedPageScope}=await import(`./internal/otel/index.mjs`),releaseSlug=readReleaseSlugFromGlobals(),handle=buildOtelProvider(omitUndefined({clientOptions:targets.ingest,getDeviceId:()=>kernel.device.getDeviceId(),getSessionId:()=>kernel.session.getId(),getPropagationSessionId:()=>kernel.consent.get()?.analytics===!1?null:kernel.session.getId(),isDeviceInfoEnabled:()=>kernel.isDeviceInfoCaptureEnabled(),releaseSlug,sdkStack:buildSdkStack(wrapperVersions),serviceName:tracing.serviceName||void 0,serviceNamespace:tracing.serviceNamespace,additionalSpanProcessors:[...tracing.spanProcessors??[],...tracing.additionalSpanProcessors??[]],additionalLogRecordProcessors:tracing.additionalLogRecordProcessors,additionalMetricReaders:tracing.additionalMetricReaders,urlRedaction:kernel.urlRedaction})),scopeSpanInput=omitUndefined({tracer:handle.tracerProvider.getTracer(`@interfere/react/navigation`),resolveRoute:tracing.resolveRoute}),extracted=readPropagationFromDocument();handle.contextManager.setPageScope(extracted??seedPageScope(scopeSpanInput)),handle.contextManager.setRotation(createPageScopeRotator(scopeSpanInput),PAGE_SCOPE_MAX_AGE_MS);let disposeNavigationScope=installNavigationScope({...scopeSpanInput,setPageScope:ctx=>{handle.contextManager.setPageScope(ctx)}}),instrumentations=registerBundledInstrumentations(omitUndefined({tracerProvider:handle.tracerProvider,loggerProvider:handle.loggerProvider,ignoreUrls:[INGEST_IGNORE_RE,`${targets.config.baseUrl}/v3/config`,`${targets.ingest.baseUrl}/v3/session`,REPLAY_UPLOAD_RE],apiHosts:tracing.apiHosts,propagateContextUrls:tracing.propagateContextUrls,resolveRoute:tracing.resolveRoute,captureFailedRequests:tracing.captureFailedRequests,redactUrl:kernel.redactUrl,privacyPolicy:kernel.privacyPolicy,isInteractionCaptureEnabled:()=>kernel.isInteractionCaptureEnabled()}));tracing.webVitals!==!1&&captureWebVitals(omitUndefined({flush:async()=>handle.flush(),meter:handle.meterProvider.getMeter(`@interfere/react/web-vitals`),resolveRoute:tracing.resolveRoute})),kernel.attachOtel(handle,()=>{disposeNavigationScope(),instrumentations.dispose()},{setPageEventsEnabled:instrumentations.setPageEventsEnabled})}async function fetchRemoteConfig(configTarget,fetcher){try{let client=new InterfereClient({...configTarget,fetch:Object.assign(async(url,init)=>fetcher(url,{...init,credentials:`omit`}),fetcher)});return remoteConfigInputSchema.parse(await client.config.getSdkConfig())}catch{return log.warn(`remote config fetch failed, using local defaults`),null}}function readReleaseSlugFromGlobals(){let value=getGlobal(RELEASE_SLUG_GLOBAL);return typeof value==`string`?releaseSlugSchema.parse(value):null}export{readReleaseSlugFromGlobals as i,buildSdkStack as n,createKernel as r,Kernel as t};
|
|
1
|
+
import{t as createLogger}from"./log-D6Ht--tv.mjs";import{r as onPageUnloading,t as onPageHidden}from"./page-lifecycle-DTWqGlz2.mjs";import{t as SessionTracker}from"./api-BUYnj5MA.mjs";import{n as getStringGlobal,t as getGlobal}from"./global-DYq1Z4_H.mjs";import{i as setIngestHost,r as resolveTargets}from"./config-VOyDjqS7.mjs";import{a as resolvePrivacyPolicy}from"./privacy-CRuL0X8r.mjs";import{t as PRODUCER_VERSION}from"./version-CU2o2z22.mjs";import{t as INGEST_IGNORE_RE}from"./exporter-CcNtHR8L.mjs";import{t as recordInitialNavigation}from"./initial-navigation-YeK6UUHX.mjs";import{n as recordExceptionOnSpan,r as startExceptionSpan,t as buildExceptionEventAttrs}from"./exception-span-B74fhBQb.mjs";import{t as PluginRuntime}from"./plugin-runtime-B1oFO16q.mjs";import{isNonErrorException,shouldDropBrowserExtensionNoise,shouldDropUnresolvableStack}from"@interfere/types/sdk/errors";import{trace}from"@opentelemetry/api";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{InterfereClient}from"@interfere/javascript";import{releaseSlugSchema}from"@interfere/types/releases/slug";import{FORCE_ENABLE_GLOBAL,RELEASE_SLUG_GLOBAL,SDK_STACK_GLOBAL}from"@interfere/types/sdk/injected-globals";import{readBakedPlugins,remoteConfigInputSchema}from"@interfere/types/sdk/remote-config";import{SERVICE_NAME_GLOBAL}from"@interfere/types/sdk/service-name";import{redactUrl,resolveUrlRedaction}from"@interfere/types/sdk/url-redaction";const log=createLogger(`kernel`),REPLAY_UPLOAD_RE=/\/v3\/replay\/upload\//u;function buildSdkStack(wrapperVersions){return[...wrapperVersions??[],PRODUCER_VERSION]}var Kernel=class{consent;identity;device;session;privacyPolicy;urlRedaction;redactUrl=url=>redactUrl(url,this.urlRedaction);seen=new WeakSet;initialNavigationSeen=new Set;runtime=null;otel=null;otelDispose=null;otelControls=null;deviceInfoCaptureEnabled=!1;unsubscribePageHidden=null;unsubscribePageUnloading=null;tracker;constructor(tracker,privacy={}){this.tracker=tracker,this.privacyPolicy=resolvePrivacyPolicy(privacy),this.urlRedaction=resolveUrlRedaction(privacy.urls),this.consent={get:()=>this.requireRuntime().getConsent(),set:value=>{let runtime=this.requireRuntime();value===void 0?runtime.resetConsent():runtime.setConsent(value)}},this.identity={clear:()=>{this.tracker.reset()},get:()=>this.tracker.getIdentity(),set:async params=>this.tracker.identify(params)},this.device={getDeviceId:()=>this.tracker.getDeviceId(),getFpHash:()=>this.tracker.getFpHash()},this.session={getId:()=>this.tracker.sessionId(),getWindowId:()=>this.tracker.windowId()},this.unsubscribePageHidden=onPageHidden(()=>{this.flush().catch(()=>{})}),this.unsubscribePageUnloading=onPageUnloading(()=>{this.flush().catch(()=>{})})}attachRuntime(runtime){this.runtime=runtime}requireRuntime(){if(!this.runtime)throw Error(`Kernel runtime not attached. createKernel must call attachRuntime before any consent/dispose path runs.`);return this.runtime}getSessionId(){return this.tracker.sessionId()??``}getWindowId(){return this.tracker.windowId()??``}onSessionPause(handler){return this.tracker.onSessionPause(handler)}onSessionResume(handler){return this.tracker.onSessionResume(handler)}getPluginConfigState(key){return this.requireRuntime().getPluginConfigState(key)}getReplayConfig(){return this.requireRuntime().getReplayConfig()}isInteractionCaptureEnabled(){return this.requireRuntime().isInteractionCaptureEnabled()}subscribePluginConfigState(key,listener){return this.requireRuntime().subscribePluginConfigState(key,listener)}getTracer(name){return this.otel?.tracerProvider.getTracer(name)??trace.getTracer(name)}startPageEventsCapture(){let{otelControls:controls,otel}=this;return!controls||!otel?null:(controls.setPageEventsEnabled(!0),this.recordInitialNavigation(otel.loggerProvider),(()=>{controls.setPageEventsEnabled(!1)}))}startDeviceInfoCapture(){return this.tracker.startDeviceIdentity(),this.deviceInfoCaptureEnabled=!0,(reason=>{this.deviceInfoCaptureEnabled=!1,reason===`consent-revoked`&&this.tracker.discardDeviceIdentity()})}isDeviceInfoCaptureEnabled(){return this.deviceInfoCaptureEnabled}recordException(value,opts){if(!isNonErrorException(value)){if(this.seen.has(value))return;this.seen.add(value)}if(!isNonErrorException(value)){let stacks=[],current=value;for(let depth=0;current&&depth<5;depth+=1)current.stack&&stacks.push(current.stack),current=current.cause instanceof Error?current.cause:void 0;if(shouldDropBrowserExtensionNoise(stacks)||shouldDropUnresolvableStack(stacks))return}let attrs=buildExceptionEventAttrs(value,opts),active=trace.getActiveSpan();if(active?.isRecording()){recordExceptionOnSpan(active,value,attrs,opts.mechanism.handled);return}let tracer=this.otel?.tracerProvider.getTracer(`@interfere/react/exception`);if(!tracer)return;let span=startExceptionSpan(tracer,value);recordExceptionOnSpan(span,value,attrs,opts.mechanism.handled),span.end()}recordLog(input){this.otel&&this.otel.loggerProvider.getLogger(`@interfere/react`).emit(omitUndefined({body:input.body,severityNumber:input.severityNumber,severityText:input.severityText,attributes:input.attributes}))}recordInitialNavigation(loggerProvider){recordInitialNavigation({getSessionId:()=>this.session.getId(),getWindowId:()=>this.session.getWindowId(),loggerProvider,redactUrl:this.redactUrl,seen:this.initialNavigationSeen})}async flush(){this.otel&&await this.otel.flush()}attachOtel(handle,dispose,controls){this.otel=handle,this.otelDispose=dispose,this.otelControls=controls??null}syncProviderConfig(config){this.requireRuntime().applyProviderConfig(config.plugins,config.consent)}async dispose(){this.unsubscribePageHidden?.(),this.unsubscribePageHidden=null,this.unsubscribePageUnloading?.(),this.unsubscribePageUnloading=null,this.runtime&&await this.runtime.dispose(),this.tracker.dispose(),this.otelDispose?.(),this.otelDispose=null,this.otel&&=(await this.otel.shutdown(),null)}};async function createKernel(input={}){let{opts={}}=input,fetcher=opts.fetch??globalThis.fetch.bind(globalThis),remotePlugins=await resolveRemotePlugins(opts,fetcher),targets=resolveTargets(opts.apiHost);log.info(`ingest: %s`,targets.ingest.baseUrl),getGlobal(FORCE_ENABLE_GLOBAL)&&log.warn(`FORCE_ENABLE is active. Events will be dropped by production ingest. This should only be set during local development.`);let tracker=new SessionTracker({fetcher,target:targets.ingest});opts._wrapperVersions?.length&&Object.assign(globalThis,{[SDK_STACK_GLOBAL]:opts._wrapperVersions});let kernel=new Kernel(tracker,opts.privacy),runtime=new PluginRuntime(kernel,opts.consent,remotePlugins??{});if(kernel.attachRuntime(runtime),tracker.start(),runtime.start(),opts.tracing!==!1){let resolvedTracing={...typeof opts.tracing==`object`?opts.tracing:void 0},serviceName=opts.serviceName||getStringGlobal(SERVICE_NAME_GLOBAL);serviceName&&(resolvedTracing.serviceName=serviceName),opts.serviceNamespace!==void 0&&(resolvedTracing.serviceNamespace=opts.serviceNamespace),opts._internalAdditionalSpanProcessors&&(resolvedTracing.additionalSpanProcessors=opts._internalAdditionalSpanProcessors),opts._internalAdditionalLogRecordProcessors&&(resolvedTracing.additionalLogRecordProcessors=opts._internalAdditionalLogRecordProcessors),opts._internalAdditionalMetricReaders&&(resolvedTracing.additionalMetricReaders=opts._internalAdditionalMetricReaders),await wireOtel(kernel,targets,opts._wrapperVersions,resolvedTracing)}return remotePlugins?runtime.applyRemoteConfig(remotePlugins):runtime.applyRemoteConfigDefaults(),kernel}async function resolveRemotePlugins(opts,fetcher){let baked=readBakedPlugins();if(baked)return baked;let remoteConfig=await fetchRemoteConfig(resolveTargets(opts.apiHost).config,fetcher);return remoteConfig?.ingestUrl&&setIngestHost(remoteConfig.ingestUrl),remoteConfig?.plugins??null}async function wireOtel(kernel,targets,wrapperVersions,tracing){let{buildOtelProvider,captureWebVitals,createPageScopeRotator,installNavigationScope,PAGE_SCOPE_MAX_AGE_MS,readPropagationFromDocument,registerBundledInstrumentations,seedPageScope}=await import(`./internal/otel/index.mjs`),releaseSlug=readReleaseSlugFromGlobals(),handle=buildOtelProvider(omitUndefined({clientOptions:targets.ingest,getDeviceId:()=>kernel.device.getDeviceId(),getSessionId:()=>kernel.session.getId(),getPropagationSessionId:()=>kernel.consent.get()?.analytics===!1?null:kernel.session.getId(),isDeviceInfoEnabled:()=>kernel.isDeviceInfoCaptureEnabled(),releaseSlug,sdkStack:buildSdkStack(wrapperVersions),serviceName:tracing.serviceName||void 0,serviceNamespace:tracing.serviceNamespace,additionalSpanProcessors:[...tracing.spanProcessors??[],...tracing.additionalSpanProcessors??[]],additionalLogRecordProcessors:tracing.additionalLogRecordProcessors,additionalMetricReaders:tracing.additionalMetricReaders,urlRedaction:kernel.urlRedaction})),scopeSpanInput=omitUndefined({tracer:handle.tracerProvider.getTracer(`@interfere/react/navigation`),resolveRoute:tracing.resolveRoute}),extracted=readPropagationFromDocument();handle.contextManager.setPageScope(extracted??seedPageScope(scopeSpanInput)),handle.contextManager.setRotation(createPageScopeRotator(scopeSpanInput),PAGE_SCOPE_MAX_AGE_MS);let disposeNavigationScope=installNavigationScope({...scopeSpanInput,setPageScope:ctx=>{handle.contextManager.setPageScope(ctx)}}),instrumentations=registerBundledInstrumentations(omitUndefined({tracerProvider:handle.tracerProvider,loggerProvider:handle.loggerProvider,ignoreUrls:[INGEST_IGNORE_RE,`${targets.config.baseUrl}/v3/config`,`${targets.ingest.baseUrl}/v3/session`,REPLAY_UPLOAD_RE],apiHosts:tracing.apiHosts,propagateContextUrls:tracing.propagateContextUrls,resolveRoute:tracing.resolveRoute,captureFailedRequests:tracing.captureFailedRequests,redactUrl:kernel.redactUrl,privacyPolicy:kernel.privacyPolicy,isInteractionCaptureEnabled:()=>kernel.isInteractionCaptureEnabled()}));tracing.webVitals!==!1&&captureWebVitals(omitUndefined({flush:async()=>handle.flush(),meter:handle.meterProvider.getMeter(`@interfere/react/web-vitals`),resolveRoute:tracing.resolveRoute})),kernel.attachOtel(handle,()=>{disposeNavigationScope(),instrumentations.dispose()},{setPageEventsEnabled:instrumentations.setPageEventsEnabled})}async function fetchRemoteConfig(configTarget,fetcher){try{let client=new InterfereClient({...configTarget,fetch:Object.assign(async(url,init)=>fetcher(url,{...init,credentials:`omit`}),fetcher)});return remoteConfigInputSchema.parse(await client.config.getSdkConfig())}catch{return log.warn(`remote config fetch failed, using local defaults`),null}}function readReleaseSlugFromGlobals(){let value=getGlobal(RELEASE_SLUG_GLOBAL);return typeof value==`string`?releaseSlugSchema.parse(value):null}export{readReleaseSlugFromGlobals as i,buildSdkStack as n,createKernel as r,Kernel as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as createLogger}from"../../log-D6Ht--tv.mjs";import{n as onPageShown,r as onPageUnloading,t as onPageHidden}from"../../page-lifecycle-DTWqGlz2.mjs";import{r as resolveTargets}from"../../config-VOyDjqS7.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{n as deliverChunk,t as REPLAY_TRACER_NAME}from"../../delivery-
|
|
1
|
+
import{t as createLogger}from"../../log-D6Ht--tv.mjs";import{n as onPageShown,r as onPageUnloading,t as onPageHidden}from"../../page-lifecycle-DTWqGlz2.mjs";import{r as resolveTargets}from"../../config-VOyDjqS7.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{n as deliverChunk,t as REPLAY_TRACER_NAME}from"../../delivery-BXEtTvnO.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{omitUndefined}from"@interfere/helpers/omit-undefined";import{EventType}from"@rrweb/types";const log=createLogger(`replay`);function isBrowserApiRejection(error){return Object.prototype.toString.call(error)===`[object DOMException]`}const replayPlugin={name:`replay`,setup(ctx){let targets=resolveTargets(),recorder=null,flushTimer=null,unsubscribeConfig=null,unsubscribeHidden=null,unsubscribeShown=null,unsubscribeUnloading=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(reason,detail){halted||(halted=!0,ctx.getTracer(REPLAY_TRACER_NAME).startSpan(`replay.halt`,{attributes:omitUndefined({"replay.halt.reason":reason,"replay.halt.detail":detail,"replay.halt.recorder_faults":recorderFaults})}).end(),startup.abort(),clearFlushTimer(),recorder?.stop(),recorder=null)}function clearFlushTimer(){flushTimer&&=(clearInterval(flushTimer),null)}function armFlushTimer(){clearFlushTimer(),flushTimer=setInterval(()=>{clearFlushTimer(),flushTimer=setInterval(flush,1e4),flush()},2e3)}function handleResult(result){if(result===`ok`){consecutiveFailures=0;return}if(result===`skipped`){log.warn(`replay chunk rejected as a segment conflict; skipping it`),consecutiveFailures=0;return}if(result===`fatal`){log.warn(`replay halted: upload rejected`),halt(`upload-rejected`);return}consecutiveFailures+=1,consecutiveFailures>=3&&(log.warn(`replay halted after %d consecutive upload failures`,consecutiveFailures),halt(`upload-failed`))}function handleRecorderFault(error){if(isBrowserApiRejection(error)){log.debug(`recorder passed through a browser API rejection: %s`,error instanceof Error?error.name:`DOMException`);return}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(`recorder-faults`,error instanceof Error?error.constructor.name:`UnknownError`)))}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?.unload??!1)}async function sendChunk(payload,unload){try{handleResult(await deliverChunk({target:targets.ingest,chunk:{segmentId:sequence.take(),windowId},compressor,ctx,payload,unload}))}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?{unload:!0}:void 0))},resumeRecording=()=>{isPaused&&(isPaused=!1,recorder?.start(),armFlushTimer())},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()}),armFlushTimer(),unsubscribeHidden=onPageHidden(()=>{pauseRecording(!0)}),unsubscribeUnloading=onPageUnloading(()=>{flush({unload:!0})}),unsubscribeShown=onPageShown(resumeRecording),unsubscribePause=ctx.onSessionPause(()=>{pauseRecording(!1)}),unsubscribeResume=ctx.onSessionResume(resumeRecording),log.debug(`recording started`))})().catch(error=>{let detail=error instanceof Error?error.constructor.name:`UnknownError`;log.warn(`replay initialization failed: %s`,detail),halt(`init-failed`,detail)}),reason=>{reason===`consent-revoked`?(buffer.drain(),log.debug(`replay buffer discarded: consent revoked`)):flush(),startup.abort(),recorder?.stop(),clearFlushTimer(),unsubscribeConfig?.(),unsubscribeHidden?.(),unsubscribeShown?.(),unsubscribeUnloading?.(),unsubscribePause?.(),unsubscribeResume?.(),compressor.dispose()}}};export{replayPlugin as default};
|
|
@@ -4,7 +4,7 @@ import { n as ReplayChunkPayload } from "../../../chunking-OfmdRxfq.mjs";
|
|
|
4
4
|
import { t as Compressor } from "../../../compressor-host-D3At2PKg.mjs";
|
|
5
5
|
//#region src/plugins/replay/upload/delivery.d.ts
|
|
6
6
|
export declare const REPLAY_TRACER_NAME = "@interfere/react/replay";
|
|
7
|
-
export type DeliverResult = "ok" | "retryable" | "fatal";
|
|
7
|
+
export type DeliverResult = "ok" | "skipped" | "retryable" | "fatal";
|
|
8
8
|
export interface ReplayChunkRef {
|
|
9
9
|
segmentId: number;
|
|
10
10
|
windowId: string;
|
|
@@ -18,5 +18,5 @@ export interface DeliverInput {
|
|
|
18
18
|
/** The page is hiding or unloading: compress synchronously and ask the browser to finish the request after the page unloads while the shared keepalive body budget has room. */
|
|
19
19
|
unload: boolean;
|
|
20
20
|
}
|
|
21
|
-
export declare function deliverChunk({ ctx, chunk, target, compressor, payload, unload }: DeliverInput): Promise<"fatal" | "ok" | "retryable">;
|
|
21
|
+
export declare function deliverChunk({ ctx, chunk, target, compressor, payload, unload }: DeliverInput): Promise<"fatal" | "ok" | "retryable" | "skipped">;
|
|
22
22
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as deliverChunk,t as REPLAY_TRACER_NAME}from"../../../delivery-
|
|
1
|
+
import{n as deliverChunk,t as REPLAY_TRACER_NAME}from"../../../delivery-BXEtTvnO.mjs";export{REPLAY_TRACER_NAME,deliverChunk};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as getStringGlobal}from"./global-DYq1Z4_H.mjs";import{n as SDK_NAME,r as SDK_VERSION}from"./version-
|
|
1
|
+
import{n as getStringGlobal}from"./global-DYq1Z4_H.mjs";import{n as SDK_NAME,r as SDK_VERSION}from"./version-CU2o2z22.mjs";import{i as createTraceExporter,n as createLogExporter,r as createMetricExporter}from"./exporter-CcNtHR8L.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:7e4,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:75e3,exportTimeoutMillis:7e4,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({timeoutMillis:75e3}),metricReader.forceFlush({timeoutMillis:75e3}),loggerProvider.forceFlush({timeoutMillis:75e3})])},loggerProvider,meterProvider,metricReader,shutdown:async()=>{isShutdown=!0,await Promise.allSettled([tracerProvider.shutdown(),meterProvider.shutdown(),loggerProvider.shutdown()])},tracerProvider}}export{buildOtelProvider as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var name=`@interfere/react`,version=`12.
|
|
1
|
+
var name=`@interfere/react`,version=`12.3.0`;const SDK_NAME=name,SDK_VERSION=version,PRODUCER_VERSION=`${SDK_NAME}@${SDK_VERSION}`;export{SDK_NAME as n,SDK_VERSION as r,PRODUCER_VERSION as t};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interfere/react",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.3.0",
|
|
4
4
|
"description": "Client-side React SDK for Interfere. Error tracking, session replay, and analytics.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"error-tracking",
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"@interfere/constants": "^9.3.0",
|
|
97
97
|
"@interfere/helpers": "^9.3.0",
|
|
98
98
|
"@interfere/javascript": "^0.3.0",
|
|
99
|
-
"@interfere/types": "^10.
|
|
99
|
+
"@interfere/types": "^10.5.0",
|
|
100
100
|
"@opentelemetry/api": "1.9.1",
|
|
101
101
|
"@opentelemetry/api-logs": "0.222.0",
|
|
102
102
|
"@opentelemetry/context-zone": "2.11.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as createLogger}from"./log-D6Ht--tv.mjs";import{t as reserveKeepaliveBody}from"./keepalive-budget-DeafGnVZ.mjs";import{t as gzipForUnload}from"./unload-gzip-WX9FyWPs.mjs";import{t as uploadReplayChunk}from"./upload-BIh8Q5UQ.mjs";import{omitUndefined}from"@interfere/helpers/omit-undefined";const log=createLogger(`replay`),REPLAY_TRACER_NAME=`@interfere/react/replay`,textEncoder=new TextEncoder;async function prepareBody(compressor,rawBytes){if(!compressor.gzip)return{body:rawBytes,encoding:null,release:null};try{return{body:await compressor.gzip(rawBytes),encoding:`gzip`,release:null}}catch(error){return log.warn(`gzip failed for chunk; sending uncompressed: %o`,error),{body:rawBytes,encoding:null,release:null}}}function prepareUnloadBody(rawBytes){let rawRelease=reserveKeepaliveBody(rawBytes.byteLength);if(rawRelease)return{body:rawBytes,encoding:null,release:rawRelease};let compressed=gzipForUnload(rawBytes);return compressed?{body:compressed,encoding:`gzip`,release:reserveKeepaliveBody(compressed.byteLength)}:{body:rawBytes,encoding:null,release: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,unload}){let sessionId=ctx.getSessionId();if(!sessionId)return`ok`;let rawBytes=textEncoder.encode(payload.bodyJson),uncompressedBytes=rawBytes.byteLength,prepared=unload?prepareUnloadBody(rawBytes):await prepareBody(compressor,rawBytes),headers={"x-replay-meta":encodeReplayMeta(chunk,payload)};prepared.encoding===`gzip`&&(headers[`content-encoding`]=`gzip`);let keepalive=prepared.release!==null,response;try{let upload=await uploadReplayChunk(target,sessionId,prepared.body,headers,{keepalive});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`}finally{prepared.release?.()}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,"replay.chunk.unload":unload||void 0,"replay.chunk.keepalive":unload?keepalive:void 0});return ctx.getTracer(REPLAY_TRACER_NAME).startSpan(`replay.chunk`,{attributes}).end(),`ok`}export{deliverChunk as n,REPLAY_TRACER_NAME as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as reserveKeepaliveBody}from"./keepalive-budget-DeafGnVZ.mjs";import{t as PRODUCER_VERSION}from"./version-CSFECZRw.mjs";import{t as IngestLogExporter}from"./exporter-logs-DS2AXWnV.mjs";import{t as IngestMetricExporter}from"./exporter-metrics-DZYqUo6_.mjs";import{toError}from"@interfere/types/sdk/errors";import{InterfereClient,InterfereError}from"@interfere/javascript";import{TELEMETRY_EXPORT_TIMEOUT_MS,retryTelemetry}from"@interfere/helpers/retry-telemetry";import{ExportResultCode}from"@opentelemetry/core";import{JsonTraceSerializer}from"@opentelemetry/otlp-transformer";import{z}from"zod";const INGEST_IGNORE_RE=/\/drain\/v1\/(?:traces|logs|metrics)(?:\?|$)/u;let ingestHalted=!1,consecutiveAuthRejections=0;function resetIngestHalt(){ingestHalted=!1,consecutiveAuthRejections=0}function isIngestHalted(){return ingestHalted}const textEncoder=new TextEncoder;function detectUnacceptableExport(error){if(ingestHalted||error.statusCode!==422&&error.statusCode!==401)return;let body=error.body;if(typeof body==`object`&&body&&`code`in body){if(error.statusCode===422&&body.code===`RELEASE_NOT_FOUND`){ingestHalted=!0,console.warn(`[interfere] the ingest endpoint does not recognize this build's release. Telemetry export is disabled for this page load. Check that source-map upload and finalization succeeded and that build and runtime use the same surface key.`);return}if(error.statusCode===401&&body.code===`AUTH_PK_INVALID`){if(consecutiveAuthRejections+=1,consecutiveAuthRejections<3)return;ingestHalted=!0,console.warn(`[interfere] the ingest endpoint rejected this page's public key ${consecutiveAuthRejections} times in a row — telemetry export is disabled for this page load. Check that INTERFERE_PUBLIC_KEY matches an active surface.`)}}}function makeSender(input,signal){let client=new InterfereClient({...input.clientOptions,maxRetries:0,timeoutInSeconds:TELEMETRY_EXPORT_TIMEOUT_MS/1e3,fetch:Object.assign(async(url,init)=>{let body=init?.body,bytes=typeof body==`string`?textEncoder.encode(body).byteLength:0,release=reserveKeepaliveBody(bytes);try{return await retryTelemetry(async abortSignal=>globalThis.fetch(url,{...init,credentials:`omit`,keepalive:release!==null,signal:abortSignal}),init?.signal)}finally{release?.()}},globalThis.fetch)});return((payload,resultCallback)=>{if(!payload||payload.byteLength===0){resultCallback({code:ExportResultCode.SUCCESS});return}if(ingestHalted){resultCallback({code:ExportResultCode.FAILED,error:Error(`ingest halted: the ingest endpoint rejected this build's release`)});return}(async()=>{try{let body=z.record(z.string(),z.unknown()).parse(JSON.parse(new TextDecoder().decode(payload)));await client.drain.otlpExport({signal,body},{headers:{"x-interfere-producer-version":PRODUCER_VERSION}}),consecutiveAuthRejections=0,resultCallback({code:ExportResultCode.SUCCESS})}catch(error){error instanceof InterfereError&&detectUnacceptableExport(error),resultCallback({code:ExportResultCode.FAILED,error:toError(error)})}})()})}var IngestTraceExporter=class{send;constructor(send){this.send=send}export(spans,resultCallback){if(spans.length===0){resultCallback({code:ExportResultCode.SUCCESS});return}this.send(JsonTraceSerializer.serializeRequest(spans),resultCallback)}async shutdown(){return Promise.resolve()}async forceFlush(){return Promise.resolve()}};function createTraceExporter(input){return new IngestTraceExporter(makeSender(input,`traces`))}function createMetricExporter(input,gatedResourceAttributes){return new IngestMetricExporter(makeSender(input,`metrics`),gatedResourceAttributes)}function createLogExporter(input){return new IngestLogExporter(makeSender(input,`logs`))}export{isIngestHalted as a,createTraceExporter as i,createLogExporter as n,resetIngestHalt as o,createMetricExporter as r,INGEST_IGNORE_RE as t};
|