@jitsu/js 1.9.3-canary.801.20240514214630 → 1.9.4

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.
@@ -0,0 +1,31 @@
1
+ <!DOCTYPE html>
2
+
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="utf-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+
8
+ <title>Tracking page</title>
9
+ <script>
10
+ window.testOnload = async j => {
11
+ await j.setAnonymousId("john-doe-id-1");
12
+ await j.identify("john-nondoe", { email: "john@example.com" });
13
+ await j.track("pageLoaded", { trackParam: "trackValue" });
14
+ await j.reset();
15
+ await j.track("pageLoaded", { trackParam: "trackValue" });
16
+ };
17
+ </script>
18
+ <script
19
+ type="text/javascript"
20
+ src="<%=trackingBase%>/p.js"
21
+ data-onload="testOnload"
22
+ data-debug="true"
23
+ data-init-only="true"
24
+ defer
25
+ ></script>
26
+ </head>
27
+
28
+ <body>
29
+ <h1>Test</h1>
30
+ </body>
31
+ </html>
@@ -244,6 +244,41 @@ test("url-bug", async ({ browser }) => {
244
244
  expect(pagePath).toEqual("/");
245
245
  });
246
246
 
247
+ test("reset", async ({ browser }) => {
248
+ clearRequestLog();
249
+ const browserContext = await browser.newContext();
250
+ const { page, uncaughtErrors } = await createLoggingPage(browserContext);
251
+ const [pageResult] = await Promise.all([page.goto(`${server.baseUrl}/reset.html`)]);
252
+ await page.waitForFunction(() => window["jitsu"] !== undefined, undefined, {
253
+ timeout: 1000,
254
+ polling: 100,
255
+ });
256
+ expect(pageResult.status()).toBe(200);
257
+ //wait for some time since the server has an artificial latency of 30ms
258
+ await new Promise(resolve => setTimeout(resolve, 1000));
259
+ expect(uncaughtErrors.length).toEqual(0);
260
+ expect(requestLog.length).toBe(3);
261
+ console.log(
262
+ `📝 Request log size of ${requestLog.length}`,
263
+ requestLog.map(x => describeEvent(x.type, x.body))
264
+ );
265
+ const [identifyEvent, firstTrack, secondTrack] = requestLog;
266
+ expect(firstTrack.body.anonymousId).toEqual("john-doe-id-1");
267
+
268
+ const cookies = await browserContext.cookies();
269
+ // all cookies should be cleared by .reset()
270
+ // but new cookie for new anonymousId should be set
271
+ expect(cookies.length).toBe(1);
272
+ expect(cookies[0].name).toEqual("__eventn_id");
273
+ const newAnonymousId = cookies[0].value;
274
+ console.log(`🍪Cookies`, cookies);
275
+
276
+ expect(secondTrack.body.anonymousId).not.toBeNull();
277
+ expect(secondTrack.body.anonymousId).toBeDefined();
278
+ expect(secondTrack.body.anonymousId).toEqual(newAnonymousId);
279
+ expect(secondTrack.body.anonymousId).not.toEqual("john-doe-id-1");
280
+ });
281
+
247
282
  test("basic", async ({ browser }) => {
248
283
  clearRequestLog();
249
284
  const browserContext = await browser.newContext();
@@ -24,9 +24,7 @@ export type InternalPluginDescriptor = {
24
24
  };
25
25
  export type DeviceOptions = AnalyticsPluginDescriptor | InternalPluginDescriptor;
26
26
  export type JitsuPluginConfig = JitsuOptions & {
27
- storageWrapper?: (persistentStorage: PersistentStorage) => PersistentStorage & {
28
- reset: () => void;
29
- };
27
+ storageWrapper?: (persistentStorage: PersistentStorage) => PersistentStorage;
30
28
  };
31
29
  declare const jitsuAnalyticsPlugin: (pluginConfig?: JitsuPluginConfig) => AnalyticsPlugin;
32
30
  export declare function randomId(hashString?: string | undefined): string;
package/dist/jitsu.cjs.js CHANGED
@@ -71,7 +71,23 @@ function findScript(src) {
71
71
  const scripts = Array.prototype.slice.call(window.document.querySelectorAll("script"));
72
72
  return scripts.find(s => s.src === src);
73
73
  }
74
- function loadScript(src, attributes) {
74
+ function buildScriptSrc(src, options) {
75
+ let result = src;
76
+ if (!result.startsWith("http")) {
77
+ result = `https://${(options === null || options === void 0 ? void 0 : options.www) ? "www." : ""}${result}`;
78
+ }
79
+ if (options === null || options === void 0 ? void 0 : options.min) {
80
+ result = result + ".min.js";
81
+ }
82
+ else if (options === null || options === void 0 ? void 0 : options.js) {
83
+ result = result + ".js";
84
+ }
85
+ if (options === null || options === void 0 ? void 0 : options.query) {
86
+ result += "?" + options.query;
87
+ }
88
+ return result;
89
+ }
90
+ function loadScript(src, options) {
75
91
  const found = findScript(src);
76
92
  if (found !== undefined) {
77
93
  const status = found === null || found === void 0 ? void 0 : found.getAttribute("status");
@@ -86,13 +102,13 @@ function loadScript(src, attributes) {
86
102
  }
87
103
  }
88
104
  return new Promise((resolve, reject) => {
89
- var _a;
105
+ var _a, _b;
90
106
  const script = window.document.createElement("script");
91
107
  script.type = "text/javascript";
92
- script.src = src;
108
+ script.src = buildScriptSrc(src, options);
93
109
  script.async = true;
94
110
  script.setAttribute("status", "loading");
95
- for (const [k, v] of Object.entries(attributes !== null && attributes !== void 0 ? attributes : {})) {
111
+ for (const [k, v] of Object.entries((_a = options === null || options === void 0 ? void 0 : options.attributes) !== null && _a !== void 0 ? _a : {})) {
96
112
  script.setAttribute(k, v);
97
113
  }
98
114
  script.onload = () => {
@@ -106,7 +122,7 @@ function loadScript(src, attributes) {
106
122
  reject(new Error(`Failed to load ${src}`));
107
123
  };
108
124
  const tag = window.document.getElementsByTagName("script")[0];
109
- (_a = tag.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(script, tag);
125
+ (_b = tag.parentElement) === null || _b === void 0 ? void 0 : _b.insertBefore(script, tag);
110
126
  });
111
127
  }
112
128
 
@@ -206,6 +222,7 @@ var __awaiter$4 = (undefined && undefined.__awaiter) || function (thisArg, _argu
206
222
  step((generator = generator.apply(thisArg, _arguments || [])).next());
207
223
  });
208
224
  };
225
+ const cdn = "cdn.lr-ingest.io/";
209
226
  const logrocketPlugin = {
210
227
  id: "logrocket",
211
228
  handle(config, payload) {
@@ -256,7 +273,7 @@ function initLogrocketIfNeeded(appId) {
256
273
  return;
257
274
  }
258
275
  setLogRocketState("loading");
259
- loadScript(`https://cdn.lr-ingest.io/LogRocket.min.js`, { crossOrigin: "anonymous" })
276
+ loadScript(`${cdn}LogRocket`, { min: true, attributes: { crossOrigin: "anonymous" } })
260
277
  .then(() => {
261
278
  if (window["LogRocket"]) {
262
279
  try {
@@ -379,8 +396,8 @@ function initGtmIfNeeded(config, payload) {
379
396
  event: "gtm.js",
380
397
  });
381
398
  const dl = l != "dataLayer" ? "&l=" + l : "";
382
- const scriptSrc = "https://www.googletagmanager.com/gtm.js?id=" + i + dl;
383
- loadScript(scriptSrc)
399
+ const scriptSrc = "googletagmanager.com/gtm";
400
+ loadScript(scriptSrc, { www: true, js: true, query: "id=" + i + dl })
384
401
  .then(() => {
385
402
  setGtmState("loaded");
386
403
  })
@@ -401,7 +418,7 @@ var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _argu
401
418
  step((generator = generator.apply(thisArg, _arguments || [])).next());
402
419
  });
403
420
  };
404
- const defaultScriptSrc = "https://www.googletagmanager.com/gtag/js";
421
+ const defaultScriptSrc = "googletagmanager.com/gtag/js";
405
422
  const ga4Plugin = {
406
423
  id: "ga4-tag",
407
424
  handle(config, payload) {
@@ -463,7 +480,6 @@ function initGa4IfNeeded(config, payload) {
463
480
  const dlParam = dlName !== "dataLayer" ? "&l=" + dlName : "";
464
481
  // to work with both GA4 and GTM
465
482
  const tagId = config.measurementIds;
466
- const scriptSrc = `${defaultScriptSrc}?id=${tagId}${dlParam}`;
467
483
  window[dlName] = window[dlName] || [];
468
484
  const gtag = function () {
469
485
  window[dlName].push(arguments);
@@ -473,7 +489,7 @@ function initGa4IfNeeded(config, payload) {
473
489
  gtag(
474
490
  // @ts-ignore
475
491
  "config", tagId, Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId } : {})), (!config.autoPageView ? { send_page_view: false } : {})));
476
- loadScript(scriptSrc)
492
+ loadScript(defaultScriptSrc, { query: `id=${tagId}${dlParam}`, www: true })
477
493
  .then(() => {
478
494
  setGa4State("loaded");
479
495
  })
@@ -1112,8 +1128,15 @@ function getGa4Ids(runtime) {
1112
1128
  return undefined;
1113
1129
  }
1114
1130
  }
1115
- function removeCookie(name) {
1116
- document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:01 GMT;";
1131
+ function removeCookie(name, { domain, secure }) {
1132
+ document.cookie =
1133
+ name +
1134
+ "=;domain=" +
1135
+ domain +
1136
+ ";path=/" +
1137
+ ";expires=Thu, 01 Jan 1970 00:00:01 GMT;SameSite=" +
1138
+ (secure ? "None" : "Lax") +
1139
+ (secure ? ";secure" : "");
1117
1140
  }
1118
1141
  function setCookie(name, val, { domain, secure }) {
1119
1142
  document.cookie =
@@ -1155,7 +1178,18 @@ const cookieStorage = (cookieDomain, key2cookie) => {
1155
1178
  return parse(result);
1156
1179
  },
1157
1180
  removeItem(key) {
1158
- removeCookie(key2cookie[key] || key);
1181
+ removeCookie(key2cookie[key] || key, {
1182
+ domain: cookieDomain,
1183
+ secure: window.location.protocol === "https:",
1184
+ });
1185
+ },
1186
+ reset() {
1187
+ for (const v of Object.values(key2cookie)) {
1188
+ removeCookie(v, {
1189
+ domain: cookieDomain,
1190
+ secure: window.location.protocol === "https:",
1191
+ });
1192
+ }
1159
1193
  },
1160
1194
  };
1161
1195
  };
@@ -1226,6 +1260,9 @@ const emptyRuntime = (config) => ({
1226
1260
  store() {
1227
1261
  const storage = {};
1228
1262
  return {
1263
+ reset() {
1264
+ Object.keys(storage).forEach(key => delete storage[key]);
1265
+ },
1229
1266
  setItem(key, val) {
1230
1267
  if (config.debug) {
1231
1268
  console.log(`[JITSU EMPTY RUNTIME] Set storage item ${key}=${JSON.stringify(val)}`);
@@ -1497,7 +1534,8 @@ function send(method, payload, jitsuConfig, instance, store) {
1497
1534
  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);
1498
1535
  }
1499
1536
  else {
1500
- if (typeof window !== "undefined") {
1537
+ //double protection, ingest should not return destinations in s2s mode
1538
+ if (isInBrowser()) {
1501
1539
  if (jitsuConfig.debug) {
1502
1540
  console.log(`[JITSU] Processing device destinations: `, JSON.stringify(responseJson.destinations, null, 2));
1503
1541
  }
@@ -1542,9 +1580,11 @@ const jitsuAnalyticsPlugin = (pluginConfig = {}) => {
1542
1580
  return send("identify", payload, config, instance, storage);
1543
1581
  },
1544
1582
  reset: args => {
1545
- //clear storage cache
1546
- if (pluginConfig.storageWrapper) {
1547
- pluginConfig.storageWrapper(args.instance.storage).reset();
1583
+ const { config, instance } = args;
1584
+ const storage = pluginConfig.storageWrapper ? pluginConfig.storageWrapper(instance.storage) : instance.storage;
1585
+ storage === null || storage === void 0 ? void 0 : storage.reset();
1586
+ if (config.debug) {
1587
+ console.log("[JITSU DEBUG] Resetting Jitsu plugin storage");
1548
1588
  }
1549
1589
  },
1550
1590
  methods: {
@@ -1656,9 +1696,9 @@ function createUnderlyingAnalyticsInstance(opts, rt, plugins = []) {
1656
1696
  },
1657
1697
  reset() {
1658
1698
  for (const key of [...Object.keys(storageCache)]) {
1659
- storage.removeItem(key);
1660
1699
  delete storageCache[key];
1661
1700
  }
1701
+ storage.reset();
1662
1702
  },
1663
1703
  removeItem(key) {
1664
1704
  if (opts.debug) {
@@ -1715,7 +1755,20 @@ function createUnderlyingAnalyticsInstance(opts, rt, plugins = []) {
1715
1755
  userState.anonymousId = id;
1716
1756
  }
1717
1757
  analytics.setAnonymousId(id);
1718
- }, group(groupId, traits, options, callback) {
1758
+ }, reset() {
1759
+ return __awaiter(this, void 0, void 0, function* () {
1760
+ if (opts.debug) {
1761
+ console.log("[JITSU DEBUG] Called reset(). Storage state", JSON.stringify(analytics.user()));
1762
+ }
1763
+ storage.reset();
1764
+ yield analytics.reset();
1765
+ this.setAnonymousId(uuid());
1766
+ if (opts.debug) {
1767
+ console.log("[JITSU DEBUG] User state after reset", JSON.stringify(analytics.user()));
1768
+ }
1769
+ });
1770
+ },
1771
+ group(groupId, traits, options, callback) {
1719
1772
  return __awaiter(this, void 0, void 0, function* () {
1720
1773
  const results = [];
1721
1774
  for (const plugin of Object.values(analytics.plugins)) {
@@ -1764,6 +1817,15 @@ function jitsuAnalytics(_opts) {
1764
1817
  // result.loaded(createUnderlyingAnalyticsInstance(opts, rt));
1765
1818
  // }
1766
1819
  }
1820
+ function uuid() {
1821
+ var u = "", m = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx", i = 0, rb = (Math.random() * 0xffffffff) | 0;
1822
+ while (i++ < 36) {
1823
+ var c = m[i - 1], r = rb & 0xf, v = c == "x" ? r : (r & 0x3) | 0x8;
1824
+ u += c == "-" || c == "4" ? c : v.toString(16);
1825
+ rb = i % 8 == 0 ? (Math.random() * 0xffffffff) | 0 : rb >> 4;
1826
+ }
1827
+ return u;
1828
+ }
1767
1829
 
1768
1830
  exports.emptyAnalytics = emptyAnalytics;
1769
1831
  exports.emptyRuntime = emptyRuntime;
package/dist/jitsu.d.ts CHANGED
@@ -52,6 +52,7 @@ type PersistentStorage = {
52
52
  getItem: (key: string, options?: any) => any;
53
53
  setItem: (key: string, value: any, options?: any) => void;
54
54
  removeItem: (key: string, options?: any) => void;
55
+ reset: () => void;
55
56
  };
56
57
  type RuntimeFacade = {
57
58
  store(): PersistentStorage;
package/dist/jitsu.es.js CHANGED
@@ -69,7 +69,23 @@ function findScript(src) {
69
69
  const scripts = Array.prototype.slice.call(window.document.querySelectorAll("script"));
70
70
  return scripts.find(s => s.src === src);
71
71
  }
72
- function loadScript(src, attributes) {
72
+ function buildScriptSrc(src, options) {
73
+ let result = src;
74
+ if (!result.startsWith("http")) {
75
+ result = `https://${(options === null || options === void 0 ? void 0 : options.www) ? "www." : ""}${result}`;
76
+ }
77
+ if (options === null || options === void 0 ? void 0 : options.min) {
78
+ result = result + ".min.js";
79
+ }
80
+ else if (options === null || options === void 0 ? void 0 : options.js) {
81
+ result = result + ".js";
82
+ }
83
+ if (options === null || options === void 0 ? void 0 : options.query) {
84
+ result += "?" + options.query;
85
+ }
86
+ return result;
87
+ }
88
+ function loadScript(src, options) {
73
89
  const found = findScript(src);
74
90
  if (found !== undefined) {
75
91
  const status = found === null || found === void 0 ? void 0 : found.getAttribute("status");
@@ -84,13 +100,13 @@ function loadScript(src, attributes) {
84
100
  }
85
101
  }
86
102
  return new Promise((resolve, reject) => {
87
- var _a;
103
+ var _a, _b;
88
104
  const script = window.document.createElement("script");
89
105
  script.type = "text/javascript";
90
- script.src = src;
106
+ script.src = buildScriptSrc(src, options);
91
107
  script.async = true;
92
108
  script.setAttribute("status", "loading");
93
- for (const [k, v] of Object.entries(attributes !== null && attributes !== void 0 ? attributes : {})) {
109
+ for (const [k, v] of Object.entries((_a = options === null || options === void 0 ? void 0 : options.attributes) !== null && _a !== void 0 ? _a : {})) {
94
110
  script.setAttribute(k, v);
95
111
  }
96
112
  script.onload = () => {
@@ -104,7 +120,7 @@ function loadScript(src, attributes) {
104
120
  reject(new Error(`Failed to load ${src}`));
105
121
  };
106
122
  const tag = window.document.getElementsByTagName("script")[0];
107
- (_a = tag.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(script, tag);
123
+ (_b = tag.parentElement) === null || _b === void 0 ? void 0 : _b.insertBefore(script, tag);
108
124
  });
109
125
  }
110
126
 
@@ -204,6 +220,7 @@ var __awaiter$4 = (undefined && undefined.__awaiter) || function (thisArg, _argu
204
220
  step((generator = generator.apply(thisArg, _arguments || [])).next());
205
221
  });
206
222
  };
223
+ const cdn = "cdn.lr-ingest.io/";
207
224
  const logrocketPlugin = {
208
225
  id: "logrocket",
209
226
  handle(config, payload) {
@@ -254,7 +271,7 @@ function initLogrocketIfNeeded(appId) {
254
271
  return;
255
272
  }
256
273
  setLogRocketState("loading");
257
- loadScript(`https://cdn.lr-ingest.io/LogRocket.min.js`, { crossOrigin: "anonymous" })
274
+ loadScript(`${cdn}LogRocket`, { min: true, attributes: { crossOrigin: "anonymous" } })
258
275
  .then(() => {
259
276
  if (window["LogRocket"]) {
260
277
  try {
@@ -377,8 +394,8 @@ function initGtmIfNeeded(config, payload) {
377
394
  event: "gtm.js",
378
395
  });
379
396
  const dl = l != "dataLayer" ? "&l=" + l : "";
380
- const scriptSrc = "https://www.googletagmanager.com/gtm.js?id=" + i + dl;
381
- loadScript(scriptSrc)
397
+ const scriptSrc = "googletagmanager.com/gtm";
398
+ loadScript(scriptSrc, { www: true, js: true, query: "id=" + i + dl })
382
399
  .then(() => {
383
400
  setGtmState("loaded");
384
401
  })
@@ -399,7 +416,7 @@ var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _argu
399
416
  step((generator = generator.apply(thisArg, _arguments || [])).next());
400
417
  });
401
418
  };
402
- const defaultScriptSrc = "https://www.googletagmanager.com/gtag/js";
419
+ const defaultScriptSrc = "googletagmanager.com/gtag/js";
403
420
  const ga4Plugin = {
404
421
  id: "ga4-tag",
405
422
  handle(config, payload) {
@@ -461,7 +478,6 @@ function initGa4IfNeeded(config, payload) {
461
478
  const dlParam = dlName !== "dataLayer" ? "&l=" + dlName : "";
462
479
  // to work with both GA4 and GTM
463
480
  const tagId = config.measurementIds;
464
- const scriptSrc = `${defaultScriptSrc}?id=${tagId}${dlParam}`;
465
481
  window[dlName] = window[dlName] || [];
466
482
  const gtag = function () {
467
483
  window[dlName].push(arguments);
@@ -471,7 +487,7 @@ function initGa4IfNeeded(config, payload) {
471
487
  gtag(
472
488
  // @ts-ignore
473
489
  "config", tagId, Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId } : {})), (!config.autoPageView ? { send_page_view: false } : {})));
474
- loadScript(scriptSrc)
490
+ loadScript(defaultScriptSrc, { query: `id=${tagId}${dlParam}`, www: true })
475
491
  .then(() => {
476
492
  setGa4State("loaded");
477
493
  })
@@ -1110,8 +1126,15 @@ function getGa4Ids(runtime) {
1110
1126
  return undefined;
1111
1127
  }
1112
1128
  }
1113
- function removeCookie(name) {
1114
- document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:01 GMT;";
1129
+ function removeCookie(name, { domain, secure }) {
1130
+ document.cookie =
1131
+ name +
1132
+ "=;domain=" +
1133
+ domain +
1134
+ ";path=/" +
1135
+ ";expires=Thu, 01 Jan 1970 00:00:01 GMT;SameSite=" +
1136
+ (secure ? "None" : "Lax") +
1137
+ (secure ? ";secure" : "");
1115
1138
  }
1116
1139
  function setCookie(name, val, { domain, secure }) {
1117
1140
  document.cookie =
@@ -1153,7 +1176,18 @@ const cookieStorage = (cookieDomain, key2cookie) => {
1153
1176
  return parse(result);
1154
1177
  },
1155
1178
  removeItem(key) {
1156
- removeCookie(key2cookie[key] || key);
1179
+ removeCookie(key2cookie[key] || key, {
1180
+ domain: cookieDomain,
1181
+ secure: window.location.protocol === "https:",
1182
+ });
1183
+ },
1184
+ reset() {
1185
+ for (const v of Object.values(key2cookie)) {
1186
+ removeCookie(v, {
1187
+ domain: cookieDomain,
1188
+ secure: window.location.protocol === "https:",
1189
+ });
1190
+ }
1157
1191
  },
1158
1192
  };
1159
1193
  };
@@ -1224,6 +1258,9 @@ const emptyRuntime = (config) => ({
1224
1258
  store() {
1225
1259
  const storage = {};
1226
1260
  return {
1261
+ reset() {
1262
+ Object.keys(storage).forEach(key => delete storage[key]);
1263
+ },
1227
1264
  setItem(key, val) {
1228
1265
  if (config.debug) {
1229
1266
  console.log(`[JITSU EMPTY RUNTIME] Set storage item ${key}=${JSON.stringify(val)}`);
@@ -1495,7 +1532,8 @@ function send(method, payload, jitsuConfig, instance, store) {
1495
1532
  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);
1496
1533
  }
1497
1534
  else {
1498
- if (typeof window !== "undefined") {
1535
+ //double protection, ingest should not return destinations in s2s mode
1536
+ if (isInBrowser()) {
1499
1537
  if (jitsuConfig.debug) {
1500
1538
  console.log(`[JITSU] Processing device destinations: `, JSON.stringify(responseJson.destinations, null, 2));
1501
1539
  }
@@ -1540,9 +1578,11 @@ const jitsuAnalyticsPlugin = (pluginConfig = {}) => {
1540
1578
  return send("identify", payload, config, instance, storage);
1541
1579
  },
1542
1580
  reset: args => {
1543
- //clear storage cache
1544
- if (pluginConfig.storageWrapper) {
1545
- pluginConfig.storageWrapper(args.instance.storage).reset();
1581
+ const { config, instance } = args;
1582
+ const storage = pluginConfig.storageWrapper ? pluginConfig.storageWrapper(instance.storage) : instance.storage;
1583
+ storage === null || storage === void 0 ? void 0 : storage.reset();
1584
+ if (config.debug) {
1585
+ console.log("[JITSU DEBUG] Resetting Jitsu plugin storage");
1546
1586
  }
1547
1587
  },
1548
1588
  methods: {
@@ -1654,9 +1694,9 @@ function createUnderlyingAnalyticsInstance(opts, rt, plugins = []) {
1654
1694
  },
1655
1695
  reset() {
1656
1696
  for (const key of [...Object.keys(storageCache)]) {
1657
- storage.removeItem(key);
1658
1697
  delete storageCache[key];
1659
1698
  }
1699
+ storage.reset();
1660
1700
  },
1661
1701
  removeItem(key) {
1662
1702
  if (opts.debug) {
@@ -1713,7 +1753,20 @@ function createUnderlyingAnalyticsInstance(opts, rt, plugins = []) {
1713
1753
  userState.anonymousId = id;
1714
1754
  }
1715
1755
  analytics.setAnonymousId(id);
1716
- }, group(groupId, traits, options, callback) {
1756
+ }, reset() {
1757
+ return __awaiter(this, void 0, void 0, function* () {
1758
+ if (opts.debug) {
1759
+ console.log("[JITSU DEBUG] Called reset(). Storage state", JSON.stringify(analytics.user()));
1760
+ }
1761
+ storage.reset();
1762
+ yield analytics.reset();
1763
+ this.setAnonymousId(uuid());
1764
+ if (opts.debug) {
1765
+ console.log("[JITSU DEBUG] User state after reset", JSON.stringify(analytics.user()));
1766
+ }
1767
+ });
1768
+ },
1769
+ group(groupId, traits, options, callback) {
1717
1770
  return __awaiter(this, void 0, void 0, function* () {
1718
1771
  const results = [];
1719
1772
  for (const plugin of Object.values(analytics.plugins)) {
@@ -1762,5 +1815,14 @@ function jitsuAnalytics(_opts) {
1762
1815
  // result.loaded(createUnderlyingAnalyticsInstance(opts, rt));
1763
1816
  // }
1764
1817
  }
1818
+ function uuid() {
1819
+ var u = "", m = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx", i = 0, rb = (Math.random() * 0xffffffff) | 0;
1820
+ while (i++ < 36) {
1821
+ var c = m[i - 1], r = rb & 0xf, v = c == "x" ? r : (r & 0x3) | 0x8;
1822
+ u += c == "-" || c == "4" ? c : v.toString(16);
1823
+ rb = i % 8 == 0 ? (Math.random() * 0xffffffff) | 0 : rb >> 4;
1824
+ }
1825
+ return u;
1826
+ }
1765
1827
 
1766
1828
  export { emptyAnalytics, emptyRuntime, isInBrowser, jitsuAnalytics, parseQuery, randomId, windowRuntime };
@@ -1 +1,8 @@
1
- export declare function loadScript(src: string, attributes?: Record<string, string>): Promise<HTMLScriptElement>;
1
+ export type ScriptOptions = {
2
+ attributes?: Record<string, string>;
3
+ www?: boolean;
4
+ js?: boolean;
5
+ min?: boolean;
6
+ query?: string;
7
+ };
8
+ export declare function loadScript(src: string, options?: ScriptOptions): Promise<HTMLScriptElement>;