@devskin/browser-sdk 1.0.30 → 1.0.32
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/network.d.ts.map +1 -1
- package/dist/collectors/performance.d.ts.map +1 -1
- package/dist/devskin.cjs.js +172 -182
- package/dist/devskin.cjs.js.map +1 -1
- package/dist/devskin.esm.js +172 -182
- package/dist/devskin.esm.js.map +1 -1
- package/dist/devskin.umd.js +172 -182
- 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.map +1 -1
- package/dist/transport.d.ts +3 -1
- package/dist/transport.d.ts.map +1 -1
- package/dist/types.d.ts +8 -7
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/devskin.umd.js
CHANGED
|
@@ -4,6 +4,38 @@
|
|
|
4
4
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.DevSkin = factory());
|
|
5
5
|
})(this, (function () { 'use strict';
|
|
6
6
|
|
|
7
|
+
/******************************************************************************
|
|
8
|
+
Copyright (c) Microsoft Corporation.
|
|
9
|
+
|
|
10
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
11
|
+
purpose with or without fee is hereby granted.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
14
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
15
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
16
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
17
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
18
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
19
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
20
|
+
***************************************************************************** */
|
|
21
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
function __awaiter$1(thisArg, _arguments, P, generator) {
|
|
25
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
26
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
27
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
28
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
29
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
30
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
35
|
+
var e = new Error(message);
|
|
36
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
37
|
+
};
|
|
38
|
+
|
|
7
39
|
class DeviceCollector {
|
|
8
40
|
constructor(config) {
|
|
9
41
|
this.config = config;
|
|
@@ -121,38 +153,6 @@
|
|
|
121
153
|
}
|
|
122
154
|
}
|
|
123
155
|
|
|
124
|
-
/******************************************************************************
|
|
125
|
-
Copyright (c) Microsoft Corporation.
|
|
126
|
-
|
|
127
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
128
|
-
purpose with or without fee is hereby granted.
|
|
129
|
-
|
|
130
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
131
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
132
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
133
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
134
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
135
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
136
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
137
|
-
***************************************************************************** */
|
|
138
|
-
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
function __awaiter$1(thisArg, _arguments, P, generator) {
|
|
142
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
143
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
144
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
145
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
146
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
147
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
152
|
-
var e = new Error(message);
|
|
153
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
154
|
-
};
|
|
155
|
-
|
|
156
156
|
class LocationCollector {
|
|
157
157
|
constructor(config) {
|
|
158
158
|
this.config = config;
|
|
@@ -340,12 +340,12 @@
|
|
|
340
340
|
if (this.config.debug) {
|
|
341
341
|
console.log(`[DevSkin] Web Vital ${metric.name}:`, metric.value);
|
|
342
342
|
}
|
|
343
|
-
// Send metric to backend
|
|
343
|
+
// Send metric to backend - match backend schema
|
|
344
344
|
this.transport.sendPerformanceMetric({
|
|
345
|
-
|
|
345
|
+
metricName: metric.name, // Changed from 'name' to 'metricName'
|
|
346
346
|
value: metric.value,
|
|
347
347
|
rating: metric.rating,
|
|
348
|
-
|
|
348
|
+
url: window.location.href,
|
|
349
349
|
timestamp: new Date().toISOString(),
|
|
350
350
|
});
|
|
351
351
|
}
|
|
@@ -368,19 +368,9 @@
|
|
|
368
368
|
});
|
|
369
369
|
}
|
|
370
370
|
this.transport.sendPerformanceMetric({
|
|
371
|
-
|
|
371
|
+
metricName: 'Navigation',
|
|
372
372
|
value: windowLoad,
|
|
373
|
-
|
|
374
|
-
domLoad,
|
|
375
|
-
windowLoad,
|
|
376
|
-
navigationType: navigation.type,
|
|
377
|
-
redirectCount: navigation.redirectCount,
|
|
378
|
-
dns: timing.domainLookupEnd - timing.domainLookupStart,
|
|
379
|
-
tcp: timing.connectEnd - timing.connectStart,
|
|
380
|
-
request: timing.responseStart - timing.requestStart,
|
|
381
|
-
response: timing.responseEnd - timing.responseStart,
|
|
382
|
-
dom: timing.domComplete - timing.domLoading,
|
|
383
|
-
},
|
|
373
|
+
url: window.location.href,
|
|
384
374
|
timestamp: new Date().toISOString(),
|
|
385
375
|
});
|
|
386
376
|
}, 0);
|
|
@@ -414,9 +404,9 @@
|
|
|
414
404
|
console.log('[DevSkin] Resource Timings:', resourceStats);
|
|
415
405
|
}
|
|
416
406
|
this.transport.sendPerformanceMetric({
|
|
417
|
-
|
|
407
|
+
metricName: 'Resources',
|
|
418
408
|
value: resources.length,
|
|
419
|
-
|
|
409
|
+
url: window.location.href,
|
|
420
410
|
timestamp: new Date().toISOString(),
|
|
421
411
|
});
|
|
422
412
|
}, 1000);
|
|
@@ -433,13 +423,9 @@
|
|
|
433
423
|
console.log('[DevSkin] Long Task detected:', entry);
|
|
434
424
|
}
|
|
435
425
|
this.transport.sendPerformanceMetric({
|
|
436
|
-
|
|
426
|
+
metricName: 'LongTask',
|
|
437
427
|
value: entry.duration,
|
|
438
|
-
|
|
439
|
-
name: entry.name,
|
|
440
|
-
entryType: entry.entryType,
|
|
441
|
-
startTime: entry.startTime,
|
|
442
|
-
},
|
|
428
|
+
url: window.location.href,
|
|
443
429
|
timestamp: new Date().toISOString(),
|
|
444
430
|
});
|
|
445
431
|
}
|
|
@@ -679,7 +665,7 @@
|
|
|
679
665
|
return;
|
|
680
666
|
const originalFetch = window.fetch;
|
|
681
667
|
window.fetch = (...args) => __awaiter$1(this, void 0, void 0, function* () {
|
|
682
|
-
var _a, _b
|
|
668
|
+
var _a, _b;
|
|
683
669
|
const [resource, config] = args;
|
|
684
670
|
const url = typeof resource === 'string'
|
|
685
671
|
? resource
|
|
@@ -705,26 +691,18 @@
|
|
|
705
691
|
const networkRequest = {
|
|
706
692
|
url,
|
|
707
693
|
method,
|
|
708
|
-
|
|
709
|
-
duration,
|
|
710
|
-
|
|
711
|
-
type: 'fetch',
|
|
694
|
+
statusCode: response.status,
|
|
695
|
+
durationMs: duration,
|
|
696
|
+
responseSize: yield this.getResponseSize(clonedResponse),
|
|
712
697
|
timestamp: new Date().toISOString(),
|
|
713
|
-
failed: !response.ok,
|
|
714
698
|
};
|
|
715
699
|
// Capture headers if enabled
|
|
716
700
|
if ((_b = this.config.networkRequestOptions) === null || _b === void 0 ? void 0 : _b.captureHeaders) {
|
|
717
|
-
networkRequest.
|
|
701
|
+
networkRequest.responseHeaders = this.headersToObject(response.headers);
|
|
718
702
|
}
|
|
719
|
-
// Capture
|
|
720
|
-
if (
|
|
721
|
-
|
|
722
|
-
const text = yield clonedResponse.text();
|
|
723
|
-
networkRequest.body = text.substring(0, 10000); // Limit to 10KB
|
|
724
|
-
}
|
|
725
|
-
catch (error) {
|
|
726
|
-
// Body might not be readable
|
|
727
|
-
}
|
|
703
|
+
// Capture error message for failed requests
|
|
704
|
+
if (!response.ok) {
|
|
705
|
+
networkRequest.errorMessage = `HTTP ${response.status} ${response.statusText}`;
|
|
728
706
|
}
|
|
729
707
|
if (this.config.debug) {
|
|
730
708
|
console.log('[DevSkin] Network request tracked:', networkRequest);
|
|
@@ -738,10 +716,9 @@
|
|
|
738
716
|
const networkRequest = {
|
|
739
717
|
url,
|
|
740
718
|
method,
|
|
741
|
-
duration,
|
|
742
|
-
type: 'fetch',
|
|
719
|
+
durationMs: duration,
|
|
743
720
|
timestamp: new Date().toISOString(),
|
|
744
|
-
|
|
721
|
+
errorMessage: error instanceof Error ? error.message : 'Network request failed',
|
|
745
722
|
};
|
|
746
723
|
if (this.config.debug) {
|
|
747
724
|
console.log('[DevSkin] Network request failed:', networkRequest);
|
|
@@ -780,7 +757,7 @@
|
|
|
780
757
|
const collector = window.__devskinNetworkCollector;
|
|
781
758
|
// Track when request completes
|
|
782
759
|
const handleLoad = () => {
|
|
783
|
-
var _a, _b
|
|
760
|
+
var _a, _b;
|
|
784
761
|
const duration = Date.now() - devskin.startTime;
|
|
785
762
|
// Check if should be ignored
|
|
786
763
|
if (collector === null || collector === void 0 ? void 0 : collector.shouldIgnoreUrl(devskin.url)) {
|
|
@@ -795,25 +772,17 @@
|
|
|
795
772
|
const networkRequest = {
|
|
796
773
|
url: devskin.url,
|
|
797
774
|
method: devskin.method,
|
|
798
|
-
|
|
799
|
-
duration,
|
|
800
|
-
type: 'xhr',
|
|
775
|
+
statusCode: xhr.status,
|
|
776
|
+
durationMs: duration,
|
|
801
777
|
timestamp: new Date().toISOString(),
|
|
802
|
-
failed: xhr.status === 0 || xhr.status >= 400,
|
|
803
778
|
};
|
|
804
779
|
// Capture headers if enabled
|
|
805
780
|
if ((_b = collector === null || collector === void 0 ? void 0 : collector.config.networkRequestOptions) === null || _b === void 0 ? void 0 : _b.captureHeaders) {
|
|
806
|
-
networkRequest.
|
|
781
|
+
networkRequest.responseHeaders = collector.parseResponseHeaders(xhr.getAllResponseHeaders());
|
|
807
782
|
}
|
|
808
|
-
// Capture
|
|
809
|
-
if (
|
|
810
|
-
networkRequest.
|
|
811
|
-
try {
|
|
812
|
-
networkRequest.body = (_d = xhr.responseText) === null || _d === void 0 ? void 0 : _d.substring(0, 10000);
|
|
813
|
-
}
|
|
814
|
-
catch (error) {
|
|
815
|
-
// Response might not be readable
|
|
816
|
-
}
|
|
783
|
+
// Capture error message for failed requests
|
|
784
|
+
if (xhr.status === 0 || xhr.status >= 400) {
|
|
785
|
+
networkRequest.errorMessage = `HTTP ${xhr.status} ${xhr.statusText}`;
|
|
817
786
|
}
|
|
818
787
|
if (collector === null || collector === void 0 ? void 0 : collector.config.debug) {
|
|
819
788
|
console.log('[DevSkin] XHR request tracked:', networkRequest);
|
|
@@ -826,10 +795,9 @@
|
|
|
826
795
|
const networkRequest = {
|
|
827
796
|
url: devskin.url,
|
|
828
797
|
method: devskin.method,
|
|
829
|
-
duration,
|
|
830
|
-
type: 'xhr',
|
|
798
|
+
durationMs: duration,
|
|
831
799
|
timestamp: new Date().toISOString(),
|
|
832
|
-
|
|
800
|
+
errorMessage: 'XHR request failed',
|
|
833
801
|
};
|
|
834
802
|
if (collector === null || collector === void 0 ? void 0 : collector.config.debug) {
|
|
835
803
|
console.log('[DevSkin] XHR request failed:', networkRequest);
|
|
@@ -13592,6 +13560,7 @@
|
|
|
13592
13560
|
this.flushInterval = null;
|
|
13593
13561
|
this.maxQueueSize = 20; // Reduced from 50
|
|
13594
13562
|
this.flushIntervalMs = 2000; // 2 seconds (reduced from 5s)
|
|
13563
|
+
this.sessionId = null;
|
|
13595
13564
|
this.apiUrl = config.apiUrl || 'https://api.devskin.com';
|
|
13596
13565
|
// Start periodic flush
|
|
13597
13566
|
this.startPeriodicFlush();
|
|
@@ -13608,6 +13577,9 @@
|
|
|
13608
13577
|
});
|
|
13609
13578
|
}
|
|
13610
13579
|
}
|
|
13580
|
+
setSessionId(sessionId) {
|
|
13581
|
+
this.sessionId = sessionId;
|
|
13582
|
+
}
|
|
13611
13583
|
sendEvent(event) {
|
|
13612
13584
|
this.enqueue('event', event);
|
|
13613
13585
|
}
|
|
@@ -13616,8 +13588,11 @@
|
|
|
13616
13588
|
this.sendToBackend('/v1/analytics/identify', user);
|
|
13617
13589
|
}
|
|
13618
13590
|
startSession(session) {
|
|
13619
|
-
|
|
13620
|
-
|
|
13591
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
13592
|
+
// Send session start immediately to RUM endpoint
|
|
13593
|
+
// MUST await to ensure session is created before other requests
|
|
13594
|
+
yield this.sendToBackend('/v1/rum/sessions', session);
|
|
13595
|
+
});
|
|
13621
13596
|
}
|
|
13622
13597
|
sendError(error) {
|
|
13623
13598
|
this.enqueue('error', error);
|
|
@@ -13729,9 +13704,16 @@
|
|
|
13729
13704
|
}
|
|
13730
13705
|
}
|
|
13731
13706
|
enqueue(type, data) {
|
|
13732
|
-
// Add applicationId to RUM events (event, error, network, performance)
|
|
13707
|
+
// Add applicationId and sessionId to RUM events (event, error, network, performance)
|
|
13733
13708
|
// Heatmap uses apiKey/appId in payload root instead
|
|
13734
|
-
|
|
13709
|
+
let enrichedData = data;
|
|
13710
|
+
if (type !== 'heatmap') {
|
|
13711
|
+
enrichedData = Object.assign(Object.assign({}, data), { applicationId: this.config.appId });
|
|
13712
|
+
// Add sessionId to network and performance requests (required by backend)
|
|
13713
|
+
if ((type === 'network' || type === 'performance') && this.sessionId) {
|
|
13714
|
+
enrichedData.sessionId = this.sessionId;
|
|
13715
|
+
}
|
|
13716
|
+
}
|
|
13735
13717
|
this.queue.push({
|
|
13736
13718
|
type,
|
|
13737
13719
|
data: enrichedData,
|
|
@@ -13895,7 +13877,6 @@
|
|
|
13895
13877
|
* Initialize the DevSkin SDK
|
|
13896
13878
|
*/
|
|
13897
13879
|
init(config) {
|
|
13898
|
-
var _a;
|
|
13899
13880
|
if (this.initialized) {
|
|
13900
13881
|
console.warn('[DevSkin] SDK already initialized');
|
|
13901
13882
|
return;
|
|
@@ -13918,69 +13899,71 @@
|
|
|
13918
13899
|
this.locationCollector = new LocationCollector(this.config);
|
|
13919
13900
|
this.browserCollector = new BrowserCollector(this.config);
|
|
13920
13901
|
// Start session (will now include device/browser/location data)
|
|
13921
|
-
|
|
13922
|
-
|
|
13923
|
-
|
|
13924
|
-
|
|
13925
|
-
|
|
13926
|
-
|
|
13927
|
-
|
|
13928
|
-
|
|
13929
|
-
|
|
13930
|
-
|
|
13931
|
-
|
|
13932
|
-
|
|
13933
|
-
|
|
13934
|
-
|
|
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
|
-
|
|
13902
|
+
// Wait for session creation to complete before starting collectors
|
|
13903
|
+
this.startSession().then(() => {
|
|
13904
|
+
// Session created, now safe to start collectors that send data
|
|
13905
|
+
var _a, _b;
|
|
13906
|
+
if (this.config.captureWebVitals) {
|
|
13907
|
+
this.performanceCollector = new PerformanceCollector(this.config, this.transport);
|
|
13908
|
+
this.performanceCollector.start();
|
|
13909
|
+
}
|
|
13910
|
+
if (this.config.captureErrors) {
|
|
13911
|
+
this.errorCollector = new ErrorCollector(this.config, this.transport);
|
|
13912
|
+
this.errorCollector.start();
|
|
13913
|
+
}
|
|
13914
|
+
if (this.config.captureNetworkRequests) {
|
|
13915
|
+
this.networkCollector = new NetworkCollector(this.config, this.transport);
|
|
13916
|
+
this.networkCollector.start();
|
|
13917
|
+
}
|
|
13918
|
+
// Initialize heatmap collector - SEMPRE habilitado
|
|
13919
|
+
// Merge default heatmap config with user config
|
|
13920
|
+
const heatmapConfig = Object.assign({ enabled: true, trackClicks: true, trackScroll: true, trackMouseMovement: true, mouseMoveSampling: 0.1 }, this.config.heatmapOptions);
|
|
13921
|
+
this.config.heatmapOptions = heatmapConfig;
|
|
13922
|
+
this.heatmapCollector = new HeatmapCollector(this.config, this.transport);
|
|
13923
|
+
this.heatmapCollector.start();
|
|
13924
|
+
// Initialize screenshot collector and capture page
|
|
13925
|
+
this.screenshotCollector = new ScreenshotCollector(this.config, this.transport);
|
|
13926
|
+
this.screenshotCollector.captureAndSend(this.sessionId, window.location.href);
|
|
13927
|
+
if (this.config.debug) {
|
|
13928
|
+
console.log('[DevSkin] Heatmap collection enabled (always on)');
|
|
13929
|
+
}
|
|
13930
|
+
// Initialize session recording with rrweb
|
|
13931
|
+
if ((_a = this.config.sessionRecording) === null || _a === void 0 ? void 0 : _a.enabled) {
|
|
13932
|
+
// Use RRWebRecorder for complete DOM recording
|
|
13933
|
+
this.rrwebRecorder = new RRWebRecorder(this.sessionId, {
|
|
13934
|
+
enabled: true,
|
|
13935
|
+
sampleRate: this.config.sessionRecording.sampling || 0.5,
|
|
13936
|
+
blockClass: 'rr-block',
|
|
13937
|
+
ignoreClass: this.config.sessionRecording.ignoreClass || 'rr-ignore',
|
|
13938
|
+
maskAllInputs: this.config.sessionRecording.maskAllInputs !== undefined
|
|
13939
|
+
? this.config.sessionRecording.maskAllInputs
|
|
13940
|
+
: true,
|
|
13941
|
+
maskInputOptions: {
|
|
13942
|
+
password: true,
|
|
13943
|
+
email: true,
|
|
13944
|
+
tel: true,
|
|
13945
|
+
},
|
|
13946
|
+
recordCanvas: this.config.sessionRecording.recordCanvas || false,
|
|
13947
|
+
collectFonts: true,
|
|
13948
|
+
inlineStylesheet: true,
|
|
13949
|
+
checkoutEveryNms: 5 * 60 * 1000, // Every 5 minutes
|
|
13950
|
+
checkoutEveryNth: 200, // Every 200 events
|
|
13951
|
+
}, (events) => {
|
|
13952
|
+
var _a;
|
|
13953
|
+
// Send rrweb events to backend
|
|
13954
|
+
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.sendRecordingEvents(this.sessionId, events);
|
|
13955
|
+
});
|
|
13956
|
+
// Start recording immediately (session already created)
|
|
13957
|
+
this.rrwebRecorder.start();
|
|
13977
13958
|
if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.debug) {
|
|
13978
13959
|
console.log('[DevSkin] RRWeb recording started for session:', this.sessionId);
|
|
13979
13960
|
}
|
|
13980
|
-
}
|
|
13981
|
-
|
|
13982
|
-
|
|
13983
|
-
|
|
13961
|
+
}
|
|
13962
|
+
// Track initial page view
|
|
13963
|
+
this.trackPageView();
|
|
13964
|
+
}).catch((err) => {
|
|
13965
|
+
console.error('[DevSkin] Failed to create session:', err);
|
|
13966
|
+
});
|
|
13984
13967
|
// Track page visibility changes
|
|
13985
13968
|
this.setupVisibilityTracking();
|
|
13986
13969
|
// Track page unload
|
|
@@ -14105,32 +14088,39 @@
|
|
|
14105
14088
|
* Private methods
|
|
14106
14089
|
*/
|
|
14107
14090
|
startSession() {
|
|
14108
|
-
|
|
14109
|
-
|
|
14110
|
-
|
|
14111
|
-
|
|
14112
|
-
|
|
14113
|
-
|
|
14114
|
-
|
|
14115
|
-
|
|
14116
|
-
|
|
14117
|
-
|
|
14091
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
14092
|
+
var _a, _b, _c, _d, _e;
|
|
14093
|
+
// Check if there's an active session (stored in sessionStorage to persist across page navigations)
|
|
14094
|
+
const existingSessionId = sessionStorage.getItem('devskin_session_id');
|
|
14095
|
+
const existingSessionStart = sessionStorage.getItem('devskin_session_start');
|
|
14096
|
+
if (existingSessionId && existingSessionStart) {
|
|
14097
|
+
// Resume existing session
|
|
14098
|
+
this.sessionId = existingSessionId;
|
|
14099
|
+
this.sessionStartTime = parseInt(existingSessionStart, 10);
|
|
14100
|
+
// Set sessionId in transport so it can be added to network/performance requests
|
|
14101
|
+
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.setSessionId(this.sessionId);
|
|
14102
|
+
if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.debug) {
|
|
14103
|
+
console.log('[DevSkin] Resuming existing session:', this.sessionId);
|
|
14104
|
+
}
|
|
14105
|
+
// Send page view but DON'T create a new session
|
|
14106
|
+
// The session is already created, just continue it
|
|
14107
|
+
return;
|
|
14118
14108
|
}
|
|
14119
|
-
//
|
|
14120
|
-
|
|
14121
|
-
|
|
14122
|
-
|
|
14123
|
-
|
|
14124
|
-
|
|
14125
|
-
|
|
14126
|
-
|
|
14127
|
-
|
|
14128
|
-
|
|
14129
|
-
|
|
14130
|
-
|
|
14131
|
-
|
|
14132
|
-
|
|
14133
|
-
}
|
|
14109
|
+
// Create new session
|
|
14110
|
+
this.sessionId = this.generateId();
|
|
14111
|
+
this.sessionStartTime = Date.now();
|
|
14112
|
+
// Store in sessionStorage (persists across page navigations in same tab)
|
|
14113
|
+
sessionStorage.setItem('devskin_session_id', this.sessionId);
|
|
14114
|
+
sessionStorage.setItem('devskin_session_start', this.sessionStartTime.toString());
|
|
14115
|
+
// Set sessionId in transport so it can be added to network/performance requests
|
|
14116
|
+
(_c = this.transport) === null || _c === void 0 ? void 0 : _c.setSessionId(this.sessionId);
|
|
14117
|
+
const sessionData = Object.assign({ sessionId: this.sessionId, userId: this.userId || undefined, anonymousId: this.anonymousId, startedAt: new Date().toISOString(), platform: 'web' }, this.getContextData());
|
|
14118
|
+
// CRITICAL: Await session creation to ensure it exists before sending metrics/requests
|
|
14119
|
+
yield ((_d = this.transport) === null || _d === void 0 ? void 0 : _d.startSession(sessionData));
|
|
14120
|
+
if ((_e = this.config) === null || _e === void 0 ? void 0 : _e.debug) {
|
|
14121
|
+
console.log('[DevSkin] New session created:', this.sessionId);
|
|
14122
|
+
}
|
|
14123
|
+
});
|
|
14134
14124
|
}
|
|
14135
14125
|
getContextData() {
|
|
14136
14126
|
var _a, _b, _c, _d;
|