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.
- package/dist/cdn/sitepong.min.js +5 -5
- package/dist/cdn/sitepong.min.js.map +1 -1
- package/dist/entries/node.d.mts +2 -2
- package/dist/entries/node.d.ts +2 -2
- package/dist/entries/rn.d.ts +995 -0
- package/dist/entries/rn.js +240 -29
- package/dist/entries/rn.js.map +1 -1
- package/dist/entries/web.d.mts +2 -2
- package/dist/entries/web.d.ts +2 -2
- package/dist/entries/web.js +2094 -1235
- package/dist/entries/web.js.map +1 -1
- package/dist/entries/web.mjs +2093 -1236
- package/dist/entries/web.mjs.map +1 -1
- package/dist/index.d.mts +162 -3
- package/dist/index.d.ts +162 -3
- package/dist/index.js +158 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +157 -18
- package/dist/index.mjs.map +1 -1
- package/dist/nextjs/index.d.mts +2 -2
- package/dist/nextjs/index.d.ts +2 -2
- package/dist/react/index.d.mts +4 -4
- package/dist/react/index.d.ts +4 -4
- package/dist/react/index.js +158 -16
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +157 -17
- package/dist/react/index.mjs.map +1 -1
- package/dist/server/index.d.mts +3 -3
- package/dist/server/index.d.ts +3 -3
- package/dist/{types-DQSv7JAE.d.ts → types-BTA43eyz.d.ts} +1 -1
- package/dist/{types-Cms9VXx9.d.mts → types-CphqOTfm.d.mts} +1 -1
- package/dist/{types-BEqbz0tw.d.mts → types-DPINdOQW.d.mts} +2 -0
- package/dist/{types-BEqbz0tw.d.ts → types-DPINdOQW.d.ts} +2 -0
- package/package.json +8 -3
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() {
|
|
@@ -522,6 +520,60 @@ function clearSession() {
|
|
|
522
520
|
memorySessionTs = null;
|
|
523
521
|
}
|
|
524
522
|
|
|
523
|
+
// src/analytics/utm.ts
|
|
524
|
+
var STORAGE_KEY2 = "sp_utm";
|
|
525
|
+
var UTM_KEYS = [
|
|
526
|
+
["source", "utm_source"],
|
|
527
|
+
["medium", "utm_medium"],
|
|
528
|
+
["campaign", "utm_campaign"],
|
|
529
|
+
["term", "utm_term"],
|
|
530
|
+
["content", "utm_content"]
|
|
531
|
+
];
|
|
532
|
+
function parseFromLocation() {
|
|
533
|
+
if (typeof window === "undefined" || !window.location || !window.location.search) return null;
|
|
534
|
+
let params;
|
|
535
|
+
try {
|
|
536
|
+
params = new URLSearchParams(window.location.search);
|
|
537
|
+
} catch {
|
|
538
|
+
return null;
|
|
539
|
+
}
|
|
540
|
+
const result = {};
|
|
541
|
+
let found = false;
|
|
542
|
+
for (const [key, queryKey] of UTM_KEYS) {
|
|
543
|
+
const value = params.get(queryKey);
|
|
544
|
+
if (value) {
|
|
545
|
+
result[key] = value;
|
|
546
|
+
found = true;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
return found ? result : null;
|
|
550
|
+
}
|
|
551
|
+
function readStored() {
|
|
552
|
+
if (typeof sessionStorage === "undefined") return null;
|
|
553
|
+
try {
|
|
554
|
+
const raw = sessionStorage.getItem(STORAGE_KEY2);
|
|
555
|
+
if (!raw) return null;
|
|
556
|
+
const parsed = JSON.parse(raw);
|
|
557
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
558
|
+
} catch {
|
|
559
|
+
return null;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
function writeStored(utm) {
|
|
563
|
+
if (typeof sessionStorage === "undefined") return;
|
|
564
|
+
try {
|
|
565
|
+
sessionStorage.setItem(STORAGE_KEY2, JSON.stringify(utm));
|
|
566
|
+
} catch {
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
function getSessionUtm() {
|
|
570
|
+
const stored = readStored();
|
|
571
|
+
if (stored) return stored;
|
|
572
|
+
const fresh = parseFromLocation();
|
|
573
|
+
if (fresh) writeStored(fresh);
|
|
574
|
+
return fresh;
|
|
575
|
+
}
|
|
576
|
+
|
|
525
577
|
// src/analytics/autocapture.ts
|
|
526
578
|
var DEFAULT_BLOCK_SELECTORS = [
|
|
527
579
|
"[data-sp-no-capture]",
|
|
@@ -530,6 +582,7 @@ var DEFAULT_BLOCK_SELECTORS = [
|
|
|
530
582
|
var MAX_TEXT_LENGTH = 255;
|
|
531
583
|
var AutocaptureModule = class {
|
|
532
584
|
constructor(config, callback) {
|
|
585
|
+
this.listeners = [];
|
|
533
586
|
this.clickHandler = null;
|
|
534
587
|
this.submitHandler = null;
|
|
535
588
|
this.active = false;
|
|
@@ -544,6 +597,27 @@ var AutocaptureModule = class {
|
|
|
544
597
|
};
|
|
545
598
|
this.callback = callback;
|
|
546
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
|
+
}
|
|
547
621
|
start() {
|
|
548
622
|
if (this.active || typeof document === "undefined" || typeof document.addEventListener !== "function") return;
|
|
549
623
|
this.active = true;
|
|
@@ -576,7 +650,7 @@ var AutocaptureModule = class {
|
|
|
576
650
|
properties.$event_type = "click";
|
|
577
651
|
properties.$x = e.clientX;
|
|
578
652
|
properties.$y = e.clientY;
|
|
579
|
-
this.
|
|
653
|
+
this.emit({
|
|
580
654
|
type: "click",
|
|
581
655
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
582
656
|
properties
|
|
@@ -598,7 +672,7 @@ var AutocaptureModule = class {
|
|
|
598
672
|
};
|
|
599
673
|
const elemProps = this.getElementProperties(form);
|
|
600
674
|
Object.assign(properties, elemProps);
|
|
601
|
-
this.
|
|
675
|
+
this.emit({
|
|
602
676
|
type: "form_submit",
|
|
603
677
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
604
678
|
properties
|
|
@@ -815,6 +889,14 @@ var AnalyticsManager = class {
|
|
|
815
889
|
);
|
|
816
890
|
this.autocaptureModule.start();
|
|
817
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
|
+
}
|
|
818
900
|
track(eventName, properties) {
|
|
819
901
|
if (!this.config.enabled) return;
|
|
820
902
|
const event = this.createEvent("track", { name: eventName, properties });
|
|
@@ -928,7 +1010,9 @@ var AnalyticsManager = class {
|
|
|
928
1010
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
929
1011
|
url: typeof window !== "undefined" && window.location ? window.location.href : void 0,
|
|
930
1012
|
referrer: typeof document !== "undefined" && typeof document.referrer === "string" ? document.referrer : void 0,
|
|
931
|
-
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0
|
|
1013
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0,
|
|
1014
|
+
utm: getSessionUtm() || void 0,
|
|
1015
|
+
appVersion: this.config.appVersion || void 0
|
|
932
1016
|
};
|
|
933
1017
|
}
|
|
934
1018
|
enqueue(event) {
|
|
@@ -1626,7 +1710,7 @@ var DEFAULT_REMOTE_CONFIG = {
|
|
|
1626
1710
|
};
|
|
1627
1711
|
|
|
1628
1712
|
// src/remote-config/manager.ts
|
|
1629
|
-
var
|
|
1713
|
+
var STORAGE_KEY3 = "sitepong_remote_config";
|
|
1630
1714
|
var STORAGE_TS_KEY = "sitepong_remote_config_ts";
|
|
1631
1715
|
var RemoteConfigManager = class {
|
|
1632
1716
|
constructor(options) {
|
|
@@ -1669,7 +1753,7 @@ var RemoteConfigManager = class {
|
|
|
1669
1753
|
const storage = this.options.storage;
|
|
1670
1754
|
if (!storage) return;
|
|
1671
1755
|
try {
|
|
1672
|
-
const cached = await storage.getItem(
|
|
1756
|
+
const cached = await storage.getItem(STORAGE_KEY3);
|
|
1673
1757
|
const cachedTs = await storage.getItem(STORAGE_TS_KEY);
|
|
1674
1758
|
if (cached && cachedTs) {
|
|
1675
1759
|
const age = Date.now() - parseInt(cachedTs, 10);
|
|
@@ -1730,7 +1814,7 @@ var RemoteConfigManager = class {
|
|
|
1730
1814
|
const storage = this.options.storage;
|
|
1731
1815
|
if (!storage) return;
|
|
1732
1816
|
try {
|
|
1733
|
-
await storage.setItem(
|
|
1817
|
+
await storage.setItem(STORAGE_KEY3, JSON.stringify(this.config));
|
|
1734
1818
|
await storage.setItem(STORAGE_TS_KEY, String(Date.now()));
|
|
1735
1819
|
} catch {
|
|
1736
1820
|
this.log("Failed to cache remote config");
|
|
@@ -1986,7 +2070,7 @@ function stripTrailingSlash(url) {
|
|
|
1986
2070
|
var superlinkClient = new SuperLinkClient();
|
|
1987
2071
|
|
|
1988
2072
|
// src/superlink/parse.ts
|
|
1989
|
-
var
|
|
2073
|
+
var UTM_KEYS2 = [
|
|
1990
2074
|
["source", "utm_source"],
|
|
1991
2075
|
["medium", "utm_medium"],
|
|
1992
2076
|
["campaign", "utm_campaign"],
|
|
@@ -2002,7 +2086,7 @@ function parseUniversalLink(url) {
|
|
|
2002
2086
|
}
|
|
2003
2087
|
const params = parsed.searchParams;
|
|
2004
2088
|
const utm = {};
|
|
2005
|
-
for (const [key, queryKey] of
|
|
2089
|
+
for (const [key, queryKey] of UTM_KEYS2) {
|
|
2006
2090
|
const value = params.get(queryKey);
|
|
2007
2091
|
if (value) utm[key] = value;
|
|
2008
2092
|
}
|
|
@@ -2069,13 +2153,13 @@ function getMatchedDeepLink() {
|
|
|
2069
2153
|
}
|
|
2070
2154
|
|
|
2071
2155
|
// src/superlink/web.ts
|
|
2072
|
-
var
|
|
2156
|
+
var STORAGE_KEY4 = "sp_superlink";
|
|
2073
2157
|
var captured = null;
|
|
2074
2158
|
var didCapture = false;
|
|
2075
|
-
function
|
|
2159
|
+
function readStored2() {
|
|
2076
2160
|
if (typeof sessionStorage === "undefined") return null;
|
|
2077
2161
|
try {
|
|
2078
|
-
const raw = sessionStorage.getItem(
|
|
2162
|
+
const raw = sessionStorage.getItem(STORAGE_KEY4);
|
|
2079
2163
|
if (!raw) return null;
|
|
2080
2164
|
const parsed = JSON.parse(raw);
|
|
2081
2165
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
@@ -2083,10 +2167,10 @@ function readStored() {
|
|
|
2083
2167
|
return null;
|
|
2084
2168
|
}
|
|
2085
2169
|
}
|
|
2086
|
-
function
|
|
2170
|
+
function writeStored2(link) {
|
|
2087
2171
|
if (typeof sessionStorage === "undefined") return;
|
|
2088
2172
|
try {
|
|
2089
|
-
sessionStorage.setItem(
|
|
2173
|
+
sessionStorage.setItem(STORAGE_KEY4, JSON.stringify(link));
|
|
2090
2174
|
} catch {
|
|
2091
2175
|
}
|
|
2092
2176
|
}
|
|
@@ -2134,7 +2218,7 @@ function extractIdentityMetadata(url) {
|
|
|
2134
2218
|
function captureWebDeepLink() {
|
|
2135
2219
|
if (didCapture) return captured;
|
|
2136
2220
|
didCapture = true;
|
|
2137
|
-
const stored =
|
|
2221
|
+
const stored = readStored2();
|
|
2138
2222
|
if (stored) {
|
|
2139
2223
|
captured = stored;
|
|
2140
2224
|
return captured;
|
|
@@ -2143,7 +2227,7 @@ function captureWebDeepLink() {
|
|
|
2143
2227
|
const link = parseUniversalLink(window.location.href);
|
|
2144
2228
|
if (link && hasPayload(link)) {
|
|
2145
2229
|
captured = link;
|
|
2146
|
-
|
|
2230
|
+
writeStored2(link);
|
|
2147
2231
|
void superlinkClient.reportEvent({
|
|
2148
2232
|
type: "opened",
|
|
2149
2233
|
click_id: link.click_id,
|
|
@@ -2324,6 +2408,8 @@ var SitePongClient = class {
|
|
|
2324
2408
|
this.databaseTracker = null;
|
|
2325
2409
|
this.profiler = null;
|
|
2326
2410
|
this.remoteConfigManager = null;
|
|
2411
|
+
this.watchtowerCapture = null;
|
|
2412
|
+
this.watchtowerOptions = void 0;
|
|
2327
2413
|
this.envUnsubs = [];
|
|
2328
2414
|
this.identifyHooks = [];
|
|
2329
2415
|
this.config = {
|
|
@@ -2443,6 +2529,12 @@ var SitePongClient = class {
|
|
|
2443
2529
|
} else if (config.replay?.enabled) {
|
|
2444
2530
|
this.log("Replay requested but not available on this platform (web only).");
|
|
2445
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
|
+
}
|
|
2446
2538
|
if (config.crons?.enabled) {
|
|
2447
2539
|
this.cronManager = new CronMonitorManager({
|
|
2448
2540
|
apiKey: config.apiKey,
|
|
@@ -2682,6 +2774,7 @@ var SitePongClient = class {
|
|
|
2682
2774
|
this.log("identify hook failed:", err);
|
|
2683
2775
|
}
|
|
2684
2776
|
}
|
|
2777
|
+
this.watchtowerCapture?.setDistinctId(userId);
|
|
2685
2778
|
if (!this.analyticsManager) {
|
|
2686
2779
|
this.log("Analytics not enabled. Set analytics.enabled: true in init()");
|
|
2687
2780
|
return;
|
|
@@ -2749,6 +2842,49 @@ var SitePongClient = class {
|
|
|
2749
2842
|
getReplaySessionId() {
|
|
2750
2843
|
return this.replayManager?.getSessionId() ?? null;
|
|
2751
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
|
+
}
|
|
2752
2888
|
// --- Performance (Tier 7) ---
|
|
2753
2889
|
startTransaction(name, data) {
|
|
2754
2890
|
if (!this.performanceManager) {
|
|
@@ -2900,6 +3036,7 @@ var SitePongClient = class {
|
|
|
2900
3036
|
if (this.replayManager) {
|
|
2901
3037
|
this.replayManager.setUser(null);
|
|
2902
3038
|
}
|
|
3039
|
+
this.watchtowerCapture?.setDistinctId(null);
|
|
2903
3040
|
}
|
|
2904
3041
|
addBreadcrumb(breadcrumb) {
|
|
2905
3042
|
this.log("Breadcrumb added:", breadcrumb);
|
|
@@ -3124,6 +3261,8 @@ var getDeviceSignals = sitepong.getDeviceSignals.bind(sitepong);
|
|
|
3124
3261
|
var getFraudCheck = sitepong.getFraudCheck.bind(sitepong);
|
|
3125
3262
|
var startReplay = sitepong.startReplay.bind(sitepong);
|
|
3126
3263
|
var stopReplay = sitepong.stopReplay.bind(sitepong);
|
|
3264
|
+
var startWatchtowerCapture = sitepong.startWatchtowerCapture.bind(sitepong);
|
|
3265
|
+
var stopWatchtowerCapture = sitepong.stopWatchtowerCapture.bind(sitepong);
|
|
3127
3266
|
var isReplayRecording = sitepong.isReplayRecording.bind(sitepong);
|
|
3128
3267
|
var getReplaySessionId = sitepong.getReplaySessionId.bind(sitepong);
|
|
3129
3268
|
var startTransaction = sitepong.startTransaction.bind(sitepong);
|
|
@@ -3237,7 +3376,9 @@ exports.startProfileSpan = startProfileSpan;
|
|
|
3237
3376
|
exports.startReplay = startReplay;
|
|
3238
3377
|
exports.startSpan = startSpan;
|
|
3239
3378
|
exports.startTransaction = startTransaction;
|
|
3379
|
+
exports.startWatchtowerCapture = startWatchtowerCapture;
|
|
3240
3380
|
exports.stopReplay = stopReplay;
|
|
3381
|
+
exports.stopWatchtowerCapture = stopWatchtowerCapture;
|
|
3241
3382
|
exports.superlinkClient = superlinkClient;
|
|
3242
3383
|
exports.superlinkIdentify = identify;
|
|
3243
3384
|
exports.track = track;
|