@jitsu/js 1.6.1 → 1.7.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/.turbo/turbo-build.log +105 -105
- package/.turbo/turbo-clean.log +5 -5
- package/.turbo/turbo-test.log +1293 -50
- package/__tests__/node/nodejs.test.ts +38 -0
- package/dist/index.d.ts +1 -10
- package/dist/jitsu.cjs.js +80 -36
- package/dist/jitsu.d.ts +2 -0
- package/dist/jitsu.es.js +81 -35
- package/dist/web/p.js.txt +1219 -1
- package/package.json +4 -4
- package/rollup.config.js +8 -1
- package/src/analytics-plugin.ts +67 -26
- package/src/browser.ts +26 -4
- package/src/index.ts +17 -4
- package/src/jitsu.ts +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jitsu/js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Jitsu Dev Team <dev@jitsu.com>",
|
|
6
6
|
"main": "dist/jitsu.cjs.js",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"private": false,
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@playwright/test": "1.
|
|
15
|
+
"@playwright/test": "1.39.0",
|
|
16
16
|
"@rollup/plugin-commonjs": "^23.0.2",
|
|
17
17
|
"@rollup/plugin-json": "^5.0.1",
|
|
18
18
|
"@rollup/plugin-multi-entry": "^6.0.0",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"rollup": "^3.2.5",
|
|
35
35
|
"ts-jest": "29.0.5",
|
|
36
36
|
"typescript": "^4.9.5",
|
|
37
|
-
"@jitsu/protocols": "1.
|
|
37
|
+
"@jitsu/protocols": "1.7.2"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"analytics": "
|
|
40
|
+
"analytics": "0.8.9"
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
43
|
"clean": "rm -rf ./dist",
|
package/rollup.config.js
CHANGED
|
@@ -4,9 +4,16 @@ const commonjs = require("@rollup/plugin-commonjs");
|
|
|
4
4
|
const rollupJson = require("@rollup/plugin-json");
|
|
5
5
|
const terser = require("@rollup/plugin-terser");
|
|
6
6
|
|
|
7
|
+
|
|
7
8
|
module.exports = [
|
|
8
9
|
{
|
|
9
|
-
plugins: [
|
|
10
|
+
plugins: [
|
|
11
|
+
multi(),
|
|
12
|
+
resolve({ preferBuiltins: false }),
|
|
13
|
+
commonjs(),
|
|
14
|
+
rollupJson(),
|
|
15
|
+
(process.JITSU_JS_DEBUG_BUILD = "1" ? undefined : terser()),
|
|
16
|
+
],
|
|
10
17
|
input: "./compiled/src/browser.js",
|
|
11
18
|
output: {
|
|
12
19
|
file: `dist/web/p.js.txt`,
|
package/src/analytics-plugin.ts
CHANGED
|
@@ -77,23 +77,32 @@ function getCookie(name: string) {
|
|
|
77
77
|
return parts.length === 2 ? parts.pop().split(";").shift() : undefined;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
function
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
80
|
+
function getGa4Ids(runtime: RuntimeFacade) {
|
|
81
|
+
const allCookies = runtime.getCookies();
|
|
82
|
+
const clientId = allCookies["_ga"]?.split(".").slice(-2).join(".");
|
|
83
|
+
const gaSessionCookies = Object.entries(allCookies).filter(([key]) => key.startsWith("_ga_"));
|
|
84
|
+
const sessionIds =
|
|
85
|
+
gaSessionCookies.length > 0
|
|
86
|
+
? Object.fromEntries(
|
|
87
|
+
gaSessionCookies
|
|
88
|
+
.map(([key, value]) => {
|
|
89
|
+
if (typeof value !== "string") {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
const parts = value.split(".");
|
|
93
|
+
if (parts.length < 3) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
return [key.substring("_ga_".length), parts[2]];
|
|
97
|
+
})
|
|
98
|
+
.filter(v => v !== null)
|
|
99
|
+
)
|
|
100
|
+
: undefined;
|
|
101
|
+
if (clientId || sessionIds) {
|
|
102
|
+
return { ga4: { clientId, sessionIds } };
|
|
103
|
+
} else {
|
|
94
104
|
return undefined;
|
|
95
105
|
}
|
|
96
|
-
return sessions;
|
|
97
106
|
}
|
|
98
107
|
|
|
99
108
|
function removeCookie(name: string) {
|
|
@@ -149,6 +158,20 @@ const cookieStorage: StorageFactory = (cookieDomain, key2cookie) => {
|
|
|
149
158
|
|
|
150
159
|
export function windowRuntime(opts: JitsuOptions): RuntimeFacade {
|
|
151
160
|
return {
|
|
161
|
+
getCookie(name: string): string | undefined {
|
|
162
|
+
const value = `; ${document.cookie}`;
|
|
163
|
+
const parts = value.split(`; ${name}=`);
|
|
164
|
+
return parts.length === 2 ? parts.pop().split(";").shift() : undefined;
|
|
165
|
+
},
|
|
166
|
+
getCookies(): Record<string, string> {
|
|
167
|
+
const value = `; ${document.cookie}`;
|
|
168
|
+
const cookies: Record<string, string> = {};
|
|
169
|
+
const matches = value.matchAll(/(\w+)=([^;]+)/g);
|
|
170
|
+
for (const match of matches) {
|
|
171
|
+
cookies[match[1]] = match[2];
|
|
172
|
+
}
|
|
173
|
+
return cookies;
|
|
174
|
+
},
|
|
152
175
|
documentEncoding(): string | undefined {
|
|
153
176
|
return window.document.characterSet;
|
|
154
177
|
},
|
|
@@ -193,6 +216,12 @@ export const emptyRuntime = (config: JitsuOptions): RuntimeFacade => ({
|
|
|
193
216
|
timezoneOffset(): number | undefined {
|
|
194
217
|
return undefined;
|
|
195
218
|
},
|
|
219
|
+
getCookie(name: string): string | undefined {
|
|
220
|
+
return undefined;
|
|
221
|
+
},
|
|
222
|
+
getCookies(): Record<string, string> {
|
|
223
|
+
return {};
|
|
224
|
+
},
|
|
196
225
|
|
|
197
226
|
store(): PersistentStorage {
|
|
198
227
|
const storage = {};
|
|
@@ -284,12 +313,9 @@ function adjustPayload(payload: any, config: JitsuOptions, storage: PersistentSt
|
|
|
284
313
|
encoding: properties.encoding || runtime.documentEncoding(),
|
|
285
314
|
},
|
|
286
315
|
clientIds: {
|
|
287
|
-
fbc: getCookie("_fbc"),
|
|
288
|
-
fbp: getCookie("_fbp"),
|
|
289
|
-
|
|
290
|
-
clientId: getCookie("_ga")?.split(".").slice(-2).join("."), //last 2 parts of GA cookie
|
|
291
|
-
sessions: getGa4Sessions(),
|
|
292
|
-
},
|
|
316
|
+
fbc: runtime.getCookie("_fbc"),
|
|
317
|
+
fbp: runtime.getCookie("_fbp"),
|
|
318
|
+
...getGa4Ids(runtime),
|
|
293
319
|
},
|
|
294
320
|
campaign: parseUtms(query),
|
|
295
321
|
};
|
|
@@ -453,7 +479,7 @@ function send(
|
|
|
453
479
|
store: PersistentStorage
|
|
454
480
|
): Promise<void> {
|
|
455
481
|
if (jitsuConfig.echoEvents) {
|
|
456
|
-
console.log(`[JITSU] sending '${method}' event:`, payload);
|
|
482
|
+
console.log(`[JITSU DEBUG] sending '${method}' event:`, payload);
|
|
457
483
|
return;
|
|
458
484
|
}
|
|
459
485
|
|
|
@@ -519,18 +545,31 @@ function send(
|
|
|
519
545
|
|
|
520
546
|
const jitsuAnalyticsPlugin = (pluginConfig: JitsuOptions = {}): AnalyticsPlugin => {
|
|
521
547
|
const storageCache: any = {};
|
|
548
|
+
|
|
522
549
|
// AnalyticsInstance's storage is async somewhere inside. So if we make 'page' call right after 'identify' call
|
|
523
550
|
// 'page' call will load traits from storage before 'identify' call had a change to save them.
|
|
524
551
|
// to avoid that we use in-memory cache for storage
|
|
525
552
|
const cachingStorageWrapper = (persistentStorage: PersistentStorage): PersistentStorage => ({
|
|
526
553
|
setItem(key: string, val: any) {
|
|
554
|
+
if (pluginConfig.debug) {
|
|
555
|
+
console.log(`[JITSU DEBUG] Caching storage setItem: ${key}=${val}`);
|
|
556
|
+
}
|
|
527
557
|
storageCache[key] = val;
|
|
528
558
|
persistentStorage.setItem(key, val);
|
|
529
559
|
},
|
|
530
560
|
getItem(key: string) {
|
|
531
|
-
|
|
561
|
+
const value = storageCache[key] || persistentStorage.getItem(key);
|
|
562
|
+
if (pluginConfig.debug) {
|
|
563
|
+
console.log(
|
|
564
|
+
`[JITSU DEBUG] Caching storage getItem: ${key}=${value}. Evicted from cache: ${!storageCache[key]}`
|
|
565
|
+
);
|
|
566
|
+
}
|
|
567
|
+
return value;
|
|
532
568
|
},
|
|
533
569
|
removeItem(key: string) {
|
|
570
|
+
if (pluginConfig.debug) {
|
|
571
|
+
console.log(`[JITSU DEBUG] Caching storage removeItem: ${key}`);
|
|
572
|
+
}
|
|
534
573
|
delete storageCache[key];
|
|
535
574
|
persistentStorage.removeItem(key);
|
|
536
575
|
},
|
|
@@ -542,10 +581,11 @@ const jitsuAnalyticsPlugin = (pluginConfig: JitsuOptions = {}): AnalyticsPlugin
|
|
|
542
581
|
return {
|
|
543
582
|
name: "jitsu",
|
|
544
583
|
config: instanceConfig,
|
|
584
|
+
|
|
545
585
|
initialize: args => {
|
|
546
586
|
const { config } = args;
|
|
547
587
|
if (config.debug) {
|
|
548
|
-
console.debug("[JITSU] Initializing Jitsu plugin with config: ", JSON.stringify(config));
|
|
588
|
+
console.debug("[JITSU DEBUG] Initializing Jitsu plugin with config: ", JSON.stringify(config, null, 2));
|
|
549
589
|
}
|
|
550
590
|
if (!config.host && !config.echoEvents) {
|
|
551
591
|
throw new Error("Please specify host variable in jitsu plugin initialization, or set echoEvents to true");
|
|
@@ -574,15 +614,16 @@ const jitsuAnalyticsPlugin = (pluginConfig: JitsuOptions = {}): AnalyticsPlugin
|
|
|
574
614
|
//analytics doesn't support group as a base method, so we need to add it manually
|
|
575
615
|
group(groupId?: ID, traits?: JSONObject | null, options?: Options, callback?: Callback) {
|
|
576
616
|
const analyticsInstance = this.instance;
|
|
617
|
+
const cacheWrap = cachingStorageWrapper(analyticsInstance.storage);
|
|
577
618
|
const user = analyticsInstance.user();
|
|
578
619
|
const userId = options?.userId || user?.userId;
|
|
579
|
-
const anonymousId = options?.anonymousId || user?.anonymousId;
|
|
620
|
+
const anonymousId = options?.anonymousId || user?.anonymousId || cacheWrap.getItem("__anon_id");
|
|
580
621
|
return send(
|
|
581
622
|
"group",
|
|
582
623
|
{ type: "group", groupId, traits, ...(anonymousId ? { anonymousId } : {}), ...(userId ? { userId } : {}) },
|
|
583
624
|
instanceConfig,
|
|
584
625
|
analyticsInstance,
|
|
585
|
-
|
|
626
|
+
cacheWrap
|
|
586
627
|
);
|
|
587
628
|
},
|
|
588
629
|
},
|
package/src/browser.ts
CHANGED
|
@@ -53,10 +53,6 @@ function getScriptAttributes(scriptElement: HTMLScriptElement) {
|
|
|
53
53
|
|
|
54
54
|
const options = readJitsuOptions();
|
|
55
55
|
const JITSU_V2_ID: string = options.namespace || "jitsu";
|
|
56
|
-
|
|
57
|
-
if (window[JITSU_V2_ID]) {
|
|
58
|
-
console.log("Jitsu is already initialized");
|
|
59
|
-
}
|
|
60
56
|
if (options.debug) {
|
|
61
57
|
console.log(`Jitsu options: `, JSON.stringify(options));
|
|
62
58
|
}
|
|
@@ -75,6 +71,32 @@ function getScriptAttributes(scriptElement: HTMLScriptElement) {
|
|
|
75
71
|
}
|
|
76
72
|
window[JITSU_V2_ID] = jitsu;
|
|
77
73
|
|
|
74
|
+
/**
|
|
75
|
+
* New callback based queue, see below
|
|
76
|
+
*/
|
|
77
|
+
//make a copy of the queue
|
|
78
|
+
const callbackQueue = [...(window[JITSU_V2_ID + "Q"] || [])];
|
|
79
|
+
//replace push with a function that calls callback immediately
|
|
80
|
+
window[JITSU_V2_ID + "Q"] = {
|
|
81
|
+
push: (callback: any) => {
|
|
82
|
+
if (typeof callback === "function") {
|
|
83
|
+
callback(jitsu);
|
|
84
|
+
} else {
|
|
85
|
+
console.warn(`${JITSU_V2_ID}Q.push() accepts only function, ${typeof callback} given`);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
if (options.debug) {
|
|
91
|
+
console.log(`Jitsu callback queue size: ${callbackQueue.length}`, callbackQueue);
|
|
92
|
+
}
|
|
93
|
+
callbackQueue.forEach((callback: any) => {
|
|
94
|
+
try {
|
|
95
|
+
callback(jitsu);
|
|
96
|
+
} catch (e: any) {
|
|
97
|
+
console.warn(`Error processing callback from Jitsu queue`, e);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
78
100
|
if (!options.initOnly) {
|
|
79
101
|
jitsu.page();
|
|
80
102
|
}
|
package/src/index.ts
CHANGED
|
@@ -23,7 +23,8 @@ export default function parse(input) {
|
|
|
23
23
|
return value;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
export const emptyAnalytics = {
|
|
26
|
+
export const emptyAnalytics: AnalyticsInterface = {
|
|
27
|
+
setAnonymousId: () => {},
|
|
27
28
|
track: () => Promise.resolve(),
|
|
28
29
|
page: () => Promise.resolve(),
|
|
29
30
|
user: () => ({}),
|
|
@@ -37,10 +38,11 @@ function createUnderlyingAnalyticsInstance(
|
|
|
37
38
|
rt: RuntimeFacade,
|
|
38
39
|
plugins: any[] = []
|
|
39
40
|
): AnalyticsInterface {
|
|
41
|
+
const storage = rt.store();
|
|
40
42
|
const analytics = Analytics({
|
|
41
43
|
app: "test",
|
|
42
44
|
debug: !!opts.debug,
|
|
43
|
-
storage
|
|
45
|
+
storage,
|
|
44
46
|
plugins: [jitsuAnalyticsPlugin(opts), ...plugins],
|
|
45
47
|
} as any);
|
|
46
48
|
const originalPage = analytics.page;
|
|
@@ -56,6 +58,19 @@ function createUnderlyingAnalyticsInstance(
|
|
|
56
58
|
};
|
|
57
59
|
return {
|
|
58
60
|
...analytics,
|
|
61
|
+
setAnonymousId: (id: string) => {
|
|
62
|
+
if (opts.debug) {
|
|
63
|
+
console.log("[JITSU DEBUG] Setting anonymous id to " + id);
|
|
64
|
+
//Workaround for analytics.js bug. Underlying setAnonymousId doesn't work set the id immediately,
|
|
65
|
+
//so we got to it manually here. See https://github.com/jitsucom/jitsu/issues/1060
|
|
66
|
+
storage.setItem("__anon_id", id);
|
|
67
|
+
const userState = analytics.user();
|
|
68
|
+
if (userState) {
|
|
69
|
+
userState.anonymousId = id;
|
|
70
|
+
}
|
|
71
|
+
(analytics as any).setAnonymousId(id);
|
|
72
|
+
}
|
|
73
|
+
},
|
|
59
74
|
group(groupId?: ID, traits?: JSONObject | null, options?: Options, callback?: Callback): Promise<DispatchedEvent> {
|
|
60
75
|
for (const plugin of Object.values(analytics.plugins)) {
|
|
61
76
|
if (plugin["group"]) {
|
|
@@ -98,5 +113,3 @@ export function jitsuAnalytics(opts: JitsuOptions): AnalyticsInterface {
|
|
|
98
113
|
|
|
99
114
|
export * from "./jitsu";
|
|
100
115
|
export * from "./analytics-plugin";
|
|
101
|
-
export { applyFilters } from "./destination-plugins";
|
|
102
|
-
export { getTopLevelDomain } from "./tlds";
|
package/src/jitsu.ts
CHANGED
|
@@ -52,6 +52,9 @@ type RuntimeFacade = {
|
|
|
52
52
|
language(): string | undefined;
|
|
53
53
|
pageUrl(): string | undefined;
|
|
54
54
|
documentEncoding(): string | undefined;
|
|
55
|
+
getCookie(name: string): string | undefined;
|
|
56
|
+
getCookies(): Record<string, string>;
|
|
57
|
+
|
|
55
58
|
timezoneOffset(): number | undefined;
|
|
56
59
|
screen():
|
|
57
60
|
| {
|