@devskin/browser-sdk 1.0.39 → 1.0.41
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/collectors/heatmap.d.ts +3 -1
- package/dist/collectors/heatmap.d.ts.map +1 -1
- package/dist/devskin.cjs.js +122 -96
- package/dist/devskin.cjs.js.map +1 -1
- package/dist/devskin.esm.js +122 -96
- package/dist/devskin.esm.js.map +1 -1
- package/dist/devskin.umd.js +122 -96
- package/dist/devskin.umd.js.map +1 -1
- package/dist/devskin.umd.min.js +2 -2
- 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/types.d.ts +2 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/devskin.umd.js
CHANGED
|
@@ -863,9 +863,11 @@
|
|
|
863
863
|
}
|
|
864
864
|
|
|
865
865
|
class HeatmapCollector {
|
|
866
|
-
constructor(config, transport) {
|
|
866
|
+
constructor(config, transport, anonymousId, sessionId) {
|
|
867
867
|
this.config = config;
|
|
868
868
|
this.transport = transport;
|
|
869
|
+
this.anonymousId = anonymousId;
|
|
870
|
+
this.sessionId = sessionId;
|
|
869
871
|
this.clickData = [];
|
|
870
872
|
this.scrollData = [];
|
|
871
873
|
this.mouseMoveData = [];
|
|
@@ -1009,21 +1011,21 @@
|
|
|
1009
1011
|
// Send clicks individually (backend expects one click event per item)
|
|
1010
1012
|
if (this.clickData.length > 0) {
|
|
1011
1013
|
this.clickData.forEach(click => {
|
|
1012
|
-
this.transport.sendHeatmapData(Object.assign({ type: 'click' }, click));
|
|
1014
|
+
this.transport.sendHeatmapData(Object.assign({ type: 'click', anonymousId: this.anonymousId, sessionId: this.sessionId }, click));
|
|
1013
1015
|
});
|
|
1014
1016
|
this.clickData = [];
|
|
1015
1017
|
}
|
|
1016
1018
|
// Send scroll data individually
|
|
1017
1019
|
if (this.scrollData.length > 0) {
|
|
1018
1020
|
this.scrollData.forEach(scroll => {
|
|
1019
|
-
this.transport.sendHeatmapData(Object.assign({ type: 'scroll' }, scroll));
|
|
1021
|
+
this.transport.sendHeatmapData(Object.assign({ type: 'scroll', anonymousId: this.anonymousId, sessionId: this.sessionId }, scroll));
|
|
1020
1022
|
});
|
|
1021
1023
|
this.scrollData = [];
|
|
1022
1024
|
}
|
|
1023
1025
|
// Send mouse moves individually
|
|
1024
1026
|
if (this.mouseMoveData.length > 0) {
|
|
1025
1027
|
this.mouseMoveData.forEach(move => {
|
|
1026
|
-
this.transport.sendHeatmapData(Object.assign({ type: 'mousemove' }, move));
|
|
1028
|
+
this.transport.sendHeatmapData(Object.assign({ type: 'mousemove', anonymousId: this.anonymousId, sessionId: this.sessionId }, move));
|
|
1027
1029
|
});
|
|
1028
1030
|
this.mouseMoveData = [];
|
|
1029
1031
|
}
|
|
@@ -13878,6 +13880,7 @@
|
|
|
13878
13880
|
this.anonymousId = null;
|
|
13879
13881
|
this.sessionStartTime = 0;
|
|
13880
13882
|
this.initialized = false;
|
|
13883
|
+
this.initializing = false;
|
|
13881
13884
|
this.heartbeatInterval = null;
|
|
13882
13885
|
// Collectors
|
|
13883
13886
|
this.deviceCollector = null;
|
|
@@ -13893,12 +13896,15 @@
|
|
|
13893
13896
|
}
|
|
13894
13897
|
/**
|
|
13895
13898
|
* Initialize the DevSkin SDK
|
|
13899
|
+
* Uses requestIdleCallback to defer heavy initialization without blocking the page
|
|
13896
13900
|
*/
|
|
13897
13901
|
init(config) {
|
|
13898
|
-
if (this.initialized) {
|
|
13899
|
-
console.warn('[DevSkin] SDK already initialized');
|
|
13902
|
+
if (this.initialized || this.initializing) {
|
|
13903
|
+
console.warn('[DevSkin] SDK already initialized or initializing');
|
|
13900
13904
|
return;
|
|
13901
13905
|
}
|
|
13906
|
+
// Mark as initializing to prevent duplicate init() calls
|
|
13907
|
+
this.initializing = true;
|
|
13902
13908
|
this.config = Object.assign({ debug: false, captureWebVitals: true, captureNetworkRequests: true, captureErrors: true, captureUserAgent: true, captureLocation: true, captureDevice: true, heatmapOptions: {
|
|
13903
13909
|
enabled: true,
|
|
13904
13910
|
trackClicks: true,
|
|
@@ -13908,99 +13914,118 @@
|
|
|
13908
13914
|
if (this.config.debug) {
|
|
13909
13915
|
console.log('[DevSkin] Initializing SDK with config:', this.config);
|
|
13910
13916
|
}
|
|
13911
|
-
// Initialize
|
|
13917
|
+
// Initialize lightweight components immediately (needed for session context)
|
|
13912
13918
|
this.transport = new Transport(this.config);
|
|
13913
|
-
// Generate anonymous ID if not exists
|
|
13914
13919
|
this.anonymousId = this.getOrCreateAnonymousId();
|
|
13915
|
-
// Initialize collectors BEFORE starting session (so getContextData works)
|
|
13916
13920
|
this.deviceCollector = new DeviceCollector(this.config);
|
|
13917
13921
|
this.locationCollector = new LocationCollector(this.config);
|
|
13918
13922
|
this.browserCollector = new BrowserCollector(this.config);
|
|
13919
|
-
//
|
|
13920
|
-
|
|
13921
|
-
|
|
13922
|
-
//
|
|
13923
|
-
|
|
13924
|
-
|
|
13925
|
-
|
|
13926
|
-
this.
|
|
13927
|
-
|
|
13928
|
-
|
|
13929
|
-
|
|
13930
|
-
this.
|
|
13931
|
-
|
|
13932
|
-
|
|
13933
|
-
|
|
13934
|
-
this.
|
|
13935
|
-
|
|
13936
|
-
|
|
13937
|
-
|
|
13938
|
-
|
|
13939
|
-
|
|
13940
|
-
|
|
13941
|
-
|
|
13942
|
-
|
|
13943
|
-
|
|
13944
|
-
|
|
13945
|
-
|
|
13946
|
-
|
|
13947
|
-
|
|
13948
|
-
|
|
13949
|
-
|
|
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
|
-
|
|
13923
|
+
// Defer heavy initialization to avoid blocking page load/rendering
|
|
13924
|
+
const initHeavyCollectors = () => {
|
|
13925
|
+
// Start session (will now include device/browser/location data)
|
|
13926
|
+
// Wait for session creation to complete before starting collectors
|
|
13927
|
+
this.startSession().then(() => {
|
|
13928
|
+
// Session created, now safe to start collectors that send data
|
|
13929
|
+
var _a, _b;
|
|
13930
|
+
if (this.config.captureWebVitals) {
|
|
13931
|
+
this.performanceCollector = new PerformanceCollector(this.config, this.transport);
|
|
13932
|
+
this.performanceCollector.start();
|
|
13933
|
+
}
|
|
13934
|
+
if (this.config.captureErrors) {
|
|
13935
|
+
this.errorCollector = new ErrorCollector(this.config, this.transport);
|
|
13936
|
+
this.errorCollector.start();
|
|
13937
|
+
}
|
|
13938
|
+
if (this.config.captureNetworkRequests) {
|
|
13939
|
+
this.networkCollector = new NetworkCollector(this.config, this.transport);
|
|
13940
|
+
this.networkCollector.start();
|
|
13941
|
+
}
|
|
13942
|
+
// Initialize heatmap collector - SEMPRE habilitado
|
|
13943
|
+
// Merge default heatmap config with user config
|
|
13944
|
+
const heatmapConfig = Object.assign({ enabled: true, trackClicks: true, trackScroll: true, trackMouseMovement: true, mouseMoveSampling: 0.1 }, this.config.heatmapOptions);
|
|
13945
|
+
this.config.heatmapOptions = heatmapConfig;
|
|
13946
|
+
this.heatmapCollector = new HeatmapCollector(this.config, this.transport, this.anonymousId, this.sessionId);
|
|
13947
|
+
this.heatmapCollector.start();
|
|
13948
|
+
// Initialize screenshot collector and capture page
|
|
13949
|
+
this.screenshotCollector = new ScreenshotCollector(this.config, this.transport);
|
|
13950
|
+
this.screenshotCollector.captureAndSend(this.sessionId, window.location.href);
|
|
13951
|
+
if (this.config.debug) {
|
|
13952
|
+
console.log('[DevSkin] Heatmap collection enabled (always on)');
|
|
13953
|
+
}
|
|
13954
|
+
// Initialize session recording with rrweb
|
|
13955
|
+
if ((_a = this.config.sessionRecording) === null || _a === void 0 ? void 0 : _a.enabled) {
|
|
13956
|
+
// Use RRWebRecorder for complete DOM recording
|
|
13957
|
+
// Pass sessionStartTime to ensure timestamp continuity across page navigations
|
|
13958
|
+
this.rrwebRecorder = new RRWebRecorder(this.sessionId, {
|
|
13959
|
+
enabled: true,
|
|
13960
|
+
sampleRate: this.config.sessionRecording.sampling || 0.5,
|
|
13961
|
+
blockClass: 'rr-block',
|
|
13962
|
+
ignoreClass: this.config.sessionRecording.ignoreClass || 'rr-ignore',
|
|
13963
|
+
maskAllInputs: this.config.sessionRecording.maskAllInputs !== undefined
|
|
13964
|
+
? this.config.sessionRecording.maskAllInputs
|
|
13965
|
+
: true,
|
|
13966
|
+
maskInputOptions: {
|
|
13967
|
+
password: true,
|
|
13968
|
+
email: true,
|
|
13969
|
+
tel: true,
|
|
13970
|
+
},
|
|
13971
|
+
recordCanvas: this.config.sessionRecording.recordCanvas || false,
|
|
13972
|
+
collectFonts: true,
|
|
13973
|
+
inlineStylesheet: true,
|
|
13974
|
+
checkoutEveryNms: 5 * 60 * 1000, // Every 5 minutes
|
|
13975
|
+
checkoutEveryNth: 200, // Every 200 events
|
|
13976
|
+
}, (events) => {
|
|
13977
|
+
var _a;
|
|
13978
|
+
// Send rrweb events to backend
|
|
13979
|
+
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.sendRecordingEvents(this.sessionId, events);
|
|
13980
|
+
}, this.sessionStartTime // Pass session start time for timestamp continuity
|
|
13981
|
+
);
|
|
13982
|
+
// Start recording immediately (session already created)
|
|
13983
|
+
this.rrwebRecorder.start();
|
|
13984
|
+
if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.debug) {
|
|
13985
|
+
console.log('[DevSkin] RRWeb recording started for session:', this.sessionId);
|
|
13986
|
+
}
|
|
13980
13987
|
}
|
|
13988
|
+
// Track initial page view
|
|
13989
|
+
this.trackPageView();
|
|
13990
|
+
// Start heartbeat to update session duration every 30 seconds
|
|
13991
|
+
this.startHeartbeat();
|
|
13992
|
+
}).catch((err) => {
|
|
13993
|
+
console.error('[DevSkin] Failed to create session:', err);
|
|
13994
|
+
});
|
|
13995
|
+
// Track page visibility changes
|
|
13996
|
+
this.setupVisibilityTracking();
|
|
13997
|
+
// Track page unload
|
|
13998
|
+
this.setupUnloadTracking();
|
|
13999
|
+
// Mark as fully initialized only after everything is loaded
|
|
14000
|
+
this.initialized = true;
|
|
14001
|
+
this.initializing = false;
|
|
14002
|
+
};
|
|
14003
|
+
// Use requestIdleCallback to defer heavy initialization (non-blocking)
|
|
14004
|
+
// Falls back to setTimeout for browsers that don't support it
|
|
14005
|
+
if (typeof window !== 'undefined') {
|
|
14006
|
+
if ('requestIdleCallback' in window) {
|
|
14007
|
+
window.requestIdleCallback(initHeavyCollectors, { timeout: 2000 });
|
|
13981
14008
|
}
|
|
13982
|
-
|
|
13983
|
-
|
|
13984
|
-
|
|
13985
|
-
|
|
13986
|
-
}
|
|
13987
|
-
|
|
13988
|
-
|
|
13989
|
-
|
|
13990
|
-
|
|
13991
|
-
// Track page unload
|
|
13992
|
-
this.setupUnloadTracking();
|
|
13993
|
-
this.initialized = true;
|
|
14009
|
+
else {
|
|
14010
|
+
// Fallback for older browsers
|
|
14011
|
+
setTimeout(initHeavyCollectors, 1);
|
|
14012
|
+
}
|
|
14013
|
+
}
|
|
14014
|
+
else {
|
|
14015
|
+
// Node.js environment (SSR)
|
|
14016
|
+
initHeavyCollectors();
|
|
14017
|
+
}
|
|
13994
14018
|
if (this.config.debug) {
|
|
13995
|
-
console.log('[DevSkin] SDK
|
|
14019
|
+
console.log('[DevSkin] SDK initialization started (heavy collectors loading in background)');
|
|
13996
14020
|
}
|
|
13997
14021
|
}
|
|
13998
14022
|
/**
|
|
13999
14023
|
* Track a custom event
|
|
14024
|
+
* Works immediately after init() even if heavy collectors are still loading
|
|
14000
14025
|
*/
|
|
14001
14026
|
track(eventName, properties) {
|
|
14002
|
-
var _a, _b;
|
|
14003
|
-
if (!this.
|
|
14027
|
+
var _a, _b, _c, _d;
|
|
14028
|
+
if (!this.transport) {
|
|
14004
14029
|
console.warn('[DevSkin] SDK not initialized. Call init() first.');
|
|
14005
14030
|
return;
|
|
14006
14031
|
}
|
|
@@ -14008,15 +14033,15 @@
|
|
|
14008
14033
|
eventName: eventName,
|
|
14009
14034
|
eventType: 'track',
|
|
14010
14035
|
timestamp: new Date().toISOString(),
|
|
14011
|
-
sessionId: this.sessionId,
|
|
14012
|
-
userId: this.userId
|
|
14013
|
-
anonymousId: this.anonymousId
|
|
14036
|
+
sessionId: (_a = this.sessionId) !== null && _a !== void 0 ? _a : undefined,
|
|
14037
|
+
userId: (_b = this.userId) !== null && _b !== void 0 ? _b : undefined,
|
|
14038
|
+
anonymousId: (_c = this.anonymousId) !== null && _c !== void 0 ? _c : undefined,
|
|
14014
14039
|
properties: Object.assign(Object.assign({}, properties), this.getContextData()),
|
|
14015
14040
|
pageUrl: window.location.href,
|
|
14016
14041
|
pageTitle: document.title,
|
|
14017
14042
|
};
|
|
14018
|
-
|
|
14019
|
-
if ((
|
|
14043
|
+
this.transport.sendEvent(eventData);
|
|
14044
|
+
if ((_d = this.config) === null || _d === void 0 ? void 0 : _d.debug) {
|
|
14020
14045
|
console.log('[DevSkin] Event tracked:', eventData);
|
|
14021
14046
|
}
|
|
14022
14047
|
}
|
|
@@ -14045,23 +14070,24 @@
|
|
|
14045
14070
|
}
|
|
14046
14071
|
/**
|
|
14047
14072
|
* Identify a user
|
|
14073
|
+
* Works immediately after init() even if heavy collectors are still loading
|
|
14048
14074
|
*/
|
|
14049
14075
|
identify(userId, traits) {
|
|
14050
|
-
var _a, _b;
|
|
14051
|
-
if (!this.
|
|
14076
|
+
var _a, _b, _c;
|
|
14077
|
+
if (!this.transport) {
|
|
14052
14078
|
console.warn('[DevSkin] SDK not initialized. Call init() first.');
|
|
14053
14079
|
return;
|
|
14054
14080
|
}
|
|
14055
14081
|
this.userId = userId;
|
|
14056
14082
|
const userData = {
|
|
14057
14083
|
userId: userId,
|
|
14058
|
-
anonymousId: this.anonymousId
|
|
14084
|
+
anonymousId: (_a = this.anonymousId) !== null && _a !== void 0 ? _a : undefined,
|
|
14059
14085
|
traits: Object.assign(Object.assign({}, traits), this.getContextData()),
|
|
14060
|
-
sessionId: this.sessionId,
|
|
14086
|
+
sessionId: (_b = this.sessionId) !== null && _b !== void 0 ? _b : undefined,
|
|
14061
14087
|
timestamp: new Date().toISOString(),
|
|
14062
14088
|
};
|
|
14063
|
-
|
|
14064
|
-
if ((
|
|
14089
|
+
this.transport.identifyUser(userData);
|
|
14090
|
+
if ((_c = this.config) === null || _c === void 0 ? void 0 : _c.debug) {
|
|
14065
14091
|
console.log('[DevSkin] User identified:', userData);
|
|
14066
14092
|
}
|
|
14067
14093
|
}
|