@journium/js 1.2.3 → 1.3.0

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.
@@ -27,6 +27,8 @@ export declare class AutocaptureTracker {
27
27
  private getElementType;
28
28
  private getElementText;
29
29
  private getElementsChain;
30
+ private extractSemanticClasses;
31
+ private isHashLike;
30
32
  private isSafeInputType;
31
33
  }
32
34
  //# sourceMappingURL=AutocaptureTracker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AutocaptureTracker.d.ts","sourceRoot":"","sources":["../src/AutocaptureTracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAa,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAE/D;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,kBAAuB;IAcpE;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IA0BhD,KAAK,IAAI,IAAI;IAwBb,IAAI,IAAI,IAAI;IAcZ,OAAO,CAAC,gBAAgB;IAoBxB,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,wBAAwB;IAuBhC,OAAO,CAAC,mBAAmB;IA2B3B,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,oBAAoB;IAiE5B,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,kBAAkB;IAuC1B,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,gBAAgB;IAqFxB,OAAO,CAAC,eAAe;CAKxB"}
1
+ {"version":3,"file":"AutocaptureTracker.d.ts","sourceRoot":"","sources":["../src/AutocaptureTracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAa,kBAAkB,EAA6B,MAAM,gBAAgB,CAAC;AAE1F;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,kBAAuB;IAgBpE;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IA4BhD,KAAK,IAAI,IAAI;IAwBb,IAAI,IAAI,IAAI;IAcZ,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,qBAAqB;IAgB7B,OAAO,CAAC,qBAAqB;IAgB7B,OAAO,CAAC,wBAAwB;IAuBhC,OAAO,CAAC,mBAAmB;IA2B3B,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,oBAAoB;IAoG5B,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,kBAAkB;IAuC1B,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,gBAAgB;IAqFxB,OAAO,CAAC,sBAAsB;IA0B9B,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,eAAe;CAKxB"}
@@ -1 +1 @@
1
- {"version":3,"file":"JourniumAnalytics.d.ts","sourceRoot":"","sources":["../src/JourniumAnalytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiD,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAKrH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,wBAAwB,CAAC,CAAa;gBAElC,MAAM,EAAE,cAAc;IAqBlC,OAAO,CAAC,sBAAsB;IAsB9B,OAAO,CAAC,yBAAyB;IAiBjC,qDAAqD;IACrD,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIhE,wFAAwF;IACxF,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIxE,oEAAoE;IACpE,KAAK,IAAI,IAAI;IAIb,0EAA0E;IAC1E,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI3D;;;;OAIG;IACH,gBAAgB,IAAI,IAAI;IA6BxB,yEAAyE;IACzE,eAAe,IAAI,IAAI;IAMvB;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAoCjC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAiC3B,qEAAqE;IAC/D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,0EAA0E;IAC1E,mBAAmB;IAInB;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,GAAG,MAAM,IAAI;IAI9E,wGAAwG;IACxG,OAAO,IAAI,IAAI;CAQhB;AAED,+EAA+E;AAC/E,eAAO,MAAM,IAAI,GAAI,QAAQ,cAAc,KAAG,iBAE7C,CAAC;;mBAF2B,cAAc,KAAG,iBAAiB;;AAI/D,wBAAwB"}
1
+ {"version":3,"file":"JourniumAnalytics.d.ts","sourceRoot":"","sources":["../src/JourniumAnalytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiD,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAMrH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,wBAAwB,CAAC,CAAa;gBAElC,MAAM,EAAE,cAAc;IAqBlC,OAAO,CAAC,sBAAsB;IAsB9B,OAAO,CAAC,yBAAyB;IAiBjC,qDAAqD;IACrD,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIhE,wFAAwF;IACxF,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIxE,oEAAoE;IACpE,KAAK,IAAI,IAAI;IAIb,0EAA0E;IAC1E,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI3D;;;;OAIG;IACH,gBAAgB,IAAI,IAAI;IA6BxB,yEAAyE;IACzE,eAAe,IAAI,IAAI;IAMvB;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAoCjC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAiC3B,qEAAqE;IAC/D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,0EAA0E;IAC1E,mBAAmB;IAInB;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,GAAG,MAAM,IAAI;IAI9E,wGAAwG;IACxG,OAAO,IAAI,IAAI;CAQhB;AAED,+EAA+E;AAC/E,eAAO,MAAM,IAAI,GAAI,QAAQ,cAAc,KAAG,iBAS7C,CAAC;;mBAT2B,cAAc,KAAG,iBAAiB;;AAW/D,wBAAwB"}
@@ -1,3 +1,4 @@
1
+ import { PageviewProperties } from '@journium/core';
1
2
  import { JourniumClient } from './JourniumClient';
2
3
  export declare class PageviewTracker {
3
4
  private client;
@@ -6,7 +7,7 @@ export declare class PageviewTracker {
6
7
  private originalReplaceState;
7
8
  private popStateHandler;
8
9
  constructor(client: JourniumClient);
9
- capturePageview(customProperties?: Record<string, unknown>): void;
10
+ capturePageview(customProperties?: PageviewProperties): void;
10
11
  /**
11
12
  * Start automatic autocapture for pageviews
12
13
  * @param captureInitialPageview - whether to fire a $pageview immediately on start (default: true).
@@ -1 +1 @@
1
- {"version":3,"file":"PageviewTracker.d.ts","sourceRoot":"","sources":["../src/PageviewTracker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,iBAAiB,CAAgD;IACzE,OAAO,CAAC,oBAAoB,CAAmD;IAC/E,OAAO,CAAC,eAAe,CAA6B;gBAExC,MAAM,EAAE,cAAc;IAIlC,eAAe,CAAC,gBAAgB,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI;IAkBrE;;;;;;OAMG;IACH,yBAAyB,CAAC,sBAAsB,GAAE,OAAc,EAAE,YAAY,GAAE,OAAc,GAAG,IAAI;IA8BrG;;;OAGG;IACH,eAAe,IAAI,IAAI;CAmBxB"}
1
+ {"version":3,"file":"PageviewTracker.d.ts","sourceRoot":"","sources":["../src/PageviewTracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA4C,MAAM,gBAAgB,CAAC;AAC9F,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,iBAAiB,CAAgD;IACzE,OAAO,CAAC,oBAAoB,CAAmD;IAC/E,OAAO,CAAC,eAAe,CAA6B;gBAExC,MAAM,EAAE,cAAc;IAIlC,eAAe,CAAC,gBAAgB,GAAE,kBAAuB,GAAG,IAAI;IAkBhE;;;;;;OAMG;IACH,yBAAyB,CAAC,sBAAsB,GAAE,OAAc,EAAE,YAAY,GAAE,OAAc,GAAG,IAAI;IA8BrG;;;OAGG;IACH,eAAe,IAAI,IAAI;CAmBxB"}
package/dist/index.cjs CHANGED
@@ -1,5 +1,8 @@
1
1
  'use strict';
2
2
 
3
+ // @journium/js@1.3.0 is replaced at build time by @rollup/plugin-replace
4
+ const SDK_VERSION = '@journium/js@1.3.0';
5
+
3
6
  /**
4
7
  * uuidv7: A JavaScript implementation of UUID version 7
5
8
  *
@@ -940,6 +943,7 @@ class JourniumClient {
940
943
  Logger.setDebug((_a = this.effectiveOptions.debug) !== null && _a !== void 0 ? _a : false);
941
944
  }
942
945
  buildIdentityProperties(userProperties = {}) {
946
+ var _a, _b;
943
947
  const identity = this.identityManager.getIdentity();
944
948
  const userAgentInfo = this.identityManager.getUserAgentInfo();
945
949
  return {
@@ -950,7 +954,7 @@ class JourniumClient {
950
954
  $current_url: typeof window !== 'undefined' ? window.location.href : '',
951
955
  $pathname: typeof window !== 'undefined' ? window.location.pathname : '',
952
956
  ...userAgentInfo,
953
- $lib_version: '0.1.0', // TODO: Get from package.json
957
+ $sdk_version: (_b = (_a = this.config.options) === null || _a === void 0 ? void 0 : _a._sdkVersion) !== null && _b !== void 0 ? _b : 'unknown',
954
958
  $platform: 'web',
955
959
  ...userProperties,
956
960
  };
@@ -1091,7 +1095,7 @@ class PageviewTracker {
1091
1095
  $host: url.host,
1092
1096
  $pathname: url.pathname,
1093
1097
  $search: url.search,
1094
- $title: getPageTitle(),
1098
+ $page_title: getPageTitle(),
1095
1099
  $referrer: getReferrer(),
1096
1100
  ...customProperties,
1097
1101
  };
@@ -1167,6 +1171,8 @@ class AutocaptureTracker {
1167
1171
  ignoreClasses: ['journium-ignore'],
1168
1172
  ignoreElements: ['script', 'style', 'noscript'],
1169
1173
  captureContentText: true,
1174
+ dataAttributePrefixes: ['jrnm-'],
1175
+ dataAttributeNames: ['data-testid', 'data-track'],
1170
1176
  ...options,
1171
1177
  };
1172
1178
  }
@@ -1188,6 +1194,8 @@ class AutocaptureTracker {
1188
1194
  ignoreClasses: ['journium-ignore'],
1189
1195
  ignoreElements: ['script', 'style', 'noscript'],
1190
1196
  captureContentText: true,
1197
+ dataAttributePrefixes: ['jrnm-'],
1198
+ dataAttributeNames: ['data-testid', 'data-track'],
1191
1199
  ...options,
1192
1200
  };
1193
1201
  // Restart if it was active before
@@ -1230,10 +1238,7 @@ class AutocaptureTracker {
1230
1238
  return;
1231
1239
  }
1232
1240
  const properties = this.getElementProperties(target, 'click');
1233
- this.client.track('$autocapture', {
1234
- $event_type: 'click',
1235
- ...properties,
1236
- });
1241
+ this.client.track('$autocapture', properties);
1237
1242
  };
1238
1243
  document.addEventListener('click', clickListener, true);
1239
1244
  this.listeners.set('click', clickListener);
@@ -1245,10 +1250,7 @@ class AutocaptureTracker {
1245
1250
  return;
1246
1251
  }
1247
1252
  const properties = this.getFormProperties(target, 'submit');
1248
- this.client.track('$autocapture', {
1249
- $event_type: 'submit',
1250
- ...properties,
1251
- });
1253
+ this.client.track('$autocapture', properties);
1252
1254
  };
1253
1255
  document.addEventListener('submit', submitListener, true);
1254
1256
  this.listeners.set('submit', submitListener);
@@ -1260,10 +1262,7 @@ class AutocaptureTracker {
1260
1262
  return;
1261
1263
  }
1262
1264
  const properties = this.getInputProperties(target, 'change');
1263
- this.client.track('$autocapture', {
1264
- $event_type: 'change',
1265
- ...properties,
1266
- });
1265
+ this.client.track('$autocapture', properties);
1267
1266
  };
1268
1267
  document.addEventListener('change', changeListener, true);
1269
1268
  this.listeners.set('change', changeListener);
@@ -1316,6 +1315,7 @@ class AutocaptureTracker {
1316
1315
  }
1317
1316
  getElementProperties(element, eventType) {
1318
1317
  const properties = {
1318
+ $event_type: eventType,
1319
1319
  $element_tag: element.tagName.toLowerCase(),
1320
1320
  $element_type: this.getElementType(element),
1321
1321
  };
@@ -1325,6 +1325,7 @@ class AutocaptureTracker {
1325
1325
  }
1326
1326
  if (element.className) {
1327
1327
  properties.$element_classes = Array.from(element.classList);
1328
+ properties.$element_semantic_classes = this.extractSemanticClasses(element.classList);
1328
1329
  }
1329
1330
  // Element attributes
1330
1331
  const relevantAttributes = ['name', 'role', 'aria-label', 'data-testid', 'data-track'];
@@ -1334,6 +1335,33 @@ class AutocaptureTracker {
1334
1335
  properties[`$element_${attr.replace('-', '_')}`] = value;
1335
1336
  }
1336
1337
  });
1338
+ // Configurable data-* attribute capture
1339
+ const prefixes = this.options.dataAttributePrefixes || ['jrnm-'];
1340
+ const exactNames = new Set(this.options.dataAttributeNames || ['data-testid', 'data-track']);
1341
+ const relevantSet = new Set(relevantAttributes);
1342
+ let dataAttrCount = 0;
1343
+ for (let i = 0; i < element.attributes.length && dataAttrCount < 10; i++) {
1344
+ const attr = element.attributes.item(i);
1345
+ if (!attr || !attr.name.startsWith('data-'))
1346
+ continue;
1347
+ if (relevantSet.has(attr.name))
1348
+ continue;
1349
+ const suffix = attr.name.slice(5); // strip 'data-'
1350
+ const matchesPrefix = prefixes.some(p => suffix.startsWith(p));
1351
+ const matchesName = exactNames.has(attr.name);
1352
+ if (matchesPrefix || matchesName) {
1353
+ const propName = `$attr_${attr.name.replace(/-/g, '_')}`;
1354
+ properties[propName] = attr.value;
1355
+ dataAttrCount++;
1356
+ }
1357
+ }
1358
+ // Link href as first-class property
1359
+ if (element.tagName.toLowerCase() === 'a') {
1360
+ const href = element.getAttribute('href');
1361
+ if (href) {
1362
+ properties.$element_href = href;
1363
+ }
1364
+ }
1337
1365
  // Element content
1338
1366
  if (this.options.captureContentText) {
1339
1367
  const text = this.getElementText(element);
@@ -1363,10 +1391,13 @@ class AutocaptureTracker {
1363
1391
  properties.$parent_id = element.parentElement.id;
1364
1392
  }
1365
1393
  }
1366
- // URL information
1394
+ // URL and page context
1367
1395
  properties.$current_url = window.location.href;
1368
1396
  properties.$host = window.location.host;
1369
1397
  properties.$pathname = window.location.pathname;
1398
+ properties.$search = window.location.search;
1399
+ properties.$page_title = document.title;
1400
+ properties.$referrer = document.referrer;
1370
1401
  return properties;
1371
1402
  }
1372
1403
  getFormProperties(form, eventType) {
@@ -1515,6 +1546,38 @@ class AutocaptureTracker {
1515
1546
  ids: ids.reverse()
1516
1547
  };
1517
1548
  }
1549
+ extractSemanticClasses(classList) {
1550
+ const results = new Set();
1551
+ for (let i = 0; i < classList.length; i++) {
1552
+ const cls = classList.item(i);
1553
+ if (!cls)
1554
+ continue;
1555
+ const parts = cls.split('__');
1556
+ if (parts.length >= 3) {
1557
+ // CSS module pattern: Module__hash__name → take last segment
1558
+ const last = parts[parts.length - 1];
1559
+ if (last)
1560
+ results.add(last);
1561
+ }
1562
+ else if (parts.length === 2) {
1563
+ // 2-part __ class (e.g., Module__hash) → drop, no semantic name
1564
+ continue;
1565
+ }
1566
+ else {
1567
+ // Single-part class — keep unless it looks like a hash
1568
+ if (!this.isHashLike(cls)) {
1569
+ results.add(cls);
1570
+ }
1571
+ }
1572
+ }
1573
+ return Array.from(results);
1574
+ }
1575
+ isHashLike(value) {
1576
+ // Hash-like: alphanumeric, 5-10 chars, contains both letters and digits
1577
+ return /^[a-zA-Z0-9]{5,10}$/.test(value)
1578
+ && /[a-zA-Z]/.test(value)
1579
+ && /[0-9]/.test(value);
1580
+ }
1518
1581
  isSafeInputType(type) {
1519
1582
  // Don't capture values for sensitive input types
1520
1583
  const sensitiveTypes = ['password', 'email', 'tel', 'credit-card-number'];
@@ -1701,6 +1764,14 @@ class JourniumAnalytics {
1701
1764
  }
1702
1765
  /** Create and return a new JourniumAnalytics instance for the given config. */
1703
1766
  const init = (config) => {
1767
+ var _a;
1768
+ // Set SDK version if not already set by a framework SDK (React, Next.js, Angular)
1769
+ if (!((_a = config.options) === null || _a === void 0 ? void 0 : _a._sdkVersion)) {
1770
+ config = {
1771
+ ...config,
1772
+ options: { ...config.options, _sdkVersion: SDK_VERSION },
1773
+ };
1774
+ }
1704
1775
  return new JourniumAnalytics(config);
1705
1776
  };
1706
1777