countly-sdk-web 26.1.0 → 26.1.2
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 +8 -0
- package/cypress/e2e/bridged_utils.cy.js +1 -1
- package/cypress/e2e/device_id_change.cy.js +45 -0
- 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 +330 -2
- package/lib/countly.min.js +251 -241
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -275,3 +275,48 @@ describe("Set ID change tests ", () => {
|
|
|
275
275
|
});
|
|
276
276
|
|
|
277
277
|
});
|
|
278
|
+
|
|
279
|
+
describe("Device ID remote config sequencing", () => {
|
|
280
|
+
it("delays remote config refetch by 1 second after merge device ID changes", () => {
|
|
281
|
+
hp.haltAndClearStorage(() => {
|
|
282
|
+
var fakeServer = hp.createFakeRequestHandler({
|
|
283
|
+
onRequest: function (req) {
|
|
284
|
+
if (req.functionName === "fetch_remote_config_explicit") {
|
|
285
|
+
return { status: 200, responseText: "{}" };
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return { status: 200, responseText: '{"result":"Success"}' };
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
var inst = Countly.init({
|
|
293
|
+
app_key: hp.appKey,
|
|
294
|
+
url: "https://test.count.ly",
|
|
295
|
+
device_id: "old ID",
|
|
296
|
+
debug: true,
|
|
297
|
+
use_explicit_rc_api: true,
|
|
298
|
+
disable_sdk_behavior_settings_updates: true,
|
|
299
|
+
fake_request_handler: fakeServer.handler
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
cy.wait(hp.sWait).then(() => {
|
|
303
|
+
inst.remote_config = function () { };
|
|
304
|
+
fakeServer.clear();
|
|
305
|
+
Countly.change_id("new ID", true);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
cy.wait(300).then(() => {
|
|
309
|
+
var earlyRemoteConfigRequest = fakeServer.getRequests().find((req) => req.functionName === "fetch_remote_config_explicit");
|
|
310
|
+
expect(earlyRemoteConfigRequest).to.not.exist;
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
cy.wait(1100).then(() => {
|
|
314
|
+
var requests = fakeServer.getRequests();
|
|
315
|
+
var remoteConfigRequest = requests.find((req) => req.functionName === "fetch_remote_config_explicit");
|
|
316
|
+
|
|
317
|
+
expect(remoteConfigRequest).to.exist;
|
|
318
|
+
expect(remoteConfigRequest.params.device_id).to.equal("new ID");
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
});
|
|
@@ -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);
|