sitepong 0.2.1 → 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.
- package/dist/cdn/sitepong.min.js +5 -5
- package/dist/cdn/sitepong.min.js.map +1 -1
- package/dist/entries/rn.d.ts +995 -0
- package/dist/entries/rn.js +178 -23
- package/dist/entries/rn.js.map +1 -1
- package/dist/entries/web.d.mts +1 -1
- package/dist/entries/web.d.ts +1 -1
- package/dist/entries/web.js +1916 -1113
- package/dist/entries/web.js.map +1 -1
- package/dist/entries/web.mjs +1915 -1114
- package/dist/entries/web.mjs.map +1 -1
- package/dist/index.d.mts +160 -1
- package/dist/index.d.ts +160 -1
- package/dist/index.js +89 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +88 -5
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +89 -3
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +88 -4
- package/dist/react/index.mjs.map +1 -1
- package/package.json +8 -3
package/dist/index.d.mts
CHANGED
|
@@ -157,6 +157,137 @@ declare global {
|
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
interface AutocaptureEvent {
|
|
161
|
+
type: 'click' | 'form_submit' | 'page_view';
|
|
162
|
+
timestamp: string;
|
|
163
|
+
properties: Record<string, unknown>;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Watchtower Web Tap Capture (Phase P3)
|
|
168
|
+
*
|
|
169
|
+
* Captures tap/screen_view/session lifecycle events per the Watchtower wire
|
|
170
|
+
* contract (docs/watchtower-mobile-spec.md §1) and uploads masked screen
|
|
171
|
+
* templates on fingerprint miss (§1.2).
|
|
172
|
+
*
|
|
173
|
+
* - Tap events come from the EXISTING autocapture click path (no duplicate
|
|
174
|
+
* listeners) — the AutocaptureModule's selector/element resolution is reused.
|
|
175
|
+
* - Screen fingerprints are dHash'd (via @sitepong/capture-core, the reference
|
|
176
|
+
* implementation) over a masked rasterization of the page. Rasterization is
|
|
177
|
+
* done with the SVG-foreignObject trick over the replay serializer's masked
|
|
178
|
+
* structural snapshot, always off the hot path (idle callbacks, throttled).
|
|
179
|
+
* - The click handler itself only records + enqueues; batching is 50 events /
|
|
180
|
+
* 10 s / pagehide. Rage classification is server-side — never sent here.
|
|
181
|
+
*/
|
|
182
|
+
|
|
183
|
+
/** Result of rasterizing the (already masked) page. */
|
|
184
|
+
interface RasterResult {
|
|
185
|
+
/** Tightly packed RGBA bytes, width*height*4. */
|
|
186
|
+
rgba: Uint8Array;
|
|
187
|
+
width: number;
|
|
188
|
+
height: number;
|
|
189
|
+
/** Base64 PNG of the same masked canvas, or null when encoding failed. */
|
|
190
|
+
pngBase64: string | null;
|
|
191
|
+
}
|
|
192
|
+
interface PageRasterizer {
|
|
193
|
+
/** Resolve null (never throw) when the page cannot be rasterized. */
|
|
194
|
+
rasterize(): Promise<RasterResult | null>;
|
|
195
|
+
}
|
|
196
|
+
interface TransportResponse {
|
|
197
|
+
ok: boolean;
|
|
198
|
+
status: number;
|
|
199
|
+
}
|
|
200
|
+
type TapTransport = (url: string, body: string, opts: {
|
|
201
|
+
headers: Record<string, string>;
|
|
202
|
+
keepalive?: boolean;
|
|
203
|
+
}) => Promise<TransportResponse>;
|
|
204
|
+
/** Anything exposing the AutocaptureModule secondary-listener API. */
|
|
205
|
+
interface AutocaptureSource {
|
|
206
|
+
addListener(cb: (event: AutocaptureEvent) => void): () => void;
|
|
207
|
+
}
|
|
208
|
+
interface WatchtowerCaptureConfig {
|
|
209
|
+
apiKey: string;
|
|
210
|
+
projectId: string;
|
|
211
|
+
/** Base endpoint — events go to `${endpoint}/api/taps`, templates to `${endpoint}/api/taps/template`. */
|
|
212
|
+
endpoint: string;
|
|
213
|
+
appVersion?: string;
|
|
214
|
+
/** Flush when the queue reaches this size (spec §1.3, default 50). */
|
|
215
|
+
maxBatchSize?: number;
|
|
216
|
+
/** Flush interval in ms (spec §1.3, default 10000). */
|
|
217
|
+
flushInterval?: number;
|
|
218
|
+
/** Min ms between rasterizations of the same route (default 1000). */
|
|
219
|
+
templateThrottleMs?: number;
|
|
220
|
+
/** Extra CSS selector blocked (greyed out) in the masked snapshot. */
|
|
221
|
+
blockSelector?: string;
|
|
222
|
+
/** CSS selector whose text is masked in the snapshot. */
|
|
223
|
+
maskSelector?: string;
|
|
224
|
+
debug?: boolean;
|
|
225
|
+
/** Injectable rasterizer (tests). Defaults to the DOM SVG-foreignObject rasterizer. */
|
|
226
|
+
rasterizer?: PageRasterizer;
|
|
227
|
+
/** Injectable transport (tests). Defaults to fetch. */
|
|
228
|
+
transport?: TapTransport;
|
|
229
|
+
}
|
|
230
|
+
declare class WatchtowerWebCapture {
|
|
231
|
+
private config;
|
|
232
|
+
private session;
|
|
233
|
+
private queue;
|
|
234
|
+
private flushTimer;
|
|
235
|
+
private flushFailures;
|
|
236
|
+
private disabled;
|
|
237
|
+
private active;
|
|
238
|
+
private distinctId;
|
|
239
|
+
private currentScreen;
|
|
240
|
+
private transport;
|
|
241
|
+
private rasterizer;
|
|
242
|
+
private detachAutocapture;
|
|
243
|
+
private ownAutocapture;
|
|
244
|
+
private originalPushState;
|
|
245
|
+
private originalReplaceState;
|
|
246
|
+
private popstateHandler;
|
|
247
|
+
private pagehideHandler;
|
|
248
|
+
private fpCache;
|
|
249
|
+
private uploadedFps;
|
|
250
|
+
private lastRasterAt;
|
|
251
|
+
private rasterInFlight;
|
|
252
|
+
constructor(config: WatchtowerCaptureConfig);
|
|
253
|
+
/**
|
|
254
|
+
* Start capturing. Pass the existing AutocaptureModule (via
|
|
255
|
+
* AnalyticsManager.getAutocaptureModule()) to reuse its click listener +
|
|
256
|
+
* selector resolution; when absent, a private clicks-only module is created.
|
|
257
|
+
*/
|
|
258
|
+
start(source?: AutocaptureSource | null): void;
|
|
259
|
+
stop(): void;
|
|
260
|
+
isActive(): boolean;
|
|
261
|
+
getSessionId(): string;
|
|
262
|
+
/** Stamped as distinct_id on every subsequent event (identify() feeds this). */
|
|
263
|
+
setDistinctId(distinctId: string | null): void;
|
|
264
|
+
private onAutocaptureEvent;
|
|
265
|
+
/** Record a tap. Coordinates are viewport CSS px; normalization happens here. */
|
|
266
|
+
recordTap(input: {
|
|
267
|
+
selector: string;
|
|
268
|
+
label?: string;
|
|
269
|
+
role?: string;
|
|
270
|
+
clientX: number;
|
|
271
|
+
clientY: number;
|
|
272
|
+
}): void;
|
|
273
|
+
private setupNavigationTracking;
|
|
274
|
+
private handleRouteChange;
|
|
275
|
+
private setupPagehide;
|
|
276
|
+
private baseEvent;
|
|
277
|
+
private enqueue;
|
|
278
|
+
private startFlushTimer;
|
|
279
|
+
flush(opts?: {
|
|
280
|
+
keepalive?: boolean;
|
|
281
|
+
}): Promise<void>;
|
|
282
|
+
private headers;
|
|
283
|
+
private scheduleFingerprint;
|
|
284
|
+
private captureFingerprint;
|
|
285
|
+
private maybeUploadTemplate;
|
|
286
|
+
private combinedBlockSelector;
|
|
287
|
+
private pathname;
|
|
288
|
+
private log;
|
|
289
|
+
}
|
|
290
|
+
|
|
160
291
|
declare class ReplayManager {
|
|
161
292
|
private config;
|
|
162
293
|
private recording;
|
|
@@ -999,6 +1130,7 @@ interface WebManagerFactories {
|
|
|
999
1130
|
createReplay?: (cfg: Record<string, unknown>) => ReplayManager;
|
|
1000
1131
|
createFingerprint?: (cfg: Record<string, unknown>) => FingerprintManager;
|
|
1001
1132
|
createPerformance?: (cfg: Record<string, unknown>) => PerformanceManager;
|
|
1133
|
+
createWatchtowerCapture?: (cfg: Record<string, unknown>) => WatchtowerWebCapture;
|
|
1002
1134
|
}
|
|
1003
1135
|
/**
|
|
1004
1136
|
* Platform-entry-only: inject web-only manager factories. Called by
|
|
@@ -1069,6 +1201,22 @@ interface SitePongInitConfig extends SitePongConfig {
|
|
|
1069
1201
|
/** Rolling buffer duration in ms — how many seconds of replay to keep before an error (default: 20000) */
|
|
1070
1202
|
bufferDuration?: number;
|
|
1071
1203
|
};
|
|
1204
|
+
/** Watchtower tap capture (web) — tap timeline events + masked screen templates */
|
|
1205
|
+
watchtower?: {
|
|
1206
|
+
enabled?: boolean;
|
|
1207
|
+
/** Project ID sent as X-Project-ID on /api/taps requests (required) */
|
|
1208
|
+
projectId?: string;
|
|
1209
|
+
/** Override base endpoint for /api/taps + /api/taps/template (default: main endpoint) */
|
|
1210
|
+
endpoint?: string;
|
|
1211
|
+
/** Flush at this many buffered events (default: 50) */
|
|
1212
|
+
maxBatchSize?: number;
|
|
1213
|
+
/** Flush interval in ms (default: 10000) */
|
|
1214
|
+
flushInterval?: number;
|
|
1215
|
+
/** Extra CSS selector blocked out of the masked screen template */
|
|
1216
|
+
blockSelector?: string;
|
|
1217
|
+
/** CSS selector whose text is masked in the screen template */
|
|
1218
|
+
maskSelector?: string;
|
|
1219
|
+
};
|
|
1072
1220
|
/** Cron monitoring configuration */
|
|
1073
1221
|
crons?: {
|
|
1074
1222
|
enabled?: boolean;
|
|
@@ -1117,6 +1265,8 @@ declare class SitePongClient {
|
|
|
1117
1265
|
private databaseTracker;
|
|
1118
1266
|
private profiler;
|
|
1119
1267
|
private remoteConfigManager;
|
|
1268
|
+
private watchtowerCapture;
|
|
1269
|
+
private watchtowerOptions;
|
|
1120
1270
|
private currentScreen?;
|
|
1121
1271
|
private envUnsubs;
|
|
1122
1272
|
private identifyHooks;
|
|
@@ -1179,6 +1329,13 @@ declare class SitePongClient {
|
|
|
1179
1329
|
stopReplay(): void;
|
|
1180
1330
|
isReplayRecording(): boolean;
|
|
1181
1331
|
getReplaySessionId(): string | null;
|
|
1332
|
+
/**
|
|
1333
|
+
* Start Watchtower web tap capture. Options merge over `watchtower` from
|
|
1334
|
+
* init(); `projectId` is required (either here or in init config). Reuses
|
|
1335
|
+
* the analytics AutocaptureModule's click listener when autocapture is on.
|
|
1336
|
+
*/
|
|
1337
|
+
startWatchtowerCapture(options?: SitePongInitConfig['watchtower']): boolean;
|
|
1338
|
+
stopWatchtowerCapture(): void;
|
|
1182
1339
|
startTransaction(name: string, data?: Record<string, unknown>): string;
|
|
1183
1340
|
endTransaction(id: string, status?: 'ok' | 'error'): void;
|
|
1184
1341
|
startSpan(transactionId: string, name: string, data?: Record<string, unknown>): string;
|
|
@@ -1279,6 +1436,8 @@ declare const getDeviceSignals: () => Promise<DeviceSignals>;
|
|
|
1279
1436
|
declare const getFraudCheck: () => Promise<FraudCheckResult>;
|
|
1280
1437
|
declare const startReplay: () => boolean;
|
|
1281
1438
|
declare const stopReplay: () => void;
|
|
1439
|
+
declare const startWatchtowerCapture: (options?: SitePongInitConfig["watchtower"]) => boolean;
|
|
1440
|
+
declare const stopWatchtowerCapture: () => void;
|
|
1282
1441
|
declare const isReplayRecording: () => boolean;
|
|
1283
1442
|
declare const getReplaySessionId: () => string | null;
|
|
1284
1443
|
declare const startTransaction: (name: string, data?: Record<string, unknown>) => string;
|
|
@@ -1316,4 +1475,4 @@ declare const isRemoteConfigFeatureEnabled: (key: string, defaultValue?: boolean
|
|
|
1316
1475
|
declare const onRemoteConfigChange: (listener: (config: RemoteConfig) => void) => () => void;
|
|
1317
1476
|
declare const registerIdentifyHook: (hook: (userId: string) => void) => () => void;
|
|
1318
1477
|
|
|
1319
|
-
export { type CapturedError, type CronCheckinOptions, type CronHandle, DEFAULT_SUPERLINK_ENDPOINT, type DatabaseQueryEvent, type DatabaseTrackerConfig, type DeferredDeepLinkHandler, type DeviceInfo, type DeviceSignals, type EnvironmentAdapter, type ErrorContext, type FraudCheckResult, GroupTraits, type MetricOptions, type MutableRNEnvironmentAdapter, type PerformanceConfig, type PerformanceSpan, type PerformanceTransaction, type PlatformName, type ProfileData, type ProfileFrame, type ProfilerConfig, type RemoteConfig, type RemoteConfigFeatures, type RemoteConfigSampling, ReplayConfig, type ResourceTimingBreakdown, type SitePongConfig, type SitePongInitConfig, SuperLinkClient, type SuperLinkConfig, type SuperLinkDeepLink, type SuperLinkEventType, type SuperLinkFingerprint, type SuperLinkIdentityMetadata, type SuperLinkMatchRequest, type SuperLinkMatchResponse, type SuperLinkMatchType, type SuperLinkPlatform, type TraceContext, TracePropagator, TrackProperties, UserTraits, type VisitorIdResult, type WebManagerFactories, type WebVitals, addBreadcrumb, areFlagsReady, captureError, captureMessage, captureWebDeepLink, clearAnonymousId, clearUser, sitepong as client, completeFromScan, createTraceContext, cronCheckin, cronStart, cronWrap, dbTrack, dbTrackSync, sitepong as default, 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, identify$1 as superlinkIdentify, track, trackPageView, waitForFlags, writeClipboardToken };
|
|
1478
|
+
export { type CapturedError, type CronCheckinOptions, type CronHandle, DEFAULT_SUPERLINK_ENDPOINT, type DatabaseQueryEvent, type DatabaseTrackerConfig, type DeferredDeepLinkHandler, type DeviceInfo, type DeviceSignals, type EnvironmentAdapter, type ErrorContext, type FraudCheckResult, GroupTraits, type MetricOptions, type MutableRNEnvironmentAdapter, type PerformanceConfig, type PerformanceSpan, type PerformanceTransaction, type PlatformName, type ProfileData, type ProfileFrame, type ProfilerConfig, type RemoteConfig, type RemoteConfigFeatures, type RemoteConfigSampling, ReplayConfig, type ResourceTimingBreakdown, type SitePongConfig, type SitePongInitConfig, SuperLinkClient, type SuperLinkConfig, type SuperLinkDeepLink, type SuperLinkEventType, type SuperLinkFingerprint, type SuperLinkIdentityMetadata, type SuperLinkMatchRequest, type SuperLinkMatchResponse, type SuperLinkMatchType, type SuperLinkPlatform, type TraceContext, TracePropagator, TrackProperties, UserTraits, type VisitorIdResult, type WebManagerFactories, type WebVitals, addBreadcrumb, areFlagsReady, captureError, captureMessage, captureWebDeepLink, clearAnonymousId, clearUser, sitepong as client, completeFromScan, createTraceContext, cronCheckin, cronStart, cronWrap, dbTrack, dbTrackSync, sitepong as default, 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, identify$1 as superlinkIdentify, track, trackPageView, waitForFlags, writeClipboardToken };
|
package/dist/index.d.ts
CHANGED
|
@@ -157,6 +157,137 @@ declare global {
|
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
interface AutocaptureEvent {
|
|
161
|
+
type: 'click' | 'form_submit' | 'page_view';
|
|
162
|
+
timestamp: string;
|
|
163
|
+
properties: Record<string, unknown>;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Watchtower Web Tap Capture (Phase P3)
|
|
168
|
+
*
|
|
169
|
+
* Captures tap/screen_view/session lifecycle events per the Watchtower wire
|
|
170
|
+
* contract (docs/watchtower-mobile-spec.md §1) and uploads masked screen
|
|
171
|
+
* templates on fingerprint miss (§1.2).
|
|
172
|
+
*
|
|
173
|
+
* - Tap events come from the EXISTING autocapture click path (no duplicate
|
|
174
|
+
* listeners) — the AutocaptureModule's selector/element resolution is reused.
|
|
175
|
+
* - Screen fingerprints are dHash'd (via @sitepong/capture-core, the reference
|
|
176
|
+
* implementation) over a masked rasterization of the page. Rasterization is
|
|
177
|
+
* done with the SVG-foreignObject trick over the replay serializer's masked
|
|
178
|
+
* structural snapshot, always off the hot path (idle callbacks, throttled).
|
|
179
|
+
* - The click handler itself only records + enqueues; batching is 50 events /
|
|
180
|
+
* 10 s / pagehide. Rage classification is server-side — never sent here.
|
|
181
|
+
*/
|
|
182
|
+
|
|
183
|
+
/** Result of rasterizing the (already masked) page. */
|
|
184
|
+
interface RasterResult {
|
|
185
|
+
/** Tightly packed RGBA bytes, width*height*4. */
|
|
186
|
+
rgba: Uint8Array;
|
|
187
|
+
width: number;
|
|
188
|
+
height: number;
|
|
189
|
+
/** Base64 PNG of the same masked canvas, or null when encoding failed. */
|
|
190
|
+
pngBase64: string | null;
|
|
191
|
+
}
|
|
192
|
+
interface PageRasterizer {
|
|
193
|
+
/** Resolve null (never throw) when the page cannot be rasterized. */
|
|
194
|
+
rasterize(): Promise<RasterResult | null>;
|
|
195
|
+
}
|
|
196
|
+
interface TransportResponse {
|
|
197
|
+
ok: boolean;
|
|
198
|
+
status: number;
|
|
199
|
+
}
|
|
200
|
+
type TapTransport = (url: string, body: string, opts: {
|
|
201
|
+
headers: Record<string, string>;
|
|
202
|
+
keepalive?: boolean;
|
|
203
|
+
}) => Promise<TransportResponse>;
|
|
204
|
+
/** Anything exposing the AutocaptureModule secondary-listener API. */
|
|
205
|
+
interface AutocaptureSource {
|
|
206
|
+
addListener(cb: (event: AutocaptureEvent) => void): () => void;
|
|
207
|
+
}
|
|
208
|
+
interface WatchtowerCaptureConfig {
|
|
209
|
+
apiKey: string;
|
|
210
|
+
projectId: string;
|
|
211
|
+
/** Base endpoint — events go to `${endpoint}/api/taps`, templates to `${endpoint}/api/taps/template`. */
|
|
212
|
+
endpoint: string;
|
|
213
|
+
appVersion?: string;
|
|
214
|
+
/** Flush when the queue reaches this size (spec §1.3, default 50). */
|
|
215
|
+
maxBatchSize?: number;
|
|
216
|
+
/** Flush interval in ms (spec §1.3, default 10000). */
|
|
217
|
+
flushInterval?: number;
|
|
218
|
+
/** Min ms between rasterizations of the same route (default 1000). */
|
|
219
|
+
templateThrottleMs?: number;
|
|
220
|
+
/** Extra CSS selector blocked (greyed out) in the masked snapshot. */
|
|
221
|
+
blockSelector?: string;
|
|
222
|
+
/** CSS selector whose text is masked in the snapshot. */
|
|
223
|
+
maskSelector?: string;
|
|
224
|
+
debug?: boolean;
|
|
225
|
+
/** Injectable rasterizer (tests). Defaults to the DOM SVG-foreignObject rasterizer. */
|
|
226
|
+
rasterizer?: PageRasterizer;
|
|
227
|
+
/** Injectable transport (tests). Defaults to fetch. */
|
|
228
|
+
transport?: TapTransport;
|
|
229
|
+
}
|
|
230
|
+
declare class WatchtowerWebCapture {
|
|
231
|
+
private config;
|
|
232
|
+
private session;
|
|
233
|
+
private queue;
|
|
234
|
+
private flushTimer;
|
|
235
|
+
private flushFailures;
|
|
236
|
+
private disabled;
|
|
237
|
+
private active;
|
|
238
|
+
private distinctId;
|
|
239
|
+
private currentScreen;
|
|
240
|
+
private transport;
|
|
241
|
+
private rasterizer;
|
|
242
|
+
private detachAutocapture;
|
|
243
|
+
private ownAutocapture;
|
|
244
|
+
private originalPushState;
|
|
245
|
+
private originalReplaceState;
|
|
246
|
+
private popstateHandler;
|
|
247
|
+
private pagehideHandler;
|
|
248
|
+
private fpCache;
|
|
249
|
+
private uploadedFps;
|
|
250
|
+
private lastRasterAt;
|
|
251
|
+
private rasterInFlight;
|
|
252
|
+
constructor(config: WatchtowerCaptureConfig);
|
|
253
|
+
/**
|
|
254
|
+
* Start capturing. Pass the existing AutocaptureModule (via
|
|
255
|
+
* AnalyticsManager.getAutocaptureModule()) to reuse its click listener +
|
|
256
|
+
* selector resolution; when absent, a private clicks-only module is created.
|
|
257
|
+
*/
|
|
258
|
+
start(source?: AutocaptureSource | null): void;
|
|
259
|
+
stop(): void;
|
|
260
|
+
isActive(): boolean;
|
|
261
|
+
getSessionId(): string;
|
|
262
|
+
/** Stamped as distinct_id on every subsequent event (identify() feeds this). */
|
|
263
|
+
setDistinctId(distinctId: string | null): void;
|
|
264
|
+
private onAutocaptureEvent;
|
|
265
|
+
/** Record a tap. Coordinates are viewport CSS px; normalization happens here. */
|
|
266
|
+
recordTap(input: {
|
|
267
|
+
selector: string;
|
|
268
|
+
label?: string;
|
|
269
|
+
role?: string;
|
|
270
|
+
clientX: number;
|
|
271
|
+
clientY: number;
|
|
272
|
+
}): void;
|
|
273
|
+
private setupNavigationTracking;
|
|
274
|
+
private handleRouteChange;
|
|
275
|
+
private setupPagehide;
|
|
276
|
+
private baseEvent;
|
|
277
|
+
private enqueue;
|
|
278
|
+
private startFlushTimer;
|
|
279
|
+
flush(opts?: {
|
|
280
|
+
keepalive?: boolean;
|
|
281
|
+
}): Promise<void>;
|
|
282
|
+
private headers;
|
|
283
|
+
private scheduleFingerprint;
|
|
284
|
+
private captureFingerprint;
|
|
285
|
+
private maybeUploadTemplate;
|
|
286
|
+
private combinedBlockSelector;
|
|
287
|
+
private pathname;
|
|
288
|
+
private log;
|
|
289
|
+
}
|
|
290
|
+
|
|
160
291
|
declare class ReplayManager {
|
|
161
292
|
private config;
|
|
162
293
|
private recording;
|
|
@@ -999,6 +1130,7 @@ interface WebManagerFactories {
|
|
|
999
1130
|
createReplay?: (cfg: Record<string, unknown>) => ReplayManager;
|
|
1000
1131
|
createFingerprint?: (cfg: Record<string, unknown>) => FingerprintManager;
|
|
1001
1132
|
createPerformance?: (cfg: Record<string, unknown>) => PerformanceManager;
|
|
1133
|
+
createWatchtowerCapture?: (cfg: Record<string, unknown>) => WatchtowerWebCapture;
|
|
1002
1134
|
}
|
|
1003
1135
|
/**
|
|
1004
1136
|
* Platform-entry-only: inject web-only manager factories. Called by
|
|
@@ -1069,6 +1201,22 @@ interface SitePongInitConfig extends SitePongConfig {
|
|
|
1069
1201
|
/** Rolling buffer duration in ms — how many seconds of replay to keep before an error (default: 20000) */
|
|
1070
1202
|
bufferDuration?: number;
|
|
1071
1203
|
};
|
|
1204
|
+
/** Watchtower tap capture (web) — tap timeline events + masked screen templates */
|
|
1205
|
+
watchtower?: {
|
|
1206
|
+
enabled?: boolean;
|
|
1207
|
+
/** Project ID sent as X-Project-ID on /api/taps requests (required) */
|
|
1208
|
+
projectId?: string;
|
|
1209
|
+
/** Override base endpoint for /api/taps + /api/taps/template (default: main endpoint) */
|
|
1210
|
+
endpoint?: string;
|
|
1211
|
+
/** Flush at this many buffered events (default: 50) */
|
|
1212
|
+
maxBatchSize?: number;
|
|
1213
|
+
/** Flush interval in ms (default: 10000) */
|
|
1214
|
+
flushInterval?: number;
|
|
1215
|
+
/** Extra CSS selector blocked out of the masked screen template */
|
|
1216
|
+
blockSelector?: string;
|
|
1217
|
+
/** CSS selector whose text is masked in the screen template */
|
|
1218
|
+
maskSelector?: string;
|
|
1219
|
+
};
|
|
1072
1220
|
/** Cron monitoring configuration */
|
|
1073
1221
|
crons?: {
|
|
1074
1222
|
enabled?: boolean;
|
|
@@ -1117,6 +1265,8 @@ declare class SitePongClient {
|
|
|
1117
1265
|
private databaseTracker;
|
|
1118
1266
|
private profiler;
|
|
1119
1267
|
private remoteConfigManager;
|
|
1268
|
+
private watchtowerCapture;
|
|
1269
|
+
private watchtowerOptions;
|
|
1120
1270
|
private currentScreen?;
|
|
1121
1271
|
private envUnsubs;
|
|
1122
1272
|
private identifyHooks;
|
|
@@ -1179,6 +1329,13 @@ declare class SitePongClient {
|
|
|
1179
1329
|
stopReplay(): void;
|
|
1180
1330
|
isReplayRecording(): boolean;
|
|
1181
1331
|
getReplaySessionId(): string | null;
|
|
1332
|
+
/**
|
|
1333
|
+
* Start Watchtower web tap capture. Options merge over `watchtower` from
|
|
1334
|
+
* init(); `projectId` is required (either here or in init config). Reuses
|
|
1335
|
+
* the analytics AutocaptureModule's click listener when autocapture is on.
|
|
1336
|
+
*/
|
|
1337
|
+
startWatchtowerCapture(options?: SitePongInitConfig['watchtower']): boolean;
|
|
1338
|
+
stopWatchtowerCapture(): void;
|
|
1182
1339
|
startTransaction(name: string, data?: Record<string, unknown>): string;
|
|
1183
1340
|
endTransaction(id: string, status?: 'ok' | 'error'): void;
|
|
1184
1341
|
startSpan(transactionId: string, name: string, data?: Record<string, unknown>): string;
|
|
@@ -1279,6 +1436,8 @@ declare const getDeviceSignals: () => Promise<DeviceSignals>;
|
|
|
1279
1436
|
declare const getFraudCheck: () => Promise<FraudCheckResult>;
|
|
1280
1437
|
declare const startReplay: () => boolean;
|
|
1281
1438
|
declare const stopReplay: () => void;
|
|
1439
|
+
declare const startWatchtowerCapture: (options?: SitePongInitConfig["watchtower"]) => boolean;
|
|
1440
|
+
declare const stopWatchtowerCapture: () => void;
|
|
1282
1441
|
declare const isReplayRecording: () => boolean;
|
|
1283
1442
|
declare const getReplaySessionId: () => string | null;
|
|
1284
1443
|
declare const startTransaction: (name: string, data?: Record<string, unknown>) => string;
|
|
@@ -1316,4 +1475,4 @@ declare const isRemoteConfigFeatureEnabled: (key: string, defaultValue?: boolean
|
|
|
1316
1475
|
declare const onRemoteConfigChange: (listener: (config: RemoteConfig) => void) => () => void;
|
|
1317
1476
|
declare const registerIdentifyHook: (hook: (userId: string) => void) => () => void;
|
|
1318
1477
|
|
|
1319
|
-
export { type CapturedError, type CronCheckinOptions, type CronHandle, DEFAULT_SUPERLINK_ENDPOINT, type DatabaseQueryEvent, type DatabaseTrackerConfig, type DeferredDeepLinkHandler, type DeviceInfo, type DeviceSignals, type EnvironmentAdapter, type ErrorContext, type FraudCheckResult, GroupTraits, type MetricOptions, type MutableRNEnvironmentAdapter, type PerformanceConfig, type PerformanceSpan, type PerformanceTransaction, type PlatformName, type ProfileData, type ProfileFrame, type ProfilerConfig, type RemoteConfig, type RemoteConfigFeatures, type RemoteConfigSampling, ReplayConfig, type ResourceTimingBreakdown, type SitePongConfig, type SitePongInitConfig, SuperLinkClient, type SuperLinkConfig, type SuperLinkDeepLink, type SuperLinkEventType, type SuperLinkFingerprint, type SuperLinkIdentityMetadata, type SuperLinkMatchRequest, type SuperLinkMatchResponse, type SuperLinkMatchType, type SuperLinkPlatform, type TraceContext, TracePropagator, TrackProperties, UserTraits, type VisitorIdResult, type WebManagerFactories, type WebVitals, addBreadcrumb, areFlagsReady, captureError, captureMessage, captureWebDeepLink, clearAnonymousId, clearUser, sitepong as client, completeFromScan, createTraceContext, cronCheckin, cronStart, cronWrap, dbTrack, dbTrackSync, sitepong as default, 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, identify$1 as superlinkIdentify, track, trackPageView, waitForFlags, writeClipboardToken };
|
|
1478
|
+
export { type CapturedError, type CronCheckinOptions, type CronHandle, DEFAULT_SUPERLINK_ENDPOINT, type DatabaseQueryEvent, type DatabaseTrackerConfig, type DeferredDeepLinkHandler, type DeviceInfo, type DeviceSignals, type EnvironmentAdapter, type ErrorContext, type FraudCheckResult, GroupTraits, type MetricOptions, type MutableRNEnvironmentAdapter, type PerformanceConfig, type PerformanceSpan, type PerformanceTransaction, type PlatformName, type ProfileData, type ProfileFrame, type ProfilerConfig, type RemoteConfig, type RemoteConfigFeatures, type RemoteConfigSampling, ReplayConfig, type ResourceTimingBreakdown, type SitePongConfig, type SitePongInitConfig, SuperLinkClient, type SuperLinkConfig, type SuperLinkDeepLink, type SuperLinkEventType, type SuperLinkFingerprint, type SuperLinkIdentityMetadata, type SuperLinkMatchRequest, type SuperLinkMatchResponse, type SuperLinkMatchType, type SuperLinkPlatform, type TraceContext, TracePropagator, TrackProperties, UserTraits, type VisitorIdResult, type WebManagerFactories, type WebVitals, addBreadcrumb, areFlagsReady, captureError, captureMessage, captureWebDeepLink, clearAnonymousId, clearUser, sitepong as client, completeFromScan, createTraceContext, cronCheckin, cronStart, cronWrap, dbTrack, dbTrackSync, sitepong as default, 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, identify$1 as superlinkIdentify, track, trackPageView, waitForFlags, writeClipboardToken };
|
package/dist/index.js
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
require('web-vitals');
|
|
6
|
-
|
|
7
5
|
// src/flags/anonymous-id.ts
|
|
8
6
|
var STORAGE_KEY = "sitepong_anonymous_id";
|
|
9
7
|
function generateUUID() {
|
|
@@ -584,6 +582,7 @@ var DEFAULT_BLOCK_SELECTORS = [
|
|
|
584
582
|
var MAX_TEXT_LENGTH = 255;
|
|
585
583
|
var AutocaptureModule = class {
|
|
586
584
|
constructor(config, callback) {
|
|
585
|
+
this.listeners = [];
|
|
587
586
|
this.clickHandler = null;
|
|
588
587
|
this.submitHandler = null;
|
|
589
588
|
this.active = false;
|
|
@@ -598,6 +597,27 @@ var AutocaptureModule = class {
|
|
|
598
597
|
};
|
|
599
598
|
this.callback = callback;
|
|
600
599
|
}
|
|
600
|
+
/**
|
|
601
|
+
* Register a secondary listener that receives the same events as the
|
|
602
|
+
* primary callback (e.g. Watchtower tap capture reusing the single click
|
|
603
|
+
* listener + selector resolution). Returns an unsubscribe function.
|
|
604
|
+
*/
|
|
605
|
+
addListener(cb) {
|
|
606
|
+
this.listeners.push(cb);
|
|
607
|
+
return () => {
|
|
608
|
+
const idx = this.listeners.indexOf(cb);
|
|
609
|
+
if (idx >= 0) this.listeners.splice(idx, 1);
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
emit(event) {
|
|
613
|
+
this.callback(event);
|
|
614
|
+
for (const listener of this.listeners) {
|
|
615
|
+
try {
|
|
616
|
+
listener(event);
|
|
617
|
+
} catch {
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
601
621
|
start() {
|
|
602
622
|
if (this.active || typeof document === "undefined" || typeof document.addEventListener !== "function") return;
|
|
603
623
|
this.active = true;
|
|
@@ -630,7 +650,7 @@ var AutocaptureModule = class {
|
|
|
630
650
|
properties.$event_type = "click";
|
|
631
651
|
properties.$x = e.clientX;
|
|
632
652
|
properties.$y = e.clientY;
|
|
633
|
-
this.
|
|
653
|
+
this.emit({
|
|
634
654
|
type: "click",
|
|
635
655
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
636
656
|
properties
|
|
@@ -652,7 +672,7 @@ var AutocaptureModule = class {
|
|
|
652
672
|
};
|
|
653
673
|
const elemProps = this.getElementProperties(form);
|
|
654
674
|
Object.assign(properties, elemProps);
|
|
655
|
-
this.
|
|
675
|
+
this.emit({
|
|
656
676
|
type: "form_submit",
|
|
657
677
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
658
678
|
properties
|
|
@@ -869,6 +889,14 @@ var AnalyticsManager = class {
|
|
|
869
889
|
);
|
|
870
890
|
this.autocaptureModule.start();
|
|
871
891
|
}
|
|
892
|
+
/**
|
|
893
|
+
* The live AutocaptureModule (if click/form autocapture is enabled) —
|
|
894
|
+
* Watchtower tap capture attaches to it so there is only ONE document-level
|
|
895
|
+
* click listener and one selector/element resolution path.
|
|
896
|
+
*/
|
|
897
|
+
getAutocaptureModule() {
|
|
898
|
+
return this.autocaptureModule;
|
|
899
|
+
}
|
|
872
900
|
track(eventName, properties) {
|
|
873
901
|
if (!this.config.enabled) return;
|
|
874
902
|
const event = this.createEvent("track", { name: eventName, properties });
|
|
@@ -2380,6 +2408,8 @@ var SitePongClient = class {
|
|
|
2380
2408
|
this.databaseTracker = null;
|
|
2381
2409
|
this.profiler = null;
|
|
2382
2410
|
this.remoteConfigManager = null;
|
|
2411
|
+
this.watchtowerCapture = null;
|
|
2412
|
+
this.watchtowerOptions = void 0;
|
|
2383
2413
|
this.envUnsubs = [];
|
|
2384
2414
|
this.identifyHooks = [];
|
|
2385
2415
|
this.config = {
|
|
@@ -2499,6 +2529,12 @@ var SitePongClient = class {
|
|
|
2499
2529
|
} else if (config.replay?.enabled) {
|
|
2500
2530
|
this.log("Replay requested but not available on this platform (web only).");
|
|
2501
2531
|
}
|
|
2532
|
+
this.watchtowerOptions = config.watchtower;
|
|
2533
|
+
if (config.watchtower?.enabled && webManagerFactories.createWatchtowerCapture) {
|
|
2534
|
+
this.startWatchtowerCapture();
|
|
2535
|
+
} else if (config.watchtower?.enabled) {
|
|
2536
|
+
this.log("Watchtower capture requested but not available on this platform (web only).");
|
|
2537
|
+
}
|
|
2502
2538
|
if (config.crons?.enabled) {
|
|
2503
2539
|
this.cronManager = new CronMonitorManager({
|
|
2504
2540
|
apiKey: config.apiKey,
|
|
@@ -2738,6 +2774,7 @@ var SitePongClient = class {
|
|
|
2738
2774
|
this.log("identify hook failed:", err);
|
|
2739
2775
|
}
|
|
2740
2776
|
}
|
|
2777
|
+
this.watchtowerCapture?.setDistinctId(userId);
|
|
2741
2778
|
if (!this.analyticsManager) {
|
|
2742
2779
|
this.log("Analytics not enabled. Set analytics.enabled: true in init()");
|
|
2743
2780
|
return;
|
|
@@ -2805,6 +2842,49 @@ var SitePongClient = class {
|
|
|
2805
2842
|
getReplaySessionId() {
|
|
2806
2843
|
return this.replayManager?.getSessionId() ?? null;
|
|
2807
2844
|
}
|
|
2845
|
+
// --- Watchtower tap capture (web) ---
|
|
2846
|
+
/**
|
|
2847
|
+
* Start Watchtower web tap capture. Options merge over `watchtower` from
|
|
2848
|
+
* init(); `projectId` is required (either here or in init config). Reuses
|
|
2849
|
+
* the analytics AutocaptureModule's click listener when autocapture is on.
|
|
2850
|
+
*/
|
|
2851
|
+
startWatchtowerCapture(options) {
|
|
2852
|
+
if (!webManagerFactories.createWatchtowerCapture) {
|
|
2853
|
+
this.log("Watchtower capture not available on this platform (web only).");
|
|
2854
|
+
return false;
|
|
2855
|
+
}
|
|
2856
|
+
if (!this.initialized || !this.config.apiKey) {
|
|
2857
|
+
this.log("Watchtower capture requires init() to be called first.");
|
|
2858
|
+
return false;
|
|
2859
|
+
}
|
|
2860
|
+
const opts = { ...this.watchtowerOptions, ...options };
|
|
2861
|
+
if (!opts.projectId) {
|
|
2862
|
+
this.log("Watchtower capture requires watchtower.projectId.");
|
|
2863
|
+
return false;
|
|
2864
|
+
}
|
|
2865
|
+
if (this.watchtowerCapture) {
|
|
2866
|
+
this.watchtowerCapture.stop();
|
|
2867
|
+
this.watchtowerCapture = null;
|
|
2868
|
+
}
|
|
2869
|
+
this.watchtowerCapture = webManagerFactories.createWatchtowerCapture({
|
|
2870
|
+
apiKey: this.config.apiKey,
|
|
2871
|
+
projectId: opts.projectId,
|
|
2872
|
+
endpoint: opts.endpoint || this.config.endpoint || DEFAULT_ENDPOINT3,
|
|
2873
|
+
appVersion: this.config.release || void 0,
|
|
2874
|
+
maxBatchSize: opts.maxBatchSize,
|
|
2875
|
+
flushInterval: opts.flushInterval,
|
|
2876
|
+
blockSelector: opts.blockSelector,
|
|
2877
|
+
maskSelector: opts.maskSelector,
|
|
2878
|
+
debug: this.config.debug
|
|
2879
|
+
});
|
|
2880
|
+
this.watchtowerCapture.start(this.analyticsManager?.getAutocaptureModule() ?? null);
|
|
2881
|
+
return true;
|
|
2882
|
+
}
|
|
2883
|
+
stopWatchtowerCapture() {
|
|
2884
|
+
if (!this.watchtowerCapture) return;
|
|
2885
|
+
this.watchtowerCapture.stop();
|
|
2886
|
+
this.watchtowerCapture = null;
|
|
2887
|
+
}
|
|
2808
2888
|
// --- Performance (Tier 7) ---
|
|
2809
2889
|
startTransaction(name, data) {
|
|
2810
2890
|
if (!this.performanceManager) {
|
|
@@ -2956,6 +3036,7 @@ var SitePongClient = class {
|
|
|
2956
3036
|
if (this.replayManager) {
|
|
2957
3037
|
this.replayManager.setUser(null);
|
|
2958
3038
|
}
|
|
3039
|
+
this.watchtowerCapture?.setDistinctId(null);
|
|
2959
3040
|
}
|
|
2960
3041
|
addBreadcrumb(breadcrumb) {
|
|
2961
3042
|
this.log("Breadcrumb added:", breadcrumb);
|
|
@@ -3180,6 +3261,8 @@ var getDeviceSignals = sitepong.getDeviceSignals.bind(sitepong);
|
|
|
3180
3261
|
var getFraudCheck = sitepong.getFraudCheck.bind(sitepong);
|
|
3181
3262
|
var startReplay = sitepong.startReplay.bind(sitepong);
|
|
3182
3263
|
var stopReplay = sitepong.stopReplay.bind(sitepong);
|
|
3264
|
+
var startWatchtowerCapture = sitepong.startWatchtowerCapture.bind(sitepong);
|
|
3265
|
+
var stopWatchtowerCapture = sitepong.stopWatchtowerCapture.bind(sitepong);
|
|
3183
3266
|
var isReplayRecording = sitepong.isReplayRecording.bind(sitepong);
|
|
3184
3267
|
var getReplaySessionId = sitepong.getReplaySessionId.bind(sitepong);
|
|
3185
3268
|
var startTransaction = sitepong.startTransaction.bind(sitepong);
|
|
@@ -3293,7 +3376,9 @@ exports.startProfileSpan = startProfileSpan;
|
|
|
3293
3376
|
exports.startReplay = startReplay;
|
|
3294
3377
|
exports.startSpan = startSpan;
|
|
3295
3378
|
exports.startTransaction = startTransaction;
|
|
3379
|
+
exports.startWatchtowerCapture = startWatchtowerCapture;
|
|
3296
3380
|
exports.stopReplay = stopReplay;
|
|
3381
|
+
exports.stopWatchtowerCapture = stopWatchtowerCapture;
|
|
3297
3382
|
exports.superlinkClient = superlinkClient;
|
|
3298
3383
|
exports.superlinkIdentify = identify;
|
|
3299
3384
|
exports.track = track;
|