@devskin/browser-sdk 1.0.40 → 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/devskin.cjs.js +116 -92
- package/dist/devskin.cjs.js.map +1 -1
- package/dist/devskin.esm.js +116 -92
- package/dist/devskin.esm.js.map +1 -1
- package/dist/devskin.umd.js +116 -92
- package/dist/devskin.umd.js.map +1 -1
- package/dist/devskin.umd.min.js +1 -1
- 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
|
@@ -13880,6 +13880,7 @@
|
|
|
13880
13880
|
this.anonymousId = null;
|
|
13881
13881
|
this.sessionStartTime = 0;
|
|
13882
13882
|
this.initialized = false;
|
|
13883
|
+
this.initializing = false;
|
|
13883
13884
|
this.heartbeatInterval = null;
|
|
13884
13885
|
// Collectors
|
|
13885
13886
|
this.deviceCollector = null;
|
|
@@ -13895,12 +13896,15 @@
|
|
|
13895
13896
|
}
|
|
13896
13897
|
/**
|
|
13897
13898
|
* Initialize the DevSkin SDK
|
|
13899
|
+
* Uses requestIdleCallback to defer heavy initialization without blocking the page
|
|
13898
13900
|
*/
|
|
13899
13901
|
init(config) {
|
|
13900
|
-
if (this.initialized) {
|
|
13901
|
-
console.warn('[DevSkin] SDK already initialized');
|
|
13902
|
+
if (this.initialized || this.initializing) {
|
|
13903
|
+
console.warn('[DevSkin] SDK already initialized or initializing');
|
|
13902
13904
|
return;
|
|
13903
13905
|
}
|
|
13906
|
+
// Mark as initializing to prevent duplicate init() calls
|
|
13907
|
+
this.initializing = true;
|
|
13904
13908
|
this.config = Object.assign({ debug: false, captureWebVitals: true, captureNetworkRequests: true, captureErrors: true, captureUserAgent: true, captureLocation: true, captureDevice: true, heatmapOptions: {
|
|
13905
13909
|
enabled: true,
|
|
13906
13910
|
trackClicks: true,
|
|
@@ -13910,99 +13914,118 @@
|
|
|
13910
13914
|
if (this.config.debug) {
|
|
13911
13915
|
console.log('[DevSkin] Initializing SDK with config:', this.config);
|
|
13912
13916
|
}
|
|
13913
|
-
// Initialize
|
|
13917
|
+
// Initialize lightweight components immediately (needed for session context)
|
|
13914
13918
|
this.transport = new Transport(this.config);
|
|
13915
|
-
// Generate anonymous ID if not exists
|
|
13916
13919
|
this.anonymousId = this.getOrCreateAnonymousId();
|
|
13917
|
-
// Initialize collectors BEFORE starting session (so getContextData works)
|
|
13918
13920
|
this.deviceCollector = new DeviceCollector(this.config);
|
|
13919
13921
|
this.locationCollector = new LocationCollector(this.config);
|
|
13920
13922
|
this.browserCollector = new BrowserCollector(this.config);
|
|
13921
|
-
//
|
|
13922
|
-
|
|
13923
|
-
|
|
13924
|
-
//
|
|
13925
|
-
|
|
13926
|
-
|
|
13927
|
-
|
|
13928
|
-
this.
|
|
13929
|
-
|
|
13930
|
-
|
|
13931
|
-
|
|
13932
|
-
this.
|
|
13933
|
-
|
|
13934
|
-
|
|
13935
|
-
|
|
13936
|
-
this.
|
|
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
|
-
|
|
13980
|
-
|
|
13981
|
-
|
|
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
|
+
}
|
|
13982
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 });
|
|
13983
14008
|
}
|
|
13984
|
-
|
|
13985
|
-
|
|
13986
|
-
|
|
13987
|
-
|
|
13988
|
-
}
|
|
13989
|
-
|
|
13990
|
-
|
|
13991
|
-
|
|
13992
|
-
|
|
13993
|
-
// Track page unload
|
|
13994
|
-
this.setupUnloadTracking();
|
|
13995
|
-
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
|
+
}
|
|
13996
14018
|
if (this.config.debug) {
|
|
13997
|
-
console.log('[DevSkin] SDK
|
|
14019
|
+
console.log('[DevSkin] SDK initialization started (heavy collectors loading in background)');
|
|
13998
14020
|
}
|
|
13999
14021
|
}
|
|
14000
14022
|
/**
|
|
14001
14023
|
* Track a custom event
|
|
14024
|
+
* Works immediately after init() even if heavy collectors are still loading
|
|
14002
14025
|
*/
|
|
14003
14026
|
track(eventName, properties) {
|
|
14004
|
-
var _a, _b;
|
|
14005
|
-
if (!this.
|
|
14027
|
+
var _a, _b, _c, _d;
|
|
14028
|
+
if (!this.transport) {
|
|
14006
14029
|
console.warn('[DevSkin] SDK not initialized. Call init() first.');
|
|
14007
14030
|
return;
|
|
14008
14031
|
}
|
|
@@ -14010,15 +14033,15 @@
|
|
|
14010
14033
|
eventName: eventName,
|
|
14011
14034
|
eventType: 'track',
|
|
14012
14035
|
timestamp: new Date().toISOString(),
|
|
14013
|
-
sessionId: this.sessionId,
|
|
14014
|
-
userId: this.userId
|
|
14015
|
-
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,
|
|
14016
14039
|
properties: Object.assign(Object.assign({}, properties), this.getContextData()),
|
|
14017
14040
|
pageUrl: window.location.href,
|
|
14018
14041
|
pageTitle: document.title,
|
|
14019
14042
|
};
|
|
14020
|
-
|
|
14021
|
-
if ((
|
|
14043
|
+
this.transport.sendEvent(eventData);
|
|
14044
|
+
if ((_d = this.config) === null || _d === void 0 ? void 0 : _d.debug) {
|
|
14022
14045
|
console.log('[DevSkin] Event tracked:', eventData);
|
|
14023
14046
|
}
|
|
14024
14047
|
}
|
|
@@ -14047,23 +14070,24 @@
|
|
|
14047
14070
|
}
|
|
14048
14071
|
/**
|
|
14049
14072
|
* Identify a user
|
|
14073
|
+
* Works immediately after init() even if heavy collectors are still loading
|
|
14050
14074
|
*/
|
|
14051
14075
|
identify(userId, traits) {
|
|
14052
|
-
var _a, _b;
|
|
14053
|
-
if (!this.
|
|
14076
|
+
var _a, _b, _c;
|
|
14077
|
+
if (!this.transport) {
|
|
14054
14078
|
console.warn('[DevSkin] SDK not initialized. Call init() first.');
|
|
14055
14079
|
return;
|
|
14056
14080
|
}
|
|
14057
14081
|
this.userId = userId;
|
|
14058
14082
|
const userData = {
|
|
14059
14083
|
userId: userId,
|
|
14060
|
-
anonymousId: this.anonymousId
|
|
14084
|
+
anonymousId: (_a = this.anonymousId) !== null && _a !== void 0 ? _a : undefined,
|
|
14061
14085
|
traits: Object.assign(Object.assign({}, traits), this.getContextData()),
|
|
14062
|
-
sessionId: this.sessionId,
|
|
14086
|
+
sessionId: (_b = this.sessionId) !== null && _b !== void 0 ? _b : undefined,
|
|
14063
14087
|
timestamp: new Date().toISOString(),
|
|
14064
14088
|
};
|
|
14065
|
-
|
|
14066
|
-
if ((
|
|
14089
|
+
this.transport.identifyUser(userData);
|
|
14090
|
+
if ((_c = this.config) === null || _c === void 0 ? void 0 : _c.debug) {
|
|
14067
14091
|
console.log('[DevSkin] User identified:', userData);
|
|
14068
14092
|
}
|
|
14069
14093
|
}
|