clarity-js 0.7.4 → 0.7.6

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.
@@ -143,11 +143,11 @@ function time(event) {
143
143
  var ts = event && event.timeStamp > 0 ? event.timeStamp : performance.now();
144
144
  return Math.max(Math.round(ts - startTime), 0);
145
145
  }
146
- function stop$C() {
146
+ function stop$D() {
147
147
  startTime = 0;
148
148
  }
149
149
 
150
- var version$1 = "0.7.4";
150
+ var version$1 = "0.7.6";
151
151
 
152
152
  // tslint:disable: no-bitwise
153
153
  function hash (input, precision) {
@@ -197,6 +197,7 @@ function text$1(value, hint, privacy, mangle) {
197
197
  case 3 /* Privacy.TextImage */:
198
198
  switch (hint) {
199
199
  case "*T" /* Layout.Constant.TextTag */:
200
+ case "data-" /* Layout.Constant.DataAttribute */:
200
201
  return mangle ? mangleText(value) : mask(value);
201
202
  case "src":
202
203
  case "srcset":
@@ -215,6 +216,7 @@ function text$1(value, hint, privacy, mangle) {
215
216
  case 4 /* Privacy.Exclude */:
216
217
  switch (hint) {
217
218
  case "*T" /* Layout.Constant.TextTag */:
219
+ case "data-" /* Layout.Constant.DataAttribute */:
218
220
  return mangle ? mangleText(value) : mask(value);
219
221
  case "value":
220
222
  case "input":
@@ -224,6 +226,25 @@ function text$1(value, hint, privacy, mangle) {
224
226
  case "checksum":
225
227
  return "" /* Data.Constant.Empty */;
226
228
  }
229
+ break;
230
+ case 5 /* Privacy.Snapshot */:
231
+ switch (hint) {
232
+ case "*T" /* Layout.Constant.TextTag */:
233
+ case "data-" /* Layout.Constant.DataAttribute */:
234
+ return scrub(value);
235
+ case "value":
236
+ case "input":
237
+ case "click":
238
+ case "change":
239
+ return Array(5 /* Data.Setting.WordLength */).join("\u2022" /* Data.Constant.Mask */);
240
+ case "checksum":
241
+ case "src":
242
+ case "srcset":
243
+ case "alt":
244
+ case "title":
245
+ return "" /* Data.Constant.Empty */;
246
+ }
247
+ break;
227
248
  }
228
249
  }
229
250
  return value;
@@ -251,6 +272,10 @@ function mangleText(value) {
251
272
  function mask(value) {
252
273
  return value.replace(catchallRegex, "\u2022" /* Data.Constant.Mask */);
253
274
  }
275
+ function scrub(value) {
276
+ regex(); // Initialize regular expressions
277
+ return value.replace(letterRegex, "\u25AA" /* Data.Constant.Letter */).replace(digitRegex, "\u25AB" /* Data.Constant.Digit */);
278
+ }
254
279
  function mangleToken(value) {
255
280
  var length = ((Math.floor(value.length / 5 /* Data.Setting.WordLength */) + 1) * 5 /* Data.Setting.WordLength */);
256
281
  var output = "" /* Layout.Constant.Empty */;
@@ -259,13 +284,7 @@ function mangleToken(value) {
259
284
  }
260
285
  return output;
261
286
  }
262
- function redact(value) {
263
- var spaceIndex = -1;
264
- var gap = 0;
265
- var hasDigit = false;
266
- var hasEmail = false;
267
- var hasWhitespace = false;
268
- var array = null;
287
+ function regex() {
269
288
  // Initialize unicode regex, if supported by the browser
270
289
  // Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes
271
290
  if (unicodeRegex && digitRegex === null) {
@@ -278,6 +297,15 @@ function redact(value) {
278
297
  unicodeRegex = false;
279
298
  }
280
299
  }
300
+ }
301
+ function redact(value) {
302
+ var spaceIndex = -1;
303
+ var gap = 0;
304
+ var hasDigit = false;
305
+ var hasEmail = false;
306
+ var hasWhitespace = false;
307
+ var array = null;
308
+ regex(); // Initialize regular expressions
281
309
  for (var i = 0; i < value.length; i++) {
282
310
  var c = value.charCodeAt(i);
283
311
  hasDigit = hasDigit || (c >= 48 /* Data.Character.Zero */ && c <= 57 /* Data.Character.Nine */); // Check for digits in the current word
@@ -389,7 +417,7 @@ function compute$c() {
389
417
  encode$1(4 /* Event.Baseline */);
390
418
  }
391
419
  }
392
- function stop$B() {
420
+ function stop$C() {
393
421
  reset$q();
394
422
  }
395
423
 
@@ -400,7 +428,7 @@ var baseline = /*#__PURE__*/Object.freeze({
400
428
  reset: reset$q,
401
429
  start: start$F,
402
430
  get state () { return state$a; },
403
- stop: stop$B,
431
+ stop: stop$C,
404
432
  track: track$7,
405
433
  visibility: visibility
406
434
  });
@@ -426,7 +454,7 @@ function start$E() {
426
454
  updates$3 = {};
427
455
  count$1(5 /* Metric.InvokeCount */);
428
456
  }
429
- function stop$A() {
457
+ function stop$B() {
430
458
  data$i = {};
431
459
  updates$3 = {};
432
460
  }
@@ -504,7 +532,7 @@ function ping() {
504
532
  suspend();
505
533
  }
506
534
  }
507
- function stop$z() {
535
+ function stop$A() {
508
536
  clearTimeout(timeout$6);
509
537
  last = 0;
510
538
  interval = 0;
@@ -515,14 +543,14 @@ var ping$1 = /*#__PURE__*/Object.freeze({
515
543
  get data () { return data$h; },
516
544
  reset: reset$o,
517
545
  start: start$D,
518
- stop: stop$z
546
+ stop: stop$A
519
547
  });
520
548
 
521
549
  var data$g = null;
522
550
  function start$C() {
523
551
  data$g = {};
524
552
  }
525
- function stop$y() {
553
+ function stop$z() {
526
554
  data$g = {};
527
555
  }
528
556
  function track$6(event, time) {
@@ -555,7 +583,7 @@ var summary = /*#__PURE__*/Object.freeze({
555
583
  get data () { return data$g; },
556
584
  reset: reset$n,
557
585
  start: start$C,
558
- stop: stop$y,
586
+ stop: stop$z,
559
587
  track: track$6
560
588
  });
561
589
 
@@ -584,7 +612,7 @@ function upgrade(key) {
584
612
  encode$1(3 /* Event.Upgrade */);
585
613
  }
586
614
  }
587
- function stop$x() {
615
+ function stop$y() {
588
616
  data$f = null;
589
617
  }
590
618
 
@@ -592,7 +620,7 @@ var upgrade$1 = /*#__PURE__*/Object.freeze({
592
620
  __proto__: null,
593
621
  get data () { return data$f; },
594
622
  start: start$B,
595
- stop: stop$x,
623
+ stop: stop$y,
596
624
  upgrade: upgrade
597
625
  });
598
626
 
@@ -632,7 +660,7 @@ function compute$9() {
632
660
  function reset$m() {
633
661
  data$e = {};
634
662
  }
635
- function stop$w() {
663
+ function stop$x() {
636
664
  reset$m();
637
665
  }
638
666
 
@@ -644,7 +672,7 @@ var variable = /*#__PURE__*/Object.freeze({
644
672
  reset: reset$m,
645
673
  set: set,
646
674
  start: start$A,
647
- stop: stop$w
675
+ stop: stop$x
648
676
  });
649
677
 
650
678
  /******************************************************************************
@@ -764,13 +792,13 @@ function start$z() {
764
792
  start$E();
765
793
  modules$1.forEach(function (x) { return measure(x.start)(); });
766
794
  }
767
- function stop$v() {
795
+ function stop$w() {
768
796
  // Stop modules in the reverse order of their initialization
769
797
  // The ordering below should respect inter-module dependency.
770
798
  // E.g. if upgrade depends on upload, then upgrade needs to end before upload.
771
799
  // Similarly, if upload depends on metadata, upload needs to end before metadata.
772
800
  modules$1.slice().reverse().forEach(function (x) { return measure(x.stop)(); });
773
- stop$A();
801
+ stop$B();
774
802
  }
775
803
  function compute$8() {
776
804
  compute$9();
@@ -920,7 +948,7 @@ function start$x() {
920
948
  reset$k();
921
949
  parse$1(document, true);
922
950
  }
923
- function stop$u() {
951
+ function stop$v() {
924
952
  reset$k();
925
953
  }
926
954
  function reset$k() {
@@ -1267,7 +1295,7 @@ var dom = /*#__PURE__*/Object.freeze({
1267
1295
  parse: parse$1,
1268
1296
  sameorigin: sameorigin,
1269
1297
  start: start$x,
1270
- stop: stop$u,
1298
+ stop: stop$v,
1271
1299
  update: update$1,
1272
1300
  updates: updates$2
1273
1301
  });
@@ -1378,7 +1406,7 @@ function restart$2(timer) {
1378
1406
  tracker[id].yield = y;
1379
1407
  }
1380
1408
  }
1381
- function stop$t(timer) {
1409
+ function stop$u(timer) {
1382
1410
  var end = performance.now();
1383
1411
  var id = key(timer);
1384
1412
  var duration = end - tracker[id].start;
@@ -1398,7 +1426,7 @@ function suspend$1(timer) {
1398
1426
  case 0:
1399
1427
  id = key(timer);
1400
1428
  if (!(id in tracker)) return [3 /*break*/, 2];
1401
- stop$t(timer);
1429
+ stop$u(timer);
1402
1430
  _a = tracker[id];
1403
1431
  return [4 /*yield*/, wait()];
1404
1432
  case 1:
@@ -1541,7 +1569,7 @@ function compute$7() {
1541
1569
  encode$4(8 /* Event.Document */);
1542
1570
  }
1543
1571
  }
1544
- function end() {
1572
+ function stop$t() {
1545
1573
  reset$i();
1546
1574
  }
1547
1575
 
@@ -1676,7 +1704,7 @@ function str$1(input) {
1676
1704
  return input.toString(36);
1677
1705
  }
1678
1706
  function attribute(key, value, privacy) {
1679
- return "".concat(key, "=").concat(text$1(value, key, privacy));
1707
+ return "".concat(key, "=").concat(text$1(value, key.indexOf("data-" /* Constant.DataAttribute */) === 0 ? "data-" /* Constant.DataAttribute */ : key, privacy));
1680
1708
  }
1681
1709
 
1682
1710
  var state$8 = [];
@@ -1849,7 +1877,7 @@ function stop$r() {
1849
1877
  reset$g();
1850
1878
  }
1851
1879
 
1852
- function offset (element) {
1880
+ function offset(element) {
1853
1881
  var output = { x: 0, y: 0 };
1854
1882
  // Walk up the chain to ensure we compute offset distance correctly
1855
1883
  // In case where we may have nested IFRAMEs, we keep walking up until we get to the top most parent page
@@ -1922,6 +1950,18 @@ function handler$2(event, root, evt) {
1922
1950
  schedule$1(encode$3.bind(this, event));
1923
1951
  }
1924
1952
  }
1953
+ function link(node) {
1954
+ while (node && node !== document) {
1955
+ if (node.nodeType === Node.ELEMENT_NODE) {
1956
+ var element = node;
1957
+ if (element.tagName === "A") {
1958
+ return element;
1959
+ }
1960
+ }
1961
+ node = node.parentNode;
1962
+ }
1963
+ return null;
1964
+ }
1925
1965
  function text(element) {
1926
1966
  var output = null;
1927
1967
  if (element) {
@@ -2561,7 +2601,7 @@ function processNode (node, source) {
2561
2601
  case "HEAD":
2562
2602
  var head = { tag: tag, attributes: attributes };
2563
2603
  var l = insideFrame && ((_a = node.ownerDocument) === null || _a === void 0 ? void 0 : _a.location) ? node.ownerDocument.location : location;
2564
- head.attributes["*B" /* Constant.Base */] = l.protocol + "//" + l.hostname + l.pathname;
2604
+ head.attributes["*B" /* Constant.Base */] = l.protocol + "//" + l.host + l.pathname;
2565
2605
  dom[call](node, parent, head, source);
2566
2606
  break;
2567
2607
  case "BASE":
@@ -2571,7 +2611,7 @@ function processNode (node, source) {
2571
2611
  // We create "a" element so we can generate protocol and hostname for relative paths like "/path/"
2572
2612
  var a = document.createElement("a");
2573
2613
  a.href = attributes["href"];
2574
- baseHead.data.attributes["*B" /* Constant.Base */] = a.protocol + "//" + a.hostname + a.pathname;
2614
+ baseHead.data.attributes["*B" /* Constant.Base */] = a.protocol + "//" + a.host + a.pathname;
2575
2615
  }
2576
2616
  break;
2577
2617
  case "STYLE":
@@ -2659,7 +2699,7 @@ function getAttributes(element) {
2659
2699
 
2660
2700
  function traverse (root, timer, source) {
2661
2701
  return __awaiter(this, void 0, void 0, function () {
2662
- var queue, node, next, state, subnode;
2702
+ var queue, entry, next, state, subnode;
2663
2703
  return __generator(this, function (_a) {
2664
2704
  switch (_a.label) {
2665
2705
  case 0:
@@ -2667,8 +2707,8 @@ function traverse (root, timer, source) {
2667
2707
  _a.label = 1;
2668
2708
  case 1:
2669
2709
  if (!(queue.length > 0)) return [3 /*break*/, 4];
2670
- node = queue.shift();
2671
- next = node.firstChild;
2710
+ entry = queue.shift();
2711
+ next = entry.firstChild;
2672
2712
  while (next) {
2673
2713
  queue.push(next);
2674
2714
  next = next.nextSibling;
@@ -2683,7 +2723,7 @@ function traverse (root, timer, source) {
2683
2723
  if (state === 2 /* Task.Stop */) {
2684
2724
  return [3 /*break*/, 4];
2685
2725
  }
2686
- subnode = processNode(node, source);
2726
+ subnode = processNode(entry, source);
2687
2727
  if (subnode) {
2688
2728
  queue.push(subnode);
2689
2729
  }
@@ -2866,7 +2906,7 @@ function process$1() {
2866
2906
  _b.sent();
2867
2907
  return [3 /*break*/, 1];
2868
2908
  case 8:
2869
- stop$t(timer);
2909
+ stop$u(timer);
2870
2910
  return [2 /*return*/];
2871
2911
  }
2872
2912
  });
@@ -2998,18 +3038,6 @@ function target(evt) {
2998
3038
  active$2(); // Mark active periods of time so mutations can continue uninterrupted
2999
3039
  return node.nodeType === Node.DOCUMENT_NODE ? node.documentElement : node;
3000
3040
  }
3001
- function link(node) {
3002
- while (node && node !== document) {
3003
- if (node.nodeType === Node.ELEMENT_NODE) {
3004
- var element = node;
3005
- if (element.tagName === "A") {
3006
- return element;
3007
- }
3008
- }
3009
- node = node.parentNode;
3010
- }
3011
- return null;
3012
- }
3013
3041
  function metadata$2(node, event, text) {
3014
3042
  if (text === void 0) { text = null; }
3015
3043
  // If the node is null, we return a reserved value for id: 0. Valid assignment of id begins from 1+.
@@ -3068,7 +3096,7 @@ function encode$3 (type, ts) {
3068
3096
  entry = _c[_b];
3069
3097
  cTarget = metadata$2(entry.data.target, entry.event, entry.data.text);
3070
3098
  tokens = [entry.time, entry.event];
3071
- cHash = cTarget.hash.join("." /* Constant.Dot */);
3099
+ cHash = cTarget.hash ? cTarget.hash.join("." /* Constant.Dot */) : "" /* Constant.Empty */;
3072
3100
  tokens.push(cTarget.id);
3073
3101
  tokens.push(entry.data.x);
3074
3102
  tokens.push(entry.data.y);
@@ -3288,6 +3316,7 @@ function queue(tokens, transmit) {
3288
3316
  discoverBytes += event_1.length;
3289
3317
  case 37 /* Event.Box */:
3290
3318
  case 6 /* Event.Mutation */:
3319
+ case 43 /* Event.Snapshot */:
3291
3320
  playbackBytes += event_1.length;
3292
3321
  playback.push(event_1);
3293
3322
  break;
@@ -3383,7 +3412,7 @@ function send(payload, zipped, sequence, beacon) {
3383
3412
  if (beacon === void 0) { beacon = false; }
3384
3413
  // Upload data if a valid URL is defined in the config
3385
3414
  if (typeof config$1.upload === "string" /* Constant.String */) {
3386
- var url = config$1.upload;
3415
+ var url_1 = config$1.upload;
3387
3416
  var dispatched = false;
3388
3417
  // If it's the last payload, attempt to upload using sendBeacon first.
3389
3418
  // The advantage to using sendBeacon is that browser can decide to upload asynchronously, improving chances of success
@@ -3392,7 +3421,7 @@ function send(payload, zipped, sequence, beacon) {
3392
3421
  if (beacon && "sendBeacon" in navigator) {
3393
3422
  try {
3394
3423
  // Navigator needs to be bound to sendBeacon before it is used to avoid errors in some browsers
3395
- dispatched = navigator.sendBeacon.bind(navigator)(url, payload);
3424
+ dispatched = navigator.sendBeacon.bind(navigator)(url_1, payload);
3396
3425
  if (dispatched) {
3397
3426
  done(sequence);
3398
3427
  }
@@ -3414,7 +3443,9 @@ function send(payload, zipped, sequence, beacon) {
3414
3443
  transit[sequence] = { data: payload, attempts: 1 };
3415
3444
  }
3416
3445
  var xhr_1 = new XMLHttpRequest();
3417
- xhr_1.open("POST", url);
3446
+ xhr_1.open("POST", url_1, true);
3447
+ xhr_1.timeout = 15000 /* Setting.UploadTimeout */;
3448
+ xhr_1.ontimeout = function () { report(new Error("".concat("Timeout" /* Constant.Timeout */, " : ").concat(url_1))); };
3418
3449
  if (sequence !== null) {
3419
3450
  xhr_1.onreadystatechange = function () { measure(check$3)(xhr_1, sequence); };
3420
3451
  }
@@ -4259,7 +4290,7 @@ function report(e) {
4259
4290
  // Using POST request instead of a GET request (img-src) to not violate existing CSP rules
4260
4291
  // Since, Clarity already uses XHR to upload data, we stick with similar POST mechanism for reporting too
4261
4292
  var xhr = new XMLHttpRequest();
4262
- xhr.open("POST", url);
4293
+ xhr.open("POST", url, true);
4263
4294
  xhr.send(JSON.stringify(payload));
4264
4295
  history$1.push(e.message);
4265
4296
  }
@@ -4381,7 +4412,7 @@ function stop$5() {
4381
4412
  reset$2();
4382
4413
  reset$1();
4383
4414
  reset$j();
4384
- stop$C();
4415
+ stop$D();
4385
4416
  status = false;
4386
4417
  }
4387
4418
  function active() {
@@ -4470,7 +4501,7 @@ function discover() {
4470
4501
  return [4 /*yield*/, encode$4(5 /* Event.Discover */, timer, ts)];
4471
4502
  case 2:
4472
4503
  _a.sent();
4473
- stop$t(timer);
4504
+ stop$u(timer);
4474
4505
  return [2 /*return*/];
4475
4506
  }
4476
4507
  });
@@ -4488,9 +4519,9 @@ function start$3() {
4488
4519
  }
4489
4520
  function stop$3() {
4490
4521
  stop$s();
4491
- stop$u();
4522
+ stop$v();
4492
4523
  stop$f();
4493
- end();
4524
+ stop$t();
4494
4525
  }
4495
4526
 
4496
4527
  var layout = /*#__PURE__*/Object.freeze({
@@ -4659,7 +4690,7 @@ function stop$2() {
4659
4690
  function host(url) {
4660
4691
  var a = document.createElement("a");
4661
4692
  a.href = url;
4662
- return a.hostname;
4693
+ return a.host;
4663
4694
  }
4664
4695
 
4665
4696
  function start$1() {
@@ -4715,7 +4746,7 @@ function stop() {
4715
4746
  if (active()) {
4716
4747
  // Stop modules in the reverse order of their initialization and start queuing up items again
4717
4748
  modules.slice().reverse().forEach(function (x) { return measure(x.stop)(); });
4718
- stop$v();
4749
+ stop$w();
4719
4750
  stop$5();
4720
4751
  setup();
4721
4752
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clarity-js",
3
- "version": "0.7.4",
3
+ "version": "0.7.6",
4
4
  "description": "An analytics library that uses web page interactions to generate aggregated insights",
5
5
  "author": "Microsoft Corp.",
6
6
  "license": "MIT",
package/rollup.config.ts CHANGED
@@ -46,11 +46,11 @@ export default [
46
46
  plugins: [
47
47
  alias({
48
48
  entries: [
49
- { find: '@src/interaction/change', replacement: '@src/core/blank' },
50
- { find: '@src/interaction/clipboard', replacement: '@src/core/blank' },
51
- { find: '@src/interaction/input', replacement: '@src/core/blank' },
52
- { find: '@src/interaction/pointer', replacement: '@src/core/blank' },
53
- { find: '@src/interaction/selection', replacement: '@src/core/blank' }
49
+ { find: '@src/layout/document', replacement: '@src/layout/document' },
50
+ { find: '@src/layout/encode', replacement: '@src/insight/encode' },
51
+ { find: /@src\/interaction\/(change|clipboard|input|pointer|selection)/, replacement: '@src/insight/blank' },
52
+ { find: /@src\/layout.*/, replacement: '@src/insight/snapshot' },
53
+ { find: /@src\/performance.*/, replacement: '@src/insight/blank' }
54
54
  ]
55
55
  }),
56
56
  resolve(),
@@ -19,7 +19,7 @@ export function report(e: Error): Error {
19
19
  // Using POST request instead of a GET request (img-src) to not violate existing CSP rules
20
20
  // Since, Clarity already uses XHR to upload data, we stick with similar POST mechanism for reporting too
21
21
  let xhr = new XMLHttpRequest();
22
- xhr.open("POST", url);
22
+ xhr.open("POST", url, true);
23
23
  xhr.send(JSON.stringify(payload));
24
24
  history.push(e.message);
25
25
  }
package/src/core/scrub.ts CHANGED
@@ -30,6 +30,7 @@ export function text(value: string, hint: string, privacy: Privacy, mangle: bool
30
30
  case Privacy.TextImage:
31
31
  switch (hint) {
32
32
  case Layout.Constant.TextTag:
33
+ case Layout.Constant.DataAttribute:
33
34
  return mangle ? mangleText(value) : mask(value);
34
35
  case "src":
35
36
  case "srcset":
@@ -48,6 +49,7 @@ export function text(value: string, hint: string, privacy: Privacy, mangle: bool
48
49
  case Privacy.Exclude:
49
50
  switch (hint) {
50
51
  case Layout.Constant.TextTag:
52
+ case Layout.Constant.DataAttribute:
51
53
  return mangle ? mangleText(value) : mask(value);
52
54
  case "value":
53
55
  case "input":
@@ -57,6 +59,25 @@ export function text(value: string, hint: string, privacy: Privacy, mangle: bool
57
59
  case "checksum":
58
60
  return Data.Constant.Empty;
59
61
  }
62
+ break;
63
+ case Privacy.Snapshot:
64
+ switch (hint) {
65
+ case Layout.Constant.TextTag:
66
+ case Layout.Constant.DataAttribute:
67
+ return scrub(value);
68
+ case "value":
69
+ case "input":
70
+ case "click":
71
+ case "change":
72
+ return Array(Data.Setting.WordLength).join(Data.Constant.Mask);
73
+ case "checksum":
74
+ case "src":
75
+ case "srcset":
76
+ case "alt":
77
+ case "title":
78
+ return Data.Constant.Empty;
79
+ }
80
+ break;
60
81
  }
61
82
  }
62
83
  return value;
@@ -83,11 +104,16 @@ function mangleText(value: string): string {
83
104
  }
84
105
  return value;
85
106
  }
86
-
107
+
87
108
  function mask(value: string): string {
88
109
  return value.replace(catchallRegex, Data.Constant.Mask);
89
110
  }
90
111
 
112
+ function scrub(value: string): string {
113
+ regex(); // Initialize regular expressions
114
+ return value.replace(letterRegex, Data.Constant.Letter).replace(digitRegex, Data.Constant.Digit);
115
+ }
116
+
91
117
  function mangleToken(value: string): string {
92
118
  let length = ((Math.floor(value.length / Data.Setting.WordLength) + 1) * Data.Setting.WordLength);
93
119
  let output: string = Layout.Constant.Empty;
@@ -97,14 +123,7 @@ function mangleToken(value: string): string {
97
123
  return output;
98
124
  }
99
125
 
100
- function redact(value: string): string {
101
- let spaceIndex = -1;
102
- let gap = 0;
103
- let hasDigit = false;
104
- let hasEmail = false;
105
- let hasWhitespace = false;
106
- let array = null;
107
-
126
+ function regex(): void {
108
127
  // Initialize unicode regex, if supported by the browser
109
128
  // Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes
110
129
  if (unicodeRegex && digitRegex === null) {
@@ -114,6 +133,17 @@ function redact(value: string): string {
114
133
  currencyRegex = new RegExp("\\p{Sc}", "gu");
115
134
  } catch { unicodeRegex = false; }
116
135
  }
136
+ }
137
+
138
+ function redact(value: string): string {
139
+ let spaceIndex = -1;
140
+ let gap = 0;
141
+ let hasDigit = false;
142
+ let hasEmail = false;
143
+ let hasWhitespace = false;
144
+ let array = null;
145
+
146
+ regex(); // Initialize regular expressions
117
147
 
118
148
  for (let i = 0; i < value.length; i++) {
119
149
  let c = value.charCodeAt(i);
@@ -1,2 +1,2 @@
1
- let version = "0.7.4";
1
+ let version = "0.7.6";
2
2
  export default version;
@@ -16,6 +16,7 @@ import * as ping from "@src/data/ping";
16
16
  import * as timeline from "@src/interaction/timeline";
17
17
  import * as region from "@src/layout/region";
18
18
  import * as extract from "@src/data/extract";
19
+ import { report } from "@src/core/report";
19
20
 
20
21
  let discoverBytes: number = 0;
21
22
  let playbackBytes: number = 0;
@@ -48,7 +49,8 @@ export function queue(tokens: Token[], transmit: boolean = true): void {
48
49
  case Event.Discover:
49
50
  discoverBytes += event.length;
50
51
  case Event.Box:
51
- case Event.Mutation:
52
+ case Event.Mutation:
53
+ case Event.Snapshot:
52
54
  playbackBytes += event.length;
53
55
  playback.push(event);
54
56
  break;
@@ -169,7 +171,9 @@ function send(payload: string, zipped: Uint8Array, sequence: number, beacon: boo
169
171
  // Not all browsers support compression API and the support for it in supported browsers is still experimental
170
172
  if (sequence in transit) { transit[sequence].attempts++; } else { transit[sequence] = { data: payload, attempts: 1 }; }
171
173
  let xhr = new XMLHttpRequest();
172
- xhr.open("POST", url);
174
+ xhr.open("POST", url, true);
175
+ xhr.timeout = Setting.UploadTimeout;
176
+ xhr.ontimeout = () => { report(new Error(`${Constant.Timeout} : ${url}`)) };
173
177
  if (sequence !== null) { xhr.onreadystatechange = (): void => { measure(check)(xhr, sequence); }; }
174
178
  xhr.withCredentials = true;
175
179
  if (zipped) {
@@ -4,6 +4,8 @@ export let data = null;
4
4
  /* Intentionally blank module with empty code */
5
5
 
6
6
  export function start(): void {}
7
- export function observe(): void {}
8
7
  export function reset(): void {}
9
8
  export function stop(): void {}
9
+ export function log(): void {}
10
+ export function observe(): void {}
11
+ export function compute(): void {}