@interfere/react 12.4.2 → 12.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/dist/activity-BXnqBJEN.mjs +1 -0
  2. package/dist/{activity-CShcwAW_.d.mts → activity-CBQdSlah.d.mts} +2 -0
  3. package/dist/api-BEM97FWM.mjs +1 -0
  4. package/dist/{api-BXjfYV5Z.d.mts → api-hCzqicRd.d.mts} +2 -3
  5. package/dist/carryover-BAFBokML.d.mts +20 -0
  6. package/dist/carryover-jGdEwhSK.mjs +1 -0
  7. package/dist/cors-guard-CBFsXK5N.mjs +1 -0
  8. package/dist/delivery-MVXiPjqc.mjs +1 -0
  9. package/dist/delivery-ST8Q6V23.d.mts +29 -0
  10. package/dist/environment-CC7GnqAv.mjs +1 -0
  11. package/dist/environment-CTK2srrC.d.mts +4 -0
  12. package/dist/error-boundary.d.mts +1 -1
  13. package/dist/export-carryover-Y9VbQiAB.mjs +1 -0
  14. package/dist/exporter-DqqNP_gQ.mjs +1 -0
  15. package/dist/{exporter-logs-DMr5-1Yi.d.mts → exporter-SwuW_zLa.d.mts} +15 -12
  16. package/dist/{exporter-logs-BbzSiQJi.mjs → exporter-logs-DSG5ys_2.mjs} +1 -1
  17. package/dist/{exporter-metrics-DZYqUo6_.mjs → exporter-metrics-B5xXu8sz.mjs} +1 -1
  18. package/dist/failed-request-evidence-BYcXgFbX.mjs +1 -0
  19. package/dist/failure-policy-BRdTiUfP.d.mts +21 -0
  20. package/dist/failure-policy-Czdz-YWP.mjs +1 -0
  21. package/dist/index-BplJLwnY.d.mts +4 -0
  22. package/dist/instrumentations-BV6-EClr.mjs +1 -0
  23. package/dist/{instrumentations-zBdPJHog.d.mts → instrumentations-CSV9Xo8t.d.mts} +4 -23
  24. package/dist/internal/activity/activity.d.mts +1 -1
  25. package/dist/internal/activity/activity.mjs +1 -1
  26. package/dist/internal/capture/capture-boundary.d.mts +1 -1
  27. package/dist/internal/capture/capture.d.mts +1 -1
  28. package/dist/internal/environment/environment.d.mts +2 -2
  29. package/dist/internal/environment/environment.mjs +1 -1
  30. package/dist/internal/kernel-registry.d.mts +1 -1
  31. package/dist/internal/kernel.d.mts +3 -3
  32. package/dist/internal/kernel.mjs +1 -1
  33. package/dist/internal/otel/export-carryover.d.mts +12 -0
  34. package/dist/internal/otel/export-carryover.mjs +1 -0
  35. package/dist/internal/otel/exporter-logs.d.mts +1 -1
  36. package/dist/internal/otel/exporter-logs.mjs +1 -1
  37. package/dist/internal/otel/exporter-metrics.d.mts +1 -1
  38. package/dist/internal/otel/exporter-metrics.mjs +1 -1
  39. package/dist/internal/otel/exporter.d.mts +1 -1
  40. package/dist/internal/otel/exporter.mjs +1 -1
  41. package/dist/internal/otel/index.d.mts +4 -3
  42. package/dist/internal/otel/index.mjs +1 -1
  43. package/dist/internal/otel/instrumentations/cors-guard.d.mts +1 -1
  44. package/dist/internal/otel/instrumentations/cors-guard.mjs +1 -1
  45. package/dist/internal/otel/instrumentations/failed-request-evidence.d.mts +12 -0
  46. package/dist/internal/otel/instrumentations/failed-request-evidence.mjs +1 -0
  47. package/dist/internal/otel/instrumentations/failure-policy.d.mts +2 -0
  48. package/dist/internal/otel/instrumentations/failure-policy.mjs +1 -0
  49. package/dist/internal/otel/instrumentations/instrumentations.d.mts +3 -2
  50. package/dist/internal/otel/instrumentations/instrumentations.mjs +1 -1
  51. package/dist/internal/otel/instrumentations/propagation-targets.d.mts +1 -0
  52. package/dist/internal/otel/instrumentations/propagation-targets.mjs +1 -1
  53. package/dist/internal/otel/instrumentations/request-callsite.d.mts +6 -0
  54. package/dist/internal/otel/instrumentations/request-callsite.mjs +1 -0
  55. package/dist/internal/otel/keepalive-chunks.d.mts +2 -2
  56. package/dist/internal/otel/keepalive-chunks.mjs +1 -1
  57. package/dist/internal/otel/provider.d.mts +1 -1
  58. package/dist/internal/otel/provider.mjs +1 -1
  59. package/dist/internal/plugins/plugin-runtime.d.mts +1 -1
  60. package/dist/internal/react-context.d.mts +1 -1
  61. package/dist/internal/sw-queue.mjs +1 -1
  62. package/dist/internal/version.mjs +1 -1
  63. package/dist/internal/wrapper-singleton.d.mts +1 -1
  64. package/dist/internal/wrapper-singleton.mjs +1 -1
  65. package/dist/keepalive-chunks-Cb8TUzqR.mjs +1 -0
  66. package/dist/kernel-B2aSrvOQ.mjs +1 -0
  67. package/dist/{msw-C0yLYJU2.mjs → msw-CedHiv_x.mjs} +2 -2
  68. package/dist/plugins/device.d.mts +1 -1
  69. package/dist/plugins/errors.d.mts +1 -1
  70. package/dist/plugins/lib/loader.d.mts +1 -1
  71. package/dist/plugins/lib/types.d.mts +1 -1
  72. package/dist/plugins/logs.d.mts +1 -1
  73. package/dist/plugins/page-events.d.mts +1 -1
  74. package/dist/plugins/rage-clicks.d.mts +1 -1
  75. package/dist/plugins/replay/index.d.mts +1 -1
  76. package/dist/plugins/replay/index.mjs +1 -1
  77. package/dist/plugins/replay/upload/carryover.d.mts +2 -0
  78. package/dist/plugins/replay/upload/carryover.mjs +1 -0
  79. package/dist/plugins/replay/upload/delivery.d.mts +2 -25
  80. package/dist/plugins/replay/upload/delivery.mjs +1 -1
  81. package/dist/plugins/replay/upload/retry-queue.d.mts +15 -0
  82. package/dist/plugins/replay/upload/retry-queue.mjs +1 -0
  83. package/dist/plugins/replay/upload/upload.d.mts +1 -0
  84. package/dist/plugins/replay/upload/upload.mjs +1 -1
  85. package/dist/propagation-targets-CfPOwH4t.mjs +1 -0
  86. package/dist/{provider-vp8Aao8Q.d.mts → provider-D3MUu4Pe.d.mts} +6 -5
  87. package/dist/{provider-Dy0mVCx5.d.mts → provider-DVei_D8K.d.mts} +1 -0
  88. package/dist/{provider-B8YtuhDX.mjs → provider-ToSOe7C4.mjs} +1 -1
  89. package/dist/provider.d.mts +1 -1
  90. package/dist/react-error-handler.d.mts +1 -1
  91. package/dist/request-callsite-DAf7lGBK.mjs +3 -0
  92. package/dist/retry-queue-CUNYO4gZ.mjs +1 -0
  93. package/dist/session-BkvyVdtV.mjs +1 -0
  94. package/dist/tracking/api.d.mts +1 -1
  95. package/dist/tracking/api.mjs +1 -1
  96. package/dist/tracking/lifecycle.fixture.d.mts +1 -1
  97. package/dist/tracking/lifecycle.fixture.mjs +1 -1
  98. package/dist/tracking/registration.fixture.d.mts +1 -1
  99. package/dist/tracking/registration.fixture.mjs +1 -1
  100. package/dist/tracking/session.d.mts +1 -0
  101. package/dist/tracking/session.mjs +1 -1
  102. package/dist/{upload-D55WVf_o.mjs → upload-B9hdPLYo.mjs} +1 -1
  103. package/dist/{version-CPcWUmrA.mjs → version-D3OKw6oO.mjs} +1 -1
  104. package/package.json +6 -5
  105. package/dist/activity-oYlZ5aa1.mjs +0 -1
  106. package/dist/api-C8aG7li1.mjs +0 -1
  107. package/dist/cors-guard-CwkqEjzL.mjs +0 -1
  108. package/dist/delivery-D7hULClu.mjs +0 -1
  109. package/dist/environment-CoEXhF1a.mjs +0 -1
  110. package/dist/environment-CtCFKD2N.d.mts +0 -9
  111. package/dist/exporter-BtHqkV3R.mjs +0 -1
  112. package/dist/index-C3K6oR4l.d.mts +0 -4
  113. package/dist/instrumentations-qhx6Oc_F.mjs +0 -1
  114. package/dist/keepalive-chunks-BZv3PhHT.mjs +0 -1
  115. package/dist/kernel-BZI0jyJI.mjs +0 -1
  116. package/dist/propagation-targets-BXDetg0k.mjs +0 -1
  117. package/dist/session-C30CtCVv.mjs +0 -1
@@ -1,4 +1,4 @@
1
- import { C as Plugin } from "../../provider-vp8Aao8Q.mjs";
1
+ import { C as Plugin } from "../../provider-D3MUu4Pe.mjs";
2
2
  //#region src/plugins/replay/index.d.ts
3
3
  declare const replayPlugin: Plugin;
4
4
  //#endregion
@@ -1 +1 @@
1
- import{t as createLogger}from"../../log-D6Ht--tv.mjs";import{i as onPageUnloading}from"../../page-lifecycle-rJEJNdKj.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-D7hULClu.mjs";import{t as startReplayRecorder}from"../../recorder-C36qxD3q.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,unsubscribeUnloading=null,unsubscribePause=null,unsubscribeResume=null,unsubscribeException=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,opts?.trigger)}async function sendChunk(payload,unload,trigger){try{handleResult(await deliverChunk({target:targets.ingest,chunk:{segmentId:sequence.take(),windowId},compressor,ctx,payload,trigger,unload}))}catch(error){log.warn(`replay chunk dropped: %s`,error instanceof Error?error.constructor.name:`UnknownError`),handleResult(`retryable`)}}let pauseRecording=reason=>{isPaused||(isPaused=!0,recorder?.stop(),flush(reason===`hidden`?{unload:!0}:void 0))},snapshotWhilePaused=reason=>{isPaused&&!halted&&recorder?.start()&&(recorder.addCustomEvent(`interfere.paused-exception-snapshot`,{reason}),recorder.stop(),flush({trigger:`exception`}))},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(),unsubscribeUnloading=onPageUnloading(()=>{flush({unload:!0})}),unsubscribePause=ctx.onSessionPause(pauseRecording),unsubscribeResume=ctx.onSessionResume(resumeRecording),unsubscribeException=ctx.onSessionExceptionWhilePaused(snapshotWhilePaused),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?.(),unsubscribeUnloading?.(),unsubscribePause?.(),unsubscribeResume?.(),unsubscribeException?.(),compressor.dispose()}}};export{replayPlugin as default};
1
+ import{t as createLogger}from"../../log-D6Ht--tv.mjs";import{i as onPageUnloading}from"../../page-lifecycle-rJEJNdKj.mjs";import{t as clearExportCarryover}from"../../export-carryover-Y9VbQiAB.mjs";import{r as resolveTargets}from"../../config-VOyDjqS7.mjs";import{i as toRecordOptions}from"../../config-DapTbKhs.mjs";import{t as createReplayCarryover}from"../../carryover-jGdEwhSK.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-MVXiPjqc.mjs";import{t as createReplayRetryQueue}from"../../retry-queue-CUNYO4gZ.mjs";import{t as startReplayRecorder}from"../../recorder-C36qxD3q.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,unsubscribeUnloading=null,unsubscribePause=null,unsubscribeResume=null,unsubscribeException=null,isPaused=!1,startup=new AbortController,compressor=createCompressor(),windowId=ctx.getWindowId(),sequence=createSegmentSequence(windowId),retryQueue=createReplayRetryQueue(),recorderFaults=0,halted=!1,carryover=createReplayCarryover(targets.ingest,()=>!halted&&!startup.signal.aborted&&ctx.getPluginConfigState(`replay`)===`enabled`);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(),retryQueue.clear(),startup.abort(),carryover.dispose(),clearFlushTimer(),recorder?.stop(),recorder=null)}function clearFlushTimer(){flushTimer&&=(clearInterval(flushTimer),null)}function armFlushTimer(){clearFlushTimer(),flushTimer=setInterval(()=>{clearFlushTimer(),flushTimer=setInterval(()=>flush({retryPending:!0}),1e4),flush()},2e3)}function handleResult(result,chunk){result===`retryable`&&!startup.signal.aborted?retryQueue.push(chunk):result===`skipped`?log.warn(`replay chunk rejected as a segment conflict; skipping it`):result===`fatal`&&(log.warn(`replay halted: upload rejected`),halt(`upload-rejected`))}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;if(opts?.retryPending)for(let chunk of retryQueue.drain())sendChunk(chunk,opts.unload??!1);let drained=buffer.drain(),sessionId=ctx.getSessionId();if(drained.length===0||!sessionId)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({payload:toReplayChunkPayload(group),chunk:{segmentId:sequence.take(),windowId},sessionId,trigger:opts?.trigger},opts?.unload??!1)}async function sendChunk(pending,unload){try{handleResult(await deliverChunk({target:targets.ingest,carryover,...pending,compressor,ctx,unload}),pending)}catch(error){log.warn(`replay chunk upload failed: %s`,error instanceof Error?error.constructor.name:`UnknownError`),handleResult(`retryable`,pending)}}let pauseRecording=reason=>{isPaused||(isPaused=!0,recorder?.stop(),flush(reason===`hidden`?{unload:!0}:void 0))},snapshotWhilePaused=reason=>{isPaused&&!halted&&recorder?.start()&&(recorder.addCustomEvent(`interfere.paused-exception-snapshot`,{reason}),recorder.stop(),flush({trigger:`exception`}))},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(),unsubscribeUnloading=onPageUnloading(()=>{flush({unload:!0})}),unsubscribePause=ctx.onSessionPause(pauseRecording),unsubscribeResume=ctx.onSessionResume(resumeRecording),unsubscribeException=ctx.onSessionExceptionWhilePaused(snapshotWhilePaused),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`?(clearExportCarryover(`replay:`),buffer.drain(),log.debug(`replay buffer discarded: consent revoked`)):flush(),retryQueue.clear(),startup.abort(),carryover.dispose(),recorder?.stop(),clearFlushTimer(),unsubscribeConfig?.(),unsubscribeUnloading?.(),unsubscribePause?.(),unsubscribeResume?.(),unsubscribeException?.(),compressor.dispose()}}};export{replayPlugin as default};
@@ -0,0 +1,2 @@
1
+ import { t as createReplayCarryover } from "../../../carryover-BAFBokML.mjs";
2
+ export { createReplayCarryover };
@@ -0,0 +1 @@
1
+ import{t as createReplayCarryover}from"../../../carryover-jGdEwhSK.mjs";export{createReplayCarryover};
@@ -1,25 +1,2 @@
1
- import { E as PluginContext } from "../../../provider-vp8Aao8Q.mjs";
2
- import { r as resolveTargets } from "../../../config-BTWtCcDP.mjs";
3
- import { n as ReplayChunkPayload } from "../../../chunking-OfmdRxfq.mjs";
4
- import { t as Compressor } from "../../../compressor-host-D3At2PKg.mjs";
5
- //#region src/plugins/replay/upload/delivery.d.ts
6
- export declare const REPLAY_TRACER_NAME = "@interfere/react/replay";
7
- export type DeliverResult = "ok" | "skipped" | "retryable" | "fatal";
8
- export type ChunkTrigger = "exception";
9
- export interface ReplayChunkRef {
10
- segmentId: number;
11
- windowId: string;
12
- }
13
- export interface DeliverInput {
14
- target: ReturnType<typeof resolveTargets>["ingest"];
15
- chunk: ReplayChunkRef;
16
- compressor: Compressor;
17
- ctx: PluginContext;
18
- payload: ReplayChunkPayload;
19
- /** Why the chunk was cut outside the regular flush cadence, recorded on the `replay.chunk` span. */
20
- trigger?: ChunkTrigger | undefined;
21
- /** 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. */
22
- unload: boolean;
23
- }
24
- export declare function deliverChunk({ ctx, chunk, target, compressor, payload, trigger, unload }: DeliverInput): Promise<"fatal" | "ok" | "retryable" | "skipped">;
25
- //#endregion
1
+ import { a as ReplayChunkRef, i as REPLAY_TRACER_NAME, n as DeliverInput, o as deliverChunk, r as DeliverResult, t as ChunkTrigger } from "../../../delivery-ST8Q6V23.mjs";
2
+ export { ChunkTrigger, DeliverInput, DeliverResult, REPLAY_TRACER_NAME, ReplayChunkRef, deliverChunk };
@@ -1 +1 @@
1
- import{n as deliverChunk,t as REPLAY_TRACER_NAME}from"../../../delivery-D7hULClu.mjs";export{REPLAY_TRACER_NAME,deliverChunk};
1
+ import{n as deliverChunk,t as REPLAY_TRACER_NAME}from"../../../delivery-MVXiPjqc.mjs";export{REPLAY_TRACER_NAME,deliverChunk};
@@ -0,0 +1,15 @@
1
+ import { n as ReplayChunkPayload } from "../../../chunking-OfmdRxfq.mjs";
2
+ import { a as ReplayChunkRef, t as ChunkTrigger } from "../../../delivery-ST8Q6V23.mjs";
3
+ //#region src/plugins/replay/upload/retry-queue.d.ts
4
+ export interface PendingReplayChunk {
5
+ payload: ReplayChunkPayload;
6
+ chunk: ReplayChunkRef;
7
+ sessionId: string;
8
+ trigger: ChunkTrigger | undefined;
9
+ }
10
+ export declare function createReplayRetryQueue(): {
11
+ push(chunk: PendingReplayChunk): void;
12
+ drain(): PendingReplayChunk[];
13
+ clear(): void;
14
+ };
15
+ //#endregion
@@ -0,0 +1 @@
1
+ import{t as createReplayRetryQueue}from"../../../retry-queue-CUNYO4gZ.mjs";export{createReplayRetryQueue};
@@ -2,6 +2,7 @@ import { r as resolveTargets } from "../../../config-BTWtCcDP.mjs";
2
2
  //#region src/plugins/replay/upload/upload.d.ts
3
3
  export interface UploadReplayChunkOptions {
4
4
  keepalive: boolean;
5
+ signal?: AbortSignal | undefined;
5
6
  }
6
7
  export declare function uploadReplayChunk(target: ReturnType<typeof resolveTargets>["ingest"], sessionId: string, body: Uint8Array<ArrayBuffer>, headers: Record<string, string>, options?: UploadReplayChunkOptions): Promise<Response>;
7
8
  //#endregion
@@ -1 +1 @@
1
- import{t as uploadReplayChunk}from"../../../upload-D55WVf_o.mjs";export{uploadReplayChunk};
1
+ import{t as uploadReplayChunk}from"../../../upload-B9hdPLYo.mjs";export{uploadReplayChunk};
@@ -0,0 +1 @@
1
+ import{getDomain}from"tldts";const HOSTNAME_RE=/^[a-z\d-]+(?:\.[a-z\d-]+)*$/u,IPV4_RE=/^\d{1,3}(?:\.\d{1,3}){3}$/u,ESCAPE_RE=/[.*+?^${}()|[\]\\]/gu;function escapeRegExp(value){return value.replaceAll(ESCAPE_RE,String.raw`\$&`)}function normalizeHost(host){let lower=host.trim().toLowerCase().replace(/\.$/u,``);return HOSTNAME_RE.test(lower)?lower:null}function registrableDomain(host){let normalized=normalizeHost(host);return normalized?IPV4_RE.test(normalized)||!normalized.includes(`.`)?normalized:getDomain(normalized,{allowPrivateDomains:!0,extractHostname:!1}):null}function originMatcher(origin){return RegExp(`^${escapeRegExp(origin)}(?:[/?#]|$)`,`u`)}function hostMatcher(host){return RegExp(`^https?://${escapeRegExp(host)}(?::\\d+)?(?:[/?#]|$)`,`u`)}function sameSiteMatcher(pageHostname){let site=registrableDomain(pageHostname);return site?IPV4_RE.test(site)||!site.includes(`.`)?hostMatcher(site):RegExp(`^https?://(?:[a-z\\d-]+\\.)*${escapeRegExp(site)}(?::\\d+)?(?:[/?#]|$)`,`iu`):null}function knownBackendMatchers(hosts){return hosts.flatMap(host=>{let normalized=normalizeHost(host);return normalized?.includes(`.`)?[hostMatcher(normalized)]:[]})}export{sameSiteMatcher as a,registrableDomain as i,knownBackendMatchers as n,originMatcher as r,hostMatcher as t};
@@ -1,11 +1,12 @@
1
- import { c as SessionResumeReason, s as SessionPauseReason } from "./activity-CShcwAW_.mjs";
1
+ import { c as SessionResumeReason, s as SessionPauseReason } from "./activity-CBQdSlah.mjs";
2
2
  import { i as PrivacyPolicy, r as PrivacyOptions } from "./privacy-CPKosXDP.mjs";
3
3
  import { a as ReplayOption, i as ReplayConfig } from "./config-Dyc09HCZ.mjs";
4
4
  import { n as PageEventsOption } from "./page-events-config-CiJvdAaJ.mjs";
5
- import { t as SessionTracker } from "./api-BXjfYV5Z.mjs";
6
- import { n as CaptureFailedRequestsOption, t as BundledInstrumentations } from "./instrumentations-zBdPJHog.mjs";
7
- import { t as OtelProviderHandle } from "./provider-Dy0mVCx5.mjs";
8
- import "./index-C3K6oR4l.mjs";
5
+ import { t as SessionTracker } from "./api-hCzqicRd.mjs";
6
+ import { t as CaptureFailedRequestsOption } from "./failure-policy-BRdTiUfP.mjs";
7
+ import { t as BundledInstrumentations } from "./instrumentations-CSV9Xo8t.mjs";
8
+ import { t as OtelProviderHandle } from "./provider-DVei_D8K.mjs";
9
+ import "./index-BplJLwnY.mjs";
9
10
  import { t as RecordExceptionOpts } from "./exception-span-zN1tvBdh.mjs";
10
11
  import { NonErrorException } from "@interfere/types/sdk/errors";
11
12
  import { Tracer } from "@opentelemetry/api";
@@ -18,6 +18,7 @@ interface OtelProviderInput {
18
18
  * transport metadata the rest of the SDK uses — no separate auth knob.
19
19
  */
20
20
  clientOptions: InterfereClient.Options;
21
+ canPersistExports?: () => boolean;
21
22
  /**
22
23
  * Returns the current `DeviceManager` device id. Wired into per-span
23
24
  * and per-log processors so a mid-page device rotation
@@ -1 +1 @@
1
- import{n as getStringGlobal}from"./global-DYq1Z4_H.mjs";import{n as SDK_NAME,r as SDK_VERSION}from"./version-CPcWUmrA.mjs";import{i as createTraceExporter,n as createLogExporter,r as createMetricExporter}from"./exporter-BtHqkV3R.mjs";import{t as createExportFilterProcessor}from"./export-filter-CnyAaPct.mjs";import{t as PageScopeContextManager}from"./page-scope-context-manager-Bs-m4fv7.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_LOG_BATCH_OPTIONS={exportTimeoutMillis:7e4,maxExportBatchSize:200,maxQueueSize:2048,scheduledDelayMillis:5e3},BROWSER_TRACE_BATCH_OPTIONS={...BROWSER_LOG_BATCH_OPTIONS,scheduledDelayMillis:6e4};function withBaggageEntry(baggage,key,value){return value?baggage.setEntry(key,{value}):baggage.removeEntry(key)}function createSessionBaggagePropagator(opts){let propagator=new W3CBaggagePropagator;return{fields:()=>propagator.fields(),extract:(ctx,carrier,getter)=>propagator.extract(ctx,carrier,getter),inject:(ctx,carrier,setter)=>{let updated=withBaggageEntry(withBaggageEntry(propagation.getBaggage(ctx)??propagation.createBaggage(),`session.id`,opts.getSessionId()),ATTR_DEVICE_ID,opts.getDeviceId());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??[],createExportFilterProcessor(new BatchSpanProcessor(traceExporter,BROWSER_TRACE_BATCH_OPTIONS),input.onExceptionSpan)],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({getDeviceId:()=>isShutdown?null:getDeviceId(),getSessionId:()=>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_LOG_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
+ import{n as getStringGlobal}from"./global-DYq1Z4_H.mjs";import{n as SDK_NAME,r as SDK_VERSION}from"./version-D3OKw6oO.mjs";import{i as createTraceExporter,n as createLogExporter,r as createMetricExporter}from"./exporter-DqqNP_gQ.mjs";import{t as createExportFilterProcessor}from"./export-filter-CnyAaPct.mjs";import{t as PageScopeContextManager}from"./page-scope-context-manager-Bs-m4fv7.mjs";import{context,propagation}from"@opentelemetry/api";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{CompositePropagator,W3CBaggagePropagator,W3CTraceContextPropagator}from"@opentelemetry/core";import{ENVIRONMENT_GLOBAL}from"@interfere/types/sdk/injected-globals";import{createUrlRedactionSpanProcessor,resolveUrlRedaction}from"@interfere/types/sdk/url-redaction";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_LOG_BATCH_OPTIONS={exportTimeoutMillis:7e4,maxExportBatchSize:200,maxQueueSize:2048,scheduledDelayMillis:5e3},BROWSER_TRACE_BATCH_OPTIONS={...BROWSER_LOG_BATCH_OPTIONS,scheduledDelayMillis:6e4};function withBaggageEntry(baggage,key,value){return value?baggage.setEntry(key,{value}):baggage.removeEntry(key)}function createSessionBaggagePropagator(opts){let propagator=new W3CBaggagePropagator;return{fields:()=>propagator.fields(),extract:(ctx,carrier,getter)=>propagator.extract(ctx,carrier,getter),inject:(ctx,carrier,setter)=>{let updated=withBaggageEntry(withBaggageEntry(propagation.getBaggage(ctx)??propagation.createBaggage(),`session.id`,opts.getSessionId()),ATTR_DEVICE_ID,opts.getDeviceId());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,canPersistExports:input.canPersistExports}),{getSessionId}=input,{getDeviceId}=input,spanProcessors=[createUrlRedactionSpanProcessor(input.urlRedaction??resolveUrlRedaction()),createSessionSpanProcessor({getSessionId}),createDeviceSpanProcessor({getDeviceId}),createDeviceInfoSpanProcessor({attributes:deviceInfoAttributes,isEnabled:isDeviceInfoEnabled}),...input.additionalSpanProcessors??[],createExportFilterProcessor(new BatchSpanProcessor(traceExporter,BROWSER_TRACE_BATCH_OPTIONS),input.onExceptionSpan)],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({getDeviceId:()=>isShutdown?null:getDeviceId(),getSessionId:()=>isShutdown?null:getPropagationSessionId()})]}));let metricExporter=createMetricExporter({clientOptions:input.clientOptions,canPersistExports:input.canPersistExports},{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,canPersistExports:input.canPersistExports}),loggerProvider=new LoggerProvider({processors:[createSessionLogRecordProcessor({getSessionId}),createDeviceLogRecordProcessor({getDeviceId}),createDeviceInfoLogRecordProcessor({attributes:deviceInfoAttributes,isEnabled:isDeviceInfoEnabled}),new BatchLogRecordProcessor({exporter:logExporter,...BROWSER_LOG_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,4 +1,4 @@
1
1
  import { a as ReplayOption, i as ReplayConfig } from "./config-Dyc09HCZ.mjs";
2
- import { a as InterfereContextValue, b as PluginOverrides, i as InterfereContext, n as useInterfere, r as useSession, t as InterfereProvider } from "./provider-vp8Aao8Q.mjs";
2
+ import { a as InterfereContextValue, b as PluginOverrides, i as InterfereContext, n as useInterfere, r as useSession, t as InterfereProvider } from "./provider-D3MUu4Pe.mjs";
3
3
  import { n as PageEventsOption, t as PageEventsConfig } from "./page-events-config-CiJvdAaJ.mjs";
4
4
  export { InterfereContext, type InterfereContextValue, InterfereProvider, type PageEventsConfig, type PageEventsOption, type PluginOverrides, type ReplayConfig, type ReplayOption, useInterfere, useSession };
@@ -1,4 +1,4 @@
1
- import { s as Kernel } from "./provider-vp8Aao8Q.mjs";
1
+ import { s as Kernel } from "./provider-D3MUu4Pe.mjs";
2
2
  //#region src/react-error-handler.d.ts
3
3
  /** React root error-handler metadata; only componentStack is consumed. */
4
4
  interface ReactRootErrorInfo {
@@ -0,0 +1,3 @@
1
+ const requestEvidence=new WeakMap;function recordHttpFailure(span,status,method,url,mechanism,attributes={}){let evidence=requestEvidence.get(span);requestEvidence.delete(span);let details={...attributes,"http.response.status_code":status};evidence&&(details[`http.request.next_action`]=evidence.nextAction,details[`exception.stacktrace`]=(evidence.callsite.stack??``).split(`
2
+ `).slice(1,21).join(`
3
+ `).slice(0,8192).replaceAll(/https?:\/\/[^\s)]+/gu,evidence.redactUrl)),span.setAttributes(attributes),span.addEvent(`exception`,{...details,"exception.message":`HTTP ${status} ${method} ${url}`,"exception.type":`HttpResponseError`,"interfere.exception.handled":!1,"interfere.exception.kind":`error`,"interfere.exception.mechanism":mechanism})}function captureRequestEvidence(span,headers,redactUrl){requestEvidence.set(span,{callsite:Error(`HTTP request call site`),nextAction:new Headers(headers).has(`next-action`),redactUrl})}export{recordHttpFailure as n,captureRequestEvidence as t};
@@ -0,0 +1 @@
1
+ import{t as createLogger}from"./log-D6Ht--tv.mjs";import{i as utf8ByteLength}from"./chunking-qZffPbyY.mjs";const log=createLogger(`replay`);function createReplayRetryQueue(){let pending=[],totalBytes=0;return{push(chunk){let bytes=utf8ByteLength(chunk.payload.bodyJson);for(pending.push({chunk,bytes}),totalBytes+=bytes;totalBytes>16777216;){let dropped=pending.shift();if(!dropped)break;totalBytes-=dropped.bytes,log.warn(`replay retry buffer full; dropping oldest chunk of %d bytes`,dropped.bytes)}},drain(){let chunks=pending.map(({chunk})=>chunk);return pending=[],totalBytes=0,chunks},clear(){pending=[],totalBytes=0}}}export{createReplayRetryQueue as t};
@@ -0,0 +1 @@
1
+ import{sessionIdSchema}from"@interfere/types/data/session";import{v7}from"uuid";const SESSION_ID_KEY=`interfere:session_id`,LAST_ACTIVITY_KEY=`interfere:last_activity`,SESSION_STARTED_KEY=`interfere:session_started`,WINDOW_ID_KEY=`interfere:window_id`;function tryStorage(type){try{let s=globalThis[type],key=`__interfere_probe__`;return s.setItem(key,`1`),s.removeItem(key),s}catch{return null}}var SessionManager=class{sessionId=null;windowId=null;local;session;onRotate=null;lastActivityMs=0;sessionStartedMs=0;constructor(onRotate){this.local=tryStorage(`localStorage`),this.session=tryStorage(`sessionStorage`),this.onRotate=onRotate??null,this.restore()}getSessionId(){return this.sessionId?this.sessionId:this.rotate()}markActivity(){this.touch()}getLastActivityAt(){let stored=Number(this.local?.getItem(LAST_ACTIVITY_KEY));return Number.isFinite(stored)?Math.max(stored,this.lastActivityMs):this.lastActivityMs}getSessionStartedAt(){return this.sessionStartedMs}getWindowId(){if(this.windowId)return this.windowId;let stored=this.session?.getItem(WINDOW_ID_KEY);return stored?(this.windowId=stored,stored):(this.windowId=`win_${crypto.randomUUID()}`,this.session?.setItem(WINDOW_ID_KEY,this.windowId),this.windowId)}reset(){return this.rotate()}restore(){let stored=this.local?.getItem(SESSION_ID_KEY),startedRaw=this.local?.getItem(SESSION_STARTED_KEY),parsed=sessionIdSchema.safeParse(stored);this.sessionStartedMs=startedRaw?Number(startedRaw):0,parsed.success&&!this.isExpired()?(this.sessionId=parsed.data,this.touch()):this.rotate()}rotate(){return this.sessionId=sessionIdSchema.parse(v7()),this.sessionStartedMs=Date.now(),this.local?.setItem(SESSION_ID_KEY,this.sessionId),this.local?.setItem(SESSION_STARTED_KEY,String(this.sessionStartedMs)),this.touch(),this.onRotate?.(this.sessionId),this.sessionId}touch(){this.lastActivityMs=Date.now(),this.local?.setItem(LAST_ACTIVITY_KEY,String(this.lastActivityMs))}isExpired(){if(this.sessionStartedMs>0&&Date.now()-this.sessionStartedMs>864e5)return!0;let raw=this.local?.getItem(LAST_ACTIVITY_KEY),ts=raw?Number(raw):this.lastActivityMs;return ts===0||Date.now()-ts>9e5}};export{SessionManager as t};
@@ -1,2 +1,2 @@
1
- import { n as SessionTrackerOptions, t as SessionTracker } from "../api-BXjfYV5Z.mjs";
1
+ import { n as SessionTrackerOptions, t as SessionTracker } from "../api-hCzqicRd.mjs";
2
2
  export { SessionTracker, SessionTrackerOptions };
@@ -1 +1 @@
1
- import{t as SessionTracker}from"../api-C8aG7li1.mjs";export{SessionTracker};
1
+ import{t as SessionTracker}from"../api-BEM97FWM.mjs";export{SessionTracker};
@@ -1,5 +1,5 @@
1
1
  import { t as DeviceManager } from "../device-vFtWy12y.mjs";
2
- import { t as SessionTracker } from "../api-BXjfYV5Z.mjs";
2
+ import { t as SessionTracker } from "../api-hCzqicRd.mjs";
3
3
  import { z } from "zod";
4
4
  //#region src/tracking/lifecycle.fixture.d.ts
5
5
  export declare const FP_HASH = "fp-hash-lifecycle";
@@ -1 +1 @@
1
- import{a as HttpResponse,i as http,n as vi,t as worker}from"../msw-C0yLYJU2.mjs";import{a as resetPageLifecycleForTests}from"../page-lifecycle-rJEJNdKj.mjs";import{t as DeviceManager}from"../device-DRK7hhLi.mjs";import{t as GeoDetector}from"../geo-D2wa9bGs.mjs";import{t as SessionTracker}from"../api-C8aG7li1.mjs";import{sessionIdSchema}from"@interfere/types/data/session";import{z}from"zod";import{identifyParamsSchema}from"@interfere/types/sdk/identify";const BASE_URL=`https://lifecycle.invalid`,FP_HASH=`fp-hash-lifecycle`,SOURCE={name:`Audit`,type:`custom`},createSessionBody=z.strictObject({deviceId:z.uuid().nullable(),fpHash:z.string().nullable(),sessionId:sessionIdSchema}),identifySessionBody=z.strictObject({...createSessionBody.shape,...identifyParamsSchema.shape,country:z.string().max(2).optional()}),recordedBody=z.looseObject({deviceId:z.string().nullable().optional(),fpHash:z.string().nullable().optional(),identifier:z.string().optional(),sessionId:z.string().optional()}),recorded=[],waiters=[],trackers=[],requestInits=[],identifyResponse={status:200};function bodies(path){return recorded.flatMap(r=>r.path===path?[r.body]:[])}function sessions(){return bodies(`/v3/session`)}function identifies(){return bodies(`/v3/session/identify`)}function release(){for(let waiter of waiters.splice(0))bodies(waiter.path).length>=waiter.count?waiter.resolve():waiters.push(waiter)}async function arrived(path,count){let{promise,resolve}=Promise.withResolvers();waiters.push({count,path,resolve:()=>{resolve(void 0)}}),release(),await promise}async function sessionsArrived(count){await arrived(`/v3/session`,count)}async function identifiesArrived(count){await arrived(`/v3/session/identify`,count)}function inits(){return requestInits}function failIdentify(status){identifyResponse.status=status}function readyDevice(){return new DeviceManager(async()=>FP_HASH)}function pendingDevice(){let fingerprint=Promise.withResolvers();return{device:new DeviceManager(async()=>fingerprint.promise),release:hash=>{fingerprint.resolve(hash)}}}function makeTracker(device=readyDevice()){let tracker=new SessionTracker({device,fetcher:async(input,init)=>(init&&requestInits.push(init),globalThis.fetch(input,init)),geo:new GeoDetector,target:{baseUrl:BASE_URL,publicKeyHeader:{apiKey:`test-key`}}});return trackers.push(tracker),tracker}async function started(device){let tracker=makeTracker(device);return tracker.start(),await sessionsArrived(1),tracker}async function withinASecond(arrival){let{promise,resolve}=Promise.withResolvers(),timer=setTimeout(()=>{resolve(void 0)},1e3);await Promise.race([arrival,promise]),clearTimeout(timer)}async function settle(){let{promise,resolve}=Promise.withResolvers();setTimeout(()=>{resolve(void 0)},50),await promise}function setupLifecycle(){recordIngest(BASE_URL)}function recordIngest(baseUrl){recorded.length=0,waiters.length=0,requestInits.length=0,identifyResponse.status=200,worker.use(...[`/v3/session`,`/v3/session/identify`].map(path=>http.post(`${baseUrl}${path}`,async({request})=>{recorded.push({path,body:recordedBody.parse(await request.json())}),release();let status=path===`/v3/session`?200:identifyResponse.status;return HttpResponse.json({ok:status===200},{status})})))}async function teardownLifecycle(){for(let tracker of trackers.splice(0))tracker.dispose();await settle(),resetPageLifecycleForTests(),vi.useRealTimers(),await cookieStore.delete(`interfere_did`)}export{FP_HASH,SOURCE,createSessionBody,failIdentify,identifies,identifiesArrived,identifySessionBody,inits,makeTracker,pendingDevice,readyDevice,recordIngest,sessions,sessionsArrived,settle,setupLifecycle,started,teardownLifecycle,withinASecond};
1
+ import{a as HttpResponse,i as http,n as vi,t as worker}from"../msw-CedHiv_x.mjs";import{a as resetPageLifecycleForTests}from"../page-lifecycle-rJEJNdKj.mjs";import{t as DeviceManager}from"../device-DRK7hhLi.mjs";import{t as GeoDetector}from"../geo-D2wa9bGs.mjs";import{t as SessionTracker}from"../api-BEM97FWM.mjs";import{z}from"zod";import{sessionIdSchema}from"@interfere/types/data/session";import{identifyParamsSchema}from"@interfere/types/sdk/identify";const BASE_URL=`https://lifecycle.invalid`,FP_HASH=`fp-hash-lifecycle`,SOURCE={name:`Audit`,type:`custom`},createSessionBody=z.strictObject({deviceId:z.uuid().nullable(),fpHash:z.string().nullable(),sessionId:sessionIdSchema}),identifySessionBody=z.strictObject({...createSessionBody.shape,...identifyParamsSchema.shape,country:z.string().max(2).optional()}),recordedBody=z.looseObject({deviceId:z.string().nullable().optional(),fpHash:z.string().nullable().optional(),identifier:z.string().optional(),sessionId:z.string().optional()}),recorded=[],waiters=[],trackers=[],requestInits=[],identifyResponse={status:200};function bodies(path){return recorded.flatMap(r=>r.path===path?[r.body]:[])}function sessions(){return bodies(`/v3/session`)}function identifies(){return bodies(`/v3/session/identify`)}function release(){for(let waiter of waiters.splice(0))bodies(waiter.path).length>=waiter.count?waiter.resolve():waiters.push(waiter)}async function arrived(path,count){let{promise,resolve}=Promise.withResolvers();waiters.push({count,path,resolve:()=>{resolve(void 0)}}),release(),await promise}async function sessionsArrived(count){await arrived(`/v3/session`,count)}async function identifiesArrived(count){await arrived(`/v3/session/identify`,count)}function inits(){return requestInits}function failIdentify(status){identifyResponse.status=status}function readyDevice(){return new DeviceManager(async()=>FP_HASH)}function pendingDevice(){let fingerprint=Promise.withResolvers();return{device:new DeviceManager(async()=>fingerprint.promise),release:hash=>{fingerprint.resolve(hash)}}}function makeTracker(device=readyDevice()){let tracker=new SessionTracker({device,fetcher:async(input,init)=>(init&&requestInits.push(init),globalThis.fetch(input,init)),geo:new GeoDetector,target:{baseUrl:BASE_URL,publicKeyHeader:{apiKey:`test-key`}}});return trackers.push(tracker),tracker}async function started(device){let tracker=makeTracker(device);return tracker.start(),await sessionsArrived(1),tracker}async function withinASecond(arrival){let{promise,resolve}=Promise.withResolvers(),timer=setTimeout(()=>{resolve(void 0)},1e3);await Promise.race([arrival,promise]),clearTimeout(timer)}async function settle(){let{promise,resolve}=Promise.withResolvers();setTimeout(()=>{resolve(void 0)},50),await promise}function setupLifecycle(){recordIngest(BASE_URL)}function recordIngest(baseUrl){recorded.length=0,waiters.length=0,requestInits.length=0,identifyResponse.status=200,worker.use(...[`/v3/session`,`/v3/session/identify`].map(path=>http.post(`${baseUrl}${path}`,async({request})=>{recorded.push({path,body:recordedBody.parse(await request.json())}),release();let status=path===`/v3/session`?200:identifyResponse.status;return HttpResponse.json({ok:status===200},{status})})))}async function teardownLifecycle(){for(let tracker of trackers.splice(0))tracker.dispose();await settle(),resetPageLifecycleForTests(),vi.useRealTimers(),await cookieStore.delete(`interfere_did`)}export{FP_HASH,SOURCE,createSessionBody,failIdentify,identifies,identifiesArrived,identifySessionBody,inits,makeTracker,pendingDevice,readyDevice,recordIngest,sessions,sessionsArrived,settle,setupLifecycle,started,teardownLifecycle,withinASecond};
@@ -1,4 +1,4 @@
1
- import { t as SessionTracker } from "../api-BXjfYV5Z.mjs";
1
+ import { t as SessionTracker } from "../api-hCzqicRd.mjs";
2
2
  import { InterfereClient } from "@interfere/javascript";
3
3
  //#region ../../../../node_modules/.bun/vitest@5.0.5+0658583d3f365267/node_modules/vitest/optional-runtime-types.d.ts
4
4
  /* oxlint-disable typescript/ban-ts-comment */
@@ -1 +1 @@
1
- import{a as HttpResponse,i as http,n as vi,r as onTestFinished,t as worker}from"../msw-C0yLYJU2.mjs";import{t as DeviceManager}from"../device-DRK7hhLi.mjs";import{t as SessionTracker}from"../api-C8aG7li1.mjs";import{InterfereClient}from"@interfere/javascript";const sessionEndpoint=`https://registration.invalid/v3/session`;async function registration(){let device=new DeviceManager;device.init(),await device.whenFingerprintReady(),vi.useFakeTimers({toFake:[`Date`,`setTimeout`,`clearTimeout`]});let requests=[],client=new InterfereClient({baseUrl:`https://registration.invalid`,publicKeyHeader:{apiKey:`test`}}),prototype=Object.getPrototypeOf(client.sessions),registrations=vi.spyOn(prototype,`createSession`);worker.use(http.post(sessionEndpoint,()=>HttpResponse.json({ok:!0})));function recordRequest({request}){request.url===`https://registration.invalid/v3/session`&&requests.push(request.clone())}worker.events.on(`request:start`,recordRequest);let tracker=new SessionTracker({device,target:{baseUrl:`https://registration.invalid`,publicKeyHeader:{apiKey:`test`}}});async function settle(){await vi.advanceTimersByTimeAsync(0),await Promise.allSettled(registrations.mock.results.flatMap(result=>result.type===`return`?[result.value]:[]))}async function arrived(count){let deadline=performance.now()+1e4;await new Promise((resolve,reject)=>{function inspect(){if(requests.length>=count){resolve();return}if(performance.now()>deadline){reject(Error(`Expected ${count} registration requests, received ${requests.length}`));return}requestAnimationFrame(inspect)}inspect()})}return onTestFinished(()=>{tracker.dispose(),tracker.discardDeviceIdentity(),worker.events.removeListener(`request:start`,recordRequest);for(let key of[`interfere:session_id`,`interfere:last_activity`,`interfere:session_started`])localStorage.removeItem(key);vi.useRealTimers()}),{arrived,registrations,requests,settle,tracker}}export{registration,sessionEndpoint};
1
+ import{a as HttpResponse,i as http,n as vi,r as onTestFinished,t as worker}from"../msw-CedHiv_x.mjs";import{t as DeviceManager}from"../device-DRK7hhLi.mjs";import{t as SessionTracker}from"../api-BEM97FWM.mjs";import{InterfereClient}from"@interfere/javascript";const sessionEndpoint=`https://registration.invalid/v3/session`;async function registration(){let device=new DeviceManager;device.init(),await device.whenFingerprintReady(),vi.useFakeTimers({toFake:[`Date`,`setTimeout`,`clearTimeout`]});let requests=[],client=new InterfereClient({baseUrl:`https://registration.invalid`,publicKeyHeader:{apiKey:`test`}}),prototype=Object.getPrototypeOf(client.sessions),registrations=vi.spyOn(prototype,`createSession`);worker.use(http.post(sessionEndpoint,()=>HttpResponse.json({ok:!0})));function recordRequest({request}){request.url===`https://registration.invalid/v3/session`&&requests.push(request.clone())}worker.events.on(`request:start`,recordRequest);let tracker=new SessionTracker({device,target:{baseUrl:`https://registration.invalid`,publicKeyHeader:{apiKey:`test`}}});async function settle(){await vi.advanceTimersByTimeAsync(0),await Promise.allSettled(registrations.mock.results.flatMap(result=>result.type===`return`?[result.value]:[]))}async function arrived(count){let deadline=performance.now()+1e4;await new Promise((resolve,reject)=>{function inspect(){if(requests.length>=count){resolve();return}if(performance.now()>deadline){reject(Error(`Expected ${count} registration requests, received ${requests.length}`));return}requestAnimationFrame(inspect)}inspect()})}return onTestFinished(()=>{tracker.dispose(),tracker.discardDeviceIdentity(),worker.events.removeListener(`request:start`,recordRequest);for(let key of[`interfere:session_id`,`interfere:last_activity`,`interfere:session_started`])localStorage.removeItem(key);vi.useRealTimers()}),{arrived,registrations,requests,settle,tracker}}export{registration,sessionEndpoint};
@@ -12,6 +12,7 @@ export declare class SessionManager {
12
12
  constructor(onRotate?: OnRotate);
13
13
  getSessionId(): string & import("zod").$brand<"SessionId">;
14
14
  markActivity(): void;
15
+ getLastActivityAt(): number;
15
16
  getSessionStartedAt(): number;
16
17
  getWindowId(): string;
17
18
  reset(): string & import("zod").$brand<"SessionId">;
@@ -1 +1 @@
1
- import{t as SessionManager}from"../session-C30CtCVv.mjs";export{SessionManager};
1
+ import{t as SessionManager}from"../session-BkvyVdtV.mjs";export{SessionManager};
@@ -1 +1 @@
1
- import{n as stampSentAt}from"./sent-at-CEM8UV3W.mjs";async function uploadReplayChunk(target,sessionId,body,headers,options){let requestHeaders=new Headers(target.headers);target.publicKeyHeader&&requestHeaders.set(`x-interfere-public-key`,target.publicKeyHeader.apiKey);for(let[name,value]of Object.entries(headers))requestHeaders.set(name,value);return requestHeaders.set(`content-type`,`application/octet-stream`),stampSentAt(requestHeaders),fetch(new URL(`/v3/replay/upload/${encodeURIComponent(sessionId)}`,target.baseUrl),{method:`POST`,credentials:`omit`,headers:requestHeaders,body:new Blob([body]),keepalive:options?.keepalive??!1,signal:AbortSignal.timeout(target.timeoutInSeconds*1e3)})}export{uploadReplayChunk as t};
1
+ import{n as stampSentAt}from"./sent-at-CEM8UV3W.mjs";async function uploadReplayChunk(target,sessionId,body,headers,options){let requestHeaders=new Headers(target.headers);target.publicKeyHeader&&requestHeaders.set(`x-interfere-public-key`,target.publicKeyHeader.apiKey);for(let[name,value]of Object.entries(headers))requestHeaders.set(name,value);return requestHeaders.set(`content-type`,`application/octet-stream`),stampSentAt(requestHeaders),fetch(new URL(`/v3/replay/upload/${encodeURIComponent(sessionId)}`,target.baseUrl),{method:`POST`,credentials:`omit`,headers:requestHeaders,body:new Blob([body]),keepalive:options?.keepalive??!1,signal:AbortSignal.any([AbortSignal.timeout(target.timeoutInSeconds*1e3),...options?.signal?[options.signal]:[]])})}export{uploadReplayChunk as t};
@@ -1 +1 @@
1
- var name=`@interfere/react`,version=`12.4.2`;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};
1
+ var name=`@interfere/react`,version=`12.4.3`;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.4.2",
3
+ "version": "12.4.3",
4
4
  "description": "Client-side React SDK for Interfere. Error tracking, session replay, and analytics.",
5
5
  "keywords": [
6
6
  "error-tracking",
@@ -94,10 +94,10 @@
94
94
  },
95
95
  "dependencies": {
96
96
  "@fingerprintjs/fingerprintjs": "5.2.0",
97
- "@interfere/constants": "^9.3.0",
98
- "@interfere/helpers": "^9.3.0",
99
- "@interfere/javascript": "^0.3.1",
100
- "@interfere/types": "^10.6.1",
97
+ "@interfere/constants": "^9.3.1",
98
+ "@interfere/helpers": "^9.3.1",
99
+ "@interfere/javascript": "^0.3.2",
100
+ "@interfere/types": "^10.6.2",
101
101
  "@opentelemetry/api": "1.9.1",
102
102
  "@opentelemetry/api-logs": "0.222.0",
103
103
  "@opentelemetry/core": "2.11.0",
@@ -120,6 +120,7 @@
120
120
  "@ua-parser-js/pro-enterprise": "2.0.10",
121
121
  "fflate": "0.8.3",
122
122
  "rrweb": "2.1.1",
123
+ "tldts": "7.4.11",
123
124
  "uuid": "14.0.2",
124
125
  "web-vitals": "6.2.1",
125
126
  "workbox-background-sync": "7.4.1",
@@ -1 +0,0 @@
1
- import{t as createLogger}from"./log-D6Ht--tv.mjs";import{n as onPageHidden,r as onPageShown}from"./page-lifecycle-rJEJNdKj.mjs";const log=createLogger(`activity`),IDLE_AFTER_MS=3e5,EXPIRE_AFTER_MS=9e5,MAX_AGE_MS=864e5,CHECK_INTERVAL_MS=3e4,ACTIVITY_EVENTS=[`pointerdown`,`keydown`,`scroll`,`touchstart`,`mousemove`];function monotonicNow(){return typeof performance>`u`?Date.now():performance.now()}function subscribe(set,handler){return set.add(handler),(()=>{set.delete(handler)})}function fire(handlers,arg){for(let handler of handlers)try{handler(arg)}catch(error){log.warn(`activity handler threw: %s`,error instanceof Error?error.constructor.name:`UnknownError`)}}var ActivityMonitor=class{session=null;pausedFor=null;lastPausedExceptionMs=null;lastActivityMs=0;keepaliveUntilMs=0;checkTimer=null;unsubscribeShown=null;unsubscribeHidden=null;pauseHandlers=new Set;resumeHandlers=new Set;pausedExceptionHandlers=new Set;onPause(handler){return subscribe(this.pauseHandlers,handler)}onExceptionWhilePaused(handler){return subscribe(this.pausedExceptionHandlers,handler)}noteException(){if(this.pausedFor===null)return;let now=monotonicNow();this.lastPausedExceptionMs!==null&&now-this.lastPausedExceptionMs<3e5||(this.lastPausedExceptionMs=now,fire(this.pausedExceptionHandlers,this.pausedFor))}onResume(handler){return subscribe(this.resumeHandlers,handler)}start(session){if(this.checkTimer===null&&typeof globalThis.addEventListener==`function`){this.session=session,this.pausedFor=null,this.lastPausedExceptionMs=null,this.lastActivityMs=monotonicNow(),this.keepaliveUntilMs=0;for(let type of ACTIVITY_EVENTS)globalThis.addEventListener(type,this.onInput,{capture:!0,passive:!0});this.unsubscribeShown=onPageShown(this.onInput),this.unsubscribeHidden=onPageHidden(this.onHidden),this.checkTimer=setInterval(this.poll,CHECK_INTERVAL_MS)}}stop(){if(this.checkTimer!==null){clearInterval(this.checkTimer),this.checkTimer=null;for(let type of ACTIVITY_EVENTS)globalThis.removeEventListener(type,this.onInput,!0);this.unsubscribeShown?.(),this.unsubscribeHidden?.(),this.unsubscribeShown=null,this.unsubscribeHidden=null,this.session=null,this.pausedFor=null,this.lastPausedExceptionMs=null,this.lastActivityMs=0,this.keepaliveUntilMs=0}}idleMs(){return monotonicNow()-this.lastActivityMs}isOverMaxAge(){let startedAt=this.session?.startedAt()??0;return startedAt>0&&Date.now()-startedAt>=864e5}pause(reason){this.pausedFor===null&&(this.pausedFor=reason,this.lastPausedExceptionMs=null,log.debug(`session paused: %s`,reason),fire(this.pauseHandlers,reason))}onHidden=()=>{this.pause(`hidden`)};poll=()=>{this.pausedFor===null&&(this.isOverMaxAge()||this.idleMs()>=3e5)&&this.pause(`idle`)};onInput=()=>{let now=monotonicNow();if(this.isOverMaxAge()||now-this.lastActivityMs>=9e5){this.resume(now,`rotated`);return}if(this.pausedFor!==null){this.resume(now,`idle`);return}now<this.keepaliveUntilMs||(this.touch(now),this.session?.markActivity())};resume(now,reason){reason===`rotated`&&(log.debug(`resume after expiry → new session`),this.session?.reset()),this.pausedFor=null,this.lastPausedExceptionMs=null,this.touch(now),this.session?.markActivity(),fire(this.resumeHandlers,reason)}touch(now){this.lastActivityMs=now,this.keepaliveUntilMs=now+1e3}};export{MAX_AGE_MS as a,IDLE_AFTER_MS as i,CHECK_INTERVAL_MS as n,EXPIRE_AFTER_MS as r,ActivityMonitor as t};
@@ -1 +0,0 @@
1
- import{t as createLogger}from"./log-D6Ht--tv.mjs";import{t as ActivityMonitor}from"./activity-oYlZ5aa1.mjs";import{n as fetchIngest}from"./ingest-backoff-BdBT-jss.mjs";import{t as DeviceManager}from"./device-DRK7hhLi.mjs";import{t as GeoDetector}from"./geo-D2wa9bGs.mjs";import{t as SessionManager}from"./session-C30CtCVv.mjs";import{t as SessionRetry}from"./session-retry-Dgkk0yui.mjs";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{InterfereClient,InterfereError}from"@interfere/javascript";const log=createLogger(`tracking`);function syncKey(sessionId,deviceId,fpHash){return`${sessionId}|${deviceId??``}|${fpHash??``}`}var SessionTracker=class{client;device;geo;mgr=null;activity=new ActivityMonitor;currentIdentity=null;identifiedSessionId=null;identifiedDeviceId=null;lastSyncedKey=null;inflightSyncKey=null;syncAttemptMs=0;generation=0;syncRetry=new SessionRetry;syncRetryKey=null;identityStarted=!1;constructor(opts){this.client=new InterfereClient({...opts.target,maxRetries:0,timeoutInSeconds:10,fetch:Object.assign(async(input,init)=>fetchIngest(input,async()=>(opts.fetcher??globalThis.fetch)(input,{...init,credentials:`omit`,keepalive:!0})),opts.fetcher??globalThis.fetch)}),this.device=opts.device??new DeviceManager,this.geo=opts.geo??new GeoDetector}start(){this.mgr=new SessionManager(id=>{this.onRotate(id)}),this.activity.start({markActivity:()=>{this.markActivity()},reset:()=>{this.rotateSession()},startedAt:()=>this.getSessionStartedAt()})}startDeviceIdentity(){this.identityStarted||(this.invalidateSync(),this.identityStarted=!0,this.device.init(),this.geo.detect(),this.backfillIdentity())}discardDeviceIdentity(){this.invalidateSync(),this.identityStarted=!1,this.device.clear(),this.geo.clear()}async backfillIdentity(){let gen=this.generation;if(await Promise.resolve(),gen!==this.generation||!this.identityStarted)return;let initialSessionId=this.mgr?.getSessionId()??null,initialFpHash=this.device.getFpHash();initialSessionId&&await this.syncSession(initialSessionId,this.device.getDeviceId(),initialFpHash),this.currentIdentity&&this.identify(this.currentIdentity);let fpHash=await this.device.whenFingerprintReady(),sessionId=this.mgr?.getSessionId()??null;gen===this.generation&&this.identityStarted&&sessionId&&fpHash!==initialFpHash&&this.syncSession(sessionId,this.device.getDeviceId(),fpHash)}onSessionPause(handler){return this.activity.onPause(handler)}onSessionExceptionWhilePaused(handler){return this.activity.onExceptionWhilePaused(handler)}noteException(){this.activity.noteException()}onSessionResume(handler){return this.activity.onResume(handler)}sessionId(){let id=this.mgr?.getSessionId()??null;return id&&this.ensureSynced(id),id}windowId(){return this.mgr?.getWindowId()??null}markActivity(){this.mgr?.markActivity()}getSessionStartedAt(){return this.mgr?.getSessionStartedAt()??0}getDeviceId(){return this.device.getDeviceId()}getFpHash(){return this.device.getFpHash()}getIdentity(){return this.currentIdentity}async identify(params){if(!this.mgr)return;let sessionId=this.mgr.getSessionId();if(this.identifiedSessionId===sessionId&&this.identifiedDeviceId===this.device.getDeviceId()){log.debug(`skipped, already identified for session %s`,sessionId);return}this.currentIdentity=params,this.identifiedSessionId=sessionId,this.identifiedDeviceId=this.device.getDeviceId();let gen=this.generation,[fpHash,country]=await Promise.all([this.device.whenFingerprintReady(),this.geo.detect()]),deviceId=this.device.getDeviceId();if(gen!==this.generation){this.identifiedSessionId=null;return}log.info(`POST session %s → identify`,sessionId),this.postIdentify(sessionId,omitUndefined({deviceId,fpHash,sessionId,...params,country:country||void 0}))}async postIdentify(sessionId,body){try{await this.client.sessions.identifySession(body)}catch{this.identifiedSessionId=null,log.warn(`identify failed for session %s`,sessionId)}}clearIdentity(){this.currentIdentity=null,this.identifiedSessionId=null,this.identifiedDeviceId=null}reset(){this.invalidateSync(),this.clearIdentity(),this.identityStarted&&this.device.reset(),this.mgr?.reset()}rotateSession(){this.mgr?.reset()}dispose(){this.activity.stop(),this.invalidateSync(),this.clearIdentity(),this.mgr=null}invalidateSync(){this.generation+=1,this.syncRetry.reset(),this.syncRetryKey=null,this.lastSyncedKey=null,this.inflightSyncKey=null,this.syncAttemptMs=0}currentSyncKey(){let sessionId=this.mgr?.sessionId;return sessionId?syncKey(sessionId,this.device.getDeviceId(),this.device.getFpHash()):null}ensureSynced(sessionId){let deviceId=this.device.getDeviceId(),fpHash=this.device.getFpHash(),key=syncKey(sessionId,deviceId,fpHash);this.lastSyncedKey!==key&&this.inflightSyncKey!==key&&(Date.now()-this.syncAttemptMs<5e3||this.syncSession(sessionId,deviceId,fpHash))}async syncSession(sessionId,deviceId,fpHash){let key=syncKey(sessionId,deviceId,fpHash);if(this.lastSyncedKey===key||this.inflightSyncKey===key)return;this.syncRetryKey!==key&&(this.syncRetry.reset(),this.syncRetryKey=key),this.syncRetry.cancel();let{generation}=this;this.inflightSyncKey=key,this.syncAttemptMs=Date.now();try{await this.client.sessions.createSession({sessionId,deviceId,fpHash}),generation===this.generation&&key===this.currentSyncKey()&&(this.lastSyncedKey=key,this.syncRetry.reset())}catch(error){log.warn(`session sync failed`),error instanceof InterfereError&&generation===this.generation&&key===this.currentSyncKey()&&this.syncRetry.schedule(error,()=>{let current=this.mgr?.sessionId;generation===this.generation&&current&&this.ensureSynced(current)})}finally{generation===this.generation&&this.inflightSyncKey===key&&(this.inflightSyncKey=null)}}async onRotate(sessionId){this.syncAttemptMs=Date.now();let gen=this.generation;try{await Promise.resolve();let fpHash=this.device.getFpHash(),deviceId=this.device.getDeviceId();if(gen!==this.generation)return;log.debug(`POST session %s (device=%s fp=%s)`,sessionId,deviceId??`pending`,fpHash??`none`),this.syncSession(sessionId,deviceId,fpHash)}catch{}}};export{SessionTracker as t};
@@ -1 +0,0 @@
1
- import{trace}from"@opentelemetry/api";const TRACE_HEADERS=[`traceparent`,`tracestate`,`baggage`],ATTR_TRACE_PROPAGATION=`interfere.trace_propagation`,ESCAPE_RE=/[.*+?^${}()|[\]\\]/gu;function pageOrigin(){return globalThis.location.origin}function originOf(url){try{return new URL(url,globalThis.location.href).origin}catch{return null}}function isRequestInput(input){return input instanceof Request}function stripTraceHeaders(headers){for(let name of TRACE_HEADERS)headers.delete(name);return headers}function corsWarning(origin){return`[interfere] ${origin} rejected the trace headers in its CORS preflight, so Interfere resent the request without them and stops adding them to that origin for this session. To link these requests to your backend traces, add "traceparent, tracestate, baggage" to Access-Control-Allow-Headers on ${origin}.`}var OriginGuardedPattern=class extends RegExp{#isDisabled;constructor(pattern,isDisabled){super(pattern.source,pattern.flags),this.#isDisabled=isDisabled}[Symbol.match](value){return this.#isDisabled(value)?null:super[Symbol.match](value)}};function installCorsGuard(){let nativeFetch=globalThis.fetch,disabled=new Set,verified=new Set;function isDisabled(url){let origin=originOf(url);return origin!==null&&disabled.has(origin)}function planRetry(input,init){let isRequest=isRequestInput(input);if(!(isRequest?input.headers:new Headers(init?.headers)).has(`traceparent`))return null;let origin=originOf(isRequest?input.url:String(input));return origin===null||origin===pageOrigin()||verified.has(origin)||disabled.has(origin)?null:isRequest?input.body===null?{origin,retry:async()=>nativeFetch(new Request(input,{headers:stripTraceHeaders(new Headers(input.headers))})),signal:input.signal}:null:init?.body instanceof ReadableStream?null:{origin,retry:async()=>nativeFetch(input,{...init,headers:stripTraceHeaders(new Headers(init?.headers))}),signal:init?.signal}}function disable(origin){disabled.has(origin)||(disabled.add(origin),console.warn(corsWarning(origin)))}async function guardedFetch(input,init){let plan=planRetry(input,init);if(!plan)return nativeFetch(input,init);let span=trace.getActiveSpan();try{let response=await nativeFetch(input,init);return verified.add(plan.origin),response}catch(error){if(!(error instanceof TypeError)||plan.signal?.aborted)throw error;let retried;try{retried=await plan.retry()}catch{throw error}return disable(plan.origin),span?.setAttribute(ATTR_TRACE_PROPAGATION,`disabled_cors`),retried}}return globalThis.fetch=Object.assign(guardedFetch,nativeFetch),{disabledHosts:()=>[...disabled].map(origin=>new URL(origin).host),dispose:()=>{globalThis.fetch===guardedFetch&&(globalThis.fetch=nativeFetch)},guardPatterns:patterns=>patterns.map(pattern=>new OriginGuardedPattern(pattern instanceof RegExp?pattern:RegExp(`^${pattern.replace(ESCAPE_RE,String.raw`\$&`)}$`,`u`),isDisabled))}}export{installCorsGuard as n,ATTR_TRACE_PROPAGATION as t};
@@ -1 +0,0 @@
1
- import{t as createLogger}from"./log-D6Ht--tv.mjs";import{t as reserveKeepaliveBody}from"./keepalive-budget-BfoHXD04.mjs";import{t as gzipForUnload}from"./unload-gzip-WX9FyWPs.mjs";import{t as uploadReplayChunk}from"./upload-D55WVf_o.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,trigger,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;if(trigger===void 0&&!unload)return`ok`;let 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.trigger":trigger,"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 getGlobal}from"./global-DYq1Z4_H.mjs";import{FORCE_ENABLE_GLOBAL}from"@interfere/types/sdk/injected-globals";function isEnvironmentEnabled(environment,forceEnabled){return!environment||environment.NODE_ENV===`production`||environment.NODE_ENV===void 0||forceEnabled||!!environment.INTERFERE_FORCE_ENABLE}function isEnabledByEnvironment(){let environment=typeof process>`u`?void 0:process.env;return!environment||environment.NODE_ENV===`production`||environment.NODE_ENV===void 0||isEnvironmentEnabled({NODE_ENV:environment.NODE_ENV,INTERFERE_FORCE_ENABLE:environment.INTERFERE_FORCE_ENABLE},!!getGlobal(FORCE_ENABLE_GLOBAL))}export{isEnvironmentEnabled as n,isEnabledByEnvironment as t};
@@ -1,9 +0,0 @@
1
- //#region src/internal/environment/environment.d.ts
2
- interface RuntimeEnvironment {
3
- NODE_ENV?: string | undefined;
4
- INTERFERE_FORCE_ENABLE?: string | undefined;
5
- }
6
- declare function isEnvironmentEnabled(environment: RuntimeEnvironment | null | undefined, forceEnabled: boolean): boolean;
7
- declare function isEnabledByEnvironment(): boolean;
8
- //#endregion
9
- export { isEnvironmentEnabled as n, isEnabledByEnvironment as t };
@@ -1 +0,0 @@
1
- import{n as fetchIngest}from"./ingest-backoff-BdBT-jss.mjs";import{n as stampSentAt}from"./sent-at-CEM8UV3W.mjs";import{t as reserveKeepaliveBody}from"./keepalive-budget-BfoHXD04.mjs";import{t as sendInKeepaliveChunks}from"./keepalive-chunks-BZv3PhHT.mjs";import{t as PRODUCER_VERSION}from"./version-CPcWUmrA.mjs";import{t as IngestLogExporter}from"./exporter-logs-BbzSiQJi.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)=>fetchIngest(url,async()=>{let body=init?.body,bytes=typeof body==`string`?textEncoder.encode(body).byteLength:0,dispatch=async(abortSignal,keepalive)=>globalThis.fetch(url,{...init,headers:stampSentAt(new Headers(init?.headers)),credentials:`omit`,keepalive,signal:abortSignal});return retryTelemetry(async abortSignal=>{let release=reserveKeepaliveBody(bytes,32e3);if(release===null)return dispatch(abortSignal,!1);try{return await dispatch(abortSignal,!0)}catch(error){if(!(error instanceof TypeError)||abortSignal.aborted)throw error}finally{release()}return dispatch(abortSignal,!1)},init?.signal)}),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}sendInKeepaliveChunks(spans,chunk=>JsonTraceSerializer.serializeRequest(chunk),this.send,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};
@@ -1,4 +0,0 @@
1
- import "./instrumentations-zBdPJHog.mjs";
2
- import "./navigation-CkiV6lJY.mjs";
3
- import "./provider-Dy0mVCx5.mjs";
4
- import "./web-vitals-x8y70B5x.mjs";
@@ -1 +0,0 @@
1
- import{t as DEFAULT_PRIVACY_POLICY}from"./privacy-CRuL0X8r.mjs";import{t as THIRD_PARTY_IGNORE}from"./third-party-hosts-CYOuLL_s.mjs";import{n as describeActionable,r as isActionable}from"./actionable-DOmVf_ib.mjs";import{i as stampUrlAttrs,n as ATTR_URL_FULL,r as ATTR_URL_PATH}from"./url-attrs-BdcyE2n6.mjs";import{t as stampHttpSpanRoute}from"./http-span-route-t2gig-KI.mjs";import{t as createClickSpanGate}from"./click-span-gate-6dNMhjc7.mjs";import{n as installCorsGuard}from"./cors-guard-CwkqEjzL.mjs";import{i as sameSiteMatcher,n as knownBackendMatchers,t as hostMatcher}from"./propagation-targets-BXDetg0k.mjs";import{n as settleFetchFailure,r as settleXhrFailure,t as createPageExitWatch}from"./network-failure-GVLV_sUF.mjs";import{MECHANISM_TYPE}from"@interfere/types/sdk/errors";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{registerInstrumentations}from"@opentelemetry/instrumentation";import{BrowserNavigationInstrumentation,defaultSanitizeUrl}from"@opentelemetry/instrumentation-browser-navigation";import{DocumentLoadInstrumentation}from"@opentelemetry/instrumentation-document-load";import{FetchInstrumentation}from"@opentelemetry/instrumentation-fetch";import{LongTaskInstrumentation}from"@opentelemetry/instrumentation-long-task";import{UserInteractionInstrumentation}from"@opentelemetry/instrumentation-user-interaction";import{XMLHttpRequestInstrumentation}from"@opentelemetry/instrumentation-xml-http-request";import{getElementXPath}from"@opentelemetry/sdk-trace-web";const DEFAULT_FAILURE_RANGES=[[400,599]];function resolveFailureRanges(opt){if(opt===!1)return null;if(opt===void 0||opt===!0)return DEFAULT_FAILURE_RANGES;let codes=opt.statusCodes;return codes&&codes.length>0?codes:DEFAULT_FAILURE_RANGES}function createFailureGate(){let seen=new Set,windowStart=0,windowCount=0;return(key=>{if(seen.has(key))return!1;let now=Date.now();return now-windowStart>6e4&&(windowStart=now,windowCount=0),windowCount>=20?!1:(seen.size>=100&&seen.clear(),seen.add(key),windowCount+=1,!0)})}function failureKey(method,discriminator,url){let path;try{path=new URL(url).pathname}catch{path=url}return`${method} ${discriminator} ${path}`}function statusMatches(status,ranges){for(let range of ranges)if(typeof range==`number`){if(status===range)return!0}else if(status>=range[0]&&status<=range[1])return!0;return!1}function recordHttpFailure(span,status,method,url,mechanism){span.addEvent(`exception`,{"exception.message":`HTTP ${status} ${method} ${url}`,"exception.type":`HttpResponseError`,"interfere.exception.handled":!1,"interfere.exception.kind":`error`,"interfere.exception.mechanism":mechanism})}function maybeCaptureFetchFailure(span,result,failureRanges,method,url,gate){if(!failureRanges)return;let status=result?.status;typeof status!=`number`||status<=0||!statusMatches(status,failureRanges)||(!gate||gate(failureKey(method,status,url)))&&recordHttpFailure(span,status,method,url,MECHANISM_TYPE.browser.fetchFailedResponse)}function applyFetchSpanAttrs(span,request,result,failureRanges,pageExit,isTrackedUrl,resolveRoute,gate){let url=resolveFetchUrl(span,request,result);if(!url)return;let parsed;try{parsed=new URL(url)}catch{return}span.setAttribute(ATTR_URL_PATH,parsed.pathname);let tracked=isTrackedUrl(url),method=resolveFetchMethod(request);if(tracked){if(stampHttpSpanRoute(span,method,parsed.pathname,resolveRoute),isPrefetchRequest(request))return;result instanceof Response?maybeCaptureFetchFailure(span,result,failureRanges,method,url,gate):failureRanges&&settleFetchFailure(span,request,result,pageExit,method,url,()=>!gate||gate(failureKey(method,`network`,url)))}}function applyXhrSpanAttrs(span,xhr,failureRanges,pageExit,isTrackedUrl,gate,resolveRoute){let url=xhr.responseURL||spanUrlFull(span);if(!(url&&isTrackedUrl(url)))return;let parsed;try{parsed=new URL(url)}catch{return}let method=isReadableSpan(span)?String(span.attributes[`http.request.method`]??span.attributes[`http.method`]??`XHR`):`XHR`;if(span.setAttribute(ATTR_URL_PATH,parsed.pathname),stampHttpSpanRoute(span,method,parsed.pathname,resolveRoute),!failureRanges)return;let{status}=xhr;if(typeof status==`number`){if(status===0){settleXhrFailure(span,pageExit,url,()=>!gate||gate(failureKey(`XHR`,`network`,url)));return}statusMatches(status,failureRanges)&&(!gate||gate(failureKey(`XHR`,status,url)))&&recordHttpFailure(span,status,`XHR`,url,MECHANISM_TYPE.browser.xhrFailedResponse)}}function resolveFetchUrl(span,request,result){return responseUrl(result)??requestUrl(request)??spanUrlFull(span)}function isReadableSpan(span){return`attributes`in span}function spanUrlFull(span){if(!isReadableSpan(span))return null;let url=span.attributes[`url.full`]??span.attributes[`http.url`];return typeof url==`string`?url:null}function responseUrl(result){return result instanceof Response&&result.url?result.url:null}function requestUrl(request){return typeof request==`string`?request:readStringProp(request,`url`)??readStringProp(request,`href`)}function resolveFetchMethod(request){return readStringProp(request,`method`)??`GET`}function readStringProp(value,key){if(!(typeof value==`object`&&value&&key in value))return null;let prop=Reflect.get(value,key);return typeof prop==`string`?prop:null}const testOnlyApplyFetchSpanAttrs=applyFetchSpanAttrs,testOnlyApplyXhrSpanAttrs=applyXhrSpanAttrs,testOnlyResolveFailureRanges=resolveFailureRanges,testOnlyCreateFailureGate=createFailureGate,NEVER_MATCH=/^$/u,ESCAPE_RE=/[.*+?^${}()|[\]\\]/gu;function sameOriginPattern(){if(typeof window>`u`)return NEVER_MATCH;let{protocol,host}=globalThis.location;return RegExp(`^${protocol}//${host.replace(ESCAPE_RE,String.raw`\$&`)}`,`u`)}function pageSameSiteMatcher(){return typeof window>`u`?null:sameSiteMatcher(globalThis.location.hostname)}function stampInteractionAttrs(eventType,element,span,policy){let desc=describeActionable(element,policy);span.setAttribute(`ui.event_type`,eventType),span.setAttribute(`ui.target.tag`,desc.tag),desc.privacy&&(span.setAttribute(`ui.target.privacy`,desc.privacy),span.setAttribute(`target_xpath`,getElementXPath(element,!1))),desc.label&&span.setAttribute(`ui.target.label`,desc.label),desc.id&&span.setAttribute(`ui.target.id`,desc.id),desc.name&&span.setAttribute(`ui.target.name`,desc.name),desc.role&&span.setAttribute(`ui.target.role`,desc.role),desc.ariaLabel&&span.setAttribute(`ui.target.aria_label`,desc.ariaLabel),desc.text&&span.setAttribute(`ui.target.text`,desc.text)}const PREFETCH_HEADER_NAMES=[`next-router-prefetch`,`next-router-segment-prefetch`];function isPrefetchRequest(request){if(typeof request==`string`||request instanceof URL)return!1;let headers;try{headers=typeof Request<`u`&&request instanceof Request?request.headers:new Headers(request.headers)}catch{return!1}return PREFETCH_HEADER_NAMES.some(name=>headers.has(name))||headers.get(`purpose`)===`prefetch`||headers.get(`sec-purpose`)?.includes(`prefetch`)===!0}function registerBundledInstrumentations(input){let{tracerProvider,loggerProvider,ignoreUrls,apiHosts=[],backendHosts=[],propagateContextUrls=[],privacyPolicy=DEFAULT_PRIVACY_POLICY,isInteractionCaptureEnabled=()=>!0,redactUrl=url=>url}=input,{resolveRoute}=input,origin=sameOriginPattern(),sameSite=pageSameSiteMatcher(),propagateMatchers=[...sameSite?[sameSite]:[],...knownBackendMatchers(backendHosts),...apiHosts.map(host=>hostMatcher(host)),...propagateContextUrls],fetchIgnore=[...ignoreUrls,...THIRD_PARTY_IGNORE],failureRanges=resolveFailureRanges(input.captureFailedRequests),failureGate=createFailureGate(),pageExit=createPageExitWatch();function isTrackedUrl(url){return origin.test(url)||propagateMatchers.some(re=>re instanceof RegExp?re.test(url):url.includes(re))}let corsGuard=typeof window>`u`?null:installCorsGuard(),propagateTraceHeaderCorsUrls=[origin,...corsGuard?.guardPatterns(propagateMatchers)??propagateMatchers],pageEventsEnabled=!1,admitClick=createClickSpanGate(),coreInstrumentations=[new FetchInstrumentation({applyCustomAttributesOnSpan:(span,request,result)=>{applyFetchSpanAttrs(span,request,result,failureRanges,pageExit,isTrackedUrl,resolveRoute,failureGate)},ignoreUrls:fetchIgnore,measureRequestSize:!0,propagateTraceHeaderCorsUrls,requestHook:(span,request)=>{isPrefetchRequest(request)&&span.setAttribute(`http.request.prefetch`,!0)}}),new XMLHttpRequestInstrumentation({applyCustomAttributesOnSpan:(span,xhr)=>{applyXhrSpanAttrs(span,xhr,failureRanges,pageExit,isTrackedUrl,failureGate,resolveRoute)},ignoreUrls:fetchIgnore,propagateTraceHeaderCorsUrls}),new LongTaskInstrumentation({observerCallback:(span,info)=>{stampUrlAttrs(span,resolveRoute);let containerType=info.longtaskEntry.attribution[0]?.containerType;containerType&&span.setAttribute(`longtask.container_type`,containerType)}}),new UserInteractionInstrumentation({eventNames:[`click`,`submit`],shouldPreventSpanCreation:(eventType,element,span)=>!(pageEventsEnabled&&isInteractionCaptureEnabled())||eventType===`click`&&!(isActionable(element)&&admitClick(element))||(stampInteractionAttrs(eventType,element,span,privacyPolicy),stampUrlAttrs(span,resolveRoute),!1)})],pageEventsInstrumentations=[new DocumentLoadInstrumentation({applyCustomAttributesOnSpan:{resourceFetch:(span,entry)=>{let name=entry?.name;if(typeof name!=`string`)return;let url;try{url=new URL(name)}catch{return}let isCrossOrigin=typeof window<`u`&&url.origin!==globalThis.location.origin;span.updateName(isCrossOrigin?`resource: ${url.host}${url.pathname}`:`resource: ${url.pathname}`),span.setAttribute(ATTR_URL_FULL,name),span.setAttribute(ATTR_URL_PATH,url.pathname),span.setAttribute(`server.address`,url.host)}},enabled:!1}),new BrowserNavigationInstrumentation({enabled:!1,sanitizeUrl:url=>redactUrl(defaultSanitizeUrl(url))})],unregisterCore=registerInstrumentations(omitUndefined({tracerProvider,loggerProvider,instrumentations:coreInstrumentations})),unregisterPageEvents=null,setPageEventsEnabled=enabled=>{if(pageEventsEnabled=enabled,enabled){unregisterPageEvents??=registerInstrumentations(omitUndefined({tracerProvider,loggerProvider,instrumentations:pageEventsInstrumentations}));return}unregisterPageEvents?.(),unregisterPageEvents=null};return{dispose:()=>{setPageEventsEnabled(!1),unregisterCore(),corsGuard?.dispose(),pageExit.dispose()},propagationDisabledHosts:()=>corsGuard?.disabledHosts()??[],setPageEventsEnabled}}export{testOnlyResolveFailureRanges as a,testOnlyCreateFailureGate as i,testOnlyApplyFetchSpanAttrs as n,testOnlyApplyXhrSpanAttrs as r,registerBundledInstrumentations as t};
@@ -1 +0,0 @@
1
- import{t as isPageHidden}from"./page-lifecycle-rJEJNdKj.mjs";import{ExportResultCode}from"@opentelemetry/core";function splitForKeepalive(items,serialize){let chunks=[],pending=[items];for(let next=pending.pop();next;next=pending.pop()){if(next.length<=1||(serialize(next)?.byteLength??0)<=16e3){chunks.push(next);continue}let middle=Math.ceil(next.length/2);pending.push(next.slice(middle),next.slice(0,middle))}return chunks}function sendInKeepaliveChunks(items,serialize,send,resultCallback){let chunks=isPageHidden()?splitForKeepalive(items,serialize):[items];if(chunks.length===1){send(serialize(items),resultCallback);return}let pending=chunks.length,failure,settle=result=>{result.code!==ExportResultCode.SUCCESS&&(failure??=result),--pending,pending===0&&resultCallback(failure??{code:ExportResultCode.SUCCESS})};for(let chunk of chunks)send(serialize(chunk),settle)}export{sendInKeepaliveChunks as t};
@@ -1 +0,0 @@
1
- import{t as createLogger}from"./log-D6Ht--tv.mjs";import{i as onPageUnloading,n as onPageHidden}from"./page-lifecycle-rJEJNdKj.mjs";import{t as SessionTracker}from"./api-C8aG7li1.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-CPcWUmrA.mjs";import{t as INGEST_IGNORE_RE}from"./exporter-BtHqkV3R.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-DgB1_Xc5.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)}onSessionExceptionWhilePaused(handler){return this.tracker.onSessionExceptionWhilePaused(handler)}noteException(){this.tracker.noteException()}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}this.tracker.noteException();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),{plugins:remotePlugins,backendHosts}=await resolveRemoteConfig(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),backendHosts&&(resolvedTracing.backendHosts=backendHosts),await wireOtel(kernel,targets,opts._wrapperVersions,resolvedTracing)}return remotePlugins?runtime.applyRemoteConfig(remotePlugins):runtime.applyRemoteConfigDefaults(),kernel}async function resolveRemoteConfig(opts,fetcher){let baked=readBakedPlugins();if(baked)return{plugins:baked,backendHosts:void 0};let remoteConfig=await fetchRemoteConfig(resolveTargets(opts.apiHost).config,fetcher);return remoteConfig?.ingestUrl&&setIngestHost(remoteConfig.ingestUrl),{plugins:remoteConfig?.plugins??null,backendHosts:remoteConfig?.backendHosts}}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(),onExceptionSpan:()=>{kernel.noteException()},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,...tracing.ignoreUrls??[]],apiHosts:tracing.apiHosts,backendHosts:tracing.backendHosts,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 +0,0 @@
1
- const MULTI_LABEL_PUBLIC_SUFFIXES=new Set(`ac.jp,ac.nz,ac.uk,co.id,co.il,co.in,co.jp,co.kr,co.nz,co.th,co.uk,co.za,com.ar,com.au,com.br,com.cn,com.co,com.hk,com.mx,com.my,com.ph,com.pk,com.sg,com.tr,com.tw,com.ua,com.vn,edu.au,gov.uk,ne.jp,net.au,or.jp,org.au,org.uk,amplifyapp.com,appspot.com,azurestaticapps.net,azurewebsites.net,b-cdn.net,blogspot.com,cloudfront.net,codesandbox.io,deno.dev,elasticbeanstalk.com,firebaseapp.com,fly.dev,github.io,gitlab.io,glitch.me,herokuapp.com,netlify.app,ngrok-free.app,ngrok.app,ngrok.io,now.sh,onrender.com,pages.dev,railway.app,replit.app,repl.co,run.app,stackblitz.io,supabase.co,surge.sh,up.railway.app,vercel.app,web.app,webflow.io,workers.dev`.split(`,`)),HOSTNAME_RE=/^[a-z\d-]+(?:\.[a-z\d-]+)*$/u,IPV4_RE=/^\d{1,3}(?:\.\d{1,3}){3}$/u,ESCAPE_RE=/[.*+?^${}()|[\]\\]/gu;function escapeRegExp(value){return value.replaceAll(ESCAPE_RE,String.raw`\$&`)}function normalizeHost(host){let lower=host.trim().toLowerCase().replace(/\.$/u,``);return HOSTNAME_RE.test(lower)?lower:null}function registrableDomain(host){let normalized=normalizeHost(host);if(!normalized)return null;if(IPV4_RE.test(normalized))return normalized;let labels=normalized.split(`.`);if(labels.length<2)return normalized;for(let start=0;start<labels.length-1;start++){let suffix=labels.slice(start+1).join(`.`);if(MULTI_LABEL_PUBLIC_SUFFIXES.has(suffix))return labels.slice(start).join(`.`)}return MULTI_LABEL_PUBLIC_SUFFIXES.has(normalized)?null:labels.slice(-2).join(`.`)}function hostMatcher(host){return RegExp(`^https?://${escapeRegExp(host)}(?::\\d+)?(?:[/?#]|$)`,`u`)}function sameSiteMatcher(pageHostname){let site=registrableDomain(pageHostname);return site?IPV4_RE.test(site)||!site.includes(`.`)?hostMatcher(site):RegExp(`^https?://(?:[a-z\\d-]+\\.)*${escapeRegExp(site)}(?::\\d+)?(?:[/?#]|$)`,`iu`):null}function knownBackendMatchers(hosts){return hosts.flatMap(host=>{let normalized=normalizeHost(host);return normalized?.includes(`.`)?[hostMatcher(normalized)]:[]})}export{sameSiteMatcher as i,knownBackendMatchers as n,registrableDomain as r,hostMatcher as t};
@@ -1 +0,0 @@
1
- import{sessionIdSchema}from"@interfere/types/data/session";import{v7}from"uuid";const SESSION_ID_KEY=`interfere:session_id`,LAST_ACTIVITY_KEY=`interfere:last_activity`,SESSION_STARTED_KEY=`interfere:session_started`,WINDOW_ID_KEY=`interfere:window_id`;function tryStorage(type){try{let s=globalThis[type],key=`__interfere_probe__`;return s.setItem(key,`1`),s.removeItem(key),s}catch{return null}}var SessionManager=class{sessionId=null;windowId=null;local;session;onRotate=null;lastActivityMs=0;sessionStartedMs=0;constructor(onRotate){this.local=tryStorage(`localStorage`),this.session=tryStorage(`sessionStorage`),this.onRotate=onRotate??null,this.restore()}getSessionId(){return this.sessionId?this.sessionId:this.rotate()}markActivity(){this.touch()}getSessionStartedAt(){return this.sessionStartedMs}getWindowId(){if(this.windowId)return this.windowId;let stored=this.session?.getItem(WINDOW_ID_KEY);return stored?(this.windowId=stored,stored):(this.windowId=`win_${crypto.randomUUID()}`,this.session?.setItem(WINDOW_ID_KEY,this.windowId),this.windowId)}reset(){return this.rotate()}restore(){let stored=this.local?.getItem(SESSION_ID_KEY),startedRaw=this.local?.getItem(SESSION_STARTED_KEY),parsed=sessionIdSchema.safeParse(stored);this.sessionStartedMs=startedRaw?Number(startedRaw):0,parsed.success&&!this.isExpired()?(this.sessionId=parsed.data,this.touch()):this.rotate()}rotate(){return this.sessionId=sessionIdSchema.parse(v7()),this.sessionStartedMs=Date.now(),this.local?.setItem(SESSION_ID_KEY,this.sessionId),this.local?.setItem(SESSION_STARTED_KEY,String(this.sessionStartedMs)),this.touch(),this.onRotate?.(this.sessionId),this.sessionId}touch(){this.lastActivityMs=Date.now(),this.local?.setItem(LAST_ACTIVITY_KEY,String(this.lastActivityMs))}isExpired(){if(this.sessionStartedMs>0&&Date.now()-this.sessionStartedMs>864e5)return!0;let raw=this.local?.getItem(LAST_ACTIVITY_KEY),ts=raw?Number(raw):this.lastActivityMs;return ts===0||Date.now()-ts>9e5}};export{SessionManager as t};