@jitsu/js 1.9.3 → 1.9.5

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
@@ -72,7 +72,23 @@
72
72
  const scripts = Array.prototype.slice.call(window.document.querySelectorAll("script"));
73
73
  return scripts.find(s => s.src === src);
74
74
  }
75
- function loadScript(src, attributes) {
75
+ function buildScriptSrc(src, options) {
76
+ let result = src;
77
+ if (!result.startsWith("http")) {
78
+ result = `https://${(options === null || options === void 0 ? void 0 : options.www) ? "www." : ""}${result}`;
79
+ }
80
+ if (options === null || options === void 0 ? void 0 : options.min) {
81
+ result = result + ".min.js";
82
+ }
83
+ else if (options === null || options === void 0 ? void 0 : options.js) {
84
+ result = result + ".js";
85
+ }
86
+ if (options === null || options === void 0 ? void 0 : options.query) {
87
+ result += "?" + options.query;
88
+ }
89
+ return result;
90
+ }
91
+ function loadScript(src, options) {
76
92
  const found = findScript(src);
77
93
  if (found !== undefined) {
78
94
  const status = found === null || found === void 0 ? void 0 : found.getAttribute("status");
@@ -87,13 +103,13 @@
87
103
  }
88
104
  }
89
105
  return new Promise((resolve, reject) => {
90
- var _a;
106
+ var _a, _b;
91
107
  const script = window.document.createElement("script");
92
108
  script.type = "text/javascript";
93
- script.src = src;
109
+ script.src = buildScriptSrc(src, options);
94
110
  script.async = true;
95
111
  script.setAttribute("status", "loading");
96
- for (const [k, v] of Object.entries(attributes !== null && attributes !== void 0 ? attributes : {})) {
112
+ for (const [k, v] of Object.entries((_a = options === null || options === void 0 ? void 0 : options.attributes) !== null && _a !== void 0 ? _a : {})) {
97
113
  script.setAttribute(k, v);
98
114
  }
99
115
  script.onload = () => {
@@ -107,7 +123,7 @@
107
123
  reject(new Error(`Failed to load ${src}`));
108
124
  };
109
125
  const tag = window.document.getElementsByTagName("script")[0];
110
- (_a = tag.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(script, tag);
126
+ (_b = tag.parentElement) === null || _b === void 0 ? void 0 : _b.insertBefore(script, tag);
111
127
  });
112
128
  }
113
129
 
@@ -207,6 +223,7 @@
207
223
  step((generator = generator.apply(thisArg, _arguments || [])).next());
208
224
  });
209
225
  };
226
+ const cdn = "cdn.lr-ingest.io/";
210
227
  const logrocketPlugin = {
211
228
  id: "logrocket",
212
229
  handle(config, payload) {
@@ -257,7 +274,7 @@
257
274
  return;
258
275
  }
259
276
  setLogRocketState("loading");
260
- loadScript(`https://cdn.lr-ingest.io/LogRocket.min.js`, { crossOrigin: "anonymous" })
277
+ loadScript(`${cdn}LogRocket`, { min: true, attributes: { crossOrigin: "anonymous" } })
261
278
  .then(() => {
262
279
  if (window["LogRocket"]) {
263
280
  try {
@@ -380,8 +397,8 @@
380
397
  event: "gtm.js",
381
398
  });
382
399
  const dl = l != "dataLayer" ? "&l=" + l : "";
383
- const scriptSrc = "https://www.googletagmanager.com/gtm.js?id=" + i + dl;
384
- loadScript(scriptSrc)
400
+ const scriptSrc = "googletagmanager.com/gtm";
401
+ loadScript(scriptSrc, { www: true, js: true, query: "id=" + i + dl })
385
402
  .then(() => {
386
403
  setGtmState("loaded");
387
404
  })
@@ -402,7 +419,7 @@
402
419
  step((generator = generator.apply(thisArg, _arguments || [])).next());
403
420
  });
404
421
  };
405
- const defaultScriptSrc = "https://www.googletagmanager.com/gtag/js";
422
+ const defaultScriptSrc = "googletagmanager.com/gtag/js";
406
423
  const ga4Plugin = {
407
424
  id: "ga4-tag",
408
425
  handle(config, payload) {
@@ -464,7 +481,6 @@
464
481
  const dlParam = dlName !== "dataLayer" ? "&l=" + dlName : "";
465
482
  // to work with both GA4 and GTM
466
483
  const tagId = config.measurementIds;
467
- const scriptSrc = `${defaultScriptSrc}?id=${tagId}${dlParam}`;
468
484
  window[dlName] = window[dlName] || [];
469
485
  const gtag = function () {
470
486
  window[dlName].push(arguments);
@@ -474,7 +490,7 @@
474
490
  gtag(
475
491
  // @ts-ignore
476
492
  "config", tagId, Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId } : {})), (!config.autoPageView ? { send_page_view: false } : {})));
477
- loadScript(scriptSrc)
493
+ loadScript(defaultScriptSrc, { query: `id=${tagId}${dlParam}`, www: true })
478
494
  .then(() => {
479
495
  setGa4State("loaded");
480
496
  })
@@ -1113,8 +1129,15 @@
1113
1129
  return undefined;
1114
1130
  }
1115
1131
  }
1116
- function removeCookie(name) {
1117
- document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:01 GMT;";
1132
+ function removeCookie(name, { domain, secure }) {
1133
+ document.cookie =
1134
+ name +
1135
+ "=;domain=" +
1136
+ domain +
1137
+ ";path=/" +
1138
+ ";expires=Thu, 01 Jan 1970 00:00:01 GMT;SameSite=" +
1139
+ (secure ? "None" : "Lax") +
1140
+ (secure ? ";secure" : "");
1118
1141
  }
1119
1142
  function setCookie(name, val, { domain, secure }) {
1120
1143
  document.cookie =
@@ -1156,7 +1179,18 @@
1156
1179
  return parse(result);
1157
1180
  },
1158
1181
  removeItem(key) {
1159
- removeCookie(key2cookie[key] || key);
1182
+ removeCookie(key2cookie[key] || key, {
1183
+ domain: cookieDomain,
1184
+ secure: window.location.protocol === "https:",
1185
+ });
1186
+ },
1187
+ reset() {
1188
+ for (const v of Object.values(key2cookie)) {
1189
+ removeCookie(v, {
1190
+ domain: cookieDomain,
1191
+ secure: window.location.protocol === "https:",
1192
+ });
1193
+ }
1160
1194
  },
1161
1195
  };
1162
1196
  };
@@ -1227,6 +1261,9 @@
1227
1261
  store() {
1228
1262
  const storage = {};
1229
1263
  return {
1264
+ reset() {
1265
+ Object.keys(storage).forEach(key => delete storage[key]);
1266
+ },
1230
1267
  setItem(key, val) {
1231
1268
  if (config.debug) {
1232
1269
  console.log(`[JITSU EMPTY RUNTIME] Set storage item ${key}=${JSON.stringify(val)}`);
@@ -1292,6 +1329,17 @@
1292
1329
  }
1293
1330
  return path;
1294
1331
  }
1332
+ const hashRegex = /#.*$/;
1333
+ /**
1334
+ * for compatibility with path produced by analytics.js
1335
+ * @param url
1336
+ */
1337
+ function urlPath(url) {
1338
+ const regex = /(http[s]?:\/\/)?([^\/\s]+\/)(.*)/g;
1339
+ const matches = regex.exec(url);
1340
+ const pathMatch = matches && matches[3] ? matches[3].split("?")[0].replace(hashRegex, "") : "";
1341
+ return "/" + pathMatch;
1342
+ }
1295
1343
  function adjustPayload(payload, config, storage, s2s) {
1296
1344
  var _a, _b;
1297
1345
  const runtime = config.runtime || (isInBrowser() ? windowRuntime(config) : emptyRuntime(config));
@@ -1299,8 +1347,9 @@
1299
1347
  const parsedUrl = safeCall(() => new URL(url), undefined);
1300
1348
  const query = parsedUrl ? parseQuery(parsedUrl.search) : {};
1301
1349
  const properties = payload.properties || {};
1302
- if (properties.path) {
1303
- properties.path = fixPath(properties.path);
1350
+ if (payload.type === "page" && url) {
1351
+ properties.url = url.replace(hashRegex, "");
1352
+ properties.path = fixPath(urlPath(url));
1304
1353
  }
1305
1354
  const customContext = ((_a = payload.properties) === null || _a === void 0 ? void 0 : _a.context) || {};
1306
1355
  (_b = payload.properties) === null || _b === void 0 ? true : delete _b.context;
@@ -1498,10 +1547,13 @@
1498
1547
  console.warn(`[JITSU] ${payload.type} responded with list of ${responseJson.destinations.length} destinations. However, this code is running in server-to-server mode, so destinations will be ignored`, jitsuConfig.debug ? JSON.stringify(responseJson.destinations, null, 2) : undefined);
1499
1548
  }
1500
1549
  else {
1501
- if (jitsuConfig.debug) {
1502
- console.log(`[JITSU] Processing device destinations: `, JSON.stringify(responseJson.destinations, null, 2));
1550
+ //double protection, ingest should not return destinations in s2s mode
1551
+ if (isInBrowser()) {
1552
+ if (jitsuConfig.debug) {
1553
+ console.log(`[JITSU] Processing device destinations: `, JSON.stringify(responseJson.destinations, null, 2));
1554
+ }
1555
+ return processDestinations(responseJson.destinations, method, adjustedPayload, !!jitsuConfig.debug, instance);
1503
1556
  }
1504
- return processDestinations(responseJson.destinations, method, adjustedPayload, !!jitsuConfig.debug, instance);
1505
1557
  }
1506
1558
  }
1507
1559
  return adjustedPayload;
@@ -1541,9 +1593,11 @@
1541
1593
  return send("identify", payload, config, instance, storage);
1542
1594
  },
1543
1595
  reset: args => {
1544
- //clear storage cache
1545
- if (pluginConfig.storageWrapper) {
1546
- pluginConfig.storageWrapper(args.instance.storage).reset();
1596
+ const { config, instance } = args;
1597
+ const storage = pluginConfig.storageWrapper ? pluginConfig.storageWrapper(instance.storage) : instance.storage;
1598
+ storage === null || storage === void 0 ? void 0 : storage.reset();
1599
+ if (config.debug) {
1600
+ console.log("[JITSU DEBUG] Resetting Jitsu plugin storage");
1547
1601
  }
1548
1602
  },
1549
1603
  methods: {
@@ -1646,9 +1700,9 @@
1646
1700
  },
1647
1701
  reset() {
1648
1702
  for (const key of [...Object.keys(storageCache)]) {
1649
- storage.removeItem(key);
1650
1703
  delete storageCache[key];
1651
1704
  }
1705
+ storage.reset();
1652
1706
  },
1653
1707
  removeItem(key) {
1654
1708
  if (opts.debug) {
@@ -1705,7 +1759,20 @@
1705
1759
  userState.anonymousId = id;
1706
1760
  }
1707
1761
  analytics.setAnonymousId(id);
1708
- }, group(groupId, traits, options, callback) {
1762
+ }, reset() {
1763
+ return __awaiter(this, void 0, void 0, function* () {
1764
+ if (opts.debug) {
1765
+ console.log("[JITSU DEBUG] Called reset(). Storage state", JSON.stringify(analytics.user()));
1766
+ }
1767
+ storage.reset();
1768
+ yield analytics.reset();
1769
+ this.setAnonymousId(uuid());
1770
+ if (opts.debug) {
1771
+ console.log("[JITSU DEBUG] User state after reset", JSON.stringify(analytics.user()));
1772
+ }
1773
+ });
1774
+ },
1775
+ group(groupId, traits, options, callback) {
1709
1776
  return __awaiter(this, void 0, void 0, function* () {
1710
1777
  const results = [];
1711
1778
  for (const plugin of Object.values(analytics.plugins)) {
@@ -1754,6 +1821,15 @@
1754
1821
  // result.loaded(createUnderlyingAnalyticsInstance(opts, rt));
1755
1822
  // }
1756
1823
  }
1824
+ function uuid() {
1825
+ var u = "", m = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx", i = 0, rb = (Math.random() * 0xffffffff) | 0;
1826
+ while (i++ < 36) {
1827
+ var c = m[i - 1], r = rb & 0xf, v = c == "x" ? r : (r & 0x3) | 0x8;
1828
+ u += c == "-" || c == "4" ? c : v.toString(16);
1829
+ rb = i % 8 == 0 ? (Math.random() * 0xffffffff) | 0 : rb >> 4;
1830
+ }
1831
+ return u;
1832
+ }
1757
1833
 
1758
1834
  function snakeToCamel(s) {
1759
1835
  return s.replace(/([-_][a-z])/gi, $1 => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jitsu/js",
3
- "version": "1.9.3",
3
+ "version": "1.9.5",
4
4
  "description": "",
5
5
  "author": "Jitsu Dev Team <dev@jitsu.com>",
6
6
  "main": "dist/jitsu.cjs.js",
@@ -34,8 +34,8 @@
34
34
  "rollup": "^3.2.5",
35
35
  "ts-jest": "29.0.5",
36
36
  "typescript": "^5.3.3",
37
- "@jitsu/protocols": "1.9.3",
38
- "jsondiffpatch": "1.9.3"
37
+ "@jitsu/protocols": "1.9.5",
38
+ "jsondiffpatch": "1.9.5"
39
39
  },
40
40
  "dependencies": {
41
41
  "analytics": "0.8.9"
@@ -123,8 +123,15 @@ function getGa4Ids(runtime: RuntimeFacade) {
123
123
  }
124
124
  }
125
125
 
126
- function removeCookie(name: string) {
127
- document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:01 GMT;";
126
+ function removeCookie(name: string, { domain, secure }: { domain: string; secure: boolean }) {
127
+ document.cookie =
128
+ name +
129
+ "=;domain=" +
130
+ domain +
131
+ ";path=/" +
132
+ ";expires=Thu, 01 Jan 1970 00:00:01 GMT;SameSite=" +
133
+ (secure ? "None" : "Lax") +
134
+ (secure ? ";secure" : "");
128
135
  }
129
136
 
130
137
  function setCookie(name: string, val: string, { domain, secure }: { domain: string; secure: boolean }) {
@@ -169,7 +176,18 @@ const cookieStorage: StorageFactory = (cookieDomain, key2cookie) => {
169
176
  return parse(result);
170
177
  },
171
178
  removeItem(key: string) {
172
- removeCookie(key2cookie[key] || key);
179
+ removeCookie(key2cookie[key] || key, {
180
+ domain: cookieDomain,
181
+ secure: window.location.protocol === "https:",
182
+ });
183
+ },
184
+ reset() {
185
+ for (const v of Object.values(key2cookie)) {
186
+ removeCookie(v, {
187
+ domain: cookieDomain,
188
+ secure: window.location.protocol === "https:",
189
+ });
190
+ }
173
191
  },
174
192
  };
175
193
  };
@@ -244,6 +262,9 @@ export const emptyRuntime = (config: JitsuOptions): RuntimeFacade => ({
244
262
  store(): PersistentStorage {
245
263
  const storage = {};
246
264
  return {
265
+ reset(): void {
266
+ Object.keys(storage).forEach(key => delete storage[key]);
267
+ },
247
268
  setItem(key: string, val: any) {
248
269
  if (config.debug) {
249
270
  console.log(`[JITSU EMPTY RUNTIME] Set storage item ${key}=${JSON.stringify(val)}`);
@@ -313,6 +334,19 @@ function fixPath(path: string): string {
313
334
  return path;
314
335
  }
315
336
 
337
+ const hashRegex = /#.*$/;
338
+
339
+ /**
340
+ * for compatibility with path produced by analytics.js
341
+ * @param url
342
+ */
343
+ function urlPath(url) {
344
+ const regex = /(http[s]?:\/\/)?([^\/\s]+\/)(.*)/g;
345
+ const matches = regex.exec(url);
346
+ const pathMatch = matches && matches[3] ? matches[3].split("?")[0].replace(hashRegex, "") : "";
347
+ return "/" + pathMatch;
348
+ }
349
+
316
350
  function adjustPayload(
317
351
  payload: any,
318
352
  config: JitsuOptions,
@@ -325,8 +359,9 @@ function adjustPayload(
325
359
  const query = parsedUrl ? parseQuery(parsedUrl.search) : {};
326
360
  const properties = payload.properties || {};
327
361
 
328
- if (properties.path) {
329
- properties.path = fixPath(properties.path);
362
+ if (payload.type === "page" && url) {
363
+ properties.url = url.replace(hashRegex, "");
364
+ properties.path = fixPath(urlPath(url));
330
365
  }
331
366
 
332
367
  const customContext = payload.properties?.context || {};
@@ -610,19 +645,22 @@ async function send(
610
645
  jitsuConfig.debug ? JSON.stringify(responseJson.destinations, null, 2) : undefined
611
646
  );
612
647
  } else {
613
- if (jitsuConfig.debug) {
614
- console.log(`[JITSU] Processing device destinations: `, JSON.stringify(responseJson.destinations, null, 2));
648
+ //double protection, ingest should not return destinations in s2s mode
649
+ if (isInBrowser()) {
650
+ if (jitsuConfig.debug) {
651
+ console.log(`[JITSU] Processing device destinations: `, JSON.stringify(responseJson.destinations, null, 2));
652
+ }
653
+ return processDestinations(responseJson.destinations, method, adjustedPayload, !!jitsuConfig.debug, instance);
615
654
  }
616
- return processDestinations(responseJson.destinations, method, adjustedPayload, !!jitsuConfig.debug, instance);
617
655
  }
618
656
  }
619
657
  return adjustedPayload;
620
658
  }
621
659
 
622
660
  export type JitsuPluginConfig = JitsuOptions & {
623
- storageWrapper?: (persistentStorage: PersistentStorage) => PersistentStorage & { reset: () => void };
661
+ storageWrapper?: (persistentStorage: PersistentStorage) => PersistentStorage;
624
662
  };
625
- const jitsuAnalyticsPlugin = (pluginConfig: JitsuPluginConfig = {}): AnalyticsPlugin => {
663
+ export const jitsuAnalyticsPlugin = (pluginConfig: JitsuPluginConfig = {}): AnalyticsPlugin => {
626
664
  const instanceConfig = {
627
665
  ...defaultConfig,
628
666
  ...pluginConfig,
@@ -672,9 +710,11 @@ const jitsuAnalyticsPlugin = (pluginConfig: JitsuPluginConfig = {}): AnalyticsPl
672
710
  return send("identify", payload, config, instance, storage);
673
711
  },
674
712
  reset: args => {
675
- //clear storage cache
676
- if (pluginConfig.storageWrapper) {
677
- pluginConfig.storageWrapper(args.instance.storage).reset();
713
+ const { config, instance } = args;
714
+ const storage = pluginConfig.storageWrapper ? pluginConfig.storageWrapper(instance.storage) : instance.storage;
715
+ storage?.reset();
716
+ if (config.debug) {
717
+ console.log("[JITSU DEBUG] Resetting Jitsu plugin storage");
678
718
  }
679
719
  },
680
720
  methods: {
@@ -735,5 +775,3 @@ function hash(str: string, seed: number = 0): number {
735
775
 
736
776
  return 4294967296 * (2097151 & h2) + (h1 >>> 0);
737
777
  }
738
-
739
- export default jitsuAnalyticsPlugin;
@@ -2,7 +2,7 @@ import { loadScript } from "../script-loader";
2
2
  import { AnalyticsClientEvent } from "@jitsu/protocols/analytics";
3
3
  import { applyFilters, CommonDestinationCredentials, InternalPlugin } from "./index";
4
4
 
5
- const defaultScriptSrc = "https://www.googletagmanager.com/gtag/js";
5
+ const defaultScriptSrc = "googletagmanager.com/gtag/js";
6
6
 
7
7
  export type Ga4DestinationCredentials = {
8
8
  debug?: boolean;
@@ -94,7 +94,6 @@ async function initGa4IfNeeded(config: Ga4DestinationCredentials, payload: Analy
94
94
 
95
95
  // to work with both GA4 and GTM
96
96
  const tagId = config.measurementIds;
97
- const scriptSrc = `${defaultScriptSrc}?id=${tagId}${dlParam}`;
98
97
 
99
98
  window[dlName] = window[dlName] || [];
100
99
  const gtag = function () {
@@ -112,7 +111,7 @@ async function initGa4IfNeeded(config: Ga4DestinationCredentials, payload: Analy
112
111
  }
113
112
  );
114
113
 
115
- loadScript(scriptSrc)
114
+ loadScript(defaultScriptSrc, { query: `id=${tagId}${dlParam}`, www: true })
116
115
  .then(() => {
117
116
  setGa4State("loaded");
118
117
  })
@@ -129,8 +129,8 @@ async function initGtmIfNeeded(config: GtmDestinationCredentials, payload: Analy
129
129
  event: "gtm.js",
130
130
  });
131
131
  const dl = l != "dataLayer" ? "&l=" + l : "";
132
- const scriptSrc = "https://www.googletagmanager.com/gtm.js?id=" + i + dl;
133
- loadScript(scriptSrc)
132
+ const scriptSrc = "googletagmanager.com/gtm";
133
+ loadScript(scriptSrc, { www: true, js: true, query: "id=" + i + dl })
134
134
  .then(() => {
135
135
  setGtmState("loaded");
136
136
  })
@@ -6,6 +6,8 @@ export type LogRocketDestinationCredentials = {
6
6
  appId: string;
7
7
  } & CommonDestinationCredentials;
8
8
 
9
+ const cdn = "cdn.lr-ingest.io/";
10
+
9
11
  export const logrocketPlugin: InternalPlugin<LogRocketDestinationCredentials> = {
10
12
  id: "logrocket",
11
13
  async handle(config, payload: AnalyticsClientEvent) {
@@ -63,7 +65,7 @@ async function initLogrocketIfNeeded(appId: string) {
63
65
  return;
64
66
  }
65
67
  setLogRocketState("loading");
66
- loadScript(`https://cdn.lr-ingest.io/LogRocket.min.js`, { crossOrigin: "anonymous" })
68
+ loadScript(`${cdn}LogRocket`, { min: true, attributes: { crossOrigin: "anonymous" } })
67
69
  .then(() => {
68
70
  if (window["LogRocket"]) {
69
71
  try {
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import Analytics from "analytics";
2
2
  import { AnalyticsInterface, JitsuOptions, PersistentStorage, RuntimeFacade } from "./jitsu";
3
- import jitsuAnalyticsPlugin, { emptyRuntime, isInBrowser, windowRuntime } from "./analytics-plugin";
3
+ import { jitsuAnalyticsPlugin, emptyRuntime, isInBrowser, windowRuntime } from "./analytics-plugin";
4
4
  import { Callback, DispatchedEvent, ID, JSONObject, Options } from "@jitsu/protocols/analytics";
5
5
 
6
6
  export default function parse(input) {
@@ -64,9 +64,9 @@ function createUnderlyingAnalyticsInstance(
64
64
  },
65
65
  reset() {
66
66
  for (const key of [...Object.keys(storageCache)]) {
67
- storage.removeItem(key);
68
67
  delete storageCache[key];
69
68
  }
69
+ storage.reset();
70
70
  },
71
71
  removeItem(key: string) {
72
72
  if (opts.debug) {
@@ -133,6 +133,17 @@ function createUnderlyingAnalyticsInstance(
133
133
  }
134
134
  (analytics as any).setAnonymousId(id);
135
135
  },
136
+ async reset() {
137
+ if (opts.debug) {
138
+ console.log("[JITSU DEBUG] Called reset(). Storage state", JSON.stringify(analytics.user()));
139
+ }
140
+ storage.reset();
141
+ await analytics.reset();
142
+ this.setAnonymousId(uuid());
143
+ if (opts.debug) {
144
+ console.log("[JITSU DEBUG] User state after reset", JSON.stringify(analytics.user()));
145
+ }
146
+ },
136
147
  async group(
137
148
  groupId?: ID,
138
149
  traits?: JSONObject | null,
@@ -194,5 +205,22 @@ export function jitsuAnalytics(_opts: JitsuOptions): AnalyticsInterface {
194
205
  // }
195
206
  }
196
207
 
208
+ function uuid() {
209
+ var u = "",
210
+ m = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx",
211
+ i = 0,
212
+ rb = (Math.random() * 0xffffffff) | 0;
213
+
214
+ while (i++ < 36) {
215
+ var c = m[i - 1],
216
+ r = rb & 0xf,
217
+ v = c == "x" ? r : (r & 0x3) | 0x8;
218
+
219
+ u += c == "-" || c == "4" ? c : v.toString(16);
220
+ rb = i % 8 == 0 ? (Math.random() * 0xffffffff) | 0 : rb >> 4;
221
+ }
222
+ return u;
223
+ }
224
+
197
225
  export * from "./jitsu";
198
226
  export * from "./analytics-plugin";
package/src/jitsu.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import type { AnalyticsInterface } from "@jitsu/protocols/analytics";
2
- import type { AnalyticsPlugin } from "analytics";
3
2
 
4
3
  type JitsuOptions = {
5
4
  /**
@@ -56,6 +55,7 @@ type PersistentStorage = {
56
55
  getItem: (key: string, options?: any) => any;
57
56
  setItem: (key: string, value: any, options?: any) => void;
58
57
  removeItem: (key: string, options?: any) => void;
58
+ reset: () => void;
59
59
  };
60
60
 
61
61
  type RuntimeFacade = {
@@ -83,6 +83,4 @@ type RuntimeFacade = {
83
83
 
84
84
  export declare function jitsuAnalytics(opts: JitsuOptions): AnalyticsInterface;
85
85
 
86
- export declare const jitsuAnalyticsPlugin: AnalyticsPlugin;
87
-
88
86
  export { AnalyticsInterface, JitsuOptions, PersistentStorage, RuntimeFacade };
@@ -3,7 +3,32 @@ function findScript(src: string): HTMLScriptElement | undefined {
3
3
  return scripts.find(s => s.src === src);
4
4
  }
5
5
 
6
- export function loadScript(src: string, attributes?: Record<string, string>): Promise<HTMLScriptElement> {
6
+ export type ScriptOptions = {
7
+ attributes?: Record<string, string>;
8
+ www?: boolean;
9
+ js?: boolean;
10
+ min?: boolean;
11
+ query?: string;
12
+ };
13
+
14
+ function buildScriptSrc(src: string, options?: ScriptOptions): string {
15
+ let result = src;
16
+ if (!result.startsWith("http")) {
17
+ result = `https://${options?.www ? "www." : ""}${result}`;
18
+ }
19
+ if (options?.min) {
20
+ result = result + ".min.js";
21
+ } else if (options?.js) {
22
+ result = result + ".js";
23
+ }
24
+
25
+ if (options?.query) {
26
+ result += "?" + options.query;
27
+ }
28
+ return result;
29
+ }
30
+
31
+ export function loadScript(src: string, options?: ScriptOptions): Promise<HTMLScriptElement> {
7
32
  const found = findScript(src);
8
33
 
9
34
  if (found !== undefined) {
@@ -25,11 +50,11 @@ export function loadScript(src: string, attributes?: Record<string, string>): Pr
25
50
  const script = window.document.createElement("script");
26
51
 
27
52
  script.type = "text/javascript";
28
- script.src = src;
53
+ script.src = buildScriptSrc(src, options);
29
54
  script.async = true;
30
55
 
31
56
  script.setAttribute("status", "loading");
32
- for (const [k, v] of Object.entries(attributes ?? {})) {
57
+ for (const [k, v] of Object.entries(options?.attributes ?? {})) {
33
58
  script.setAttribute(k, v);
34
59
  }
35
60