@jitsu/js 1.7.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 +489 -177
- package/__tests__/node/nodejs.test.ts +38 -0
- package/dist/index.d.ts +1 -8
- package/dist/jitsu.cjs.js +61 -35
- package/dist/jitsu.es.js +61 -35
- package/dist/web/p.js.txt +1219 -1
- package/package.json +3 -3
- package/rollup.config.js +8 -1
- package/src/analytics-plugin.ts +45 -26
- package/src/browser.ts +16 -27
- package/src/index.ts +17 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jitsu/js",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Jitsu Dev Team <dev@jitsu.com>",
|
|
6
6
|
"main": "dist/jitsu.cjs.js",
|
|
@@ -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.7.
|
|
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,25 +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
|
-
|
|
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 {
|
|
83
104
|
return undefined;
|
|
84
105
|
}
|
|
85
|
-
return Object.fromEntries(
|
|
86
|
-
gaCookies
|
|
87
|
-
.map(([key, value]) => {
|
|
88
|
-
if (typeof value !== "string") {
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
const parts = value.split(".");
|
|
92
|
-
if (parts.length < 3) {
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
return [key.substring("_ga_".length), parts[2]];
|
|
96
|
-
})
|
|
97
|
-
.filter(v => v !== null)
|
|
98
|
-
);
|
|
99
106
|
}
|
|
100
107
|
|
|
101
108
|
function removeCookie(name: string) {
|
|
@@ -308,10 +315,7 @@ function adjustPayload(payload: any, config: JitsuOptions, storage: PersistentSt
|
|
|
308
315
|
clientIds: {
|
|
309
316
|
fbc: runtime.getCookie("_fbc"),
|
|
310
317
|
fbp: runtime.getCookie("_fbp"),
|
|
311
|
-
|
|
312
|
-
clientId: runtime.getCookie("_ga")?.split(".").slice(-2).join("."), //last 2 parts of GA cookie
|
|
313
|
-
sessions: getGa4Sessions(runtime.getCookies()),
|
|
314
|
-
},
|
|
318
|
+
...getGa4Ids(runtime),
|
|
315
319
|
},
|
|
316
320
|
campaign: parseUtms(query),
|
|
317
321
|
};
|
|
@@ -475,7 +479,7 @@ function send(
|
|
|
475
479
|
store: PersistentStorage
|
|
476
480
|
): Promise<void> {
|
|
477
481
|
if (jitsuConfig.echoEvents) {
|
|
478
|
-
console.log(`[JITSU] sending '${method}' event:`, payload);
|
|
482
|
+
console.log(`[JITSU DEBUG] sending '${method}' event:`, payload);
|
|
479
483
|
return;
|
|
480
484
|
}
|
|
481
485
|
|
|
@@ -541,18 +545,31 @@ function send(
|
|
|
541
545
|
|
|
542
546
|
const jitsuAnalyticsPlugin = (pluginConfig: JitsuOptions = {}): AnalyticsPlugin => {
|
|
543
547
|
const storageCache: any = {};
|
|
548
|
+
|
|
544
549
|
// AnalyticsInstance's storage is async somewhere inside. So if we make 'page' call right after 'identify' call
|
|
545
550
|
// 'page' call will load traits from storage before 'identify' call had a change to save them.
|
|
546
551
|
// to avoid that we use in-memory cache for storage
|
|
547
552
|
const cachingStorageWrapper = (persistentStorage: PersistentStorage): PersistentStorage => ({
|
|
548
553
|
setItem(key: string, val: any) {
|
|
554
|
+
if (pluginConfig.debug) {
|
|
555
|
+
console.log(`[JITSU DEBUG] Caching storage setItem: ${key}=${val}`);
|
|
556
|
+
}
|
|
549
557
|
storageCache[key] = val;
|
|
550
558
|
persistentStorage.setItem(key, val);
|
|
551
559
|
},
|
|
552
560
|
getItem(key: string) {
|
|
553
|
-
|
|
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;
|
|
554
568
|
},
|
|
555
569
|
removeItem(key: string) {
|
|
570
|
+
if (pluginConfig.debug) {
|
|
571
|
+
console.log(`[JITSU DEBUG] Caching storage removeItem: ${key}`);
|
|
572
|
+
}
|
|
556
573
|
delete storageCache[key];
|
|
557
574
|
persistentStorage.removeItem(key);
|
|
558
575
|
},
|
|
@@ -564,10 +581,11 @@ const jitsuAnalyticsPlugin = (pluginConfig: JitsuOptions = {}): AnalyticsPlugin
|
|
|
564
581
|
return {
|
|
565
582
|
name: "jitsu",
|
|
566
583
|
config: instanceConfig,
|
|
584
|
+
|
|
567
585
|
initialize: args => {
|
|
568
586
|
const { config } = args;
|
|
569
587
|
if (config.debug) {
|
|
570
|
-
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));
|
|
571
589
|
}
|
|
572
590
|
if (!config.host && !config.echoEvents) {
|
|
573
591
|
throw new Error("Please specify host variable in jitsu plugin initialization, or set echoEvents to true");
|
|
@@ -596,15 +614,16 @@ const jitsuAnalyticsPlugin = (pluginConfig: JitsuOptions = {}): AnalyticsPlugin
|
|
|
596
614
|
//analytics doesn't support group as a base method, so we need to add it manually
|
|
597
615
|
group(groupId?: ID, traits?: JSONObject | null, options?: Options, callback?: Callback) {
|
|
598
616
|
const analyticsInstance = this.instance;
|
|
617
|
+
const cacheWrap = cachingStorageWrapper(analyticsInstance.storage);
|
|
599
618
|
const user = analyticsInstance.user();
|
|
600
619
|
const userId = options?.userId || user?.userId;
|
|
601
|
-
const anonymousId = options?.anonymousId || user?.anonymousId;
|
|
620
|
+
const anonymousId = options?.anonymousId || user?.anonymousId || cacheWrap.getItem("__anon_id");
|
|
602
621
|
return send(
|
|
603
622
|
"group",
|
|
604
623
|
{ type: "group", groupId, traits, ...(anonymousId ? { anonymousId } : {}), ...(userId ? { userId } : {}) },
|
|
605
624
|
instanceConfig,
|
|
606
625
|
analyticsInstance,
|
|
607
|
-
|
|
626
|
+
cacheWrap
|
|
608
627
|
);
|
|
609
628
|
},
|
|
610
629
|
},
|
package/src/browser.ts
CHANGED
|
@@ -53,35 +53,10 @@ function getScriptAttributes(scriptElement: HTMLScriptElement) {
|
|
|
53
53
|
|
|
54
54
|
const options = readJitsuOptions();
|
|
55
55
|
const JITSU_V2_ID: string = options.namespace || "jitsu";
|
|
56
|
-
const queue = [];
|
|
57
|
-
if (window[JITSU_V2_ID]) {
|
|
58
|
-
if (Array.isArray(window[JITSU_V2_ID])) {
|
|
59
|
-
//processing queue of events
|
|
60
|
-
if (options.debug) {
|
|
61
|
-
console.log(
|
|
62
|
-
`Initializing Jitsu with prior events queue size of ${window[JITSU_V2_ID].length}`,
|
|
63
|
-
window[JITSU_V2_ID]
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
queue.push(...window[JITSU_V2_ID]);
|
|
67
|
-
} else {
|
|
68
|
-
console.warn("Attempted to initialize Jitsu twice. Returning the existing instance");
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
56
|
if (options.debug) {
|
|
72
57
|
console.log(`Jitsu options: `, JSON.stringify(options));
|
|
73
58
|
}
|
|
74
59
|
const jitsu = jitsuAnalytics(options);
|
|
75
|
-
for (const [method, args] of queue) {
|
|
76
|
-
if (options.debug) {
|
|
77
|
-
console.log(`Processing event ${method} from Jitsu queue on`, args);
|
|
78
|
-
}
|
|
79
|
-
try {
|
|
80
|
-
jitsu[method](...args);
|
|
81
|
-
} catch (e: any) {
|
|
82
|
-
console.warn(`Error processing event ${method} from Jitsu queue on`, args, e);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
60
|
|
|
86
61
|
if (options.onload) {
|
|
87
62
|
const onloadFunction = window[options.onload] as any;
|
|
@@ -96,8 +71,22 @@ function getScriptAttributes(scriptElement: HTMLScriptElement) {
|
|
|
96
71
|
}
|
|
97
72
|
window[JITSU_V2_ID] = jitsu;
|
|
98
73
|
|
|
99
|
-
|
|
100
|
-
|
|
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
|
+
|
|
101
90
|
if (options.debug) {
|
|
102
91
|
console.log(`Jitsu callback queue size: ${callbackQueue.length}`, callbackQueue);
|
|
103
92
|
}
|
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"]) {
|