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