@devskin/browser-sdk 1.0.41 → 1.0.42
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/devskin.cjs.js +120 -36
- package/dist/devskin.cjs.js.map +1 -1
- package/dist/devskin.esm.js +120 -36
- package/dist/devskin.esm.js.map +1 -1
- package/dist/devskin.umd.js +120 -36
- package/dist/devskin.umd.js.map +1 -1
- package/dist/devskin.umd.min.js +3 -3
- package/dist/devskin.umd.min.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/recorder/rrweb.d.ts +1 -1
- package/dist/recorder/rrweb.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/devskin.cjs.js
CHANGED
|
@@ -13473,11 +13473,12 @@ class RRWebRecorder {
|
|
|
13473
13473
|
},
|
|
13474
13474
|
// Configuration options
|
|
13475
13475
|
sampling: {
|
|
13476
|
-
// Mouse
|
|
13477
|
-
|
|
13478
|
-
|
|
13479
|
-
|
|
13480
|
-
|
|
13476
|
+
// Mouse movement sampling - throttle to reduce bandwidth
|
|
13477
|
+
// e.g. 0.1 = capture 10% of mouse movements (Math.floor(1/0.1) = 10, meaning capture 1 every 10 events)
|
|
13478
|
+
mousemove: this.config.mouseMoveSampleRate !== undefined
|
|
13479
|
+
? Math.max(1, Math.floor(1 / this.config.mouseMoveSampleRate))
|
|
13480
|
+
: 10, // Default: capture 1 every 10 mouse movements (10%)
|
|
13481
|
+
// Mouse interactions (clicks, etc) - always capture
|
|
13481
13482
|
mouseInteraction: true,
|
|
13482
13483
|
// Scroll events
|
|
13483
13484
|
scroll: 150, // Throttle scroll events to every 150ms
|
|
@@ -13892,6 +13893,72 @@ class DevSkinSDK {
|
|
|
13892
13893
|
// private sessionRecorder: SessionRecorder | null = null; // Replaced by RRWebRecorder
|
|
13893
13894
|
this.rrwebRecorder = null;
|
|
13894
13895
|
}
|
|
13896
|
+
/**
|
|
13897
|
+
* Detect if the current visitor is a bot/crawler
|
|
13898
|
+
*/
|
|
13899
|
+
isBot() {
|
|
13900
|
+
if (typeof navigator === 'undefined')
|
|
13901
|
+
return true;
|
|
13902
|
+
const botPatterns = [
|
|
13903
|
+
/bot/i,
|
|
13904
|
+
/crawler/i,
|
|
13905
|
+
/spider/i,
|
|
13906
|
+
/crawling/i,
|
|
13907
|
+
/google/i,
|
|
13908
|
+
/bing/i,
|
|
13909
|
+
/yahoo/i,
|
|
13910
|
+
/duckduckgo/i,
|
|
13911
|
+
/baiduspider/i,
|
|
13912
|
+
/yandex/i,
|
|
13913
|
+
/facebookexternalhit/i,
|
|
13914
|
+
/twitterbot/i,
|
|
13915
|
+
/rogerbot/i,
|
|
13916
|
+
/linkedinbot/i,
|
|
13917
|
+
/embedly/i,
|
|
13918
|
+
/quora link preview/i,
|
|
13919
|
+
/showyoubot/i,
|
|
13920
|
+
/outbrain/i,
|
|
13921
|
+
/pinterest/i,
|
|
13922
|
+
/slackbot/i,
|
|
13923
|
+
/vkShare/i,
|
|
13924
|
+
/W3C_Validator/i,
|
|
13925
|
+
/redditbot/i,
|
|
13926
|
+
/Applebot/i,
|
|
13927
|
+
/WhatsApp/i,
|
|
13928
|
+
/flipboard/i,
|
|
13929
|
+
/tumblr/i,
|
|
13930
|
+
/bitlybot/i,
|
|
13931
|
+
/SkypeUriPreview/i,
|
|
13932
|
+
/nuzzel/i,
|
|
13933
|
+
/Discordbot/i,
|
|
13934
|
+
/Google Page Speed/i,
|
|
13935
|
+
/Qwantify/i,
|
|
13936
|
+
/pinterestbot/i,
|
|
13937
|
+
/Bitrix link preview/i,
|
|
13938
|
+
/XING-contenttabreceiver/i,
|
|
13939
|
+
/Chrome-Lighthouse/i,
|
|
13940
|
+
/telegrambot/i,
|
|
13941
|
+
/Lighthouse/i,
|
|
13942
|
+
/GTmetrix/i,
|
|
13943
|
+
/PageSpeed/i,
|
|
13944
|
+
/HeadlessChrome/i,
|
|
13945
|
+
/PhantomJS/i,
|
|
13946
|
+
];
|
|
13947
|
+
const userAgent = navigator.userAgent;
|
|
13948
|
+
// Check user agent against bot patterns
|
|
13949
|
+
if (botPatterns.some(pattern => pattern.test(userAgent))) {
|
|
13950
|
+
return true;
|
|
13951
|
+
}
|
|
13952
|
+
// Check for headless browsers
|
|
13953
|
+
if ('webdriver' in navigator && navigator.webdriver === true) {
|
|
13954
|
+
return true;
|
|
13955
|
+
}
|
|
13956
|
+
// Check for headless Chrome
|
|
13957
|
+
if (userAgent.includes('HeadlessChrome')) {
|
|
13958
|
+
return true;
|
|
13959
|
+
}
|
|
13960
|
+
return false;
|
|
13961
|
+
}
|
|
13895
13962
|
/**
|
|
13896
13963
|
* Initialize the DevSkin SDK
|
|
13897
13964
|
* Uses requestIdleCallback to defer heavy initialization without blocking the page
|
|
@@ -13924,7 +13991,7 @@ class DevSkinSDK {
|
|
|
13924
13991
|
// Wait for session creation to complete before starting collectors
|
|
13925
13992
|
this.startSession().then(() => {
|
|
13926
13993
|
// Session created, now safe to start collectors that send data
|
|
13927
|
-
var _a, _b;
|
|
13994
|
+
var _a, _b, _c;
|
|
13928
13995
|
if (this.config.captureWebVitals) {
|
|
13929
13996
|
this.performanceCollector = new PerformanceCollector(this.config, this.transport);
|
|
13930
13997
|
this.performanceCollector.start();
|
|
@@ -13951,36 +14018,53 @@ class DevSkinSDK {
|
|
|
13951
14018
|
}
|
|
13952
14019
|
// Initialize session recording with rrweb
|
|
13953
14020
|
if ((_a = this.config.sessionRecording) === null || _a === void 0 ? void 0 : _a.enabled) {
|
|
13954
|
-
//
|
|
13955
|
-
|
|
13956
|
-
|
|
13957
|
-
|
|
13958
|
-
|
|
13959
|
-
|
|
13960
|
-
|
|
13961
|
-
|
|
13962
|
-
|
|
13963
|
-
: true,
|
|
13964
|
-
|
|
13965
|
-
|
|
13966
|
-
|
|
13967
|
-
|
|
13968
|
-
|
|
13969
|
-
|
|
13970
|
-
|
|
13971
|
-
|
|
13972
|
-
|
|
13973
|
-
|
|
13974
|
-
|
|
13975
|
-
|
|
13976
|
-
|
|
13977
|
-
|
|
13978
|
-
|
|
13979
|
-
|
|
13980
|
-
|
|
13981
|
-
|
|
13982
|
-
|
|
13983
|
-
|
|
14021
|
+
// Skip recording for bots/crawlers to avoid impacting SEO
|
|
14022
|
+
const isBot = this.isBot();
|
|
14023
|
+
// Apply session sampling - decide if this session should be recorded
|
|
14024
|
+
const samplingRate = this.config.sessionRecording.sampling || 1.0;
|
|
14025
|
+
const shouldRecord = !isBot && Math.random() < samplingRate;
|
|
14026
|
+
if (shouldRecord) {
|
|
14027
|
+
// Use RRWebRecorder for complete DOM recording
|
|
14028
|
+
// Pass sessionStartTime to ensure timestamp continuity across page navigations
|
|
14029
|
+
this.rrwebRecorder = new RRWebRecorder(this.sessionId, {
|
|
14030
|
+
enabled: true,
|
|
14031
|
+
mouseMoveSampleRate: 0.5, // Sample 10% of mouse movements to reduce bandwidth
|
|
14032
|
+
blockClass: 'rr-block',
|
|
14033
|
+
ignoreClass: this.config.sessionRecording.ignoreClass || 'rr-ignore',
|
|
14034
|
+
maskAllInputs: this.config.sessionRecording.maskAllInputs !== undefined
|
|
14035
|
+
? this.config.sessionRecording.maskAllInputs
|
|
14036
|
+
: true,
|
|
14037
|
+
maskInputOptions: {
|
|
14038
|
+
password: true,
|
|
14039
|
+
email: true,
|
|
14040
|
+
tel: true,
|
|
14041
|
+
},
|
|
14042
|
+
recordCanvas: this.config.sessionRecording.recordCanvas || false,
|
|
14043
|
+
collectFonts: true,
|
|
14044
|
+
inlineStylesheet: true,
|
|
14045
|
+
checkoutEveryNms: 5 * 60 * 1000, // Every 5 minutes
|
|
14046
|
+
checkoutEveryNth: 200, // Every 200 events
|
|
14047
|
+
}, (events) => {
|
|
14048
|
+
var _a;
|
|
14049
|
+
// Send rrweb events to backend
|
|
14050
|
+
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.sendRecordingEvents(this.sessionId, events);
|
|
14051
|
+
}, this.sessionStartTime // Pass session start time for timestamp continuity
|
|
14052
|
+
);
|
|
14053
|
+
// Start recording immediately (session already created)
|
|
14054
|
+
this.rrwebRecorder.start();
|
|
14055
|
+
if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.debug) {
|
|
14056
|
+
console.log(`[DevSkin] RRWeb recording started for session: ${this.sessionId} (sampling: ${samplingRate * 100}%)`);
|
|
14057
|
+
}
|
|
14058
|
+
}
|
|
14059
|
+
else {
|
|
14060
|
+
if ((_c = this.config) === null || _c === void 0 ? void 0 : _c.debug) {
|
|
14061
|
+
if (isBot) {
|
|
14062
|
+
console.log(`[DevSkin] Session ${this.sessionId} skipped recording (bot/crawler detected for SEO optimization)`);
|
|
14063
|
+
}
|
|
14064
|
+
else {
|
|
14065
|
+
console.log(`[DevSkin] Session ${this.sessionId} not sampled for recording (sampling: ${samplingRate * 100}%)`);
|
|
14066
|
+
}
|
|
14067
|
+
}
|
|
13984
14068
|
}
|
|
13985
14069
|
}
|
|
13986
14070
|
// Track initial page view
|