@jitsu/js 1.9.3-canary.801.20240514214630 → 1.9.4
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/.turbo/turbo-build.log +6 -6
- package/.turbo/turbo-clean.log +2 -2
- package/.turbo/turbo-test.log +2192 -1973
- package/__tests__/playwright/cases/reset.html +31 -0
- package/__tests__/playwright/integration.test.ts +35 -0
- package/dist/analytics-plugin.d.ts +1 -3
- package/dist/jitsu.cjs.js +82 -20
- package/dist/jitsu.d.ts +1 -0
- package/dist/jitsu.es.js +82 -20
- package/dist/script-loader.d.ts +8 -1
- package/dist/web/p.js.txt +82 -20
- package/package.json +3 -3
- package/src/analytics-plugin.ts +32 -8
- package/src/destination-plugins/ga4.ts +2 -3
- package/src/destination-plugins/gtm.ts +2 -2
- package/src/destination-plugins/logrocket.ts +3 -1
- package/src/index.ts +29 -1
- package/src/jitsu.ts +1 -0
- package/src/script-loader.ts +28 -3
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
+
|
|
8
|
+
<title>Tracking page</title>
|
|
9
|
+
<script>
|
|
10
|
+
window.testOnload = async j => {
|
|
11
|
+
await j.setAnonymousId("john-doe-id-1");
|
|
12
|
+
await j.identify("john-nondoe", { email: "john@example.com" });
|
|
13
|
+
await j.track("pageLoaded", { trackParam: "trackValue" });
|
|
14
|
+
await j.reset();
|
|
15
|
+
await j.track("pageLoaded", { trackParam: "trackValue" });
|
|
16
|
+
};
|
|
17
|
+
</script>
|
|
18
|
+
<script
|
|
19
|
+
type="text/javascript"
|
|
20
|
+
src="<%=trackingBase%>/p.js"
|
|
21
|
+
data-onload="testOnload"
|
|
22
|
+
data-debug="true"
|
|
23
|
+
data-init-only="true"
|
|
24
|
+
defer
|
|
25
|
+
></script>
|
|
26
|
+
</head>
|
|
27
|
+
|
|
28
|
+
<body>
|
|
29
|
+
<h1>Test</h1>
|
|
30
|
+
</body>
|
|
31
|
+
</html>
|
|
@@ -244,6 +244,41 @@ test("url-bug", async ({ browser }) => {
|
|
|
244
244
|
expect(pagePath).toEqual("/");
|
|
245
245
|
});
|
|
246
246
|
|
|
247
|
+
test("reset", async ({ browser }) => {
|
|
248
|
+
clearRequestLog();
|
|
249
|
+
const browserContext = await browser.newContext();
|
|
250
|
+
const { page, uncaughtErrors } = await createLoggingPage(browserContext);
|
|
251
|
+
const [pageResult] = await Promise.all([page.goto(`${server.baseUrl}/reset.html`)]);
|
|
252
|
+
await page.waitForFunction(() => window["jitsu"] !== undefined, undefined, {
|
|
253
|
+
timeout: 1000,
|
|
254
|
+
polling: 100,
|
|
255
|
+
});
|
|
256
|
+
expect(pageResult.status()).toBe(200);
|
|
257
|
+
//wait for some time since the server has an artificial latency of 30ms
|
|
258
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
259
|
+
expect(uncaughtErrors.length).toEqual(0);
|
|
260
|
+
expect(requestLog.length).toBe(3);
|
|
261
|
+
console.log(
|
|
262
|
+
`📝 Request log size of ${requestLog.length}`,
|
|
263
|
+
requestLog.map(x => describeEvent(x.type, x.body))
|
|
264
|
+
);
|
|
265
|
+
const [identifyEvent, firstTrack, secondTrack] = requestLog;
|
|
266
|
+
expect(firstTrack.body.anonymousId).toEqual("john-doe-id-1");
|
|
267
|
+
|
|
268
|
+
const cookies = await browserContext.cookies();
|
|
269
|
+
// all cookies should be cleared by .reset()
|
|
270
|
+
// but new cookie for new anonymousId should be set
|
|
271
|
+
expect(cookies.length).toBe(1);
|
|
272
|
+
expect(cookies[0].name).toEqual("__eventn_id");
|
|
273
|
+
const newAnonymousId = cookies[0].value;
|
|
274
|
+
console.log(`🍪Cookies`, cookies);
|
|
275
|
+
|
|
276
|
+
expect(secondTrack.body.anonymousId).not.toBeNull();
|
|
277
|
+
expect(secondTrack.body.anonymousId).toBeDefined();
|
|
278
|
+
expect(secondTrack.body.anonymousId).toEqual(newAnonymousId);
|
|
279
|
+
expect(secondTrack.body.anonymousId).not.toEqual("john-doe-id-1");
|
|
280
|
+
});
|
|
281
|
+
|
|
247
282
|
test("basic", async ({ browser }) => {
|
|
248
283
|
clearRequestLog();
|
|
249
284
|
const browserContext = await browser.newContext();
|
|
@@ -24,9 +24,7 @@ export type InternalPluginDescriptor = {
|
|
|
24
24
|
};
|
|
25
25
|
export type DeviceOptions = AnalyticsPluginDescriptor | InternalPluginDescriptor;
|
|
26
26
|
export type JitsuPluginConfig = JitsuOptions & {
|
|
27
|
-
storageWrapper?: (persistentStorage: PersistentStorage) => PersistentStorage
|
|
28
|
-
reset: () => void;
|
|
29
|
-
};
|
|
27
|
+
storageWrapper?: (persistentStorage: PersistentStorage) => PersistentStorage;
|
|
30
28
|
};
|
|
31
29
|
declare const jitsuAnalyticsPlugin: (pluginConfig?: JitsuPluginConfig) => AnalyticsPlugin;
|
|
32
30
|
export declare function randomId(hashString?: string | undefined): string;
|
package/dist/jitsu.cjs.js
CHANGED
|
@@ -71,7 +71,23 @@ function findScript(src) {
|
|
|
71
71
|
const scripts = Array.prototype.slice.call(window.document.querySelectorAll("script"));
|
|
72
72
|
return scripts.find(s => s.src === src);
|
|
73
73
|
}
|
|
74
|
-
function
|
|
74
|
+
function buildScriptSrc(src, options) {
|
|
75
|
+
let result = src;
|
|
76
|
+
if (!result.startsWith("http")) {
|
|
77
|
+
result = `https://${(options === null || options === void 0 ? void 0 : options.www) ? "www." : ""}${result}`;
|
|
78
|
+
}
|
|
79
|
+
if (options === null || options === void 0 ? void 0 : options.min) {
|
|
80
|
+
result = result + ".min.js";
|
|
81
|
+
}
|
|
82
|
+
else if (options === null || options === void 0 ? void 0 : options.js) {
|
|
83
|
+
result = result + ".js";
|
|
84
|
+
}
|
|
85
|
+
if (options === null || options === void 0 ? void 0 : options.query) {
|
|
86
|
+
result += "?" + options.query;
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
function loadScript(src, options) {
|
|
75
91
|
const found = findScript(src);
|
|
76
92
|
if (found !== undefined) {
|
|
77
93
|
const status = found === null || found === void 0 ? void 0 : found.getAttribute("status");
|
|
@@ -86,13 +102,13 @@ function loadScript(src, attributes) {
|
|
|
86
102
|
}
|
|
87
103
|
}
|
|
88
104
|
return new Promise((resolve, reject) => {
|
|
89
|
-
var _a;
|
|
105
|
+
var _a, _b;
|
|
90
106
|
const script = window.document.createElement("script");
|
|
91
107
|
script.type = "text/javascript";
|
|
92
|
-
script.src = src;
|
|
108
|
+
script.src = buildScriptSrc(src, options);
|
|
93
109
|
script.async = true;
|
|
94
110
|
script.setAttribute("status", "loading");
|
|
95
|
-
for (const [k, v] of Object.entries(attributes !== null &&
|
|
111
|
+
for (const [k, v] of Object.entries((_a = options === null || options === void 0 ? void 0 : options.attributes) !== null && _a !== void 0 ? _a : {})) {
|
|
96
112
|
script.setAttribute(k, v);
|
|
97
113
|
}
|
|
98
114
|
script.onload = () => {
|
|
@@ -106,7 +122,7 @@ function loadScript(src, attributes) {
|
|
|
106
122
|
reject(new Error(`Failed to load ${src}`));
|
|
107
123
|
};
|
|
108
124
|
const tag = window.document.getElementsByTagName("script")[0];
|
|
109
|
-
(
|
|
125
|
+
(_b = tag.parentElement) === null || _b === void 0 ? void 0 : _b.insertBefore(script, tag);
|
|
110
126
|
});
|
|
111
127
|
}
|
|
112
128
|
|
|
@@ -206,6 +222,7 @@ var __awaiter$4 = (undefined && undefined.__awaiter) || function (thisArg, _argu
|
|
|
206
222
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
207
223
|
});
|
|
208
224
|
};
|
|
225
|
+
const cdn = "cdn.lr-ingest.io/";
|
|
209
226
|
const logrocketPlugin = {
|
|
210
227
|
id: "logrocket",
|
|
211
228
|
handle(config, payload) {
|
|
@@ -256,7 +273,7 @@ function initLogrocketIfNeeded(appId) {
|
|
|
256
273
|
return;
|
|
257
274
|
}
|
|
258
275
|
setLogRocketState("loading");
|
|
259
|
-
loadScript(
|
|
276
|
+
loadScript(`${cdn}LogRocket`, { min: true, attributes: { crossOrigin: "anonymous" } })
|
|
260
277
|
.then(() => {
|
|
261
278
|
if (window["LogRocket"]) {
|
|
262
279
|
try {
|
|
@@ -379,8 +396,8 @@ function initGtmIfNeeded(config, payload) {
|
|
|
379
396
|
event: "gtm.js",
|
|
380
397
|
});
|
|
381
398
|
const dl = l != "dataLayer" ? "&l=" + l : "";
|
|
382
|
-
const scriptSrc = "
|
|
383
|
-
loadScript(scriptSrc)
|
|
399
|
+
const scriptSrc = "googletagmanager.com/gtm";
|
|
400
|
+
loadScript(scriptSrc, { www: true, js: true, query: "id=" + i + dl })
|
|
384
401
|
.then(() => {
|
|
385
402
|
setGtmState("loaded");
|
|
386
403
|
})
|
|
@@ -401,7 +418,7 @@ var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _argu
|
|
|
401
418
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
402
419
|
});
|
|
403
420
|
};
|
|
404
|
-
const defaultScriptSrc = "
|
|
421
|
+
const defaultScriptSrc = "googletagmanager.com/gtag/js";
|
|
405
422
|
const ga4Plugin = {
|
|
406
423
|
id: "ga4-tag",
|
|
407
424
|
handle(config, payload) {
|
|
@@ -463,7 +480,6 @@ function initGa4IfNeeded(config, payload) {
|
|
|
463
480
|
const dlParam = dlName !== "dataLayer" ? "&l=" + dlName : "";
|
|
464
481
|
// to work with both GA4 and GTM
|
|
465
482
|
const tagId = config.measurementIds;
|
|
466
|
-
const scriptSrc = `${defaultScriptSrc}?id=${tagId}${dlParam}`;
|
|
467
483
|
window[dlName] = window[dlName] || [];
|
|
468
484
|
const gtag = function () {
|
|
469
485
|
window[dlName].push(arguments);
|
|
@@ -473,7 +489,7 @@ function initGa4IfNeeded(config, payload) {
|
|
|
473
489
|
gtag(
|
|
474
490
|
// @ts-ignore
|
|
475
491
|
"config", tagId, Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId } : {})), (!config.autoPageView ? { send_page_view: false } : {})));
|
|
476
|
-
loadScript(
|
|
492
|
+
loadScript(defaultScriptSrc, { query: `id=${tagId}${dlParam}`, www: true })
|
|
477
493
|
.then(() => {
|
|
478
494
|
setGa4State("loaded");
|
|
479
495
|
})
|
|
@@ -1112,8 +1128,15 @@ function getGa4Ids(runtime) {
|
|
|
1112
1128
|
return undefined;
|
|
1113
1129
|
}
|
|
1114
1130
|
}
|
|
1115
|
-
function removeCookie(name) {
|
|
1116
|
-
document.cookie =
|
|
1131
|
+
function removeCookie(name, { domain, secure }) {
|
|
1132
|
+
document.cookie =
|
|
1133
|
+
name +
|
|
1134
|
+
"=;domain=" +
|
|
1135
|
+
domain +
|
|
1136
|
+
";path=/" +
|
|
1137
|
+
";expires=Thu, 01 Jan 1970 00:00:01 GMT;SameSite=" +
|
|
1138
|
+
(secure ? "None" : "Lax") +
|
|
1139
|
+
(secure ? ";secure" : "");
|
|
1117
1140
|
}
|
|
1118
1141
|
function setCookie(name, val, { domain, secure }) {
|
|
1119
1142
|
document.cookie =
|
|
@@ -1155,7 +1178,18 @@ const cookieStorage = (cookieDomain, key2cookie) => {
|
|
|
1155
1178
|
return parse(result);
|
|
1156
1179
|
},
|
|
1157
1180
|
removeItem(key) {
|
|
1158
|
-
removeCookie(key2cookie[key] || key
|
|
1181
|
+
removeCookie(key2cookie[key] || key, {
|
|
1182
|
+
domain: cookieDomain,
|
|
1183
|
+
secure: window.location.protocol === "https:",
|
|
1184
|
+
});
|
|
1185
|
+
},
|
|
1186
|
+
reset() {
|
|
1187
|
+
for (const v of Object.values(key2cookie)) {
|
|
1188
|
+
removeCookie(v, {
|
|
1189
|
+
domain: cookieDomain,
|
|
1190
|
+
secure: window.location.protocol === "https:",
|
|
1191
|
+
});
|
|
1192
|
+
}
|
|
1159
1193
|
},
|
|
1160
1194
|
};
|
|
1161
1195
|
};
|
|
@@ -1226,6 +1260,9 @@ const emptyRuntime = (config) => ({
|
|
|
1226
1260
|
store() {
|
|
1227
1261
|
const storage = {};
|
|
1228
1262
|
return {
|
|
1263
|
+
reset() {
|
|
1264
|
+
Object.keys(storage).forEach(key => delete storage[key]);
|
|
1265
|
+
},
|
|
1229
1266
|
setItem(key, val) {
|
|
1230
1267
|
if (config.debug) {
|
|
1231
1268
|
console.log(`[JITSU EMPTY RUNTIME] Set storage item ${key}=${JSON.stringify(val)}`);
|
|
@@ -1497,7 +1534,8 @@ function send(method, payload, jitsuConfig, instance, store) {
|
|
|
1497
1534
|
console.warn(`[JITSU] ${payload.type} responded with list of ${responseJson.destinations.length} destinations. However, this code is running in server-to-server mode, so destinations will be ignored`, jitsuConfig.debug ? JSON.stringify(responseJson.destinations, null, 2) : undefined);
|
|
1498
1535
|
}
|
|
1499
1536
|
else {
|
|
1500
|
-
|
|
1537
|
+
//double protection, ingest should not return destinations in s2s mode
|
|
1538
|
+
if (isInBrowser()) {
|
|
1501
1539
|
if (jitsuConfig.debug) {
|
|
1502
1540
|
console.log(`[JITSU] Processing device destinations: `, JSON.stringify(responseJson.destinations, null, 2));
|
|
1503
1541
|
}
|
|
@@ -1542,9 +1580,11 @@ const jitsuAnalyticsPlugin = (pluginConfig = {}) => {
|
|
|
1542
1580
|
return send("identify", payload, config, instance, storage);
|
|
1543
1581
|
},
|
|
1544
1582
|
reset: args => {
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1583
|
+
const { config, instance } = args;
|
|
1584
|
+
const storage = pluginConfig.storageWrapper ? pluginConfig.storageWrapper(instance.storage) : instance.storage;
|
|
1585
|
+
storage === null || storage === void 0 ? void 0 : storage.reset();
|
|
1586
|
+
if (config.debug) {
|
|
1587
|
+
console.log("[JITSU DEBUG] Resetting Jitsu plugin storage");
|
|
1548
1588
|
}
|
|
1549
1589
|
},
|
|
1550
1590
|
methods: {
|
|
@@ -1656,9 +1696,9 @@ function createUnderlyingAnalyticsInstance(opts, rt, plugins = []) {
|
|
|
1656
1696
|
},
|
|
1657
1697
|
reset() {
|
|
1658
1698
|
for (const key of [...Object.keys(storageCache)]) {
|
|
1659
|
-
storage.removeItem(key);
|
|
1660
1699
|
delete storageCache[key];
|
|
1661
1700
|
}
|
|
1701
|
+
storage.reset();
|
|
1662
1702
|
},
|
|
1663
1703
|
removeItem(key) {
|
|
1664
1704
|
if (opts.debug) {
|
|
@@ -1715,7 +1755,20 @@ function createUnderlyingAnalyticsInstance(opts, rt, plugins = []) {
|
|
|
1715
1755
|
userState.anonymousId = id;
|
|
1716
1756
|
}
|
|
1717
1757
|
analytics.setAnonymousId(id);
|
|
1718
|
-
},
|
|
1758
|
+
}, reset() {
|
|
1759
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1760
|
+
if (opts.debug) {
|
|
1761
|
+
console.log("[JITSU DEBUG] Called reset(). Storage state", JSON.stringify(analytics.user()));
|
|
1762
|
+
}
|
|
1763
|
+
storage.reset();
|
|
1764
|
+
yield analytics.reset();
|
|
1765
|
+
this.setAnonymousId(uuid());
|
|
1766
|
+
if (opts.debug) {
|
|
1767
|
+
console.log("[JITSU DEBUG] User state after reset", JSON.stringify(analytics.user()));
|
|
1768
|
+
}
|
|
1769
|
+
});
|
|
1770
|
+
},
|
|
1771
|
+
group(groupId, traits, options, callback) {
|
|
1719
1772
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1720
1773
|
const results = [];
|
|
1721
1774
|
for (const plugin of Object.values(analytics.plugins)) {
|
|
@@ -1764,6 +1817,15 @@ function jitsuAnalytics(_opts) {
|
|
|
1764
1817
|
// result.loaded(createUnderlyingAnalyticsInstance(opts, rt));
|
|
1765
1818
|
// }
|
|
1766
1819
|
}
|
|
1820
|
+
function uuid() {
|
|
1821
|
+
var u = "", m = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx", i = 0, rb = (Math.random() * 0xffffffff) | 0;
|
|
1822
|
+
while (i++ < 36) {
|
|
1823
|
+
var c = m[i - 1], r = rb & 0xf, v = c == "x" ? r : (r & 0x3) | 0x8;
|
|
1824
|
+
u += c == "-" || c == "4" ? c : v.toString(16);
|
|
1825
|
+
rb = i % 8 == 0 ? (Math.random() * 0xffffffff) | 0 : rb >> 4;
|
|
1826
|
+
}
|
|
1827
|
+
return u;
|
|
1828
|
+
}
|
|
1767
1829
|
|
|
1768
1830
|
exports.emptyAnalytics = emptyAnalytics;
|
|
1769
1831
|
exports.emptyRuntime = emptyRuntime;
|
package/dist/jitsu.d.ts
CHANGED
|
@@ -52,6 +52,7 @@ type PersistentStorage = {
|
|
|
52
52
|
getItem: (key: string, options?: any) => any;
|
|
53
53
|
setItem: (key: string, value: any, options?: any) => void;
|
|
54
54
|
removeItem: (key: string, options?: any) => void;
|
|
55
|
+
reset: () => void;
|
|
55
56
|
};
|
|
56
57
|
type RuntimeFacade = {
|
|
57
58
|
store(): PersistentStorage;
|
package/dist/jitsu.es.js
CHANGED
|
@@ -69,7 +69,23 @@ function findScript(src) {
|
|
|
69
69
|
const scripts = Array.prototype.slice.call(window.document.querySelectorAll("script"));
|
|
70
70
|
return scripts.find(s => s.src === src);
|
|
71
71
|
}
|
|
72
|
-
function
|
|
72
|
+
function buildScriptSrc(src, options) {
|
|
73
|
+
let result = src;
|
|
74
|
+
if (!result.startsWith("http")) {
|
|
75
|
+
result = `https://${(options === null || options === void 0 ? void 0 : options.www) ? "www." : ""}${result}`;
|
|
76
|
+
}
|
|
77
|
+
if (options === null || options === void 0 ? void 0 : options.min) {
|
|
78
|
+
result = result + ".min.js";
|
|
79
|
+
}
|
|
80
|
+
else if (options === null || options === void 0 ? void 0 : options.js) {
|
|
81
|
+
result = result + ".js";
|
|
82
|
+
}
|
|
83
|
+
if (options === null || options === void 0 ? void 0 : options.query) {
|
|
84
|
+
result += "?" + options.query;
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
function loadScript(src, options) {
|
|
73
89
|
const found = findScript(src);
|
|
74
90
|
if (found !== undefined) {
|
|
75
91
|
const status = found === null || found === void 0 ? void 0 : found.getAttribute("status");
|
|
@@ -84,13 +100,13 @@ function loadScript(src, attributes) {
|
|
|
84
100
|
}
|
|
85
101
|
}
|
|
86
102
|
return new Promise((resolve, reject) => {
|
|
87
|
-
var _a;
|
|
103
|
+
var _a, _b;
|
|
88
104
|
const script = window.document.createElement("script");
|
|
89
105
|
script.type = "text/javascript";
|
|
90
|
-
script.src = src;
|
|
106
|
+
script.src = buildScriptSrc(src, options);
|
|
91
107
|
script.async = true;
|
|
92
108
|
script.setAttribute("status", "loading");
|
|
93
|
-
for (const [k, v] of Object.entries(attributes !== null &&
|
|
109
|
+
for (const [k, v] of Object.entries((_a = options === null || options === void 0 ? void 0 : options.attributes) !== null && _a !== void 0 ? _a : {})) {
|
|
94
110
|
script.setAttribute(k, v);
|
|
95
111
|
}
|
|
96
112
|
script.onload = () => {
|
|
@@ -104,7 +120,7 @@ function loadScript(src, attributes) {
|
|
|
104
120
|
reject(new Error(`Failed to load ${src}`));
|
|
105
121
|
};
|
|
106
122
|
const tag = window.document.getElementsByTagName("script")[0];
|
|
107
|
-
(
|
|
123
|
+
(_b = tag.parentElement) === null || _b === void 0 ? void 0 : _b.insertBefore(script, tag);
|
|
108
124
|
});
|
|
109
125
|
}
|
|
110
126
|
|
|
@@ -204,6 +220,7 @@ var __awaiter$4 = (undefined && undefined.__awaiter) || function (thisArg, _argu
|
|
|
204
220
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
205
221
|
});
|
|
206
222
|
};
|
|
223
|
+
const cdn = "cdn.lr-ingest.io/";
|
|
207
224
|
const logrocketPlugin = {
|
|
208
225
|
id: "logrocket",
|
|
209
226
|
handle(config, payload) {
|
|
@@ -254,7 +271,7 @@ function initLogrocketIfNeeded(appId) {
|
|
|
254
271
|
return;
|
|
255
272
|
}
|
|
256
273
|
setLogRocketState("loading");
|
|
257
|
-
loadScript(
|
|
274
|
+
loadScript(`${cdn}LogRocket`, { min: true, attributes: { crossOrigin: "anonymous" } })
|
|
258
275
|
.then(() => {
|
|
259
276
|
if (window["LogRocket"]) {
|
|
260
277
|
try {
|
|
@@ -377,8 +394,8 @@ function initGtmIfNeeded(config, payload) {
|
|
|
377
394
|
event: "gtm.js",
|
|
378
395
|
});
|
|
379
396
|
const dl = l != "dataLayer" ? "&l=" + l : "";
|
|
380
|
-
const scriptSrc = "
|
|
381
|
-
loadScript(scriptSrc)
|
|
397
|
+
const scriptSrc = "googletagmanager.com/gtm";
|
|
398
|
+
loadScript(scriptSrc, { www: true, js: true, query: "id=" + i + dl })
|
|
382
399
|
.then(() => {
|
|
383
400
|
setGtmState("loaded");
|
|
384
401
|
})
|
|
@@ -399,7 +416,7 @@ var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _argu
|
|
|
399
416
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
400
417
|
});
|
|
401
418
|
};
|
|
402
|
-
const defaultScriptSrc = "
|
|
419
|
+
const defaultScriptSrc = "googletagmanager.com/gtag/js";
|
|
403
420
|
const ga4Plugin = {
|
|
404
421
|
id: "ga4-tag",
|
|
405
422
|
handle(config, payload) {
|
|
@@ -461,7 +478,6 @@ function initGa4IfNeeded(config, payload) {
|
|
|
461
478
|
const dlParam = dlName !== "dataLayer" ? "&l=" + dlName : "";
|
|
462
479
|
// to work with both GA4 and GTM
|
|
463
480
|
const tagId = config.measurementIds;
|
|
464
|
-
const scriptSrc = `${defaultScriptSrc}?id=${tagId}${dlParam}`;
|
|
465
481
|
window[dlName] = window[dlName] || [];
|
|
466
482
|
const gtag = function () {
|
|
467
483
|
window[dlName].push(arguments);
|
|
@@ -471,7 +487,7 @@ function initGa4IfNeeded(config, payload) {
|
|
|
471
487
|
gtag(
|
|
472
488
|
// @ts-ignore
|
|
473
489
|
"config", tagId, Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId } : {})), (!config.autoPageView ? { send_page_view: false } : {})));
|
|
474
|
-
loadScript(
|
|
490
|
+
loadScript(defaultScriptSrc, { query: `id=${tagId}${dlParam}`, www: true })
|
|
475
491
|
.then(() => {
|
|
476
492
|
setGa4State("loaded");
|
|
477
493
|
})
|
|
@@ -1110,8 +1126,15 @@ function getGa4Ids(runtime) {
|
|
|
1110
1126
|
return undefined;
|
|
1111
1127
|
}
|
|
1112
1128
|
}
|
|
1113
|
-
function removeCookie(name) {
|
|
1114
|
-
document.cookie =
|
|
1129
|
+
function removeCookie(name, { domain, secure }) {
|
|
1130
|
+
document.cookie =
|
|
1131
|
+
name +
|
|
1132
|
+
"=;domain=" +
|
|
1133
|
+
domain +
|
|
1134
|
+
";path=/" +
|
|
1135
|
+
";expires=Thu, 01 Jan 1970 00:00:01 GMT;SameSite=" +
|
|
1136
|
+
(secure ? "None" : "Lax") +
|
|
1137
|
+
(secure ? ";secure" : "");
|
|
1115
1138
|
}
|
|
1116
1139
|
function setCookie(name, val, { domain, secure }) {
|
|
1117
1140
|
document.cookie =
|
|
@@ -1153,7 +1176,18 @@ const cookieStorage = (cookieDomain, key2cookie) => {
|
|
|
1153
1176
|
return parse(result);
|
|
1154
1177
|
},
|
|
1155
1178
|
removeItem(key) {
|
|
1156
|
-
removeCookie(key2cookie[key] || key
|
|
1179
|
+
removeCookie(key2cookie[key] || key, {
|
|
1180
|
+
domain: cookieDomain,
|
|
1181
|
+
secure: window.location.protocol === "https:",
|
|
1182
|
+
});
|
|
1183
|
+
},
|
|
1184
|
+
reset() {
|
|
1185
|
+
for (const v of Object.values(key2cookie)) {
|
|
1186
|
+
removeCookie(v, {
|
|
1187
|
+
domain: cookieDomain,
|
|
1188
|
+
secure: window.location.protocol === "https:",
|
|
1189
|
+
});
|
|
1190
|
+
}
|
|
1157
1191
|
},
|
|
1158
1192
|
};
|
|
1159
1193
|
};
|
|
@@ -1224,6 +1258,9 @@ const emptyRuntime = (config) => ({
|
|
|
1224
1258
|
store() {
|
|
1225
1259
|
const storage = {};
|
|
1226
1260
|
return {
|
|
1261
|
+
reset() {
|
|
1262
|
+
Object.keys(storage).forEach(key => delete storage[key]);
|
|
1263
|
+
},
|
|
1227
1264
|
setItem(key, val) {
|
|
1228
1265
|
if (config.debug) {
|
|
1229
1266
|
console.log(`[JITSU EMPTY RUNTIME] Set storage item ${key}=${JSON.stringify(val)}`);
|
|
@@ -1495,7 +1532,8 @@ function send(method, payload, jitsuConfig, instance, store) {
|
|
|
1495
1532
|
console.warn(`[JITSU] ${payload.type} responded with list of ${responseJson.destinations.length} destinations. However, this code is running in server-to-server mode, so destinations will be ignored`, jitsuConfig.debug ? JSON.stringify(responseJson.destinations, null, 2) : undefined);
|
|
1496
1533
|
}
|
|
1497
1534
|
else {
|
|
1498
|
-
|
|
1535
|
+
//double protection, ingest should not return destinations in s2s mode
|
|
1536
|
+
if (isInBrowser()) {
|
|
1499
1537
|
if (jitsuConfig.debug) {
|
|
1500
1538
|
console.log(`[JITSU] Processing device destinations: `, JSON.stringify(responseJson.destinations, null, 2));
|
|
1501
1539
|
}
|
|
@@ -1540,9 +1578,11 @@ const jitsuAnalyticsPlugin = (pluginConfig = {}) => {
|
|
|
1540
1578
|
return send("identify", payload, config, instance, storage);
|
|
1541
1579
|
},
|
|
1542
1580
|
reset: args => {
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1581
|
+
const { config, instance } = args;
|
|
1582
|
+
const storage = pluginConfig.storageWrapper ? pluginConfig.storageWrapper(instance.storage) : instance.storage;
|
|
1583
|
+
storage === null || storage === void 0 ? void 0 : storage.reset();
|
|
1584
|
+
if (config.debug) {
|
|
1585
|
+
console.log("[JITSU DEBUG] Resetting Jitsu plugin storage");
|
|
1546
1586
|
}
|
|
1547
1587
|
},
|
|
1548
1588
|
methods: {
|
|
@@ -1654,9 +1694,9 @@ function createUnderlyingAnalyticsInstance(opts, rt, plugins = []) {
|
|
|
1654
1694
|
},
|
|
1655
1695
|
reset() {
|
|
1656
1696
|
for (const key of [...Object.keys(storageCache)]) {
|
|
1657
|
-
storage.removeItem(key);
|
|
1658
1697
|
delete storageCache[key];
|
|
1659
1698
|
}
|
|
1699
|
+
storage.reset();
|
|
1660
1700
|
},
|
|
1661
1701
|
removeItem(key) {
|
|
1662
1702
|
if (opts.debug) {
|
|
@@ -1713,7 +1753,20 @@ function createUnderlyingAnalyticsInstance(opts, rt, plugins = []) {
|
|
|
1713
1753
|
userState.anonymousId = id;
|
|
1714
1754
|
}
|
|
1715
1755
|
analytics.setAnonymousId(id);
|
|
1716
|
-
},
|
|
1756
|
+
}, reset() {
|
|
1757
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1758
|
+
if (opts.debug) {
|
|
1759
|
+
console.log("[JITSU DEBUG] Called reset(). Storage state", JSON.stringify(analytics.user()));
|
|
1760
|
+
}
|
|
1761
|
+
storage.reset();
|
|
1762
|
+
yield analytics.reset();
|
|
1763
|
+
this.setAnonymousId(uuid());
|
|
1764
|
+
if (opts.debug) {
|
|
1765
|
+
console.log("[JITSU DEBUG] User state after reset", JSON.stringify(analytics.user()));
|
|
1766
|
+
}
|
|
1767
|
+
});
|
|
1768
|
+
},
|
|
1769
|
+
group(groupId, traits, options, callback) {
|
|
1717
1770
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1718
1771
|
const results = [];
|
|
1719
1772
|
for (const plugin of Object.values(analytics.plugins)) {
|
|
@@ -1762,5 +1815,14 @@ function jitsuAnalytics(_opts) {
|
|
|
1762
1815
|
// result.loaded(createUnderlyingAnalyticsInstance(opts, rt));
|
|
1763
1816
|
// }
|
|
1764
1817
|
}
|
|
1818
|
+
function uuid() {
|
|
1819
|
+
var u = "", m = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx", i = 0, rb = (Math.random() * 0xffffffff) | 0;
|
|
1820
|
+
while (i++ < 36) {
|
|
1821
|
+
var c = m[i - 1], r = rb & 0xf, v = c == "x" ? r : (r & 0x3) | 0x8;
|
|
1822
|
+
u += c == "-" || c == "4" ? c : v.toString(16);
|
|
1823
|
+
rb = i % 8 == 0 ? (Math.random() * 0xffffffff) | 0 : rb >> 4;
|
|
1824
|
+
}
|
|
1825
|
+
return u;
|
|
1826
|
+
}
|
|
1765
1827
|
|
|
1766
1828
|
export { emptyAnalytics, emptyRuntime, isInBrowser, jitsuAnalytics, parseQuery, randomId, windowRuntime };
|
package/dist/script-loader.d.ts
CHANGED
|
@@ -1 +1,8 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type ScriptOptions = {
|
|
2
|
+
attributes?: Record<string, string>;
|
|
3
|
+
www?: boolean;
|
|
4
|
+
js?: boolean;
|
|
5
|
+
min?: boolean;
|
|
6
|
+
query?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function loadScript(src: string, options?: ScriptOptions): Promise<HTMLScriptElement>;
|