@jitsu/js 1.5.1 → 1.6.1

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/jitsu.es.js CHANGED
@@ -108,7 +108,7 @@ function loadScript(src, attributes) {
108
108
  });
109
109
  }
110
110
 
111
- var __awaiter$3 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
111
+ var __awaiter$4 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
112
112
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
113
113
  return new (P || (P = Promise))(function (resolve, reject) {
114
114
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
@@ -120,7 +120,7 @@ var __awaiter$3 = (undefined && undefined.__awaiter) || function (thisArg, _argu
120
120
  const tagPlugin = {
121
121
  id: "tag",
122
122
  handle(config, payload) {
123
- return __awaiter$3(this, void 0, void 0, function* () {
123
+ return __awaiter$4(this, void 0, void 0, function* () {
124
124
  if (!applyFilters(payload, config)) {
125
125
  return;
126
126
  }
@@ -189,7 +189,7 @@ function replaceMacro(code, event) {
189
189
  return code.replace(/{{\s*event\s*}}/g, JSON.stringify(event));
190
190
  }
191
191
 
192
- var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
192
+ var __awaiter$3 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
193
193
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
194
194
  return new (P || (P = Promise))(function (resolve, reject) {
195
195
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
@@ -201,7 +201,7 @@ var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _argu
201
201
  const logrocketPlugin = {
202
202
  id: "logrocket",
203
203
  handle(config, payload) {
204
- return __awaiter$2(this, void 0, void 0, function* () {
204
+ return __awaiter$3(this, void 0, void 0, function* () {
205
205
  if (!applyFilters(payload, config)) {
206
206
  return;
207
207
  }
@@ -243,7 +243,7 @@ function flushLogRocketQueue(lr) {
243
243
  }
244
244
  }
245
245
  function initLogrocketIfNeeded(appId) {
246
- return __awaiter$2(this, void 0, void 0, function* () {
246
+ return __awaiter$3(this, void 0, void 0, function* () {
247
247
  if (getLogRocketState() !== "fresh") {
248
248
  return;
249
249
  }
@@ -269,7 +269,7 @@ function initLogrocketIfNeeded(appId) {
269
269
  });
270
270
  }
271
271
 
272
- var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
272
+ var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
273
273
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
274
274
  return new (P || (P = Promise))(function (resolve, reject) {
275
275
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
@@ -278,60 +278,38 @@ var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _argu
278
278
  step((generator = generator.apply(thisArg, _arguments || [])).next());
279
279
  });
280
280
  };
281
- const defaultScriptSrc = "https://www.googletagmanager.com/gtag/js";
281
+ const defaultScriptSrc$1 = "https://www.googletagmanager.com/gtag/js";
282
282
  const gtmPlugin = {
283
283
  id: "gtm",
284
284
  handle(config, payload) {
285
285
  var _a, _b;
286
- return __awaiter$1(this, void 0, void 0, function* () {
286
+ return __awaiter$2(this, void 0, void 0, function* () {
287
287
  if (!applyFilters(payload, config)) {
288
288
  return;
289
289
  }
290
- yield initGtmIfNeeded(config);
290
+ yield initGtmIfNeeded(config, payload);
291
291
  const dataLayer = window[config.dataLayerName || "dataLayer"];
292
+ const ids = Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId, userId: payload.userId } : {})), (payload.anonymousId ? { anonymousId: payload.anonymousId } : {}));
292
293
  switch (payload.type) {
293
294
  case "page":
294
295
  const { properties: pageProperties, context } = payload;
295
- const pageEvent = {
296
- event: "page_view",
297
- url: pageProperties.url,
298
- title: pageProperties.title,
299
- referer: (_b = (_a = context === null || context === void 0 ? void 0 : context.page) === null || _a === void 0 ? void 0 : _a.referrer) !== null && _b !== void 0 ? _b : "",
300
- };
301
- if (config.debug) {
302
- console.log("gtag push", pageEvent);
303
- }
296
+ const pageEvent = Object.assign({ event: "page_view", page_location: pageProperties.url, page_title: pageProperties.title, page_path: pageProperties.path, page_hash: pageProperties.hash, page_search: pageProperties.search, page_referrer: (_b = (_a = context === null || context === void 0 ? void 0 : context.page) === null || _a === void 0 ? void 0 : _a.referrer) !== null && _b !== void 0 ? _b : "" }, ids);
304
297
  dataLayer.push(pageEvent);
305
298
  break;
306
299
  case "track":
307
300
  const { properties: trackProperties } = payload;
308
- const trackEvent = Object.assign({ event: payload.event }, trackProperties);
309
- if (payload.userId) {
310
- trackEvent.userId = payload.userId;
311
- }
312
- if (payload.anonymousId) {
313
- trackEvent.anonymousId = payload.anonymousId;
314
- }
315
- if (config.debug) {
316
- console.log("gtag push", trackEvent);
317
- }
301
+ const trackEvent = Object.assign(Object.assign({ event: payload.event }, trackProperties), ids);
318
302
  dataLayer.push(trackEvent);
319
303
  break;
320
304
  case "identify":
321
305
  const { traits } = payload;
322
- const identifyEvent = Object.assign({ event: "identify" }, traits);
323
- if (payload.userId) {
324
- identifyEvent.userId = payload.userId;
325
- }
326
- if (payload.anonymousId) {
327
- identifyEvent.anonymousId = payload.anonymousId;
328
- }
329
- if (config.debug) {
330
- console.log("gtag push", identifyEvent);
331
- }
306
+ const identifyEvent = Object.assign(Object.assign({ event: "identify" }, traits), ids);
332
307
  dataLayer.push(identifyEvent);
333
308
  break;
334
309
  }
310
+ dataLayer.push(function () {
311
+ this.reset();
312
+ });
335
313
  });
336
314
  },
337
315
  };
@@ -341,8 +319,8 @@ function getGtmState() {
341
319
  function setGtmState(s) {
342
320
  window["__jitsuGtmState"] = s;
343
321
  }
344
- function initGtmIfNeeded(config) {
345
- return __awaiter$1(this, void 0, void 0, function* () {
322
+ function initGtmIfNeeded(config, payload) {
323
+ return __awaiter$2(this, void 0, void 0, function* () {
346
324
  if (getGtmState() !== "fresh") {
347
325
  return;
348
326
  }
@@ -352,26 +330,122 @@ function initGtmIfNeeded(config) {
352
330
  const previewParams = config.preview
353
331
  ? `&gtm_preview=${config.preview}&gtm_auth=${config.auth}&gtm_cookies_win=x`
354
332
  : "";
355
- const scriptSrc = `${config.customScriptSrc || defaultScriptSrc}?id=${config.containerId}${dlParam}${previewParams}`;
333
+ const tagId = config.containerId;
334
+ const scriptSrc = `${config.customScriptSrc || defaultScriptSrc$1}?id=${tagId}${dlParam}${previewParams}`;
356
335
  window[dlName] = window[dlName] || [];
357
336
  const gtag = function () {
358
337
  window[dlName].push(arguments);
359
338
  };
339
+ window[dlName].push({
340
+ user_id: payload.userId,
341
+ });
360
342
  // @ts-ignore
361
343
  gtag("js", new Date());
362
344
  // @ts-ignore
363
- gtag("config", config.containerId);
345
+ gtag("config", tagId);
364
346
  loadScript(scriptSrc)
365
347
  .then(() => {
366
348
  setGtmState("loaded");
367
349
  })
368
350
  .catch(e => {
369
- console.warn(`GTM (containerId=${config.containerId}) init failed: ${e.message}`, e);
351
+ console.warn(`GTM (containerId=${tagId}) init failed: ${e.message}`, e);
370
352
  setGtmState("failed");
371
353
  });
372
354
  });
373
355
  }
374
356
 
357
+ var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
358
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
359
+ return new (P || (P = Promise))(function (resolve, reject) {
360
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
361
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
362
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
363
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
364
+ });
365
+ };
366
+ const defaultScriptSrc = "https://www.googletagmanager.com/gtag/js";
367
+ const ga4Plugin = {
368
+ id: "ga4-tag",
369
+ handle(config, payload) {
370
+ var _a, _b;
371
+ return __awaiter$1(this, void 0, void 0, function* () {
372
+ if (!applyFilters(payload, config)) {
373
+ return;
374
+ }
375
+ yield initGa4IfNeeded(config, payload);
376
+ const dataLayer = window[config.dataLayerName || "dataLayer"];
377
+ const gtag = function () {
378
+ dataLayer.push(arguments);
379
+ };
380
+ const ids = Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId, userId: payload.userId } : {})), (payload.anonymousId ? { anonymousId: payload.anonymousId } : {}));
381
+ if (payload.userId) {
382
+ // @ts-ignore
383
+ gtag("set", { user_id: payload.userId });
384
+ }
385
+ switch (payload.type) {
386
+ case "page":
387
+ if (config.autoPageView) {
388
+ console.log("autoPageView");
389
+ break;
390
+ }
391
+ const { properties: pageProperties, context } = payload;
392
+ const pageEvent = Object.assign({ page_location: pageProperties.url, page_title: pageProperties.title, page_path: pageProperties.path, page_hash: pageProperties.hash, page_search: pageProperties.search, page_referrer: (_b = (_a = context === null || context === void 0 ? void 0 : context.page) === null || _a === void 0 ? void 0 : _a.referrer) !== null && _b !== void 0 ? _b : "" }, ids);
393
+ // @ts-ignore
394
+ gtag("event", "page_view", pageEvent);
395
+ break;
396
+ case "track":
397
+ const { properties: trackProperties } = payload;
398
+ const trackEvent = Object.assign(Object.assign({}, trackProperties), ids);
399
+ // @ts-ignore
400
+ gtag("event", payload.event, trackEvent);
401
+ break;
402
+ case "identify":
403
+ const { traits } = payload;
404
+ const identifyEvent = Object.assign(Object.assign({}, traits), ids);
405
+ // @ts-ignore
406
+ gtag("event", "identify", identifyEvent);
407
+ break;
408
+ }
409
+ });
410
+ },
411
+ };
412
+ function getGa4State() {
413
+ return window["__jitsuGa4State"] || "fresh";
414
+ }
415
+ function setGa4State(s) {
416
+ window["__jitsuGa4State"] = s;
417
+ }
418
+ function initGa4IfNeeded(config, payload) {
419
+ return __awaiter$1(this, void 0, void 0, function* () {
420
+ if (getGa4State() !== "fresh") {
421
+ return;
422
+ }
423
+ setGa4State("loading");
424
+ const dlName = config.dataLayerName || "dataLayer";
425
+ const dlParam = dlName !== "dataLayer" ? "&l=" + dlName : "";
426
+ // to work with both GA4 and GTM
427
+ const tagId = config.measurementIds;
428
+ const scriptSrc = `${defaultScriptSrc}?id=${tagId}${dlParam}`;
429
+ window[dlName] = window[dlName] || [];
430
+ const gtag = function () {
431
+ window[dlName].push(arguments);
432
+ };
433
+ // @ts-ignore
434
+ gtag("js", new Date());
435
+ gtag(
436
+ // @ts-ignore
437
+ "config", tagId, Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId } : {})), (!config.autoPageView ? { send_page_view: false } : {})));
438
+ loadScript(scriptSrc)
439
+ .then(() => {
440
+ setGa4State("loaded");
441
+ })
442
+ .catch(e => {
443
+ console.warn(`GA4 (containerId=${config.measurementIds}) init failed: ${e.message}`, e);
444
+ setGa4State("failed");
445
+ });
446
+ });
447
+ }
448
+
375
449
  function satisfyFilter(filter, subject) {
376
450
  return filter === "*" || filter.toLowerCase().trim() === (subject || "").trim().toLowerCase();
377
451
  }
@@ -392,7 +466,7 @@ function applyFilters(event, creds) {
392
466
  try {
393
467
  const eventsArray = Array.isArray(events) ? events : events.split("\n");
394
468
  const hostsArray = Array.isArray(hosts) ? hosts : hosts.split("\n");
395
- return (!!hostsArray.find(hostFilter => { var _a; return satisfyDomainFilter(hostFilter, (_a = event.context) === null || _a === void 0 ? void 0 : _a.host); }) &&
469
+ return (!!hostsArray.find(hostFilter => { var _a, _b; return satisfyDomainFilter(hostFilter, (_b = (_a = event.context) === null || _a === void 0 ? void 0 : _a.page) === null || _b === void 0 ? void 0 : _b.host); }) &&
396
470
  (!!eventsArray.find(eventFilter => satisfyFilter(eventFilter, event.type)) ||
397
471
  !!eventsArray.find(eventFilter => satisfyFilter(eventFilter, event.event))));
398
472
  }
@@ -404,6 +478,7 @@ function applyFilters(event, creds) {
404
478
  const internalDestinationPlugins = {
405
479
  [tagPlugin.id]: tagPlugin,
406
480
  [gtmPlugin.id]: gtmPlugin,
481
+ [ga4Plugin.id]: ga4Plugin,
407
482
  [logrocketPlugin.id]: logrocketPlugin,
408
483
  };
409
484
 
@@ -497,6 +572,24 @@ function getCookie(name) {
497
572
  const parts = value.split(`; ${name}=`);
498
573
  return parts.length === 2 ? parts.pop().split(";").shift() : undefined;
499
574
  }
575
+ function getGa4Sessions() {
576
+ const value = `; ${document.cookie}`;
577
+ const matches = value.matchAll(/_ga_(\w+)=([^;]+)/g);
578
+ const sessions = {};
579
+ let matchesCount = 0;
580
+ for (const match of matches) {
581
+ const parts = match[2].split(".");
582
+ if (parts.length < 3) {
583
+ continue;
584
+ }
585
+ sessions[match[1]] = parts[2];
586
+ matchesCount++;
587
+ }
588
+ if (matchesCount === 0) {
589
+ return undefined;
590
+ }
591
+ return sessions;
592
+ }
500
593
  function removeCookie(name) {
501
594
  document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:01 GMT;";
502
595
  }
@@ -647,7 +740,7 @@ function isInBrowser() {
647
740
  return typeof document !== "undefined" && typeof window !== "undefined";
648
741
  }
649
742
  function adjustPayload(payload, config, storage) {
650
- var _a, _b;
743
+ var _a, _b, _c;
651
744
  const runtime = config.runtime || (isInBrowser() ? windowRuntime(config) : emptyRuntime(config));
652
745
  const url = runtime.pageUrl();
653
746
  const parsedUrl = safeCall(() => new URL(url), undefined);
@@ -678,6 +771,10 @@ function adjustPayload(payload, config, storage) {
678
771
  clientIds: {
679
772
  fbc: getCookie("_fbc"),
680
773
  fbp: getCookie("_fbp"),
774
+ ga4: {
775
+ clientId: (_c = getCookie("_ga")) === null || _c === void 0 ? void 0 : _c.split(".").slice(-2).join("."),
776
+ sessions: getGa4Sessions(),
777
+ },
681
778
  },
682
779
  campaign: parseUtms(query),
683
780
  };
@@ -686,19 +783,25 @@ function adjustPayload(payload, config, storage) {
686
783
  delete withContext.options;
687
784
  return withContext;
688
785
  }
689
- function processDestinations(destinations, method, event, debug, analyticsInstance) {
786
+ function processDestinations(destinations, method, originalEvent, debug, analyticsInstance) {
690
787
  return __awaiter(this, void 0, void 0, function* () {
691
788
  const promises = [];
692
789
  for (const destination of destinations) {
790
+ let newEvents = [originalEvent];
791
+ if (destination.newEvents) {
792
+ newEvents = destination.newEvents.map(e => (e === "same" ? originalEvent : e));
793
+ }
693
794
  const credentials = Object.assign(Object.assign({}, destination.credentials), destination.options);
694
795
  if (destination.deviceOptions.type === "internal-plugin") {
695
796
  const plugin = internalDestinationPlugins[destination.deviceOptions.name];
696
797
  if (plugin) {
697
- try {
698
- promises.push(plugin.handle(credentials, event));
699
- }
700
- catch (e) {
701
- console.warn(`[JITSU] Error processing event with internal plugin '${destination.deviceOptions.name}': ${e === null || e === void 0 ? void 0 : e.message}`, e);
798
+ for (const event of newEvents) {
799
+ try {
800
+ promises.push(plugin.handle(credentials, event));
801
+ }
802
+ catch (e) {
803
+ console.warn(`[JITSU] Error processing event with internal plugin '${destination.deviceOptions.name}': ${e === null || e === void 0 ? void 0 : e.message}`, e);
804
+ }
702
805
  }
703
806
  }
704
807
  else {
@@ -730,11 +833,17 @@ function processDestinations(destinations, method, event, debug, analyticsInstan
730
833
  continue;
731
834
  }
732
835
  if (pluginInstance[method]) {
733
- try {
734
- pluginInstance[method]({ payload: event, config: pluginInstance.config, instance: analyticsInstance });
735
- }
736
- catch (e) {
737
- console.warn(`[JITSU] Error processing ${method}() with plugin '${destination.deviceOptions.moduleVarName}@${destination.deviceOptions.packageCdn}' for destination '${destination.id}': ${e === null || e === void 0 ? void 0 : e.message}`, e);
836
+ for (const event of newEvents) {
837
+ try {
838
+ pluginInstance[method]({
839
+ payload: event,
840
+ config: pluginInstance.config,
841
+ instance: analyticsInstance,
842
+ });
843
+ }
844
+ catch (e) {
845
+ console.warn(`[JITSU] Error processing ${method}() with plugin '${destination.deviceOptions.moduleVarName}@${destination.deviceOptions.packageCdn}' for destination '${destination.id}': ${e === null || e === void 0 ? void 0 : e.message}`, e);
846
+ }
738
847
  }
739
848
  }
740
849
  }
@@ -987,4 +1096,4 @@ function jitsuAnalytics(opts) {
987
1096
  // }
988
1097
  }
989
1098
 
990
- export { emptyAnalytics, emptyRuntime, getTopLevelDomain, isInBrowser, jitsuAnalytics, parseQuery, randomId, windowRuntime };
1099
+ export { applyFilters, emptyAnalytics, emptyRuntime, getTopLevelDomain, isInBrowser, jitsuAnalytics, parseQuery, randomId, windowRuntime };