countly-sdk-web 26.1.0 → 26.1.1
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/CHANGELOG.md +4 -0
- package/cypress/e2e/bridged_utils.cy.js +1 -1
- package/cypress/e2e/sdk_info.cy.js +1 -1
- package/examples/example_quick_async.html +63 -0
- package/examples/quick_loader/quick_async_loader.js +152 -0
- package/examples/quick_loader/quick_async_loader.min.js +4 -0
- package/lib/countly.js +312 -1
- package/lib/countly.min.js +246 -236
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<title>Countly Unified Async Loader</title>
|
|
7
|
+
<link rel="stylesheet" type="text/css" href="./style/style.css">
|
|
8
|
+
<script type="text/javascript">
|
|
9
|
+
(function(l,t){function y(c){return function(){p.push([c].concat(Array.prototype.slice.call(arguments,0)));return d}}function u(c,a,e){e=y(e||a);e.__isCountlyStub=!0;c[a]=e}function z(c){if(!v&&!m){m=!0;var a=t.createElement("script");a.type="text/javascript";a.async=!0;a.src=c;a.crossOrigin="anonymous";a.onload=function(){v=!0;m=!1;var h=l.Countly;h&&"function"===typeof h.init&&h.init(w||{});h=l.Countly;var x=p.slice();p=[];for(var q=0;q<x.length;q++){var b=x[q],f=h,A=b.slice(1);b=b[0].split(".");
|
|
10
|
+
for(var r=0;r<b.length-1;r++)f=f&&f[b[r]];b=b[b.length-1];b=f&&f[b];"function"!==typeof b||b.__isCountlyStub||b.apply(f,A||[])}};a.onerror=function(){m=!1;console.error("Countly loader failed to load SDK from:",c)};var e=t.getElementsByTagName("script")[0];e.parentNode.insertBefore(a,e)}}var d=l.Countly||(l.Countly={}),p=[],m=!1,v=!1,w=null;d.__clyBootstrap={version:"1.0.0",name:"countly-unified-loader"};for(var n="track_sessions track_pageview track_performance add_event user_details track_errors track_forms track_clicks track_scrolls track_links recordError change_id set_id uploadUserProfilePicture content.enterContentZone content.refreshContentZone content.exitContentZone feedback.showNPS feedback.showSurvey feedback.showRating userData.set userData.set_once userData.increment userData.increment_by userData.multiply userData.max userData.min userData.push userData.push_unique userData.pull userData.unset userData.save".split(" "),
|
|
11
|
+
k=0;k<n.length;k++){var g=n[k].split(".");2===g.length?(d[g[0]]=d[g[0]]||{},u(d[g[0]],g[1],n[k])):u(d,g[0],n[k])}d.init=function(c,a){"object"===typeof c&&(a=c||{},c=a.app_key);a=a||{};c&&(a.app_key=c);for(var e in a)Object.prototype.hasOwnProperty.call(a,e)&&(d[e]=a[e]);"YOUR_APP_KEY"!==d.app_key&&"https://your.server.ly"!==d.url||console.warn("Please do not use default set of app key and server url");w=a;z(d.sdk_url||"https://cdn.jsdelivr.net/npm/countly-sdk-web@latest/lib/countly.min.js");return d}})(window,
|
|
12
|
+
document);
|
|
13
|
+
|
|
14
|
+
Countly.init("YOUR_APP_KEY", {
|
|
15
|
+
url: "https://YOUR_SERVER_URL",
|
|
16
|
+
debug: true,
|
|
17
|
+
clear_stored_id: true
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
Countly.track_sessions();
|
|
21
|
+
Countly.track_pageview();
|
|
22
|
+
Countly.content.enterContentZone();
|
|
23
|
+
|
|
24
|
+
function clickEvent() {
|
|
25
|
+
Countly.add_event({
|
|
26
|
+
key: "buttonClick",
|
|
27
|
+
segmentation: {
|
|
28
|
+
id: "id"
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function uploadProfilePicture() {
|
|
34
|
+
var fileInput = document.getElementById("profilePicInput");
|
|
35
|
+
var file = fileInput.files[0];
|
|
36
|
+
if (!file) {
|
|
37
|
+
alert("Please select an image file.");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
Countly.uploadUserProfilePicture(file);
|
|
41
|
+
}
|
|
42
|
+
</script>
|
|
43
|
+
</head>
|
|
44
|
+
|
|
45
|
+
<body>
|
|
46
|
+
<div id="header">
|
|
47
|
+
<h1>Countly Unified Async Loader</h1>
|
|
48
|
+
<img id="logo" src="./images/logo.png">
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<center>
|
|
52
|
+
<img src="./images/team_countly.jpg" id="wallpaper" />
|
|
53
|
+
<br />
|
|
54
|
+
<input type="button" id="testButton" onclick="clickEvent()" value="Test Button">
|
|
55
|
+
<br /><br />
|
|
56
|
+
<input type="file" id="profilePicInput" accept="image/*">
|
|
57
|
+
<br /><br />
|
|
58
|
+
<input type="button" onclick="uploadProfilePicture()" value="Upload Profile Picture">
|
|
59
|
+
<p><a href="https://countly.com/">Countly</a></p>
|
|
60
|
+
</center>
|
|
61
|
+
</body>
|
|
62
|
+
|
|
63
|
+
</html>
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
(function (w, d) {
|
|
2
|
+
var c = w.Countly || (w.Countly = {});
|
|
3
|
+
var bootstrapMeta = {
|
|
4
|
+
version: "1.0.0",
|
|
5
|
+
name: "countly-unified-loader"
|
|
6
|
+
};
|
|
7
|
+
var pendingCalls = [];
|
|
8
|
+
var isLoading = false;
|
|
9
|
+
var isLoaded = false;
|
|
10
|
+
var initConfig = null;
|
|
11
|
+
|
|
12
|
+
c.__clyBootstrap = bootstrapMeta;
|
|
13
|
+
|
|
14
|
+
function queueCall(methodPath) {
|
|
15
|
+
return function () {
|
|
16
|
+
pendingCalls.push([methodPath].concat(Array.prototype.slice.call(arguments, 0)));
|
|
17
|
+
return c;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function addStub(target, methodName, methodPath) {
|
|
22
|
+
var stub = queueCall(methodPath || methodName);
|
|
23
|
+
stub.__isCountlyStub = true;
|
|
24
|
+
target[methodName] = stub;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function invokeMethod(root, methodPath, args) {
|
|
28
|
+
var chunks = methodPath.split(".");
|
|
29
|
+
var context = root;
|
|
30
|
+
for (var idx = 0; idx < chunks.length - 1; idx++) {
|
|
31
|
+
context = context && context[chunks[idx]];
|
|
32
|
+
}
|
|
33
|
+
var methodName = chunks[chunks.length - 1];
|
|
34
|
+
var method = context && context[methodName];
|
|
35
|
+
if (typeof method === "function" && !method.__isCountlyStub) {
|
|
36
|
+
method.apply(context, args || []);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function flushPendingCalls() {
|
|
41
|
+
var live = w.Countly;
|
|
42
|
+
var queue = pendingCalls.slice();
|
|
43
|
+
pendingCalls = [];
|
|
44
|
+
for (var idx = 0; idx < queue.length; idx++) {
|
|
45
|
+
var call = queue[idx];
|
|
46
|
+
invokeMethod(live, call[0], call.slice(1));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function loadSdk(scriptUrl) {
|
|
51
|
+
if (isLoaded || isLoading) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
isLoading = true;
|
|
55
|
+
|
|
56
|
+
var script = d.createElement("script");
|
|
57
|
+
script.type = "text/javascript";
|
|
58
|
+
script.async = true;
|
|
59
|
+
script.src = scriptUrl;
|
|
60
|
+
script.crossOrigin = "anonymous";
|
|
61
|
+
script.onload = function () {
|
|
62
|
+
isLoaded = true;
|
|
63
|
+
isLoading = false;
|
|
64
|
+
|
|
65
|
+
var live = w.Countly;
|
|
66
|
+
if (live && typeof live.init === "function") {
|
|
67
|
+
live.init(initConfig || {});
|
|
68
|
+
}
|
|
69
|
+
flushPendingCalls();
|
|
70
|
+
};
|
|
71
|
+
script.onerror = function () {
|
|
72
|
+
isLoading = false;
|
|
73
|
+
console.error("Countly loader failed to load SDK from:", scriptUrl);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
var first = d.getElementsByTagName("script")[0];
|
|
77
|
+
first.parentNode.insertBefore(script, first);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
var methods = [
|
|
81
|
+
"track_sessions",
|
|
82
|
+
"track_pageview",
|
|
83
|
+
"track_performance",
|
|
84
|
+
"add_event",
|
|
85
|
+
"user_details",
|
|
86
|
+
"track_errors",
|
|
87
|
+
"track_forms",
|
|
88
|
+
"track_clicks",
|
|
89
|
+
"track_scrolls",
|
|
90
|
+
"track_links",
|
|
91
|
+
"recordError",
|
|
92
|
+
"change_id",
|
|
93
|
+
"set_id",
|
|
94
|
+
"uploadUserProfilePicture",
|
|
95
|
+
"content.enterContentZone",
|
|
96
|
+
"content.refreshContentZone",
|
|
97
|
+
"content.exitContentZone",
|
|
98
|
+
"feedback.showNPS",
|
|
99
|
+
"feedback.showSurvey",
|
|
100
|
+
"feedback.showRating",
|
|
101
|
+
"userData.set",
|
|
102
|
+
"userData.set_once",
|
|
103
|
+
"userData.increment",
|
|
104
|
+
"userData.increment_by",
|
|
105
|
+
"userData.multiply",
|
|
106
|
+
"userData.max",
|
|
107
|
+
"userData.min",
|
|
108
|
+
"userData.push",
|
|
109
|
+
"userData.push_unique",
|
|
110
|
+
"userData.pull",
|
|
111
|
+
"userData.unset",
|
|
112
|
+
"userData.save"
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
for (var i = 0; i < methods.length; i++) {
|
|
116
|
+
var parts = methods[i].split(".");
|
|
117
|
+
if (parts.length === 2) {
|
|
118
|
+
c[parts[0]] = c[parts[0]] || {};
|
|
119
|
+
addStub(c[parts[0]], parts[1], methods[i]);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
addStub(c, parts[0], methods[i]);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
c.init = function (appKey, config) {
|
|
127
|
+
if (typeof appKey === "object") {
|
|
128
|
+
config = appKey || {};
|
|
129
|
+
appKey = config.app_key;
|
|
130
|
+
}
|
|
131
|
+
config = config || {};
|
|
132
|
+
|
|
133
|
+
if (appKey) {
|
|
134
|
+
config.app_key = appKey;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
for (var key in config) {
|
|
138
|
+
if (Object.prototype.hasOwnProperty.call(config, key)) {
|
|
139
|
+
c[key] = config[key];
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (c.app_key === "YOUR_APP_KEY" || c.url === "https://your.server.ly") {
|
|
144
|
+
console.warn("Please do not use default set of app key and server url");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
initConfig = config;
|
|
148
|
+
var sdkUrl = c.sdk_url || "https://cdn.jsdelivr.net/npm/countly-sdk-web@latest/lib/countly.min.js";
|
|
149
|
+
loadSdk(sdkUrl);
|
|
150
|
+
return c;
|
|
151
|
+
};
|
|
152
|
+
})(window, document);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
(function(l,t){function y(c){return function(){p.push([c].concat(Array.prototype.slice.call(arguments,0)));return d}}function u(c,a,e){e=y(e||a);e.__isCountlyStub=!0;c[a]=e}function z(c){if(!v&&!m){m=!0;var a=t.createElement("script");a.type="text/javascript";a.async=!0;a.src=c;a.crossOrigin="anonymous";a.onload=function(){v=!0;m=!1;var h=l.Countly;h&&"function"===typeof h.init&&h.init(w||{});h=l.Countly;var x=p.slice();p=[];for(var q=0;q<x.length;q++){var b=x[q],f=h,A=b.slice(1);b=b[0].split(".");
|
|
2
|
+
for(var r=0;r<b.length-1;r++)f=f&&f[b[r]];b=b[b.length-1];b=f&&f[b];"function"!==typeof b||b.__isCountlyStub||b.apply(f,A||[])}};a.onerror=function(){m=!1;console.error("Countly loader failed to load SDK from:",c)};var e=t.getElementsByTagName("script")[0];e.parentNode.insertBefore(a,e)}}var d=l.Countly||(l.Countly={}),p=[],m=!1,v=!1,w=null;d.__clyBootstrap={version:"1.0.0",name:"countly-unified-loader"};for(var n="track_sessions track_pageview track_performance add_event user_details track_errors track_forms track_clicks track_scrolls track_links recordError change_id set_id uploadUserProfilePicture content.enterContentZone content.refreshContentZone content.exitContentZone feedback.showNPS feedback.showSurvey feedback.showRating userData.set userData.set_once userData.increment userData.increment_by userData.multiply userData.max userData.min userData.push userData.push_unique userData.pull userData.unset userData.save".split(" "),
|
|
3
|
+
k=0;k<n.length;k++){var g=n[k].split(".");2===g.length?(d[g[0]]=d[g[0]]||{},u(d[g[0]],g[1],n[k])):u(d,g[0],n[k])}d.init=function(c,a){"object"===typeof c&&(a=c||{},c=a.app_key);a=a||{};c&&(a.app_key=c);for(var e in a)Object.prototype.hasOwnProperty.call(a,e)&&(d[e]=a[e]);"YOUR_APP_KEY"!==d.app_key&&"https://your.server.ly"!==d.url||console.warn("Please do not use default set of app key and server url");w=a;z(d.sdk_url||"https://cdn.jsdelivr.net/npm/countly-sdk-web@latest/lib/countly.min.js");return d}})(window,
|
|
4
|
+
document);
|
package/lib/countly.js
CHANGED
|
@@ -350,7 +350,7 @@
|
|
|
350
350
|
backoffCount: "cly_hc_backoff_count",
|
|
351
351
|
consecutiveBackoffCount: "cly_hc_consecutive_backoff_count"
|
|
352
352
|
});
|
|
353
|
-
var SDK_VERSION = "26.1.
|
|
353
|
+
var SDK_VERSION = "26.1.1";
|
|
354
354
|
var SDK_NAME = "javascript_native_web";
|
|
355
355
|
|
|
356
356
|
// Using this on document.referrer would return an array with 17 elements in it. The 12th element (array[11]) would be the path we are looking for. Others would be things like password and such (use https://regex101.com/ to check more)
|
|
@@ -759,6 +759,109 @@
|
|
|
759
759
|
return ua;
|
|
760
760
|
}
|
|
761
761
|
|
|
762
|
+
/**
|
|
763
|
+
* Parse Windows version from UA-CH platformVersion
|
|
764
|
+
* Chromium based browsers use platformVersion major >= 13 for Windows 11 and lower values for Windows 10.
|
|
765
|
+
*
|
|
766
|
+
* @param {string} platformVersion - platformVersion value from userAgentData.getHighEntropyValues
|
|
767
|
+
* @returns {string|null} "11", "10" or null if not parsable
|
|
768
|
+
*/
|
|
769
|
+
function parseWindowsVersionFromPlatformVersion(platformVersion) {
|
|
770
|
+
if (typeof platformVersion !== "string" || !platformVersion) {
|
|
771
|
+
return null;
|
|
772
|
+
}
|
|
773
|
+
var major = parseInt(platformVersion.split(".")[0], 10);
|
|
774
|
+
if (isNaN(major)) {
|
|
775
|
+
return null;
|
|
776
|
+
}
|
|
777
|
+
return major >= 13 ? "11" : "10";
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* Retrieve User-Agent Client Hints (high entropy values) when available.
|
|
782
|
+
*
|
|
783
|
+
* @param {Object} uaDataOverride - optional userAgentData override for testing
|
|
784
|
+
* @returns {Promise<Object|null>} resolved hints object or null
|
|
785
|
+
*/
|
|
786
|
+
function getUserAgentClientHintsInternal(uaData) {
|
|
787
|
+
if (!uaData || typeof uaData.getHighEntropyValues !== "function") {
|
|
788
|
+
return Promise.resolve(null);
|
|
789
|
+
}
|
|
790
|
+
return uaData.getHighEntropyValues(["platform", "platformVersion", "architecture", "bitness", "model", "uaFullVersion", "fullVersionList"]).then(function (values) {
|
|
791
|
+
if (!values || _typeof(values) !== "object") {
|
|
792
|
+
return null;
|
|
793
|
+
}
|
|
794
|
+
var browserName = null;
|
|
795
|
+
var browserVersion = null;
|
|
796
|
+
var versionList = Array.isArray(values.fullVersionList) ? values.fullVersionList : [];
|
|
797
|
+
var fallbackList = Array.isArray(uaData.brands) ? uaData.brands : [];
|
|
798
|
+
var normalizeBrand = function normalizeBrand(brand) {
|
|
799
|
+
return typeof brand === "string" ? brand.toLowerCase().replace(/[^a-z0-9]/g, "") : "";
|
|
800
|
+
};
|
|
801
|
+
var isGreaseBrand = function isGreaseBrand(brand) {
|
|
802
|
+
var normalized = normalizeBrand(brand);
|
|
803
|
+
return normalized === "notabrand" || normalized === "notabrand99" || normalized.indexOf("notabrand") === 0;
|
|
804
|
+
};
|
|
805
|
+
var isChromiumBrand = function isChromiumBrand(brand) {
|
|
806
|
+
return normalizeBrand(brand) === "chromium";
|
|
807
|
+
};
|
|
808
|
+
var pickEntry = function pickEntry(list, allowChromiumFallback) {
|
|
809
|
+
return list.find(function (entry) {
|
|
810
|
+
if (!entry || !entry.brand) {
|
|
811
|
+
return false;
|
|
812
|
+
}
|
|
813
|
+
if (isGreaseBrand(entry.brand)) {
|
|
814
|
+
return false;
|
|
815
|
+
}
|
|
816
|
+
if (!allowChromiumFallback && isChromiumBrand(entry.brand)) {
|
|
817
|
+
return false;
|
|
818
|
+
}
|
|
819
|
+
return true;
|
|
820
|
+
});
|
|
821
|
+
};
|
|
822
|
+
var browserEntry = pickEntry(versionList, false) || pickEntry(fallbackList, false) || pickEntry(versionList, true) || pickEntry(fallbackList, true);
|
|
823
|
+
if (browserEntry) {
|
|
824
|
+
browserName = browserEntry.brand || null;
|
|
825
|
+
browserVersion = browserEntry.version || null;
|
|
826
|
+
}
|
|
827
|
+
var parsed = {
|
|
828
|
+
platform: values.platform || uaData.platform || null,
|
|
829
|
+
platformVersion: values.platformVersion || null,
|
|
830
|
+
architecture: values.architecture || null,
|
|
831
|
+
bitness: values.bitness || null,
|
|
832
|
+
model: values.model || null,
|
|
833
|
+
uaFullVersion: values.uaFullVersion || null,
|
|
834
|
+
fullVersionList: values.fullVersionList || null,
|
|
835
|
+
browserName: browserName,
|
|
836
|
+
browserVersion: browserVersion,
|
|
837
|
+
windowsVersion: null
|
|
838
|
+
};
|
|
839
|
+
if (parsed.platform && parsed.platform.toLowerCase() === "windows") {
|
|
840
|
+
parsed.windowsVersion = parseWindowsVersionFromPlatformVersion(parsed.platformVersion);
|
|
841
|
+
}
|
|
842
|
+
return parsed;
|
|
843
|
+
})["catch"](function () {
|
|
844
|
+
return null;
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
var prefetchedUserAgentClientHintsPromise = null;
|
|
848
|
+
if (isBrowser && typeof navigator !== "undefined" && navigator.userAgentData && typeof navigator.userAgentData.getHighEntropyValues === "function") {
|
|
849
|
+
prefetchedUserAgentClientHintsPromise = getUserAgentClientHintsInternal(navigator.userAgentData);
|
|
850
|
+
}
|
|
851
|
+
function getUserAgentClientHints(uaDataOverride) {
|
|
852
|
+
if (uaDataOverride) {
|
|
853
|
+
return getUserAgentClientHintsInternal(uaDataOverride);
|
|
854
|
+
}
|
|
855
|
+
if (prefetchedUserAgentClientHintsPromise) {
|
|
856
|
+
return prefetchedUserAgentClientHintsPromise;
|
|
857
|
+
}
|
|
858
|
+
if (isBrowser && typeof navigator !== "undefined" && navigator.userAgentData && typeof navigator.userAgentData.getHighEntropyValues === "function") {
|
|
859
|
+
prefetchedUserAgentClientHintsPromise = getUserAgentClientHintsInternal(navigator.userAgentData);
|
|
860
|
+
return prefetchedUserAgentClientHintsPromise;
|
|
861
|
+
}
|
|
862
|
+
return Promise.resolve(null);
|
|
863
|
+
}
|
|
864
|
+
|
|
762
865
|
/**
|
|
763
866
|
* Returns device type information according to user agent string
|
|
764
867
|
* @memberof Countly._internals
|
|
@@ -1092,6 +1195,13 @@
|
|
|
1092
1195
|
var _journeyTriggerPending = /*#__PURE__*/new WeakMap();
|
|
1093
1196
|
var _journeyPendingEventIds = /*#__PURE__*/new WeakMap();
|
|
1094
1197
|
var _fakeRequestHandler = /*#__PURE__*/new WeakMap();
|
|
1198
|
+
var _uaClientHints = /*#__PURE__*/new WeakMap();
|
|
1199
|
+
var _uaClientHintsStatus = /*#__PURE__*/new WeakMap();
|
|
1200
|
+
var _clientHintsPromise = /*#__PURE__*/new WeakMap();
|
|
1201
|
+
var _pendingRequestBuffer = /*#__PURE__*/new WeakMap();
|
|
1202
|
+
var _clientHintsBufferTimeoutId = /*#__PURE__*/new WeakMap();
|
|
1203
|
+
var _initializeClientHints = /*#__PURE__*/new WeakMap();
|
|
1204
|
+
var _flushPendingRequestBuffer = /*#__PURE__*/new WeakMap();
|
|
1095
1205
|
var _getAndSetServerConfig = /*#__PURE__*/new WeakMap();
|
|
1096
1206
|
var _populateServerConfig = /*#__PURE__*/new WeakMap();
|
|
1097
1207
|
var _initialize = /*#__PURE__*/new WeakMap();
|
|
@@ -1141,6 +1251,7 @@
|
|
|
1141
1251
|
var _getStoredIdOrGenerateId = /*#__PURE__*/new WeakMap();
|
|
1142
1252
|
var _isUUID = /*#__PURE__*/new WeakMap();
|
|
1143
1253
|
var _getUA = /*#__PURE__*/new WeakMap();
|
|
1254
|
+
var _getBrowserInfoFromUA = /*#__PURE__*/new WeakMap();
|
|
1144
1255
|
var _getMetrics = /*#__PURE__*/new WeakMap();
|
|
1145
1256
|
var _getResolution = /*#__PURE__*/new WeakMap();
|
|
1146
1257
|
var _isReferrerUsable = /*#__PURE__*/new WeakMap();
|
|
@@ -1280,6 +1391,89 @@
|
|
|
1280
1391
|
_classPrivateFieldInitSpec(this, _journeyTriggerPending, void 0);
|
|
1281
1392
|
_classPrivateFieldInitSpec(this, _journeyPendingEventIds, void 0);
|
|
1282
1393
|
_classPrivateFieldInitSpec(this, _fakeRequestHandler, void 0);
|
|
1394
|
+
_classPrivateFieldInitSpec(this, _uaClientHints, void 0);
|
|
1395
|
+
_classPrivateFieldInitSpec(this, _uaClientHintsStatus, void 0);
|
|
1396
|
+
_classPrivateFieldInitSpec(this, _clientHintsPromise, void 0);
|
|
1397
|
+
_classPrivateFieldInitSpec(this, _pendingRequestBuffer, void 0);
|
|
1398
|
+
_classPrivateFieldInitSpec(this, _clientHintsBufferTimeoutId, void 0);
|
|
1399
|
+
/**
|
|
1400
|
+
* Fetch User-Agent Client Hints and cache values for metrics enrichment.
|
|
1401
|
+
* @private
|
|
1402
|
+
*/
|
|
1403
|
+
_classPrivateFieldInitSpec(this, _initializeClientHints, function () {
|
|
1404
|
+
if (!isBrowser) {
|
|
1405
|
+
_classPrivateFieldSet2(_uaClientHintsStatus, _this, "unavailable");
|
|
1406
|
+
_classPrivateFieldSet2(_pendingRequestBuffer, _this, null); // no buffering needed
|
|
1407
|
+
return;
|
|
1408
|
+
}
|
|
1409
|
+
var uaRaw = currentUserAgentString();
|
|
1410
|
+
var uaDataAvailable = typeof navigator !== "undefined" && !!navigator.userAgentData;
|
|
1411
|
+
var getHighEntropyValuesAvailable = uaDataAvailable && typeof navigator.userAgentData.getHighEntropyValues === "function";
|
|
1412
|
+
var uaDataPlatform = uaDataAvailable ? navigator.userAgentData.platform : undefined;
|
|
1413
|
+
var uaDataBrands = uaDataAvailable ? navigator.userAgentData.brands : undefined;
|
|
1414
|
+
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "ua_logic, raw ua string:[" + uaRaw + "]");
|
|
1415
|
+
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "ua_logic, userAgentData available:[" + uaDataAvailable + "], getHighEntropyValues available:[" + getHighEntropyValuesAvailable + "]");
|
|
1416
|
+
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "ua_logic, userAgentData low-entropy platform:[" + uaDataPlatform + "], brands:[" + JSON.stringify(uaDataBrands) + "]");
|
|
1417
|
+
_classPrivateFieldSet2(_uaClientHintsStatus, _this, "pending");
|
|
1418
|
+
_classPrivateFieldSet2(_pendingRequestBuffer, _this, []); // enable request buffering until hints resolve
|
|
1419
|
+
|
|
1420
|
+
// Safety timeout: flush buffer even if hints never resolve (e.g. API blocked)
|
|
1421
|
+
_classPrivateFieldSet2(_clientHintsBufferTimeoutId, _this, setTimeout(function () {
|
|
1422
|
+
if (_classPrivateFieldGet2(_pendingRequestBuffer, _this) !== null) {
|
|
1423
|
+
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.WARNING, "ua_logic, client hints resolution timed out after 5s, flushing pending requests with available metrics");
|
|
1424
|
+
_classPrivateFieldGet2(_flushPendingRequestBuffer, _this).call(_this);
|
|
1425
|
+
}
|
|
1426
|
+
}, 1000));
|
|
1427
|
+
_classPrivateFieldSet2(_clientHintsPromise, _this, getUserAgentClientHints().then(function (clientHints) {
|
|
1428
|
+
if (clientHints && _typeof(clientHints) === "object") {
|
|
1429
|
+
_classPrivateFieldSet2(_uaClientHints, _this, clientHints);
|
|
1430
|
+
_classPrivateFieldSet2(_uaClientHintsStatus, _this, "resolved");
|
|
1431
|
+
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "ua_logic, high-entropy hints resolved:[" + JSON.stringify(clientHints) + "]");
|
|
1432
|
+
} else {
|
|
1433
|
+
_classPrivateFieldSet2(_uaClientHintsStatus, _this, "unavailable");
|
|
1434
|
+
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "ua_logic, high-entropy hints unavailable or not returned");
|
|
1435
|
+
}
|
|
1436
|
+
})["catch"](function (err) {
|
|
1437
|
+
_classPrivateFieldSet2(_uaClientHints, _this, null);
|
|
1438
|
+
_classPrivateFieldSet2(_uaClientHintsStatus, _this, "failed");
|
|
1439
|
+
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "ua_logic, high-entropy hints fetch failed:[" + err + "]");
|
|
1440
|
+
})["finally"](function () {
|
|
1441
|
+
_classPrivateFieldGet2(_flushPendingRequestBuffer, _this).call(_this);
|
|
1442
|
+
}));
|
|
1443
|
+
});
|
|
1444
|
+
/**
|
|
1445
|
+
* Flush pending request buffer after client hints resolution.
|
|
1446
|
+
* Re-computes metrics for any buffered begin_session request so that
|
|
1447
|
+
* high-entropy Client Hints values are included. All other buffered
|
|
1448
|
+
* requests are pushed to the queue unchanged, preserving order.
|
|
1449
|
+
* @private
|
|
1450
|
+
*/
|
|
1451
|
+
_classPrivateFieldInitSpec(this, _flushPendingRequestBuffer, function () {
|
|
1452
|
+
// Clear safety timeout
|
|
1453
|
+
if (_classPrivateFieldGet2(_clientHintsBufferTimeoutId, _this)) {
|
|
1454
|
+
clearTimeout(_classPrivateFieldGet2(_clientHintsBufferTimeoutId, _this));
|
|
1455
|
+
_classPrivateFieldSet2(_clientHintsBufferTimeoutId, _this, null);
|
|
1456
|
+
}
|
|
1457
|
+
var buffer = _classPrivateFieldGet2(_pendingRequestBuffer, _this);
|
|
1458
|
+
_classPrivateFieldSet2(_pendingRequestBuffer, _this, null); // disable buffering — subsequent calls go directly to queue
|
|
1459
|
+
|
|
1460
|
+
if (!buffer || buffer.length === 0) {
|
|
1461
|
+
return;
|
|
1462
|
+
}
|
|
1463
|
+
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "ua_logic, flushing [" + buffer.length + "] pending request(s) after client hints resolution");
|
|
1464
|
+
for (var i = 0; i < buffer.length; i++) {
|
|
1465
|
+
var request = buffer[i];
|
|
1466
|
+
// Re-compute metrics for begin_session requests with now-resolved hints
|
|
1467
|
+
if (request.begin_session) {
|
|
1468
|
+
request.metrics = JSON.stringify(_classPrivateFieldGet2(_getMetrics, _this).call(_this));
|
|
1469
|
+
}
|
|
1470
|
+
if (_classPrivateFieldGet2(_requestQueue, _this).length > _classPrivateFieldGet2(_SCSizeReqQueue, _this)) {
|
|
1471
|
+
_classPrivateFieldGet2(_requestQueue, _this).shift();
|
|
1472
|
+
}
|
|
1473
|
+
_classPrivateFieldGet2(_requestQueue, _this).push(request);
|
|
1474
|
+
}
|
|
1475
|
+
_classPrivateFieldGet2(_setValueInStorage, _this).call(_this, "cly_queue", _classPrivateFieldGet2(_requestQueue, _this), true);
|
|
1476
|
+
});
|
|
1283
1477
|
/**
|
|
1284
1478
|
* Fetch and set server configuration
|
|
1285
1479
|
* Retrieves server-side settings and behavior configurations
|
|
@@ -2003,6 +2197,14 @@
|
|
|
2003
2197
|
_classPrivateFieldSet2(_journeyTriggerInProgress, _this, undefined);
|
|
2004
2198
|
_classPrivateFieldSet2(_journeyTriggerPending, _this, undefined);
|
|
2005
2199
|
_classPrivateFieldSet2(_journeyPendingEventIds, _this, undefined);
|
|
2200
|
+
if (_classPrivateFieldGet2(_clientHintsBufferTimeoutId, _this)) {
|
|
2201
|
+
clearTimeout(_classPrivateFieldGet2(_clientHintsBufferTimeoutId, _this));
|
|
2202
|
+
_classPrivateFieldSet2(_clientHintsBufferTimeoutId, _this, null);
|
|
2203
|
+
}
|
|
2204
|
+
_classPrivateFieldSet2(_pendingRequestBuffer, _this, null);
|
|
2205
|
+
_classPrivateFieldSet2(_clientHintsPromise, _this, null);
|
|
2206
|
+
_classPrivateFieldSet2(_uaClientHints, _this, null);
|
|
2207
|
+
_classPrivateFieldSet2(_uaClientHintsStatus, _this, "not_started");
|
|
2006
2208
|
});
|
|
2007
2209
|
/**
|
|
2008
2210
|
* Returns the SDK version string currently in use
|
|
@@ -2731,6 +2933,11 @@
|
|
|
2731
2933
|
return _regenerator().w(function (_context2) {
|
|
2732
2934
|
while (1) switch (_context2.n) {
|
|
2733
2935
|
case 0:
|
|
2936
|
+
// Flush any buffered requests (e.g. held while client hints were resolving)
|
|
2937
|
+
// into the real request queue so they can be sent before the content request.
|
|
2938
|
+
if (_classPrivateFieldGet2(_pendingRequestBuffer, _this) !== null) {
|
|
2939
|
+
_classPrivateFieldGet2(_flushPendingRequestBuffer, _this).call(_this);
|
|
2940
|
+
}
|
|
2734
2941
|
initialQueueLength = _classPrivateFieldGet2(_requestQueue, _this).length;
|
|
2735
2942
|
if (!(initialQueueLength === 0)) {
|
|
2736
2943
|
_context2.n = 1;
|
|
@@ -5836,6 +6043,12 @@
|
|
|
5836
6043
|
return;
|
|
5837
6044
|
}
|
|
5838
6045
|
_classPrivateFieldGet2(_prepareRequest, _this).call(_this, request);
|
|
6046
|
+
|
|
6047
|
+
// Buffer requests while client hints are still resolving
|
|
6048
|
+
if (_classPrivateFieldGet2(_pendingRequestBuffer, _this) !== null) {
|
|
6049
|
+
_classPrivateFieldGet2(_pendingRequestBuffer, _this).push(request);
|
|
6050
|
+
return;
|
|
6051
|
+
}
|
|
5839
6052
|
if (_classPrivateFieldGet2(_requestQueue, _this).length > _classPrivateFieldGet2(_SCSizeReqQueue, _this)) {
|
|
5840
6053
|
_classPrivateFieldGet2(_requestQueue, _this).shift();
|
|
5841
6054
|
}
|
|
@@ -6089,6 +6302,49 @@
|
|
|
6089
6302
|
}
|
|
6090
6303
|
return currentUserAgentString();
|
|
6091
6304
|
});
|
|
6305
|
+
/**
|
|
6306
|
+
* Basic browser name/version parsing fallback from UA string.
|
|
6307
|
+
* @private
|
|
6308
|
+
* @param {string} ua - raw user agent string
|
|
6309
|
+
* @returns {{name: string|null, version: string|null}}
|
|
6310
|
+
*/
|
|
6311
|
+
_classPrivateFieldInitSpec(this, _getBrowserInfoFromUA, function (ua) {
|
|
6312
|
+
if (!ua || typeof ua !== "string") {
|
|
6313
|
+
return {
|
|
6314
|
+
name: null,
|
|
6315
|
+
version: null
|
|
6316
|
+
};
|
|
6317
|
+
}
|
|
6318
|
+
var patterns = [{
|
|
6319
|
+
name: "Edge",
|
|
6320
|
+
regex: /Edg\/([\d\.]+)/
|
|
6321
|
+
}, {
|
|
6322
|
+
name: "Opera",
|
|
6323
|
+
regex: /OPR\/([\d\.]+)/
|
|
6324
|
+
}, {
|
|
6325
|
+
name: "Chrome",
|
|
6326
|
+
regex: /Chrome\/([\d\.]+)/
|
|
6327
|
+
}, {
|
|
6328
|
+
name: "Firefox",
|
|
6329
|
+
regex: /Firefox\/([\d\.]+)/
|
|
6330
|
+
}, {
|
|
6331
|
+
name: "Safari",
|
|
6332
|
+
regex: /Version\/([\d\.]+).*Safari/
|
|
6333
|
+
}];
|
|
6334
|
+
for (var i = 0; i < patterns.length; i++) {
|
|
6335
|
+
var match = ua.match(patterns[i].regex);
|
|
6336
|
+
if (match && match[1]) {
|
|
6337
|
+
return {
|
|
6338
|
+
name: patterns[i].name,
|
|
6339
|
+
version: match[1]
|
|
6340
|
+
};
|
|
6341
|
+
}
|
|
6342
|
+
}
|
|
6343
|
+
return {
|
|
6344
|
+
name: null,
|
|
6345
|
+
version: null
|
|
6346
|
+
};
|
|
6347
|
+
});
|
|
6092
6348
|
/**
|
|
6093
6349
|
* Get metrics of the browser or config object
|
|
6094
6350
|
* @memberof Countly._internals
|
|
@@ -6118,6 +6374,55 @@
|
|
|
6118
6374
|
if (typeof locale !== "undefined") {
|
|
6119
6375
|
metrics._locale = metrics._locale || locale;
|
|
6120
6376
|
}
|
|
6377
|
+
if (isBrowser && navigator.userAgentData && navigator.userAgentData.platform) {
|
|
6378
|
+
metrics._os = metrics._os || navigator.userAgentData.platform;
|
|
6379
|
+
}
|
|
6380
|
+
var detectedDeviceType = userAgentDeviceDetection();
|
|
6381
|
+
if (detectedDeviceType === "phone") {
|
|
6382
|
+
detectedDeviceType = "mobile";
|
|
6383
|
+
}
|
|
6384
|
+
metrics._device_type = metrics._device_type || detectedDeviceType;
|
|
6385
|
+
if (_classPrivateFieldGet2(_uaClientHints, _this) && _typeof(_classPrivateFieldGet2(_uaClientHints, _this)) === "object") {
|
|
6386
|
+
if (_classPrivateFieldGet2(_uaClientHints, _this).platform) {
|
|
6387
|
+
metrics._os = metrics._os || _classPrivateFieldGet2(_uaClientHints, _this).platform;
|
|
6388
|
+
}
|
|
6389
|
+
var osVersionFromHints = _classPrivateFieldGet2(_uaClientHints, _this).windowsVersion || _classPrivateFieldGet2(_uaClientHints, _this).platformVersion;
|
|
6390
|
+
if (osVersionFromHints) {
|
|
6391
|
+
metrics._os_version = metrics._os_version || osVersionFromHints;
|
|
6392
|
+
}
|
|
6393
|
+
if (_classPrivateFieldGet2(_uaClientHints, _this).model) {
|
|
6394
|
+
metrics._device = metrics._device || _classPrivateFieldGet2(_uaClientHints, _this).model;
|
|
6395
|
+
}
|
|
6396
|
+
if (_classPrivateFieldGet2(_uaClientHints, _this).browserName) {
|
|
6397
|
+
metrics._browser = metrics._browser || _classPrivateFieldGet2(_uaClientHints, _this).browserName;
|
|
6398
|
+
}
|
|
6399
|
+
if (_classPrivateFieldGet2(_uaClientHints, _this).browserVersion) {
|
|
6400
|
+
metrics._browser_version = metrics._browser_version || _classPrivateFieldGet2(_uaClientHints, _this).browserVersion;
|
|
6401
|
+
}
|
|
6402
|
+
if (_classPrivateFieldGet2(_uaClientHints, _this).windowsVersion) {
|
|
6403
|
+
metrics._os = metrics._os || "Windows";
|
|
6404
|
+
metrics._os_version = metrics._os_version || _classPrivateFieldGet2(_uaClientHints, _this).windowsVersion;
|
|
6405
|
+
}
|
|
6406
|
+
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "ua_logic, metrics enriched from hints:[" + JSON.stringify({
|
|
6407
|
+
_os: metrics._os,
|
|
6408
|
+
_os_version: metrics._os_version,
|
|
6409
|
+
_device: metrics._device,
|
|
6410
|
+
_device_type: metrics._device_type,
|
|
6411
|
+
_browser: metrics._browser,
|
|
6412
|
+
_browser_version: metrics._browser_version
|
|
6413
|
+
}) + "]");
|
|
6414
|
+
} else {
|
|
6415
|
+
if (_classPrivateFieldGet2(_uaClientHintsStatus, _this) === "pending") {
|
|
6416
|
+
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "ua_logic, high-entropy hints are still pending, using fallback metrics for now");
|
|
6417
|
+
} else {
|
|
6418
|
+
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "ua_logic, no high-entropy hints available, using UA fallback parsing");
|
|
6419
|
+
}
|
|
6420
|
+
}
|
|
6421
|
+
if (!metrics._browser || !metrics._browser_version) {
|
|
6422
|
+
var browserInfo = _classPrivateFieldGet2(_getBrowserInfoFromUA, _this).call(_this, metrics._ua);
|
|
6423
|
+
metrics._browser = metrics._browser || browserInfo.name;
|
|
6424
|
+
metrics._browser_version = metrics._browser_version || browserInfo.version;
|
|
6425
|
+
}
|
|
6121
6426
|
if (_classPrivateFieldGet2(_isReferrerUsable, _this).call(_this)) {
|
|
6122
6427
|
metrics._store = metrics._store || document.referrer;
|
|
6123
6428
|
}
|
|
@@ -7332,6 +7637,11 @@
|
|
|
7332
7637
|
_classPrivateFieldSet2(_journeyTriggerPending, this, false);
|
|
7333
7638
|
_classPrivateFieldSet2(_journeyPendingEventIds, this, new Set());
|
|
7334
7639
|
_classPrivateFieldSet2(_fakeRequestHandler, this, getConfig("fake_request_handler", _ob, null));
|
|
7640
|
+
_classPrivateFieldSet2(_uaClientHints, this, null);
|
|
7641
|
+
_classPrivateFieldSet2(_uaClientHintsStatus, this, "not_started");
|
|
7642
|
+
_classPrivateFieldSet2(_clientHintsPromise, this, null);
|
|
7643
|
+
_classPrivateFieldSet2(_pendingRequestBuffer, this, null);
|
|
7644
|
+
_classPrivateFieldSet2(_clientHintsBufferTimeoutId, this, null);
|
|
7335
7645
|
this.app_key = getConfig("app_key", _ob, null);
|
|
7336
7646
|
this.url = stripTrailingSlash(getConfig("url", _ob, ""));
|
|
7337
7647
|
this.serialize = getConfig("serialize", _ob, Countly.serialize);
|
|
@@ -7359,6 +7669,7 @@
|
|
|
7359
7669
|
for (var it = 0; it < Countly.features.length; it++) {
|
|
7360
7670
|
_classPrivateFieldGet2(_consents, this)[Countly.features[it]] = {};
|
|
7361
7671
|
}
|
|
7672
|
+
_classPrivateFieldGet2(_initializeClientHints, this).call(this);
|
|
7362
7673
|
_classPrivateFieldGet2(_initialize, this).call(this, _ob);
|
|
7363
7674
|
|
|
7364
7675
|
// start SDK
|