sitepong 0.2.0 → 0.2.2

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.
@@ -1,7 +1,7 @@
1
1
  import { NextRequest } from 'next/server';
2
- import { S as SitePongConfig } from '../types-Cms9VXx9.mjs';
2
+ import { S as SitePongConfig } from '../types-CphqOTfm.mjs';
3
3
  export { addBreadcrumb, captureServerException, initServer } from '../server/index.mjs';
4
- import '../types-BEqbz0tw.mjs';
4
+ import '../types-DPINdOQW.mjs';
5
5
 
6
6
  /**
7
7
  * Next.js integration for SitePong
@@ -1,7 +1,7 @@
1
1
  import { NextRequest } from 'next/server';
2
- import { S as SitePongConfig } from '../types-DQSv7JAE.js';
2
+ import { S as SitePongConfig } from '../types-BTA43eyz.js';
3
3
  export { addBreadcrumb, captureServerException, initServer } from '../server/index.js';
4
- import '../types-BEqbz0tw.js';
4
+ import '../types-DPINdOQW.js';
5
5
 
6
6
  /**
7
7
  * Next.js integration for SitePong
@@ -1,9 +1,9 @@
1
1
  import React, { Component, ReactNode, ErrorInfo } from 'react';
2
2
  import { SitePongInitConfig, ErrorContext, addBreadcrumb, DeviceSignals, WebVitals } from '../index.mjs';
3
- export { CapturedError, CronCheckinOptions, CronHandle, DEFAULT_SUPERLINK_ENDPOINT, DatabaseQueryEvent, DatabaseTrackerConfig, DeferredDeepLinkHandler, DeviceInfo, EnvironmentAdapter, FraudCheckResult, MetricOptions, MutableRNEnvironmentAdapter, PerformanceConfig, PerformanceSpan, PerformanceTransaction, PlatformName, ProfileData, ProfileFrame, ProfilerConfig, RemoteConfig, RemoteConfigFeatures, RemoteConfigSampling, ResourceTimingBreakdown, SitePongConfig, SuperLinkClient, SuperLinkConfig, SuperLinkDeepLink, SuperLinkEventType, SuperLinkFingerprint, SuperLinkIdentityMetadata, SuperLinkMatchRequest, SuperLinkMatchResponse, SuperLinkMatchType, SuperLinkPlatform, TraceContext, TracePropagator, VisitorIdResult, WebManagerFactories, areFlagsReady, captureError, captureMessage, captureWebDeepLink, clearAnonymousId, clearUser, client, completeFromScan, createTraceContext, cronCheckin, cronStart, cronWrap, dbTrack, dbTrackSync, endSpan, endTransaction, extractIdentityMetadata, extractTrace, flush, flushMetrics, flushProfiles, generateSpanId, generateTraceId, getAllFlags, getAnonymousId, getDbNPlusOnePatterns, getDbQueryCount, getDeepLink, getDeviceSignals, getFlag, getFraudCheck, getLatestProfile, getMatchedDeepLink, getProfiles, getRemoteConfig, getReplaySessionId, getVariant, getVariantPayload, getVisitorId, getWebVitals, group, identify, init, initRN, initSuperLink, isInitialized, isRemoteConfigFeatureEnabled, isReplayRecording, metricDistribution, metricGauge, metricHistogram, metricIncrement, metricStartTimer, metricTime, onDeferredDeepLink, onRemoteConfigChange, parseUniversalLink, profile, propagateTrace, refreshFlags, registerIdentifyHook, registerWebManagerFactories, resetAnalytics, resetDbQueryCount, setAnonymousId, setContext, setCurrentScreen, setEnvironment, setRNGetCurrentScreen, setTags, setUser, startProfileSpan, startReplay, startSpan, startTransaction, stopReplay, superlinkClient, superlinkIdentify, track, trackPageView, waitForFlags, writeClipboardToken } from '../index.mjs';
4
- import { C as CaptureContext, U as User } from '../types-Cms9VXx9.mjs';
5
- import { T as TrackProperties, U as UserTraits, G as GroupTraits } from '../types-BEqbz0tw.mjs';
6
- export { R as ReplayConfig, a as ReplayEvent } from '../types-BEqbz0tw.mjs';
3
+ export { CapturedError, CronCheckinOptions, CronHandle, DEFAULT_SUPERLINK_ENDPOINT, DatabaseQueryEvent, DatabaseTrackerConfig, DeferredDeepLinkHandler, DeviceInfo, EnvironmentAdapter, FraudCheckResult, MetricOptions, MutableRNEnvironmentAdapter, PerformanceConfig, PerformanceSpan, PerformanceTransaction, PlatformName, ProfileData, ProfileFrame, ProfilerConfig, RemoteConfig, RemoteConfigFeatures, RemoteConfigSampling, ResourceTimingBreakdown, SitePongConfig, SuperLinkClient, SuperLinkConfig, SuperLinkDeepLink, SuperLinkEventType, SuperLinkFingerprint, SuperLinkIdentityMetadata, SuperLinkMatchRequest, SuperLinkMatchResponse, SuperLinkMatchType, SuperLinkPlatform, TraceContext, TracePropagator, VisitorIdResult, WebManagerFactories, areFlagsReady, captureError, captureMessage, captureWebDeepLink, clearAnonymousId, clearUser, client, completeFromScan, createTraceContext, cronCheckin, cronStart, cronWrap, dbTrack, dbTrackSync, endSpan, endTransaction, extractIdentityMetadata, extractTrace, flush, flushMetrics, flushProfiles, generateSpanId, generateTraceId, getAllFlags, getAnonymousId, getDbNPlusOnePatterns, getDbQueryCount, getDeepLink, getDeviceSignals, getFlag, getFraudCheck, getLatestProfile, getMatchedDeepLink, getProfiles, getRemoteConfig, getReplaySessionId, getVariant, getVariantPayload, getVisitorId, getWebVitals, group, identify, init, initRN, initSuperLink, isInitialized, isRemoteConfigFeatureEnabled, isReplayRecording, metricDistribution, metricGauge, metricHistogram, metricIncrement, metricStartTimer, metricTime, onDeferredDeepLink, onRemoteConfigChange, parseUniversalLink, profile, propagateTrace, refreshFlags, registerIdentifyHook, registerWebManagerFactories, resetAnalytics, resetDbQueryCount, setAnonymousId, setContext, setCurrentScreen, setEnvironment, setRNGetCurrentScreen, setTags, setUser, startProfileSpan, startReplay, startSpan, startTransaction, startWatchtowerCapture, stopReplay, stopWatchtowerCapture, superlinkClient, superlinkIdentify, track, trackPageView, waitForFlags, writeClipboardToken } from '../index.mjs';
4
+ import { C as CaptureContext, U as User } from '../types-CphqOTfm.mjs';
5
+ import { T as TrackProperties, U as UserTraits, G as GroupTraits } from '../types-DPINdOQW.mjs';
6
+ export { R as ReplayConfig, a as ReplayEvent } from '../types-DPINdOQW.mjs';
7
7
 
8
8
  interface SitePongContextValue {
9
9
  isInitialized: boolean;
@@ -1,9 +1,9 @@
1
1
  import React, { Component, ReactNode, ErrorInfo } from 'react';
2
2
  import { SitePongInitConfig, ErrorContext, addBreadcrumb, DeviceSignals, WebVitals } from '../index.js';
3
- export { CapturedError, CronCheckinOptions, CronHandle, DEFAULT_SUPERLINK_ENDPOINT, DatabaseQueryEvent, DatabaseTrackerConfig, DeferredDeepLinkHandler, DeviceInfo, EnvironmentAdapter, FraudCheckResult, MetricOptions, MutableRNEnvironmentAdapter, PerformanceConfig, PerformanceSpan, PerformanceTransaction, PlatformName, ProfileData, ProfileFrame, ProfilerConfig, RemoteConfig, RemoteConfigFeatures, RemoteConfigSampling, ResourceTimingBreakdown, SitePongConfig, SuperLinkClient, SuperLinkConfig, SuperLinkDeepLink, SuperLinkEventType, SuperLinkFingerprint, SuperLinkIdentityMetadata, SuperLinkMatchRequest, SuperLinkMatchResponse, SuperLinkMatchType, SuperLinkPlatform, TraceContext, TracePropagator, VisitorIdResult, WebManagerFactories, areFlagsReady, captureError, captureMessage, captureWebDeepLink, clearAnonymousId, clearUser, client, completeFromScan, createTraceContext, cronCheckin, cronStart, cronWrap, dbTrack, dbTrackSync, endSpan, endTransaction, extractIdentityMetadata, extractTrace, flush, flushMetrics, flushProfiles, generateSpanId, generateTraceId, getAllFlags, getAnonymousId, getDbNPlusOnePatterns, getDbQueryCount, getDeepLink, getDeviceSignals, getFlag, getFraudCheck, getLatestProfile, getMatchedDeepLink, getProfiles, getRemoteConfig, getReplaySessionId, getVariant, getVariantPayload, getVisitorId, getWebVitals, group, identify, init, initRN, initSuperLink, isInitialized, isRemoteConfigFeatureEnabled, isReplayRecording, metricDistribution, metricGauge, metricHistogram, metricIncrement, metricStartTimer, metricTime, onDeferredDeepLink, onRemoteConfigChange, parseUniversalLink, profile, propagateTrace, refreshFlags, registerIdentifyHook, registerWebManagerFactories, resetAnalytics, resetDbQueryCount, setAnonymousId, setContext, setCurrentScreen, setEnvironment, setRNGetCurrentScreen, setTags, setUser, startProfileSpan, startReplay, startSpan, startTransaction, stopReplay, superlinkClient, superlinkIdentify, track, trackPageView, waitForFlags, writeClipboardToken } from '../index.js';
4
- import { C as CaptureContext, U as User } from '../types-DQSv7JAE.js';
5
- import { T as TrackProperties, U as UserTraits, G as GroupTraits } from '../types-BEqbz0tw.js';
6
- export { R as ReplayConfig, a as ReplayEvent } from '../types-BEqbz0tw.js';
3
+ export { CapturedError, CronCheckinOptions, CronHandle, DEFAULT_SUPERLINK_ENDPOINT, DatabaseQueryEvent, DatabaseTrackerConfig, DeferredDeepLinkHandler, DeviceInfo, EnvironmentAdapter, FraudCheckResult, MetricOptions, MutableRNEnvironmentAdapter, PerformanceConfig, PerformanceSpan, PerformanceTransaction, PlatformName, ProfileData, ProfileFrame, ProfilerConfig, RemoteConfig, RemoteConfigFeatures, RemoteConfigSampling, ResourceTimingBreakdown, SitePongConfig, SuperLinkClient, SuperLinkConfig, SuperLinkDeepLink, SuperLinkEventType, SuperLinkFingerprint, SuperLinkIdentityMetadata, SuperLinkMatchRequest, SuperLinkMatchResponse, SuperLinkMatchType, SuperLinkPlatform, TraceContext, TracePropagator, VisitorIdResult, WebManagerFactories, areFlagsReady, captureError, captureMessage, captureWebDeepLink, clearAnonymousId, clearUser, client, completeFromScan, createTraceContext, cronCheckin, cronStart, cronWrap, dbTrack, dbTrackSync, endSpan, endTransaction, extractIdentityMetadata, extractTrace, flush, flushMetrics, flushProfiles, generateSpanId, generateTraceId, getAllFlags, getAnonymousId, getDbNPlusOnePatterns, getDbQueryCount, getDeepLink, getDeviceSignals, getFlag, getFraudCheck, getLatestProfile, getMatchedDeepLink, getProfiles, getRemoteConfig, getReplaySessionId, getVariant, getVariantPayload, getVisitorId, getWebVitals, group, identify, init, initRN, initSuperLink, isInitialized, isRemoteConfigFeatureEnabled, isReplayRecording, metricDistribution, metricGauge, metricHistogram, metricIncrement, metricStartTimer, metricTime, onDeferredDeepLink, onRemoteConfigChange, parseUniversalLink, profile, propagateTrace, refreshFlags, registerIdentifyHook, registerWebManagerFactories, resetAnalytics, resetDbQueryCount, setAnonymousId, setContext, setCurrentScreen, setEnvironment, setRNGetCurrentScreen, setTags, setUser, startProfileSpan, startReplay, startSpan, startTransaction, startWatchtowerCapture, stopReplay, stopWatchtowerCapture, superlinkClient, superlinkIdentify, track, trackPageView, waitForFlags, writeClipboardToken } from '../index.js';
4
+ import { C as CaptureContext, U as User } from '../types-BTA43eyz.js';
5
+ import { T as TrackProperties, U as UserTraits, G as GroupTraits } from '../types-DPINdOQW.js';
6
+ export { R as ReplayConfig, a as ReplayEvent } from '../types-DPINdOQW.js';
7
7
 
8
8
  interface SitePongContextValue {
9
9
  isInitialized: boolean;
@@ -1,7 +1,6 @@
1
1
  'use strict';
2
2
 
3
3
  var react = require('react');
4
- require('web-vitals');
5
4
  var jsxRuntime = require('react/jsx-runtime');
6
5
 
7
6
  // src/react/provider.tsx
@@ -524,6 +523,60 @@ function clearSession() {
524
523
  memorySessionTs = null;
525
524
  }
526
525
 
526
+ // src/analytics/utm.ts
527
+ var STORAGE_KEY2 = "sp_utm";
528
+ var UTM_KEYS = [
529
+ ["source", "utm_source"],
530
+ ["medium", "utm_medium"],
531
+ ["campaign", "utm_campaign"],
532
+ ["term", "utm_term"],
533
+ ["content", "utm_content"]
534
+ ];
535
+ function parseFromLocation() {
536
+ if (typeof window === "undefined" || !window.location || !window.location.search) return null;
537
+ let params;
538
+ try {
539
+ params = new URLSearchParams(window.location.search);
540
+ } catch {
541
+ return null;
542
+ }
543
+ const result = {};
544
+ let found = false;
545
+ for (const [key, queryKey] of UTM_KEYS) {
546
+ const value = params.get(queryKey);
547
+ if (value) {
548
+ result[key] = value;
549
+ found = true;
550
+ }
551
+ }
552
+ return found ? result : null;
553
+ }
554
+ function readStored() {
555
+ if (typeof sessionStorage === "undefined") return null;
556
+ try {
557
+ const raw = sessionStorage.getItem(STORAGE_KEY2);
558
+ if (!raw) return null;
559
+ const parsed = JSON.parse(raw);
560
+ return parsed && typeof parsed === "object" ? parsed : null;
561
+ } catch {
562
+ return null;
563
+ }
564
+ }
565
+ function writeStored(utm) {
566
+ if (typeof sessionStorage === "undefined") return;
567
+ try {
568
+ sessionStorage.setItem(STORAGE_KEY2, JSON.stringify(utm));
569
+ } catch {
570
+ }
571
+ }
572
+ function getSessionUtm() {
573
+ const stored = readStored();
574
+ if (stored) return stored;
575
+ const fresh = parseFromLocation();
576
+ if (fresh) writeStored(fresh);
577
+ return fresh;
578
+ }
579
+
527
580
  // src/analytics/autocapture.ts
528
581
  var DEFAULT_BLOCK_SELECTORS = [
529
582
  "[data-sp-no-capture]",
@@ -532,6 +585,7 @@ var DEFAULT_BLOCK_SELECTORS = [
532
585
  var MAX_TEXT_LENGTH = 255;
533
586
  var AutocaptureModule = class {
534
587
  constructor(config, callback) {
588
+ this.listeners = [];
535
589
  this.clickHandler = null;
536
590
  this.submitHandler = null;
537
591
  this.active = false;
@@ -546,6 +600,27 @@ var AutocaptureModule = class {
546
600
  };
547
601
  this.callback = callback;
548
602
  }
603
+ /**
604
+ * Register a secondary listener that receives the same events as the
605
+ * primary callback (e.g. Watchtower tap capture reusing the single click
606
+ * listener + selector resolution). Returns an unsubscribe function.
607
+ */
608
+ addListener(cb) {
609
+ this.listeners.push(cb);
610
+ return () => {
611
+ const idx = this.listeners.indexOf(cb);
612
+ if (idx >= 0) this.listeners.splice(idx, 1);
613
+ };
614
+ }
615
+ emit(event) {
616
+ this.callback(event);
617
+ for (const listener of this.listeners) {
618
+ try {
619
+ listener(event);
620
+ } catch {
621
+ }
622
+ }
623
+ }
549
624
  start() {
550
625
  if (this.active || typeof document === "undefined" || typeof document.addEventListener !== "function") return;
551
626
  this.active = true;
@@ -578,7 +653,7 @@ var AutocaptureModule = class {
578
653
  properties.$event_type = "click";
579
654
  properties.$x = e.clientX;
580
655
  properties.$y = e.clientY;
581
- this.callback({
656
+ this.emit({
582
657
  type: "click",
583
658
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
584
659
  properties
@@ -600,7 +675,7 @@ var AutocaptureModule = class {
600
675
  };
601
676
  const elemProps = this.getElementProperties(form);
602
677
  Object.assign(properties, elemProps);
603
- this.callback({
678
+ this.emit({
604
679
  type: "form_submit",
605
680
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
606
681
  properties
@@ -817,6 +892,14 @@ var AnalyticsManager = class {
817
892
  );
818
893
  this.autocaptureModule.start();
819
894
  }
895
+ /**
896
+ * The live AutocaptureModule (if click/form autocapture is enabled) —
897
+ * Watchtower tap capture attaches to it so there is only ONE document-level
898
+ * click listener and one selector/element resolution path.
899
+ */
900
+ getAutocaptureModule() {
901
+ return this.autocaptureModule;
902
+ }
820
903
  track(eventName, properties) {
821
904
  if (!this.config.enabled) return;
822
905
  const event = this.createEvent("track", { name: eventName, properties });
@@ -930,7 +1013,9 @@ var AnalyticsManager = class {
930
1013
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
931
1014
  url: typeof window !== "undefined" && window.location ? window.location.href : void 0,
932
1015
  referrer: typeof document !== "undefined" && typeof document.referrer === "string" ? document.referrer : void 0,
933
- userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0
1016
+ userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0,
1017
+ utm: getSessionUtm() || void 0,
1018
+ appVersion: this.config.appVersion || void 0
934
1019
  };
935
1020
  }
936
1021
  enqueue(event) {
@@ -1628,7 +1713,7 @@ var DEFAULT_REMOTE_CONFIG = {
1628
1713
  };
1629
1714
 
1630
1715
  // src/remote-config/manager.ts
1631
- var STORAGE_KEY2 = "sitepong_remote_config";
1716
+ var STORAGE_KEY3 = "sitepong_remote_config";
1632
1717
  var STORAGE_TS_KEY = "sitepong_remote_config_ts";
1633
1718
  var RemoteConfigManager = class {
1634
1719
  constructor(options) {
@@ -1671,7 +1756,7 @@ var RemoteConfigManager = class {
1671
1756
  const storage = this.options.storage;
1672
1757
  if (!storage) return;
1673
1758
  try {
1674
- const cached = await storage.getItem(STORAGE_KEY2);
1759
+ const cached = await storage.getItem(STORAGE_KEY3);
1675
1760
  const cachedTs = await storage.getItem(STORAGE_TS_KEY);
1676
1761
  if (cached && cachedTs) {
1677
1762
  const age = Date.now() - parseInt(cachedTs, 10);
@@ -1732,7 +1817,7 @@ var RemoteConfigManager = class {
1732
1817
  const storage = this.options.storage;
1733
1818
  if (!storage) return;
1734
1819
  try {
1735
- await storage.setItem(STORAGE_KEY2, JSON.stringify(this.config));
1820
+ await storage.setItem(STORAGE_KEY3, JSON.stringify(this.config));
1736
1821
  await storage.setItem(STORAGE_TS_KEY, String(Date.now()));
1737
1822
  } catch {
1738
1823
  this.log("Failed to cache remote config");
@@ -1988,7 +2073,7 @@ function stripTrailingSlash(url) {
1988
2073
  var superlinkClient = new SuperLinkClient();
1989
2074
 
1990
2075
  // src/superlink/parse.ts
1991
- var UTM_KEYS = [
2076
+ var UTM_KEYS2 = [
1992
2077
  ["source", "utm_source"],
1993
2078
  ["medium", "utm_medium"],
1994
2079
  ["campaign", "utm_campaign"],
@@ -2004,7 +2089,7 @@ function parseUniversalLink(url) {
2004
2089
  }
2005
2090
  const params = parsed.searchParams;
2006
2091
  const utm = {};
2007
- for (const [key, queryKey] of UTM_KEYS) {
2092
+ for (const [key, queryKey] of UTM_KEYS2) {
2008
2093
  const value = params.get(queryKey);
2009
2094
  if (value) utm[key] = value;
2010
2095
  }
@@ -2071,13 +2156,13 @@ function getMatchedDeepLink() {
2071
2156
  }
2072
2157
 
2073
2158
  // src/superlink/web.ts
2074
- var STORAGE_KEY3 = "sp_superlink";
2159
+ var STORAGE_KEY4 = "sp_superlink";
2075
2160
  var captured = null;
2076
2161
  var didCapture = false;
2077
- function readStored() {
2162
+ function readStored2() {
2078
2163
  if (typeof sessionStorage === "undefined") return null;
2079
2164
  try {
2080
- const raw = sessionStorage.getItem(STORAGE_KEY3);
2165
+ const raw = sessionStorage.getItem(STORAGE_KEY4);
2081
2166
  if (!raw) return null;
2082
2167
  const parsed = JSON.parse(raw);
2083
2168
  return parsed && typeof parsed === "object" ? parsed : null;
@@ -2085,10 +2170,10 @@ function readStored() {
2085
2170
  return null;
2086
2171
  }
2087
2172
  }
2088
- function writeStored(link) {
2173
+ function writeStored2(link) {
2089
2174
  if (typeof sessionStorage === "undefined") return;
2090
2175
  try {
2091
- sessionStorage.setItem(STORAGE_KEY3, JSON.stringify(link));
2176
+ sessionStorage.setItem(STORAGE_KEY4, JSON.stringify(link));
2092
2177
  } catch {
2093
2178
  }
2094
2179
  }
@@ -2136,7 +2221,7 @@ function extractIdentityMetadata(url) {
2136
2221
  function captureWebDeepLink() {
2137
2222
  if (didCapture) return captured;
2138
2223
  didCapture = true;
2139
- const stored = readStored();
2224
+ const stored = readStored2();
2140
2225
  if (stored) {
2141
2226
  captured = stored;
2142
2227
  return captured;
@@ -2145,7 +2230,7 @@ function captureWebDeepLink() {
2145
2230
  const link = parseUniversalLink(window.location.href);
2146
2231
  if (link && hasPayload(link)) {
2147
2232
  captured = link;
2148
- writeStored(link);
2233
+ writeStored2(link);
2149
2234
  void superlinkClient.reportEvent({
2150
2235
  type: "opened",
2151
2236
  click_id: link.click_id,
@@ -2326,6 +2411,8 @@ var SitePongClient = class {
2326
2411
  this.databaseTracker = null;
2327
2412
  this.profiler = null;
2328
2413
  this.remoteConfigManager = null;
2414
+ this.watchtowerCapture = null;
2415
+ this.watchtowerOptions = void 0;
2329
2416
  this.envUnsubs = [];
2330
2417
  this.identifyHooks = [];
2331
2418
  this.config = {
@@ -2445,6 +2532,12 @@ var SitePongClient = class {
2445
2532
  } else if (config.replay?.enabled) {
2446
2533
  this.log("Replay requested but not available on this platform (web only).");
2447
2534
  }
2535
+ this.watchtowerOptions = config.watchtower;
2536
+ if (config.watchtower?.enabled && webManagerFactories.createWatchtowerCapture) {
2537
+ this.startWatchtowerCapture();
2538
+ } else if (config.watchtower?.enabled) {
2539
+ this.log("Watchtower capture requested but not available on this platform (web only).");
2540
+ }
2448
2541
  if (config.crons?.enabled) {
2449
2542
  this.cronManager = new CronMonitorManager({
2450
2543
  apiKey: config.apiKey,
@@ -2684,6 +2777,7 @@ var SitePongClient = class {
2684
2777
  this.log("identify hook failed:", err);
2685
2778
  }
2686
2779
  }
2780
+ this.watchtowerCapture?.setDistinctId(userId);
2687
2781
  if (!this.analyticsManager) {
2688
2782
  this.log("Analytics not enabled. Set analytics.enabled: true in init()");
2689
2783
  return;
@@ -2751,6 +2845,49 @@ var SitePongClient = class {
2751
2845
  getReplaySessionId() {
2752
2846
  return this.replayManager?.getSessionId() ?? null;
2753
2847
  }
2848
+ // --- Watchtower tap capture (web) ---
2849
+ /**
2850
+ * Start Watchtower web tap capture. Options merge over `watchtower` from
2851
+ * init(); `projectId` is required (either here or in init config). Reuses
2852
+ * the analytics AutocaptureModule's click listener when autocapture is on.
2853
+ */
2854
+ startWatchtowerCapture(options) {
2855
+ if (!webManagerFactories.createWatchtowerCapture) {
2856
+ this.log("Watchtower capture not available on this platform (web only).");
2857
+ return false;
2858
+ }
2859
+ if (!this.initialized || !this.config.apiKey) {
2860
+ this.log("Watchtower capture requires init() to be called first.");
2861
+ return false;
2862
+ }
2863
+ const opts = { ...this.watchtowerOptions, ...options };
2864
+ if (!opts.projectId) {
2865
+ this.log("Watchtower capture requires watchtower.projectId.");
2866
+ return false;
2867
+ }
2868
+ if (this.watchtowerCapture) {
2869
+ this.watchtowerCapture.stop();
2870
+ this.watchtowerCapture = null;
2871
+ }
2872
+ this.watchtowerCapture = webManagerFactories.createWatchtowerCapture({
2873
+ apiKey: this.config.apiKey,
2874
+ projectId: opts.projectId,
2875
+ endpoint: opts.endpoint || this.config.endpoint || DEFAULT_ENDPOINT3,
2876
+ appVersion: this.config.release || void 0,
2877
+ maxBatchSize: opts.maxBatchSize,
2878
+ flushInterval: opts.flushInterval,
2879
+ blockSelector: opts.blockSelector,
2880
+ maskSelector: opts.maskSelector,
2881
+ debug: this.config.debug
2882
+ });
2883
+ this.watchtowerCapture.start(this.analyticsManager?.getAutocaptureModule() ?? null);
2884
+ return true;
2885
+ }
2886
+ stopWatchtowerCapture() {
2887
+ if (!this.watchtowerCapture) return;
2888
+ this.watchtowerCapture.stop();
2889
+ this.watchtowerCapture = null;
2890
+ }
2754
2891
  // --- Performance (Tier 7) ---
2755
2892
  startTransaction(name, data) {
2756
2893
  if (!this.performanceManager) {
@@ -2902,6 +3039,7 @@ var SitePongClient = class {
2902
3039
  if (this.replayManager) {
2903
3040
  this.replayManager.setUser(null);
2904
3041
  }
3042
+ this.watchtowerCapture?.setDistinctId(null);
2905
3043
  }
2906
3044
  addBreadcrumb(breadcrumb) {
2907
3045
  this.log("Breadcrumb added:", breadcrumb);
@@ -3126,6 +3264,8 @@ var getDeviceSignals = sitepong.getDeviceSignals.bind(sitepong);
3126
3264
  var getFraudCheck = sitepong.getFraudCheck.bind(sitepong);
3127
3265
  var startReplay = sitepong.startReplay.bind(sitepong);
3128
3266
  var stopReplay = sitepong.stopReplay.bind(sitepong);
3267
+ var startWatchtowerCapture = sitepong.startWatchtowerCapture.bind(sitepong);
3268
+ var stopWatchtowerCapture = sitepong.stopWatchtowerCapture.bind(sitepong);
3129
3269
  var isReplayRecording = sitepong.isReplayRecording.bind(sitepong);
3130
3270
  var getReplaySessionId = sitepong.getReplaySessionId.bind(sitepong);
3131
3271
  var startTransaction = sitepong.startTransaction.bind(sitepong);
@@ -3608,7 +3748,9 @@ exports.startProfileSpan = startProfileSpan;
3608
3748
  exports.startReplay = startReplay;
3609
3749
  exports.startSpan = startSpan;
3610
3750
  exports.startTransaction = startTransaction;
3751
+ exports.startWatchtowerCapture = startWatchtowerCapture;
3611
3752
  exports.stopReplay = stopReplay;
3753
+ exports.stopWatchtowerCapture = stopWatchtowerCapture;
3612
3754
  exports.superlinkClient = superlinkClient;
3613
3755
  exports.superlinkIdentify = identify;
3614
3756
  exports.track = track;