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