@jitsu/js 1.5.1 → 1.7.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/README.md ADDED
@@ -0,0 +1,9 @@
1
+ ## Install
2
+
3
+ ```bash
4
+ npm install --save @jitsu/jitsu-react
5
+ ```
6
+
7
+ ## Usage
8
+
9
+ **Please read a documentation on [Jitsu Docs](https://docs.jitsu.com/sending-data/npm)**
@@ -10,6 +10,7 @@ export type DestinationDescriptor = {
10
10
  destinationType: string;
11
11
  credentials: any;
12
12
  options: any;
13
+ newEvents?: any[];
13
14
  deviceOptions: DeviceOptions;
14
15
  };
15
16
  export type AnalyticsPluginDescriptor = {
package/dist/index.d.ts CHANGED
@@ -11,4 +11,3 @@ export declare const emptyAnalytics: {
11
11
  export declare function jitsuAnalytics(opts: JitsuOptions): AnalyticsInterface;
12
12
  export * from "./jitsu";
13
13
  export * from "./analytics-plugin";
14
- export { getTopLevelDomain } from "./tlds";
package/dist/jitsu.cjs.js CHANGED
@@ -110,7 +110,7 @@ function loadScript(src, attributes) {
110
110
  });
111
111
  }
112
112
 
113
- var __awaiter$3 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
113
+ var __awaiter$4 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
114
114
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
115
115
  return new (P || (P = Promise))(function (resolve, reject) {
116
116
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
@@ -122,7 +122,7 @@ var __awaiter$3 = (undefined && undefined.__awaiter) || function (thisArg, _argu
122
122
  const tagPlugin = {
123
123
  id: "tag",
124
124
  handle(config, payload) {
125
- return __awaiter$3(this, void 0, void 0, function* () {
125
+ return __awaiter$4(this, void 0, void 0, function* () {
126
126
  if (!applyFilters(payload, config)) {
127
127
  return;
128
128
  }
@@ -191,7 +191,7 @@ function replaceMacro(code, event) {
191
191
  return code.replace(/{{\s*event\s*}}/g, JSON.stringify(event));
192
192
  }
193
193
 
194
- var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
194
+ var __awaiter$3 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
195
195
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
196
196
  return new (P || (P = Promise))(function (resolve, reject) {
197
197
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
@@ -203,7 +203,7 @@ var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _argu
203
203
  const logrocketPlugin = {
204
204
  id: "logrocket",
205
205
  handle(config, payload) {
206
- return __awaiter$2(this, void 0, void 0, function* () {
206
+ return __awaiter$3(this, void 0, void 0, function* () {
207
207
  if (!applyFilters(payload, config)) {
208
208
  return;
209
209
  }
@@ -245,7 +245,7 @@ function flushLogRocketQueue(lr) {
245
245
  }
246
246
  }
247
247
  function initLogrocketIfNeeded(appId) {
248
- return __awaiter$2(this, void 0, void 0, function* () {
248
+ return __awaiter$3(this, void 0, void 0, function* () {
249
249
  if (getLogRocketState() !== "fresh") {
250
250
  return;
251
251
  }
@@ -271,7 +271,7 @@ function initLogrocketIfNeeded(appId) {
271
271
  });
272
272
  }
273
273
 
274
- var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
274
+ var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
275
275
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
276
276
  return new (P || (P = Promise))(function (resolve, reject) {
277
277
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
@@ -280,60 +280,38 @@ var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _argu
280
280
  step((generator = generator.apply(thisArg, _arguments || [])).next());
281
281
  });
282
282
  };
283
- const defaultScriptSrc = "https://www.googletagmanager.com/gtag/js";
283
+ const defaultScriptSrc$1 = "https://www.googletagmanager.com/gtag/js";
284
284
  const gtmPlugin = {
285
285
  id: "gtm",
286
286
  handle(config, payload) {
287
287
  var _a, _b;
288
- return __awaiter$1(this, void 0, void 0, function* () {
288
+ return __awaiter$2(this, void 0, void 0, function* () {
289
289
  if (!applyFilters(payload, config)) {
290
290
  return;
291
291
  }
292
- yield initGtmIfNeeded(config);
292
+ yield initGtmIfNeeded(config, payload);
293
293
  const dataLayer = window[config.dataLayerName || "dataLayer"];
294
+ const ids = Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId, userId: payload.userId } : {})), (payload.anonymousId ? { anonymousId: payload.anonymousId } : {}));
294
295
  switch (payload.type) {
295
296
  case "page":
296
297
  const { properties: pageProperties, context } = payload;
297
- const pageEvent = {
298
- event: "page_view",
299
- url: pageProperties.url,
300
- title: pageProperties.title,
301
- 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 : "",
302
- };
303
- if (config.debug) {
304
- console.log("gtag push", pageEvent);
305
- }
298
+ 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);
306
299
  dataLayer.push(pageEvent);
307
300
  break;
308
301
  case "track":
309
302
  const { properties: trackProperties } = payload;
310
- const trackEvent = Object.assign({ event: payload.event }, trackProperties);
311
- if (payload.userId) {
312
- trackEvent.userId = payload.userId;
313
- }
314
- if (payload.anonymousId) {
315
- trackEvent.anonymousId = payload.anonymousId;
316
- }
317
- if (config.debug) {
318
- console.log("gtag push", trackEvent);
319
- }
303
+ const trackEvent = Object.assign(Object.assign({ event: payload.event }, trackProperties), ids);
320
304
  dataLayer.push(trackEvent);
321
305
  break;
322
306
  case "identify":
323
307
  const { traits } = payload;
324
- const identifyEvent = Object.assign({ event: "identify" }, traits);
325
- if (payload.userId) {
326
- identifyEvent.userId = payload.userId;
327
- }
328
- if (payload.anonymousId) {
329
- identifyEvent.anonymousId = payload.anonymousId;
330
- }
331
- if (config.debug) {
332
- console.log("gtag push", identifyEvent);
333
- }
308
+ const identifyEvent = Object.assign(Object.assign({ event: "identify" }, traits), ids);
334
309
  dataLayer.push(identifyEvent);
335
310
  break;
336
311
  }
312
+ dataLayer.push(function () {
313
+ this.reset();
314
+ });
337
315
  });
338
316
  },
339
317
  };
@@ -343,8 +321,8 @@ function getGtmState() {
343
321
  function setGtmState(s) {
344
322
  window["__jitsuGtmState"] = s;
345
323
  }
346
- function initGtmIfNeeded(config) {
347
- return __awaiter$1(this, void 0, void 0, function* () {
324
+ function initGtmIfNeeded(config, payload) {
325
+ return __awaiter$2(this, void 0, void 0, function* () {
348
326
  if (getGtmState() !== "fresh") {
349
327
  return;
350
328
  }
@@ -354,26 +332,122 @@ function initGtmIfNeeded(config) {
354
332
  const previewParams = config.preview
355
333
  ? `&gtm_preview=${config.preview}&gtm_auth=${config.auth}&gtm_cookies_win=x`
356
334
  : "";
357
- const scriptSrc = `${config.customScriptSrc || defaultScriptSrc}?id=${config.containerId}${dlParam}${previewParams}`;
335
+ const tagId = config.containerId;
336
+ const scriptSrc = `${config.customScriptSrc || defaultScriptSrc$1}?id=${tagId}${dlParam}${previewParams}`;
358
337
  window[dlName] = window[dlName] || [];
359
338
  const gtag = function () {
360
339
  window[dlName].push(arguments);
361
340
  };
341
+ window[dlName].push({
342
+ user_id: payload.userId,
343
+ });
362
344
  // @ts-ignore
363
345
  gtag("js", new Date());
364
346
  // @ts-ignore
365
- gtag("config", config.containerId);
347
+ gtag("config", tagId);
366
348
  loadScript(scriptSrc)
367
349
  .then(() => {
368
350
  setGtmState("loaded");
369
351
  })
370
352
  .catch(e => {
371
- console.warn(`GTM (containerId=${config.containerId}) init failed: ${e.message}`, e);
353
+ console.warn(`GTM (containerId=${tagId}) init failed: ${e.message}`, e);
372
354
  setGtmState("failed");
373
355
  });
374
356
  });
375
357
  }
376
358
 
359
+ var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
360
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
361
+ return new (P || (P = Promise))(function (resolve, reject) {
362
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
363
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
364
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
365
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
366
+ });
367
+ };
368
+ const defaultScriptSrc = "https://www.googletagmanager.com/gtag/js";
369
+ const ga4Plugin = {
370
+ id: "ga4-tag",
371
+ handle(config, payload) {
372
+ var _a, _b;
373
+ return __awaiter$1(this, void 0, void 0, function* () {
374
+ if (!applyFilters(payload, config)) {
375
+ return;
376
+ }
377
+ yield initGa4IfNeeded(config, payload);
378
+ const dataLayer = window[config.dataLayerName || "dataLayer"];
379
+ const gtag = function () {
380
+ dataLayer.push(arguments);
381
+ };
382
+ const ids = Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId, userId: payload.userId } : {})), (payload.anonymousId ? { anonymousId: payload.anonymousId } : {}));
383
+ if (payload.userId) {
384
+ // @ts-ignore
385
+ gtag("set", { user_id: payload.userId });
386
+ }
387
+ switch (payload.type) {
388
+ case "page":
389
+ if (config.autoPageView) {
390
+ console.log("autoPageView");
391
+ break;
392
+ }
393
+ const { properties: pageProperties, context } = payload;
394
+ 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);
395
+ // @ts-ignore
396
+ gtag("event", "page_view", pageEvent);
397
+ break;
398
+ case "track":
399
+ const { properties: trackProperties } = payload;
400
+ const trackEvent = Object.assign(Object.assign({}, trackProperties), ids);
401
+ // @ts-ignore
402
+ gtag("event", payload.event, trackEvent);
403
+ break;
404
+ case "identify":
405
+ const { traits } = payload;
406
+ const identifyEvent = Object.assign(Object.assign({}, traits), ids);
407
+ // @ts-ignore
408
+ gtag("event", "identify", identifyEvent);
409
+ break;
410
+ }
411
+ });
412
+ },
413
+ };
414
+ function getGa4State() {
415
+ return window["__jitsuGa4State"] || "fresh";
416
+ }
417
+ function setGa4State(s) {
418
+ window["__jitsuGa4State"] = s;
419
+ }
420
+ function initGa4IfNeeded(config, payload) {
421
+ return __awaiter$1(this, void 0, void 0, function* () {
422
+ if (getGa4State() !== "fresh") {
423
+ return;
424
+ }
425
+ setGa4State("loading");
426
+ const dlName = config.dataLayerName || "dataLayer";
427
+ const dlParam = dlName !== "dataLayer" ? "&l=" + dlName : "";
428
+ // to work with both GA4 and GTM
429
+ const tagId = config.measurementIds;
430
+ const scriptSrc = `${defaultScriptSrc}?id=${tagId}${dlParam}`;
431
+ window[dlName] = window[dlName] || [];
432
+ const gtag = function () {
433
+ window[dlName].push(arguments);
434
+ };
435
+ // @ts-ignore
436
+ gtag("js", new Date());
437
+ gtag(
438
+ // @ts-ignore
439
+ "config", tagId, Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId } : {})), (!config.autoPageView ? { send_page_view: false } : {})));
440
+ loadScript(scriptSrc)
441
+ .then(() => {
442
+ setGa4State("loaded");
443
+ })
444
+ .catch(e => {
445
+ console.warn(`GA4 (containerId=${config.measurementIds}) init failed: ${e.message}`, e);
446
+ setGa4State("failed");
447
+ });
448
+ });
449
+ }
450
+
377
451
  function satisfyFilter(filter, subject) {
378
452
  return filter === "*" || filter.toLowerCase().trim() === (subject || "").trim().toLowerCase();
379
453
  }
@@ -394,7 +468,7 @@ function applyFilters(event, creds) {
394
468
  try {
395
469
  const eventsArray = Array.isArray(events) ? events : events.split("\n");
396
470
  const hostsArray = Array.isArray(hosts) ? hosts : hosts.split("\n");
397
- return (!!hostsArray.find(hostFilter => { var _a; return satisfyDomainFilter(hostFilter, (_a = event.context) === null || _a === void 0 ? void 0 : _a.host); }) &&
471
+ 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); }) &&
398
472
  (!!eventsArray.find(eventFilter => satisfyFilter(eventFilter, event.type)) ||
399
473
  !!eventsArray.find(eventFilter => satisfyFilter(eventFilter, event.event))));
400
474
  }
@@ -406,6 +480,7 @@ function applyFilters(event, creds) {
406
480
  const internalDestinationPlugins = {
407
481
  [tagPlugin.id]: tagPlugin,
408
482
  [gtmPlugin.id]: gtmPlugin,
483
+ [ga4Plugin.id]: ga4Plugin,
409
484
  [logrocketPlugin.id]: logrocketPlugin,
410
485
  };
411
486
 
@@ -499,6 +574,24 @@ function getCookie(name) {
499
574
  const parts = value.split(`; ${name}=`);
500
575
  return parts.length === 2 ? parts.pop().split(";").shift() : undefined;
501
576
  }
577
+ function getGa4Sessions(allCookies) {
578
+ const gaCookies = Object.entries(allCookies).filter(([key]) => key.startsWith("_ga_"));
579
+ if (gaCookies.length === 0) {
580
+ return undefined;
581
+ }
582
+ return Object.fromEntries(gaCookies
583
+ .map(([key, value]) => {
584
+ if (typeof value !== "string") {
585
+ return null;
586
+ }
587
+ const parts = value.split(".");
588
+ if (parts.length < 3) {
589
+ return null;
590
+ }
591
+ return [key.substring("_ga_".length), parts[2]];
592
+ })
593
+ .filter(v => v !== null));
594
+ }
502
595
  function removeCookie(name) {
503
596
  document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:01 GMT;";
504
597
  }
@@ -548,6 +641,20 @@ const cookieStorage = (cookieDomain, key2cookie) => {
548
641
  };
549
642
  function windowRuntime(opts) {
550
643
  return {
644
+ getCookie(name) {
645
+ const value = `; ${document.cookie}`;
646
+ const parts = value.split(`; ${name}=`);
647
+ return parts.length === 2 ? parts.pop().split(";").shift() : undefined;
648
+ },
649
+ getCookies() {
650
+ const value = `; ${document.cookie}`;
651
+ const cookies = {};
652
+ const matches = value.matchAll(/(\w+)=([^;]+)/g);
653
+ for (const match of matches) {
654
+ cookies[match[1]] = match[2];
655
+ }
656
+ return cookies;
657
+ },
551
658
  documentEncoding() {
552
659
  return window.document.characterSet;
553
660
  },
@@ -590,6 +697,12 @@ const emptyRuntime = (config) => ({
590
697
  timezoneOffset() {
591
698
  return undefined;
592
699
  },
700
+ getCookie(name) {
701
+ return undefined;
702
+ },
703
+ getCookies() {
704
+ return {};
705
+ },
593
706
  store() {
594
707
  const storage = {};
595
708
  return {
@@ -649,7 +762,7 @@ function isInBrowser() {
649
762
  return typeof document !== "undefined" && typeof window !== "undefined";
650
763
  }
651
764
  function adjustPayload(payload, config, storage) {
652
- var _a, _b;
765
+ var _a, _b, _c;
653
766
  const runtime = config.runtime || (isInBrowser() ? windowRuntime(config) : emptyRuntime(config));
654
767
  const url = runtime.pageUrl();
655
768
  const parsedUrl = safeCall(() => new URL(url), undefined);
@@ -678,8 +791,12 @@ function adjustPayload(payload, config, storage) {
678
791
  encoding: properties.encoding || runtime.documentEncoding(),
679
792
  },
680
793
  clientIds: {
681
- fbc: getCookie("_fbc"),
682
- fbp: getCookie("_fbp"),
794
+ fbc: runtime.getCookie("_fbc"),
795
+ fbp: runtime.getCookie("_fbp"),
796
+ ga4: {
797
+ clientId: (_c = runtime.getCookie("_ga")) === null || _c === void 0 ? void 0 : _c.split(".").slice(-2).join("."),
798
+ sessions: getGa4Sessions(runtime.getCookies()),
799
+ },
683
800
  },
684
801
  campaign: parseUtms(query),
685
802
  };
@@ -688,19 +805,25 @@ function adjustPayload(payload, config, storage) {
688
805
  delete withContext.options;
689
806
  return withContext;
690
807
  }
691
- function processDestinations(destinations, method, event, debug, analyticsInstance) {
808
+ function processDestinations(destinations, method, originalEvent, debug, analyticsInstance) {
692
809
  return __awaiter(this, void 0, void 0, function* () {
693
810
  const promises = [];
694
811
  for (const destination of destinations) {
812
+ let newEvents = [originalEvent];
813
+ if (destination.newEvents) {
814
+ newEvents = destination.newEvents.map(e => (e === "same" ? originalEvent : e));
815
+ }
695
816
  const credentials = Object.assign(Object.assign({}, destination.credentials), destination.options);
696
817
  if (destination.deviceOptions.type === "internal-plugin") {
697
818
  const plugin = internalDestinationPlugins[destination.deviceOptions.name];
698
819
  if (plugin) {
699
- try {
700
- promises.push(plugin.handle(credentials, event));
701
- }
702
- catch (e) {
703
- console.warn(`[JITSU] Error processing event with internal plugin '${destination.deviceOptions.name}': ${e === null || e === void 0 ? void 0 : e.message}`, e);
820
+ for (const event of newEvents) {
821
+ try {
822
+ promises.push(plugin.handle(credentials, event));
823
+ }
824
+ catch (e) {
825
+ console.warn(`[JITSU] Error processing event with internal plugin '${destination.deviceOptions.name}': ${e === null || e === void 0 ? void 0 : e.message}`, e);
826
+ }
704
827
  }
705
828
  }
706
829
  else {
@@ -732,11 +855,17 @@ function processDestinations(destinations, method, event, debug, analyticsInstan
732
855
  continue;
733
856
  }
734
857
  if (pluginInstance[method]) {
735
- try {
736
- pluginInstance[method]({ payload: event, config: pluginInstance.config, instance: analyticsInstance });
737
- }
738
- catch (e) {
739
- 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);
858
+ for (const event of newEvents) {
859
+ try {
860
+ pluginInstance[method]({
861
+ payload: event,
862
+ config: pluginInstance.config,
863
+ instance: analyticsInstance,
864
+ });
865
+ }
866
+ catch (e) {
867
+ 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);
868
+ }
740
869
  }
741
870
  }
742
871
  }
@@ -991,7 +1120,6 @@ function jitsuAnalytics(opts) {
991
1120
 
992
1121
  exports.emptyAnalytics = emptyAnalytics;
993
1122
  exports.emptyRuntime = emptyRuntime;
994
- exports.getTopLevelDomain = getTopLevelDomain;
995
1123
  exports.isInBrowser = isInBrowser;
996
1124
  exports.jitsuAnalytics = jitsuAnalytics;
997
1125
  exports.parseQuery = parseQuery;
package/dist/jitsu.d.ts CHANGED
@@ -49,6 +49,8 @@ type RuntimeFacade = {
49
49
  language(): string | undefined;
50
50
  pageUrl(): string | undefined;
51
51
  documentEncoding(): string | undefined;
52
+ getCookie(name: string): string | undefined;
53
+ getCookies(): Record<string, string>;
52
54
  timezoneOffset(): number | undefined;
53
55
  screen(): {
54
56
  width: number;