@jitsu/js 1.0.0-canary-20230219230449 → 1.1.0-canary.14.20230602211353
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 +95 -65
- package/.turbo/turbo-clean.log +5 -5
- package/__tests__/node/nodejs.test.ts +15 -7
- package/__tests__/playwright/integration.test.ts +1 -2
- package/dist/analytics-plugin.d.ts +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/jitsu.cjs.js +304 -59
- package/dist/jitsu.d.ts +1 -1
- package/dist/jitsu.es.js +304 -60
- package/dist/version.d.ts +2 -0
- package/dist/web/p.js.txt +295 -59
- package/package.json +6 -5
- package/src/analytics-plugin.ts +56 -16
- package/src/destination-plugins/gtm.ts +112 -0
- package/src/destination-plugins/index.ts +47 -0
- package/src/destination-plugins/logrocket.ts +83 -0
- package/src/{destination-plugins.ts → destination-plugins/tag.ts} +3 -28
- package/src/index.ts +21 -3
- package/src/jitsu.ts +1 -1
- package/src/version.ts +3 -0
- package/tsconfig.json +1 -0
- package/dist/destination-plugins.d.ts +0 -13
package/src/analytics-plugin.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/* global analytics */
|
|
2
2
|
|
|
3
3
|
import { JitsuOptions, PersistentStorage, RuntimeFacade } from "./jitsu";
|
|
4
|
-
import { AnalyticsClientEvent } from "@jitsu/protocols/analytics";
|
|
4
|
+
import { AnalyticsClientEvent, Callback, ID, JSONObject, Options } from "@jitsu/protocols/analytics";
|
|
5
5
|
import parse from "./index";
|
|
6
6
|
import { AnalyticsInstance, AnalyticsPlugin } from "analytics";
|
|
7
|
-
import { internalDestinationPlugins } from "./destination-plugins";
|
|
8
7
|
import { loadScript } from "./script-loader";
|
|
8
|
+
import { internalDestinationPlugins } from "./destination-plugins";
|
|
9
|
+
import { jitsuLibraryName, jitsuVersion } from "./version";
|
|
9
10
|
|
|
10
|
-
const
|
|
11
|
+
const defaultConfig: Required<JitsuOptions> = {
|
|
11
12
|
/* Your segment writeKey */
|
|
12
13
|
writeKey: null,
|
|
13
14
|
/* Disable anonymous MTU */
|
|
@@ -15,6 +16,8 @@ const config: JitsuOptions = {
|
|
|
15
16
|
debug: false,
|
|
16
17
|
fetch: null,
|
|
17
18
|
echoEvents: false,
|
|
19
|
+
cookieDomain: undefined,
|
|
20
|
+
runtime: undefined,
|
|
18
21
|
};
|
|
19
22
|
|
|
20
23
|
export const parseQuery = (qs?: string): Record<string, string> => {
|
|
@@ -255,13 +258,13 @@ function adjustPayload(payload: any, config: JitsuOptions, storage: PersistentSt
|
|
|
255
258
|
const referrer = runtime.referrer();
|
|
256
259
|
const context = {
|
|
257
260
|
library: {
|
|
258
|
-
name:
|
|
259
|
-
version:
|
|
261
|
+
name: jitsuLibraryName,
|
|
262
|
+
version: jitsuVersion,
|
|
260
263
|
},
|
|
261
264
|
userAgent: runtime.userAgent(),
|
|
262
265
|
locale: runtime.language(),
|
|
263
266
|
screen: runtime.screen(),
|
|
264
|
-
traits: payload.type != "identify" ? { ...(restoreTraits(storage) || {}) } : undefined,
|
|
267
|
+
traits: payload.type != "identify" && payload.type != "group" ? { ...(restoreTraits(storage) || {}) } : undefined,
|
|
265
268
|
page: {
|
|
266
269
|
path: properties.path || (parsedUrl && parsedUrl.pathname),
|
|
267
270
|
referrer: referrer,
|
|
@@ -270,7 +273,7 @@ function adjustPayload(payload: any, config: JitsuOptions, storage: PersistentSt
|
|
|
270
273
|
search: properties.search || (parsedUrl && parsedUrl.search),
|
|
271
274
|
title: properties.title || runtime.pageTitle(),
|
|
272
275
|
url: properties.url || url,
|
|
273
|
-
|
|
276
|
+
encoding: properties.encoding || runtime.documentEncoding(),
|
|
274
277
|
},
|
|
275
278
|
campaign: parseUtms(query),
|
|
276
279
|
};
|
|
@@ -279,7 +282,7 @@ function adjustPayload(payload: any, config: JitsuOptions, storage: PersistentSt
|
|
|
279
282
|
timestamp: new Date().toISOString(),
|
|
280
283
|
sentAt: new Date().toISOString(),
|
|
281
284
|
messageId: randomId(properties.path || (parsedUrl && parsedUrl.pathname)),
|
|
282
|
-
writeKey: config.writeKey,
|
|
285
|
+
writeKey: validateWriteKey(config.writeKey),
|
|
283
286
|
context: deepMerge(context, customContext),
|
|
284
287
|
};
|
|
285
288
|
delete withContext.meta;
|
|
@@ -291,6 +294,7 @@ export type DestinationDescriptor = {
|
|
|
291
294
|
id: string;
|
|
292
295
|
destinationType: string;
|
|
293
296
|
credentials: any;
|
|
297
|
+
options: any;
|
|
294
298
|
deviceOptions: DeviceOptions;
|
|
295
299
|
};
|
|
296
300
|
export type AnalyticsPluginDescriptor = {
|
|
@@ -315,11 +319,13 @@ async function processDestinations(
|
|
|
315
319
|
) {
|
|
316
320
|
const promises: Promise<any>[] = [];
|
|
317
321
|
for (const destination of destinations) {
|
|
322
|
+
const credentials = { ...destination.credentials, ...destination.options };
|
|
323
|
+
|
|
318
324
|
if (destination.deviceOptions.type === "internal-plugin") {
|
|
319
325
|
const plugin = internalDestinationPlugins[destination.deviceOptions.name];
|
|
320
326
|
if (plugin) {
|
|
321
327
|
try {
|
|
322
|
-
promises.push(plugin.handle(
|
|
328
|
+
promises.push(plugin.handle(credentials, event));
|
|
323
329
|
} catch (e) {
|
|
324
330
|
console.warn(
|
|
325
331
|
`[JITSU] Error processing event with internal plugin '${destination.deviceOptions.name}': ${e?.message}`,
|
|
@@ -341,7 +347,7 @@ async function processDestinations(
|
|
|
341
347
|
} else {
|
|
342
348
|
let pluginInstance: any;
|
|
343
349
|
try {
|
|
344
|
-
pluginInstance = (typeof plugin === "function" ? plugin : plugin.init)(
|
|
350
|
+
pluginInstance = (typeof plugin === "function" ? plugin : plugin.init)(credentials);
|
|
345
351
|
} catch (e) {
|
|
346
352
|
console.warn(
|
|
347
353
|
`[JITSU] Error creating plugin '${destination.deviceOptions.moduleVarName}@${destination.deviceOptions.packageCdn}' for destination '${destination.id}': ${e?.message}`,
|
|
@@ -381,6 +387,21 @@ async function processDestinations(
|
|
|
381
387
|
}
|
|
382
388
|
}
|
|
383
389
|
|
|
390
|
+
function looksLikeCuid(id: string) {
|
|
391
|
+
return id.length === 25 && id.charAt(0) === "c";
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function validateWriteKey(writeKey?: string): string | undefined {
|
|
395
|
+
if (writeKey) {
|
|
396
|
+
const [, secret] = writeKey.split(":", 2);
|
|
397
|
+
if (!secret && !looksLikeCuid(writeKey)) {
|
|
398
|
+
throw new Error(
|
|
399
|
+
`Legacy write key detected - ${writeKey}! This format doesn't work anymore, it should be 'key:secret'. Please download a new key from Jitsu UI`
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return writeKey;
|
|
404
|
+
}
|
|
384
405
|
function send(
|
|
385
406
|
method,
|
|
386
407
|
payload,
|
|
@@ -400,13 +421,15 @@ function send(
|
|
|
400
421
|
"Please specify fetch function in jitsu plugin initialization, fetch isn't available in global scope"
|
|
401
422
|
);
|
|
402
423
|
}
|
|
403
|
-
const authHeader = {};
|
|
404
424
|
const debugHeader = jitsuConfig.debug ? { "X-Enable-Debug": "true" } : {};
|
|
405
425
|
|
|
406
426
|
// if (jitsuConfig.debug) {
|
|
407
427
|
// console.log(`[JITSU] Sending event to ${url}: `, JSON.stringify(payload, null, 2));
|
|
408
428
|
// }
|
|
409
429
|
const adjustedPayload = adjustPayload(payload, jitsuConfig, store);
|
|
430
|
+
|
|
431
|
+
const authHeader = jitsuConfig.writeKey ? { "X-Write-Key": validateWriteKey(jitsuConfig.writeKey) } : {};
|
|
432
|
+
|
|
410
433
|
return fetch(url, {
|
|
411
434
|
method: "POST",
|
|
412
435
|
headers: {
|
|
@@ -439,7 +462,7 @@ function send(
|
|
|
439
462
|
}
|
|
440
463
|
if (response.destinations) {
|
|
441
464
|
if (jitsuConfig.debug) {
|
|
442
|
-
console.log(`[JITSU] Processing device
|
|
465
|
+
console.log(`[JITSU] Processing device destinations: `, JSON.stringify(response.destinations, null, 2));
|
|
443
466
|
}
|
|
444
467
|
return processDestinations(response.destinations, method, adjustedPayload, !!jitsuConfig.debug, instance);
|
|
445
468
|
}
|
|
@@ -469,12 +492,13 @@ const jitsuAnalyticsPlugin = (pluginConfig: JitsuOptions = {}): AnalyticsPlugin
|
|
|
469
492
|
persistentStorage.removeItem(key);
|
|
470
493
|
},
|
|
471
494
|
});
|
|
495
|
+
const instanceConfig = {
|
|
496
|
+
...defaultConfig,
|
|
497
|
+
...pluginConfig,
|
|
498
|
+
};
|
|
472
499
|
return {
|
|
473
500
|
name: "jitsu",
|
|
474
|
-
config:
|
|
475
|
-
...config,
|
|
476
|
-
...pluginConfig,
|
|
477
|
-
},
|
|
501
|
+
config: instanceConfig,
|
|
478
502
|
initialize: args => {
|
|
479
503
|
const { config } = args;
|
|
480
504
|
if (config.debug) {
|
|
@@ -502,6 +526,22 @@ const jitsuAnalyticsPlugin = (pluginConfig: JitsuOptions = {}): AnalyticsPlugin
|
|
|
502
526
|
//clear storage cache
|
|
503
527
|
Object.keys(storageCache).forEach(key => delete storageCache[key]);
|
|
504
528
|
},
|
|
529
|
+
methods: {
|
|
530
|
+
//analytics doesn't support group as a base method, so we need to add it manually
|
|
531
|
+
group(groupId?: ID, traits?: JSONObject | null, options?: Options, callback?: Callback) {
|
|
532
|
+
const analyticsInstance = this.instance;
|
|
533
|
+
const user = analyticsInstance.user();
|
|
534
|
+
const userId = options?.userId || user?.userId;
|
|
535
|
+
const anonymousId = options?.anonymousId || user?.anonymousId;
|
|
536
|
+
return send(
|
|
537
|
+
"group",
|
|
538
|
+
{ type: "group", groupId, traits, ...(anonymousId ? { anonymousId } : {}), ...(userId ? { userId } : {}) },
|
|
539
|
+
instanceConfig,
|
|
540
|
+
analyticsInstance,
|
|
541
|
+
cachingStorageWrapper(analyticsInstance.storage)
|
|
542
|
+
);
|
|
543
|
+
},
|
|
544
|
+
},
|
|
505
545
|
};
|
|
506
546
|
};
|
|
507
547
|
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { loadScript } from "../script-loader";
|
|
2
|
+
import { AnalyticsClientEvent } from "@jitsu/protocols/analytics";
|
|
3
|
+
import { applyFilters, CommonDestinationCredentials, InternalPlugin } from "./index";
|
|
4
|
+
|
|
5
|
+
const defaultScriptSrc = "https://www.googletagmanager.com/gtag/js";
|
|
6
|
+
|
|
7
|
+
export type GtmDestinationCredentials = {
|
|
8
|
+
debug: boolean;
|
|
9
|
+
containerId: string;
|
|
10
|
+
dataLayerName: string;
|
|
11
|
+
preview: string;
|
|
12
|
+
auth: string;
|
|
13
|
+
customScriptSrc: string;
|
|
14
|
+
} & CommonDestinationCredentials;
|
|
15
|
+
|
|
16
|
+
export const gtmPlugin: InternalPlugin<GtmDestinationCredentials> = {
|
|
17
|
+
id: "gtm",
|
|
18
|
+
async handle(config, payload: AnalyticsClientEvent) {
|
|
19
|
+
if (!applyFilters(payload, config)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
await initGtmIfNeeded(config);
|
|
23
|
+
|
|
24
|
+
const dataLayer = window[config.dataLayerName || "dataLayer"];
|
|
25
|
+
|
|
26
|
+
switch (payload.type) {
|
|
27
|
+
case "page":
|
|
28
|
+
const { properties: pageProperties, context } = payload;
|
|
29
|
+
const pageEvent = {
|
|
30
|
+
event: "page_view",
|
|
31
|
+
url: pageProperties.url,
|
|
32
|
+
title: pageProperties.title,
|
|
33
|
+
referer: context?.page?.referrer ?? "",
|
|
34
|
+
};
|
|
35
|
+
if (config.debug) {
|
|
36
|
+
console.log("gtag push", pageEvent);
|
|
37
|
+
}
|
|
38
|
+
dataLayer.push(pageEvent);
|
|
39
|
+
break;
|
|
40
|
+
case "track":
|
|
41
|
+
const { properties: trackProperties } = payload;
|
|
42
|
+
const trackEvent: any = { event: payload.event, ...trackProperties };
|
|
43
|
+
if (payload.userId) {
|
|
44
|
+
trackEvent.userId = payload.userId;
|
|
45
|
+
}
|
|
46
|
+
if (payload.anonymousId) {
|
|
47
|
+
trackEvent.anonymousId = payload.anonymousId;
|
|
48
|
+
}
|
|
49
|
+
if (config.debug) {
|
|
50
|
+
console.log("gtag push", trackEvent);
|
|
51
|
+
}
|
|
52
|
+
dataLayer.push(trackEvent);
|
|
53
|
+
break;
|
|
54
|
+
case "identify":
|
|
55
|
+
const { traits } = payload;
|
|
56
|
+
const identifyEvent: any = { event: "identify", ...traits };
|
|
57
|
+
if (payload.userId) {
|
|
58
|
+
identifyEvent.userId = payload.userId;
|
|
59
|
+
}
|
|
60
|
+
if (payload.anonymousId) {
|
|
61
|
+
identifyEvent.anonymousId = payload.anonymousId;
|
|
62
|
+
}
|
|
63
|
+
if (config.debug) {
|
|
64
|
+
console.log("gtag push", identifyEvent);
|
|
65
|
+
}
|
|
66
|
+
dataLayer.push(identifyEvent);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type GtmState = "fresh" | "loading" | "loaded" | "failed";
|
|
73
|
+
|
|
74
|
+
function getGtmState(): GtmState {
|
|
75
|
+
return window["__jitsuGtmState"] || "fresh";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function setGtmState(s: GtmState) {
|
|
79
|
+
window["__jitsuGtmState"] = s;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function initGtmIfNeeded(config: GtmDestinationCredentials) {
|
|
83
|
+
if (getGtmState() !== "fresh") {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
setGtmState("loading");
|
|
87
|
+
|
|
88
|
+
const dlName = config.dataLayerName || "dataLayer";
|
|
89
|
+
const dlParam = dlName !== "dataLayer" ? "&l=" + dlName : "";
|
|
90
|
+
const previewParams = config.preview
|
|
91
|
+
? `>m_preview=${config.preview}>m_auth=${config.auth}>m_cookies_win=x`
|
|
92
|
+
: "";
|
|
93
|
+
const scriptSrc = `${config.customScriptSrc || defaultScriptSrc}?id=${config.containerId}${dlParam}${previewParams}`;
|
|
94
|
+
|
|
95
|
+
window[dlName] = window[dlName] || [];
|
|
96
|
+
const gtag = function () {
|
|
97
|
+
window[dlName].push(arguments);
|
|
98
|
+
};
|
|
99
|
+
// @ts-ignore
|
|
100
|
+
gtag("js", new Date());
|
|
101
|
+
// @ts-ignore
|
|
102
|
+
gtag("config", config.containerId);
|
|
103
|
+
|
|
104
|
+
loadScript(scriptSrc)
|
|
105
|
+
.then(() => {
|
|
106
|
+
setGtmState("loaded");
|
|
107
|
+
})
|
|
108
|
+
.catch(e => {
|
|
109
|
+
console.warn(`GTM (containerId=${config.containerId}) init failed: ${e.message}`, e);
|
|
110
|
+
setGtmState("failed");
|
|
111
|
+
});
|
|
112
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { AnalyticsClientEvent } from "@jitsu/protocols/analytics";
|
|
2
|
+
import { tagPlugin } from "./tag";
|
|
3
|
+
import { logrocketPlugin } from "./logrocket";
|
|
4
|
+
import { gtmPlugin } from "./gtm";
|
|
5
|
+
|
|
6
|
+
export type InternalPlugin<T> = {
|
|
7
|
+
id: string;
|
|
8
|
+
handle(config: T, payload: AnalyticsClientEvent): Promise<void>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type CommonDestinationCredentials = {
|
|
12
|
+
hosts?: string;
|
|
13
|
+
events?: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function satisfyFilter(filter: string, subject: string | undefined): boolean {
|
|
17
|
+
return filter === "*" || filter.toLowerCase().trim() === (subject || "").trim().toLowerCase();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function satisfyDomainFilter(filter: string, subject: string | undefined): boolean {
|
|
21
|
+
if (filter === "*") {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
subject = subject || "";
|
|
25
|
+
|
|
26
|
+
if (filter.startsWith("*.")) {
|
|
27
|
+
return subject.endsWith(filter.substring(1));
|
|
28
|
+
} else {
|
|
29
|
+
return filter === subject;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function applyFilters(event: AnalyticsClientEvent, creds: CommonDestinationCredentials): boolean {
|
|
34
|
+
const { hosts = "*", events = "*" } = creds;
|
|
35
|
+
const eventsArray = events.split("\n");
|
|
36
|
+
return (
|
|
37
|
+
!!hosts.split("\n").find(hostFilter => satisfyDomainFilter(hostFilter, event.context?.host)) &&
|
|
38
|
+
(!!eventsArray.find(eventFilter => satisfyFilter(eventFilter, event.type)) ||
|
|
39
|
+
!!eventsArray.find(eventFilter => satisfyFilter(eventFilter, event.event)))
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const internalDestinationPlugins: Record<string, InternalPlugin<any>> = {
|
|
44
|
+
[tagPlugin.id]: tagPlugin,
|
|
45
|
+
[gtmPlugin.id]: gtmPlugin,
|
|
46
|
+
[logrocketPlugin.id]: logrocketPlugin,
|
|
47
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { loadScript } from "../script-loader";
|
|
2
|
+
import { AnalyticsClientEvent } from "@jitsu/protocols/analytics";
|
|
3
|
+
import { applyFilters, CommonDestinationCredentials, InternalPlugin } from "./index";
|
|
4
|
+
|
|
5
|
+
export type LogRocketDestinationCredentials = {
|
|
6
|
+
appId: string;
|
|
7
|
+
} & CommonDestinationCredentials;
|
|
8
|
+
|
|
9
|
+
export const logrocketPlugin: InternalPlugin<LogRocketDestinationCredentials> = {
|
|
10
|
+
id: "logrocket",
|
|
11
|
+
async handle(config, payload: AnalyticsClientEvent) {
|
|
12
|
+
if (!applyFilters(payload, config)) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
initLogrocketIfNeeded(config.appId);
|
|
16
|
+
|
|
17
|
+
const action = logRocket => {
|
|
18
|
+
if (payload.type === "identify" && payload.userId) {
|
|
19
|
+
logRocket.identify(payload.userId, payload.traits || {});
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
getLogRocketQueue().push(action);
|
|
23
|
+
if (getLogRocketState() === "loaded") {
|
|
24
|
+
flushLogRocketQueue(window["LogRocket"]);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type LogRocketState = "fresh" | "loading" | "loaded" | "failed";
|
|
30
|
+
|
|
31
|
+
function getLogRocketState(): LogRocketState {
|
|
32
|
+
return window["__jitsuLrState"] || "fresh";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function setLogRocketState(s: LogRocketState) {
|
|
36
|
+
window["__jitsuLrState"] = s;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getLogRocketQueue(): ((lr: LogRocket) => void | Promise<void>)[] {
|
|
40
|
+
return window["__jitsuLrQueue"] || (window["__jitsuLrQueue"] = []);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type LogRocket = any;
|
|
44
|
+
|
|
45
|
+
function flushLogRocketQueue(lr: LogRocket) {
|
|
46
|
+
const queue = getLogRocketQueue();
|
|
47
|
+
|
|
48
|
+
while (queue.length > 0) {
|
|
49
|
+
const method = queue.shift();
|
|
50
|
+
try {
|
|
51
|
+
const res = method(lr);
|
|
52
|
+
if (res) {
|
|
53
|
+
res.catch(e => console.warn(`Async LogRocket method failed: ${e.message}`, e));
|
|
54
|
+
}
|
|
55
|
+
} catch (e) {
|
|
56
|
+
console.warn(`LogRocket method failed: ${e.message}`, e);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function initLogrocketIfNeeded(appId: string) {
|
|
62
|
+
if (getLogRocketState() !== "fresh") {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
setLogRocketState("loading");
|
|
66
|
+
loadScript(`https://cdn.lr-ingest.io/LogRocket.min.js`, { crossOrigin: "anonymous" })
|
|
67
|
+
.then(() => {
|
|
68
|
+
if (window["LogRocket"]) {
|
|
69
|
+
try {
|
|
70
|
+
window["LogRocket"].init(appId);
|
|
71
|
+
} catch (e) {
|
|
72
|
+
console.warn(`LogRocket (id=${appId}) init failed: ${e.message}`, e);
|
|
73
|
+
setLogRocketState("failed");
|
|
74
|
+
}
|
|
75
|
+
setLogRocketState("loaded");
|
|
76
|
+
flushLogRocketQueue(window["LogRocket"]);
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
.catch(e => {
|
|
80
|
+
console.warn(`LogRocket (id=${appId}) init failed: ${e.message}`, e);
|
|
81
|
+
setLogRocketState("failed");
|
|
82
|
+
});
|
|
83
|
+
}
|
|
@@ -1,33 +1,12 @@
|
|
|
1
1
|
import { AnalyticsClientEvent } from "@jitsu/protocols/analytics";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
export type InternalPlugin<T> = {
|
|
5
|
-
id: string;
|
|
6
|
-
handle(config: T, payload: AnalyticsClientEvent): Promise<void>;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export type CommonDestinationCredentials = {
|
|
10
|
-
hosts?: string[];
|
|
11
|
-
events?: string[];
|
|
12
|
-
};
|
|
2
|
+
import { applyFilters, CommonDestinationCredentials, InternalPlugin } from "./index";
|
|
3
|
+
import { isInBrowser, randomId } from "../analytics-plugin";
|
|
13
4
|
|
|
14
5
|
export type TagDestinationCredentials = {
|
|
15
6
|
code: string;
|
|
16
7
|
} & CommonDestinationCredentials;
|
|
17
8
|
|
|
18
|
-
|
|
19
|
-
return filter === "*" || filter.toLowerCase().trim() === (subject || "").trim().toLowerCase();
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function applyFilters(event: AnalyticsClientEvent, creds: CommonDestinationCredentials): boolean {
|
|
23
|
-
const { hosts = ["*"], events = ["*"] } = creds;
|
|
24
|
-
return (
|
|
25
|
-
!!hosts.find(hostFilter => satisfyFilter(hostFilter, event.context?.host)) &&
|
|
26
|
-
!!events.find(eventFilter => satisfyFilter(eventFilter, event.type))
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const tagPlugin: InternalPlugin<TagDestinationCredentials> = {
|
|
9
|
+
export const tagPlugin: InternalPlugin<TagDestinationCredentials> = {
|
|
31
10
|
id: "tag",
|
|
32
11
|
async handle(config, payload: AnalyticsClientEvent) {
|
|
33
12
|
if (!applyFilters(payload, config)) {
|
|
@@ -97,7 +76,3 @@ function execJs(code: string, event: any) {
|
|
|
97
76
|
function replaceMacro(code, event) {
|
|
98
77
|
return code.replace(/{{\s*event\s*}}/g, JSON.stringify(event));
|
|
99
78
|
}
|
|
100
|
-
|
|
101
|
-
export const internalDestinationPlugins: Record<string, InternalPlugin<any>> = {
|
|
102
|
-
[tagPlugin.id]: tagPlugin,
|
|
103
|
-
};
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import Analytics from "analytics";
|
|
2
2
|
import { AnalyticsInterface, JitsuOptions, RuntimeFacade } from "./jitsu";
|
|
3
3
|
import jitsuAnalyticsPlugin, { emptyRuntime, isInBrowser, windowRuntime } from "./analytics-plugin";
|
|
4
|
-
import {
|
|
5
|
-
import e from "express";
|
|
4
|
+
import { Callback, DispatchedEvent, ID, JSONObject, Options } from "@jitsu/protocols/analytics";
|
|
6
5
|
|
|
7
6
|
export default function parse(input) {
|
|
8
7
|
let value = input;
|
|
@@ -24,6 +23,15 @@ export default function parse(input) {
|
|
|
24
23
|
return value;
|
|
25
24
|
}
|
|
26
25
|
|
|
26
|
+
export const emptyAnalytics = {
|
|
27
|
+
track: () => Promise.resolve(),
|
|
28
|
+
page: () => Promise.resolve(),
|
|
29
|
+
user: () => ({}),
|
|
30
|
+
identify: () => Promise.resolve({}),
|
|
31
|
+
group: () => Promise.resolve({}),
|
|
32
|
+
reset: () => Promise.resolve({}),
|
|
33
|
+
};
|
|
34
|
+
|
|
27
35
|
function createUnderlyingAnalyticsInstance(
|
|
28
36
|
opts: JitsuOptions,
|
|
29
37
|
rt: RuntimeFacade,
|
|
@@ -46,7 +54,17 @@ function createUnderlyingAnalyticsInstance(
|
|
|
46
54
|
return originalPage(...args);
|
|
47
55
|
}
|
|
48
56
|
};
|
|
49
|
-
return
|
|
57
|
+
return {
|
|
58
|
+
...analytics,
|
|
59
|
+
group(groupId?: ID, traits?: JSONObject | null, options?: Options, callback?: Callback): Promise<DispatchedEvent> {
|
|
60
|
+
for (const plugin of Object.values(analytics.plugins)) {
|
|
61
|
+
if (plugin["group"]) {
|
|
62
|
+
plugin["group"](groupId, traits, options, callback);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return Promise.resolve({});
|
|
66
|
+
},
|
|
67
|
+
} as AnalyticsInterface;
|
|
50
68
|
}
|
|
51
69
|
|
|
52
70
|
export function jitsuAnalytics(opts: JitsuOptions): AnalyticsInterface {
|
package/src/jitsu.ts
CHANGED
|
@@ -16,7 +16,7 @@ type JitsuOptions = {
|
|
|
16
16
|
*/
|
|
17
17
|
debug?: boolean;
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* Explicitly specify cookie domain. If not set, cookie domain will be set to top level
|
|
20
20
|
* of the current domain. Example: if JS lives on "app.example.com", cookie domain will be
|
|
21
21
|
* set to ".example.com". If it lives on "example.com", cookie domain will be set to ".example.com" too
|
|
22
22
|
*/
|
package/src/version.ts
ADDED
package/tsconfig.json
CHANGED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { AnalyticsClientEvent } from "@jitsu/protocols/analytics";
|
|
2
|
-
export type InternalPlugin<T> = {
|
|
3
|
-
id: string;
|
|
4
|
-
handle(config: T, payload: AnalyticsClientEvent): Promise<void>;
|
|
5
|
-
};
|
|
6
|
-
export type CommonDestinationCredentials = {
|
|
7
|
-
hosts?: string[];
|
|
8
|
-
events?: string[];
|
|
9
|
-
};
|
|
10
|
-
export type TagDestinationCredentials = {
|
|
11
|
-
code: string;
|
|
12
|
-
} & CommonDestinationCredentials;
|
|
13
|
-
export declare const internalDestinationPlugins: Record<string, InternalPlugin<any>>;
|