@jitsu/js 1.1.0-canary.344.20230430234929 → 1.1.0-canary.388.20230519133920

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/dist/web/p.js.txt CHANGED
@@ -68,7 +68,50 @@
68
68
  return ke(_objectSpread2(_objectSpread2({}, defaultSettings), opts));
69
69
  }
70
70
 
71
- var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
71
+ function findScript(src) {
72
+ const scripts = Array.prototype.slice.call(window.document.querySelectorAll("script"));
73
+ return scripts.find(s => s.src === src);
74
+ }
75
+ function loadScript(src, attributes) {
76
+ const found = findScript(src);
77
+ if (found !== undefined) {
78
+ const status = found === null || found === void 0 ? void 0 : found.getAttribute("status");
79
+ if (status === "loaded") {
80
+ return Promise.resolve(found);
81
+ }
82
+ if (status === "loading") {
83
+ return new Promise((resolve, reject) => {
84
+ found.addEventListener("load", () => resolve(found));
85
+ found.addEventListener("error", err => reject(err));
86
+ });
87
+ }
88
+ }
89
+ return new Promise((resolve, reject) => {
90
+ var _a;
91
+ const script = window.document.createElement("script");
92
+ script.type = "text/javascript";
93
+ script.src = src;
94
+ script.async = true;
95
+ script.setAttribute("status", "loading");
96
+ for (const [k, v] of Object.entries(attributes !== null && attributes !== void 0 ? attributes : {})) {
97
+ script.setAttribute(k, v);
98
+ }
99
+ script.onload = () => {
100
+ script.onerror = script.onload = null;
101
+ script.setAttribute("status", "loaded");
102
+ resolve(script);
103
+ };
104
+ script.onerror = () => {
105
+ script.onerror = script.onload = null;
106
+ script.setAttribute("status", "error");
107
+ reject(new Error(`Failed to load ${src}`));
108
+ };
109
+ const tag = window.document.getElementsByTagName("script")[0];
110
+ (_a = tag.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(script, tag);
111
+ });
112
+ }
113
+
114
+ var __awaiter$3 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
72
115
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
73
116
  return new (P || (P = Promise))(function (resolve, reject) {
74
117
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
@@ -77,18 +120,10 @@
77
120
  step((generator = generator.apply(thisArg, _arguments || [])).next());
78
121
  });
79
122
  };
80
- function satisfyFilter(filter, subject) {
81
- return filter === "*" || filter.toLowerCase().trim() === (subject || "").trim().toLowerCase();
82
- }
83
- function applyFilters(event, creds) {
84
- const { hosts = ["*"], events = ["*"] } = creds;
85
- return (!!hosts.find(hostFilter => { var _a; return satisfyFilter(hostFilter, (_a = event.context) === null || _a === void 0 ? void 0 : _a.host); }) &&
86
- !!events.find(eventFilter => satisfyFilter(eventFilter, event.type)));
87
- }
88
123
  const tagPlugin = {
89
124
  id: "tag",
90
125
  handle(config, payload) {
91
- return __awaiter$1(this, void 0, void 0, function* () {
126
+ return __awaiter$3(this, void 0, void 0, function* () {
92
127
  if (!applyFilters(payload, config)) {
93
128
  return;
94
129
  }
@@ -156,53 +191,193 @@
156
191
  function replaceMacro(code, event) {
157
192
  return code.replace(/{{\s*event\s*}}/g, JSON.stringify(event));
158
193
  }
159
- const internalDestinationPlugins = {
160
- [tagPlugin.id]: tagPlugin,
161
- };
162
194
 
163
- function findScript(src) {
164
- const scripts = Array.prototype.slice.call(window.document.querySelectorAll("script"));
165
- return scripts.find(s => s.src === src);
195
+ var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
196
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
197
+ return new (P || (P = Promise))(function (resolve, reject) {
198
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
199
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
200
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
201
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
202
+ });
203
+ };
204
+ const logrocketPlugin = {
205
+ id: "logrocket",
206
+ handle(config, payload) {
207
+ return __awaiter$2(this, void 0, void 0, function* () {
208
+ if (!applyFilters(payload, config)) {
209
+ return;
210
+ }
211
+ initLogrocketIfNeeded(config.appId);
212
+ const action = logRocket => {
213
+ if (payload.type === "identify" && payload.userId) {
214
+ logRocket.identify(payload.userId, payload.traits || {});
215
+ }
216
+ };
217
+ getLogRocketQueue().push(action);
218
+ if (getLogRocketState() === "loaded") {
219
+ flushLogRocketQueue(window["LogRocket"]);
220
+ }
221
+ });
222
+ },
223
+ };
224
+ function getLogRocketState() {
225
+ return window["__jitsuLrState"] || "fresh";
166
226
  }
167
- function loadScript(src, attributes) {
168
- const found = findScript(src);
169
- if (found !== undefined) {
170
- const status = found === null || found === void 0 ? void 0 : found.getAttribute("status");
171
- if (status === "loaded") {
172
- return Promise.resolve(found);
227
+ function setLogRocketState(s) {
228
+ window["__jitsuLrState"] = s;
229
+ }
230
+ function getLogRocketQueue() {
231
+ return window["__jitsuLrQueue"] || (window["__jitsuLrQueue"] = []);
232
+ }
233
+ function flushLogRocketQueue(lr) {
234
+ const queue = getLogRocketQueue();
235
+ while (queue.length > 0) {
236
+ const method = queue.shift();
237
+ try {
238
+ const res = method(lr);
239
+ if (res) {
240
+ res.catch(e => console.warn(`Async LogRocket method failed: ${e.message}`, e));
241
+ }
173
242
  }
174
- if (status === "loading") {
175
- return new Promise((resolve, reject) => {
176
- found.addEventListener("load", () => resolve(found));
177
- found.addEventListener("error", err => reject(err));
178
- });
243
+ catch (e) {
244
+ console.warn(`LogRocket method failed: ${e.message}`, e);
179
245
  }
180
246
  }
181
- return new Promise((resolve, reject) => {
182
- var _a;
183
- const script = window.document.createElement("script");
184
- script.type = "text/javascript";
185
- script.src = src;
186
- script.async = true;
187
- script.setAttribute("status", "loading");
188
- for (const [k, v] of Object.entries(attributes !== null && attributes !== void 0 ? attributes : {})) {
189
- script.setAttribute(k, v);
247
+ }
248
+ function initLogrocketIfNeeded(appId) {
249
+ return __awaiter$2(this, void 0, void 0, function* () {
250
+ if (getLogRocketState() !== "fresh") {
251
+ return;
190
252
  }
191
- script.onload = () => {
192
- script.onerror = script.onload = null;
193
- script.setAttribute("status", "loaded");
194
- resolve(script);
195
- };
196
- script.onerror = () => {
197
- script.onerror = script.onload = null;
198
- script.setAttribute("status", "error");
199
- reject(new Error(`Failed to load ${src}`));
253
+ setLogRocketState("loading");
254
+ loadScript(`https://cdn.lr-ingest.io/LogRocket.min.js`, { crossOrigin: "anonymous" })
255
+ .then(() => {
256
+ if (window["LogRocket"]) {
257
+ try {
258
+ window["LogRocket"].init(appId);
259
+ }
260
+ catch (e) {
261
+ console.warn(`LogRocket (id=${appId}) init failed: ${e.message}`, e);
262
+ setLogRocketState("failed");
263
+ }
264
+ setLogRocketState("loaded");
265
+ flushLogRocketQueue(window["LogRocket"]);
266
+ }
267
+ })
268
+ .catch(e => {
269
+ console.warn(`LogRocket (id=${appId}) init failed: ${e.message}`, e);
270
+ setLogRocketState("failed");
271
+ });
272
+ });
273
+ }
274
+
275
+ var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
276
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
277
+ return new (P || (P = Promise))(function (resolve, reject) {
278
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
279
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
280
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
281
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
282
+ });
283
+ };
284
+ const defaultScriptSrc = "https://www.googletagmanager.com/gtag/js";
285
+ const gtmPlugin = {
286
+ id: "gtm",
287
+ handle(config, payload) {
288
+ return __awaiter$1(this, void 0, void 0, function* () {
289
+ if (!applyFilters(payload, config)) {
290
+ return;
291
+ }
292
+ yield initGtmIfNeeded(config);
293
+ const dataLayer = window[config.dataLayerName || "dataLayer"];
294
+ switch (payload.type) {
295
+ case "page":
296
+ const { properties: pageProperties } = payload;
297
+ const pageEvent = Object.assign({ event: "page_view" }, pageProperties);
298
+ if (config.debug) {
299
+ console.log("gtag push", pageEvent);
300
+ }
301
+ dataLayer.push(pageEvent);
302
+ break;
303
+ case "track":
304
+ const { properties: trackProperties } = payload;
305
+ const trackEvent = Object.assign({ event: payload.event }, trackProperties);
306
+ if (config.debug) {
307
+ console.log("gtag push", trackEvent);
308
+ }
309
+ dataLayer.push(trackEvent);
310
+ break;
311
+ case "identify":
312
+ const { anonymousId, userId, traits } = payload;
313
+ const user = traits;
314
+ if (userId) {
315
+ user.userId = userId;
316
+ }
317
+ if (anonymousId) {
318
+ user.anonymousId = anonymousId;
319
+ }
320
+ const identifyEvent = { event: "identify", user: user };
321
+ if (config.debug) {
322
+ console.log("gtag push", identifyEvent);
323
+ }
324
+ dataLayer.push(identifyEvent);
325
+ break;
326
+ }
327
+ });
328
+ },
329
+ };
330
+ function getGtmState() {
331
+ return window["__jitsuGtmState"] || "fresh";
332
+ }
333
+ function setGtmState(s) {
334
+ window["__jitsuGtmState"] = s;
335
+ }
336
+ function initGtmIfNeeded(config) {
337
+ return __awaiter$1(this, void 0, void 0, function* () {
338
+ if (getGtmState() !== "fresh") {
339
+ return;
340
+ }
341
+ setGtmState("loading");
342
+ const dlName = config.dataLayerName || "dataLayer";
343
+ const dlParam = dlName !== "dataLayer" ? "&l=" + dlName : "";
344
+ const previewParams = config.preview
345
+ ? `&gtm_preview=${config.preview}&gtm_auth=${config.auth}&gtm_cookies_win=x`
346
+ : "";
347
+ const scriptSrc = `${config.customScriptSrc || defaultScriptSrc}?id=${config.containerId}${dlParam}${previewParams}`;
348
+ window[dlName] = window[dlName] || [];
349
+ const gtag = function () {
350
+ window[dlName].push(arguments);
200
351
  };
201
- const tag = window.document.getElementsByTagName("script")[0];
202
- (_a = tag.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(script, tag);
352
+ // @ts-ignore
353
+ gtag("js", new Date());
354
+ // @ts-ignore
355
+ gtag("config", config.containerId);
356
+ loadScript(scriptSrc)
357
+ .then(() => {
358
+ setGtmState("loaded");
359
+ })
360
+ .catch(e => {
361
+ console.warn(`GTM (containerId=${config.containerId}) init failed: ${e.message}`, e);
362
+ setGtmState("failed");
363
+ });
203
364
  });
204
365
  }
205
366
 
367
+ function satisfyFilter(filter, subject) {
368
+ return filter === "*" || filter.toLowerCase().trim() === (subject || "").trim().toLowerCase();
369
+ }
370
+ function applyFilters(event, creds) {
371
+ const { hosts = ["*"], events = ["*"] } = creds;
372
+ return (!!hosts.find(hostFilter => { var _a; return satisfyFilter(hostFilter, (_a = event.context) === null || _a === void 0 ? void 0 : _a.host); }) &&
373
+ !!events.find(eventFilter => satisfyFilter(eventFilter, event.type)));
374
+ }
375
+ const internalDestinationPlugins = {
376
+ [tagPlugin.id]: tagPlugin,
377
+ [gtmPlugin.id]: gtmPlugin,
378
+ [logrocketPlugin.id]: logrocketPlugin,
379
+ };
380
+
206
381
  /* global analytics */
207
382
  var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
208
383
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -221,6 +396,8 @@
221
396
  debug: false,
222
397
  fetch: null,
223
398
  echoEvents: false,
399
+ cookieDomain: undefined,
400
+ runtime: undefined,
224
401
  };
225
402
  const parseQuery = (qs) => {
226
403
  if (!qs) {
@@ -444,7 +621,7 @@
444
621
  userAgent: runtime.userAgent(),
445
622
  locale: runtime.language(),
446
623
  screen: runtime.screen(),
447
- traits: payload.type != "identify" ? Object.assign({}, (restoreTraits(storage) || {})) : undefined,
624
+ traits: payload.type != "identify" && payload.type != "group" ? Object.assign({}, (restoreTraits(storage) || {})) : undefined,
448
625
  page: {
449
626
  path: properties.path || (parsedUrl && parsedUrl.pathname),
450
627
  referrer: referrer,
@@ -453,7 +630,7 @@
453
630
  search: properties.search || (parsedUrl && parsedUrl.search),
454
631
  title: properties.title || runtime.pageTitle(),
455
632
  url: properties.url || url,
456
- enconding: properties.enconding || runtime.documentEncoding(),
633
+ encoding: properties.encoding || runtime.documentEncoding(),
457
634
  },
458
635
  campaign: parseUtms(query),
459
636
  };
@@ -561,7 +738,7 @@
561
738
  }
562
739
  if (response.destinations) {
563
740
  if (jitsuConfig.debug) {
564
- console.log(`[JITSU] Processing device destianations: `, JSON.stringify(response.destinations, null, 2));
741
+ console.log(`[JITSU] Processing device destinations: `, JSON.stringify(response.destinations, null, 2));
565
742
  }
566
743
  return processDestinations(response.destinations, method, adjustedPayload, !!jitsuConfig.debug, instance);
567
744
  }
@@ -590,9 +767,10 @@
590
767
  persistentStorage.removeItem(key);
591
768
  },
592
769
  });
770
+ const instanceConfig = Object.assign(Object.assign({}, config), pluginConfig);
593
771
  return {
594
772
  name: "jitsu",
595
- config: Object.assign(Object.assign({}, config), pluginConfig),
773
+ config: instanceConfig,
596
774
  initialize: args => {
597
775
  const { config } = args;
598
776
  if (config.debug) {
@@ -620,6 +798,16 @@
620
798
  //clear storage cache
621
799
  Object.keys(storageCache).forEach(key => delete storageCache[key]);
622
800
  },
801
+ methods: {
802
+ //analytics doesn't support group as a base method, so we need to add it manually
803
+ group(groupId, traits, options, callback) {
804
+ const analyticsInstance = this.instance;
805
+ const user = analyticsInstance.user();
806
+ const userId = (options === null || options === void 0 ? void 0 : options.userId) || (user === null || user === void 0 ? void 0 : user.userId);
807
+ const anonymousId = (options === null || options === void 0 ? void 0 : options.anonymousId) || (user === null || user === void 0 ? void 0 : user.anonymousId);
808
+ return send("group", Object.assign(Object.assign({ type: "group", groupId, traits }, (anonymousId ? { anonymousId } : {})), (userId ? { userId } : {})), instanceConfig, analyticsInstance, cachingStorageWrapper(analyticsInstance.storage));
809
+ },
810
+ },
623
811
  };
624
812
  };
625
813
  function getSeed() {
@@ -683,7 +871,14 @@
683
871
  return originalPage(...args);
684
872
  }
685
873
  };
686
- return analytics;
874
+ return Object.assign(Object.assign({}, analytics), { group(groupId, traits, options, callback) {
875
+ for (const plugin of Object.values(analytics.plugins)) {
876
+ if (plugin["group"]) {
877
+ plugin["group"](groupId, traits, options, callback);
878
+ }
879
+ }
880
+ return Promise.resolve({});
881
+ } });
687
882
  }
688
883
  function jitsuAnalytics(opts) {
689
884
  const inBrowser = isInBrowser();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jitsu/js",
3
- "version": "1.1.0-canary.344.20230430234929",
3
+ "version": "1.1.0-canary.388.20230519133920",
4
4
  "description": "",
5
5
  "author": "Jitsu Dev Team <dev@jitsu.com>",
6
6
  "main": "dist/jitsu.cjs.js",
@@ -34,7 +34,7 @@
34
34
  "rollup": "^3.2.5",
35
35
  "ts-jest": "29.0.5",
36
36
  "typescript": "^4.9.5",
37
- "@jitsu/protocols": "1.1.0-canary.344.20230430234929"
37
+ "@jitsu/protocols": "1.1.0-canary.388.20230519133920"
38
38
  },
39
39
  "dependencies": {
40
40
  "analytics": "^0.8.1"
@@ -1,13 +1,13 @@
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
9
 
10
- const config: JitsuOptions = {
10
+ const config: Required<JitsuOptions> = {
11
11
  /* Your segment writeKey */
12
12
  writeKey: null,
13
13
  /* Disable anonymous MTU */
@@ -15,6 +15,8 @@ const config: JitsuOptions = {
15
15
  debug: false,
16
16
  fetch: null,
17
17
  echoEvents: false,
18
+ cookieDomain: undefined,
19
+ runtime: undefined,
18
20
  };
19
21
 
20
22
  export const parseQuery = (qs?: string): Record<string, string> => {
@@ -261,7 +263,7 @@ function adjustPayload(payload: any, config: JitsuOptions, storage: PersistentSt
261
263
  userAgent: runtime.userAgent(),
262
264
  locale: runtime.language(),
263
265
  screen: runtime.screen(),
264
- traits: payload.type != "identify" ? { ...(restoreTraits(storage) || {}) } : undefined,
266
+ traits: payload.type != "identify" && payload.type != "group" ? { ...(restoreTraits(storage) || {}) } : undefined,
265
267
  page: {
266
268
  path: properties.path || (parsedUrl && parsedUrl.pathname),
267
269
  referrer: referrer,
@@ -270,7 +272,7 @@ function adjustPayload(payload: any, config: JitsuOptions, storage: PersistentSt
270
272
  search: properties.search || (parsedUrl && parsedUrl.search),
271
273
  title: properties.title || runtime.pageTitle(),
272
274
  url: properties.url || url,
273
- enconding: properties.enconding || runtime.documentEncoding(),
275
+ encoding: properties.encoding || runtime.documentEncoding(),
274
276
  },
275
277
  campaign: parseUtms(query),
276
278
  };
@@ -441,7 +443,7 @@ function send(
441
443
  }
442
444
  if (response.destinations) {
443
445
  if (jitsuConfig.debug) {
444
- console.log(`[JITSU] Processing device destianations: `, JSON.stringify(response.destinations, null, 2));
446
+ console.log(`[JITSU] Processing device destinations: `, JSON.stringify(response.destinations, null, 2));
445
447
  }
446
448
  return processDestinations(response.destinations, method, adjustedPayload, !!jitsuConfig.debug, instance);
447
449
  }
@@ -471,12 +473,13 @@ const jitsuAnalyticsPlugin = (pluginConfig: JitsuOptions = {}): AnalyticsPlugin
471
473
  persistentStorage.removeItem(key);
472
474
  },
473
475
  });
476
+ const instanceConfig = {
477
+ ...config,
478
+ ...pluginConfig,
479
+ };
474
480
  return {
475
481
  name: "jitsu",
476
- config: {
477
- ...config,
478
- ...pluginConfig,
479
- },
482
+ config: instanceConfig,
480
483
  initialize: args => {
481
484
  const { config } = args;
482
485
  if (config.debug) {
@@ -504,6 +507,22 @@ const jitsuAnalyticsPlugin = (pluginConfig: JitsuOptions = {}): AnalyticsPlugin
504
507
  //clear storage cache
505
508
  Object.keys(storageCache).forEach(key => delete storageCache[key]);
506
509
  },
510
+ methods: {
511
+ //analytics doesn't support group as a base method, so we need to add it manually
512
+ group(groupId?: ID, traits?: JSONObject | null, options?: Options, callback?: Callback) {
513
+ const analyticsInstance = this.instance;
514
+ const user = analyticsInstance.user();
515
+ const userId = options?.userId || user?.userId;
516
+ const anonymousId = options?.anonymousId || user?.anonymousId;
517
+ return send(
518
+ "group",
519
+ { type: "group", groupId, traits, ...(anonymousId ? { anonymousId } : {}), ...(userId ? { userId } : {}) },
520
+ instanceConfig,
521
+ analyticsInstance,
522
+ cachingStorageWrapper(analyticsInstance.storage)
523
+ );
524
+ },
525
+ },
507
526
  };
508
527
  };
509
528
 
@@ -0,0 +1,102 @@
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 } = payload;
29
+ const pageEvent = { event: "page_view", ...pageProperties };
30
+ if (config.debug) {
31
+ console.log("gtag push", pageEvent);
32
+ }
33
+ dataLayer.push(pageEvent);
34
+ break;
35
+ case "track":
36
+ const { properties: trackProperties } = payload;
37
+ const trackEvent = { event: payload.event, ...trackProperties };
38
+ if (config.debug) {
39
+ console.log("gtag push", trackEvent);
40
+ }
41
+ dataLayer.push(trackEvent);
42
+ break;
43
+ case "identify":
44
+ const { anonymousId, userId, traits } = payload;
45
+ const user = traits;
46
+ if (userId) {
47
+ user.userId = userId;
48
+ }
49
+ if (anonymousId) {
50
+ user.anonymousId = anonymousId;
51
+ }
52
+ const identifyEvent = { event: "identify", user: user };
53
+ if (config.debug) {
54
+ console.log("gtag push", identifyEvent);
55
+ }
56
+ dataLayer.push(identifyEvent);
57
+ break;
58
+ }
59
+ },
60
+ };
61
+
62
+ type GtmState = "fresh" | "loading" | "loaded" | "failed";
63
+
64
+ function getGtmState(): GtmState {
65
+ return window["__jitsuGtmState"] || "fresh";
66
+ }
67
+
68
+ function setGtmState(s: GtmState) {
69
+ window["__jitsuGtmState"] = s;
70
+ }
71
+
72
+ async function initGtmIfNeeded(config: GtmDestinationCredentials) {
73
+ if (getGtmState() !== "fresh") {
74
+ return;
75
+ }
76
+ setGtmState("loading");
77
+
78
+ const dlName = config.dataLayerName || "dataLayer";
79
+ const dlParam = dlName !== "dataLayer" ? "&l=" + dlName : "";
80
+ const previewParams = config.preview
81
+ ? `&gtm_preview=${config.preview}&gtm_auth=${config.auth}&gtm_cookies_win=x`
82
+ : "";
83
+ const scriptSrc = `${config.customScriptSrc || defaultScriptSrc}?id=${config.containerId}${dlParam}${previewParams}`;
84
+
85
+ window[dlName] = window[dlName] || [];
86
+ const gtag = function () {
87
+ window[dlName].push(arguments);
88
+ };
89
+ // @ts-ignore
90
+ gtag("js", new Date());
91
+ // @ts-ignore
92
+ gtag("config", config.containerId);
93
+
94
+ loadScript(scriptSrc)
95
+ .then(() => {
96
+ setGtmState("loaded");
97
+ })
98
+ .catch(e => {
99
+ console.warn(`GTM (containerId=${config.containerId}) init failed: ${e.message}`, e);
100
+ setGtmState("failed");
101
+ });
102
+ }
@@ -0,0 +1,32 @@
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 applyFilters(event: AnalyticsClientEvent, creds: CommonDestinationCredentials): boolean {
21
+ const { hosts = ["*"], events = ["*"] } = creds;
22
+ return (
23
+ !!hosts.find(hostFilter => satisfyFilter(hostFilter, event.context?.host)) &&
24
+ !!events.find(eventFilter => satisfyFilter(eventFilter, event.type))
25
+ );
26
+ }
27
+
28
+ export const internalDestinationPlugins: Record<string, InternalPlugin<any>> = {
29
+ [tagPlugin.id]: tagPlugin,
30
+ [gtmPlugin.id]: gtmPlugin,
31
+ [logrocketPlugin.id]: logrocketPlugin,
32
+ };