@openreplay/tracker 14.0.14 → 15.0.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.
Files changed (66) hide show
  1. package/dist/cjs/common/messages.gen.d.ts +26 -7
  2. package/dist/cjs/index.js +9057 -68
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/cjs/main/app/messages.gen.d.ts +5 -2
  5. package/dist/cjs/main/app/nodes/index.d.ts +1 -1
  6. package/dist/cjs/main/app/sanitizer.d.ts +20 -0
  7. package/dist/cjs/main/app/session.d.ts +2 -2
  8. package/dist/cjs/main/modules/attributeSender.d.ts +7 -2
  9. package/dist/cjs/main/modules/input.d.ts +18 -1
  10. package/dist/lib/common/messages.gen.d.ts +26 -7
  11. package/dist/lib/index.js +113 -63
  12. package/dist/lib/index.js.map +1 -1
  13. package/dist/lib/main/app/messages.gen.d.ts +5 -2
  14. package/dist/lib/main/app/nodes/index.d.ts +1 -1
  15. package/dist/lib/main/app/sanitizer.d.ts +20 -0
  16. package/dist/lib/main/app/session.d.ts +2 -2
  17. package/dist/lib/main/modules/attributeSender.d.ts +7 -2
  18. package/dist/lib/main/modules/input.d.ts +18 -1
  19. package/dist/types/common/interaction.d.ts +37 -0
  20. package/dist/types/common/messages.gen.d.ts +567 -0
  21. package/dist/types/main/app/canvas.d.ts +28 -0
  22. package/dist/types/main/app/guards.d.ts +22 -0
  23. package/dist/types/main/app/index.d.ts +322 -0
  24. package/dist/types/main/app/logger.d.ts +17 -0
  25. package/dist/types/main/app/messages.gen.d.ts +81 -0
  26. package/dist/types/main/app/nodes/index.d.ts +31 -0
  27. package/dist/types/main/app/nodes/maintainer.d.ts +28 -0
  28. package/dist/types/main/app/observer/iframe_observer.d.ts +6 -0
  29. package/dist/types/main/app/observer/iframe_offsets.d.ts +8 -0
  30. package/dist/types/main/app/observer/observer.d.ts +29 -0
  31. package/dist/types/main/app/observer/shadow_root_observer.d.ts +4 -0
  32. package/dist/types/main/app/observer/top_observer.d.ts +31 -0
  33. package/dist/types/main/app/sanitizer.d.ts +48 -0
  34. package/dist/types/main/app/session.d.ts +57 -0
  35. package/dist/types/main/app/ticker.d.ts +18 -0
  36. package/dist/types/main/index.d.ts +111 -0
  37. package/dist/types/main/modules/attributeSender.d.ts +23 -0
  38. package/dist/types/main/modules/axiosSpy.d.ts +54 -0
  39. package/dist/types/main/modules/conditionsManager.d.ts +84 -0
  40. package/dist/types/main/modules/connection.d.ts +2 -0
  41. package/dist/types/main/modules/console.d.ts +6 -0
  42. package/dist/types/main/modules/constructedStyleSheets.d.ts +4 -0
  43. package/dist/types/main/modules/cssrules.d.ts +2 -0
  44. package/dist/types/main/modules/exception.d.ts +16 -0
  45. package/dist/types/main/modules/featureFlags.d.ts +25 -0
  46. package/dist/types/main/modules/focus.d.ts +2 -0
  47. package/dist/types/main/modules/fonts.d.ts +2 -0
  48. package/dist/types/main/modules/img.d.ts +2 -0
  49. package/dist/types/main/modules/input.d.ts +34 -0
  50. package/dist/types/main/modules/mouse.d.ts +31 -0
  51. package/dist/types/main/modules/network.d.ts +31 -0
  52. package/dist/types/main/modules/performance.d.ts +7 -0
  53. package/dist/types/main/modules/scroll.d.ts +2 -0
  54. package/dist/types/main/modules/selection.d.ts +7 -0
  55. package/dist/types/main/modules/tabs.d.ts +2 -0
  56. package/dist/types/main/modules/tagWatcher.d.ts +25 -0
  57. package/dist/types/main/modules/timing.d.ts +8 -0
  58. package/dist/types/main/modules/userTesting/SignalManager.d.ts +29 -0
  59. package/dist/types/main/modules/userTesting/dnd.d.ts +1 -0
  60. package/dist/types/main/modules/userTesting/index.d.ts +45 -0
  61. package/dist/types/main/modules/userTesting/recorder.d.ts +24 -0
  62. package/dist/types/main/modules/userTesting/styles.d.ts +277 -0
  63. package/dist/types/main/modules/userTesting/utils.d.ts +9 -0
  64. package/dist/types/main/modules/viewport.d.ts +2 -0
  65. package/dist/types/main/utils.d.ts +30 -0
  66. package/package.json +26 -20
@@ -37,8 +37,10 @@ export declare function MobX(type: string, payload: string): Messages.MobX;
37
37
  export declare function NgRx(action: string, state: string, duration: number): Messages.NgRx;
38
38
  export declare function GraphQLDeprecated(operationKind: string, operationName: string, variables: string, response: string, duration: number): Messages.GraphQLDeprecated;
39
39
  export declare function PerformanceTrack(frames: number, ticks: number, totalJSHeapSize: number, usedJSHeapSize: number): Messages.PerformanceTrack;
40
- export declare function StringDict(key: number, value: string): Messages.StringDict;
41
- export declare function SetNodeAttributeDict(id: number, nameKey: number, valueKey: number): Messages.SetNodeAttributeDict;
40
+ export declare function StringDictDeprecated(key: number, value: string): Messages.StringDictDeprecated;
41
+ export declare function SetNodeAttributeDictDeprecated(id: number, nameKey: number, valueKey: number): Messages.SetNodeAttributeDictDeprecated;
42
+ export declare function StringDict(key: string, value: string): Messages.StringDict;
43
+ export declare function SetNodeAttributeDict(id: number, name: string, value: string): Messages.SetNodeAttributeDict;
42
44
  export declare function ResourceTimingDeprecated(timestamp: number, duration: number, ttfb: number, headerSize: number, encodedBodySize: number, decodedBodySize: number, url: string, initiator: string): Messages.ResourceTimingDeprecated;
43
45
  export declare function ConnectionInformation(downlink: number, type: string): Messages.ConnectionInformation;
44
46
  export declare function SetPageVisibility(hidden: boolean): Messages.SetPageVisibility;
@@ -76,3 +78,4 @@ export declare function TagTrigger(tagId: number): Messages.TagTrigger;
76
78
  export declare function Redux(action: string, state: string, duration: number, actionTime: number): Messages.Redux;
77
79
  export declare function SetPageLocation(url: string, referrer: string, navigationStart: number, documentTitle: string): Messages.SetPageLocation;
78
80
  export declare function GraphQL(operationKind: string, operationName: string, variables: string, response: string, duration: number): Messages.GraphQL;
81
+ export declare function WebVitals(name: string, value: string): Messages.WebVitals;
@@ -16,7 +16,7 @@ export default class Nodes {
16
16
  private readonly maintainer;
17
17
  constructor(params: NodesOptions);
18
18
  syntheticMode(frameOrder: number): void;
19
- attachNodeCallback(nodeCallback: NodeCallback): number;
19
+ attachNodeCallback: (nodeCallback: NodeCallback) => number;
20
20
  scanTree: (cb: (node: Node | void) => void) => void;
21
21
  attachNodeListener: (node: Node, type: string, listener: EventListener, useCapture?: boolean) => void;
22
22
  registerNode(node: Node): [/*id:*/ number, /*isNew:*/ boolean];
@@ -5,8 +5,28 @@ export declare enum SanitizeLevel {
5
5
  Hidden = 2
6
6
  }
7
7
  export interface Options {
8
+ /**
9
+ * Sanitize emails in text DOM nodes
10
+ *
11
+ * (for inputs, look for obscureInputEmails)
12
+ * */
8
13
  obscureTextEmails: boolean;
14
+ /**
15
+ * Sanitize emails in text DOM nodes
16
+ *
17
+ * (for inputs, look for obscureInputNumbers)
18
+ * */
9
19
  obscureTextNumbers: boolean;
20
+ /**
21
+ * Sanitize the DOM node based on the returned level
22
+ * (Plain = 0, Obscured = 1, Hidden = 2)
23
+ *
24
+ * higher security levels will override other settings or data-params.
25
+ *
26
+ * @param node - the DOM node to sanitize
27
+ * @returns the level of sanitization to apply
28
+ *
29
+ * */
10
30
  domSanitizer?: (node: Element) => SanitizeLevel;
11
31
  }
12
32
  export declare const stringWiper: (input: string) => string;
@@ -42,8 +42,8 @@ export default class Session {
42
42
  setMetadata(key: string, value: string): void;
43
43
  setUserID(userID: string): void;
44
44
  setUserInfo(userInfo: UserInfo): void;
45
- private getPageNumber;
46
- incPageNo(): number;
45
+ getPageNumber: () => number | undefined;
46
+ incPageNo: () => number;
47
47
  getSessionToken(): string | undefined;
48
48
  setSessionToken(token: string): void;
49
49
  applySessionHash(hash: string): void;
@@ -1,8 +1,13 @@
1
1
  import App from '../app/index.js';
2
2
  export declare class StringDictionary {
3
+ private readonly getPageNo;
3
4
  private idx;
5
+ /** backwards dictionary of
6
+ * [repeated str:key]
7
+ * */
4
8
  private backDict;
5
- getKey(str: string): [number, boolean];
9
+ constructor(getPageNo: () => number | undefined);
10
+ getKey: (str: string) => [string, boolean];
6
11
  }
7
12
  export default class AttributeSender {
8
13
  private dict;
@@ -12,7 +17,7 @@ export default class AttributeSender {
12
17
  app: App;
13
18
  isDictDisabled: boolean;
14
19
  });
15
- sendSetAttribute(id: number, name: string, value: string): void;
20
+ sendSetAttribute: (id: number, name: string, value: string) => void;
16
21
  private applyDict;
17
22
  clear(): void;
18
23
  }
@@ -8,10 +8,27 @@ export declare const InputMode: {
8
8
  };
9
9
  export type InputModeT = (typeof InputMode)[keyof typeof InputMode];
10
10
  export interface Options {
11
+ /**
12
+ * Sanitize numbers from DOM input nodes.
13
+ *
14
+ * (for plain text nodes, look for obscureTextNumbers)
15
+ * */
11
16
  obscureInputNumbers: boolean;
17
+ /**
18
+ * Sanitize emails from DOM input nodes.
19
+ *
20
+ * (for plain text nodes, look for obscureTextEmails)
21
+ * */
12
22
  obscureInputEmails: boolean;
13
- defaultInputMode: InputModeT;
23
+ /**
24
+ * Sanitize dates from DOM input nodes.
25
+ * */
14
26
  obscureInputDates: boolean;
27
+ /**
28
+ * Default input mode for all input nodes. Higher security level
29
+ * will override other settings.
30
+ * */
31
+ defaultInputMode: InputModeT;
15
32
  }
16
33
  export default function (app: App, opts: Partial<Options>): void;
17
34
  export {};
@@ -36,8 +36,10 @@ export declare const enum Type {
36
36
  NgRx = 47,
37
37
  GraphQLDeprecated = 48,
38
38
  PerformanceTrack = 49,
39
- StringDict = 50,
40
- SetNodeAttributeDict = 51,
39
+ StringDictDeprecated = 50,
40
+ SetNodeAttributeDictDeprecated = 51,
41
+ StringDict = 43,
42
+ SetNodeAttributeDict = 52,
41
43
  ResourceTimingDeprecated = 53,
42
44
  ConnectionInformation = 54,
43
45
  SetPageVisibility = 55,
@@ -74,7 +76,8 @@ export declare const enum Type {
74
76
  TagTrigger = 120,
75
77
  Redux = 121,
76
78
  SetPageLocation = 122,
77
- GraphQL = 123
79
+ GraphQL = 123,
80
+ WebVitals = 124
78
81
  }
79
82
  export type Timestamp = [
80
83
  Type.Timestamp,
@@ -292,16 +295,27 @@ export type PerformanceTrack = [
292
295
  number,
293
296
  number
294
297
  ];
298
+ export type StringDictDeprecated = [
299
+ Type.StringDictDeprecated,
300
+ number,
301
+ string
302
+ ];
303
+ export type SetNodeAttributeDictDeprecated = [
304
+ Type.SetNodeAttributeDictDeprecated,
305
+ number,
306
+ number,
307
+ number
308
+ ];
295
309
  export type StringDict = [
296
310
  Type.StringDict,
297
- number,
311
+ string,
298
312
  string
299
313
  ];
300
314
  export type SetNodeAttributeDict = [
301
315
  Type.SetNodeAttributeDict,
302
316
  number,
303
- number,
304
- number
317
+ string,
318
+ string
305
319
  ];
306
320
  export type ResourceTimingDeprecated = [
307
321
  Type.ResourceTimingDeprecated,
@@ -544,5 +558,10 @@ export type GraphQL = [
544
558
  string,
545
559
  number
546
560
  ];
547
- type Message = Timestamp | SetPageLocationDeprecated | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequestDeprecated | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | ReduxDeprecated | Vuex | MobX | NgRx | GraphQLDeprecated | PerformanceTrack | StringDict | SetNodeAttributeDict | ResourceTimingDeprecated | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | MouseClickDeprecated | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage | NetworkRequest | WSChannel | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTiming | TabChange | TabData | CanvasNode | TagTrigger | Redux | SetPageLocation | GraphQL;
561
+ export type WebVitals = [
562
+ Type.WebVitals,
563
+ string,
564
+ string
565
+ ];
566
+ type Message = Timestamp | SetPageLocationDeprecated | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequestDeprecated | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | ReduxDeprecated | Vuex | MobX | NgRx | GraphQLDeprecated | PerformanceTrack | StringDictDeprecated | SetNodeAttributeDictDeprecated | StringDict | SetNodeAttributeDict | ResourceTimingDeprecated | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | MouseClickDeprecated | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage | NetworkRequest | WSChannel | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTiming | TabChange | TabData | CanvasNode | TagTrigger | Redux | SetPageLocation | GraphQL | WebVitals;
548
567
  export default Message;
package/dist/lib/index.js CHANGED
@@ -58,10 +58,10 @@ var _b = freb(fdeb, 0), revfd = _b.r;
58
58
  var rev = new u16(32768);
59
59
  for (var i = 0; i < 32768; ++i) {
60
60
  // reverse table algorithm from SO
61
- var x = ((i & 0xAAAA) >> 1) | ((i & 0x5555) << 1);
62
- x = ((x & 0xCCCC) >> 2) | ((x & 0x3333) << 2);
63
- x = ((x & 0xF0F0) >> 4) | ((x & 0x0F0F) << 4);
64
- rev[i] = (((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8)) >> 1;
61
+ var x$1 = ((i & 0xAAAA) >> 1) | ((i & 0x5555) << 1);
62
+ x$1 = ((x$1 & 0xCCCC) >> 2) | ((x$1 & 0x3333) << 2);
63
+ x$1 = ((x$1 & 0xF0F0) >> 4) | ((x$1 & 0x0F0F) << 4);
64
+ rev[i] = (((x$1 & 0xFF00) >> 8) | ((x$1 & 0x00FF) << 8)) >> 1;
65
65
  }
66
66
  // create huffman tree from u8 "map": index -> code length for code index
67
67
  // mb (max bits) must be at most 15
@@ -712,49 +712,54 @@ try {
712
712
  catch (e) { }
713
713
 
714
714
  class StringDictionary {
715
- constructor() {
715
+ constructor(getPageNo) {
716
+ this.getPageNo = getPageNo;
716
717
  this.idx = 1;
718
+ /** backwards dictionary of
719
+ * [repeated str:key]
720
+ * */
717
721
  this.backDict = {};
718
- }
719
- getKey(str) {
720
- let isNew = false;
721
- if (!this.backDict[str]) {
722
- isNew = true;
723
- this.backDict[str] = this.idx++;
724
- }
725
- return [this.backDict[str], isNew];
722
+ this.getKey = (str) => {
723
+ let isNew = false;
724
+ if (!this.backDict[str]) {
725
+ isNew = true;
726
+ this.backDict[str] = `${this.getPageNo() ?? 0}_${this.idx}`;
727
+ this.idx += 1;
728
+ }
729
+ return [this.backDict[str], isNew];
730
+ };
726
731
  }
727
732
  }
728
733
  class AttributeSender {
729
734
  constructor(options) {
730
- this.dict = new StringDictionary();
735
+ this.sendSetAttribute = (id, name, value) => {
736
+ if (this.isDictDisabled) {
737
+ const msg = [12 /* Type.SetNodeAttribute */, id, name, value];
738
+ return this.app.send(msg);
739
+ }
740
+ else {
741
+ const message = [
742
+ 52 /* Type.SetNodeAttributeDict */,
743
+ id,
744
+ this.applyDict(name),
745
+ this.applyDict(value),
746
+ ];
747
+ return this.app.send(message);
748
+ }
749
+ };
731
750
  this.app = options.app;
732
751
  this.isDictDisabled = options.isDictDisabled;
733
- }
734
- sendSetAttribute(id, name, value) {
735
- if (this.isDictDisabled) {
736
- const msg = [12 /* Type.SetNodeAttribute */, id, name, value];
737
- return this.app.send(msg);
738
- }
739
- else {
740
- const message = [
741
- 51 /* Type.SetNodeAttributeDict */,
742
- id,
743
- this.applyDict(name),
744
- this.applyDict(value),
745
- ];
746
- return this.app.send(message);
747
- }
752
+ this.dict = new StringDictionary(this.app.session.getPageNumber);
748
753
  }
749
754
  applyDict(str) {
750
755
  const [key, isNew] = this.dict.getKey(str);
751
756
  if (isNew) {
752
- this.app.send([50 /* Type.StringDict */, key, str]);
757
+ this.app.send([43 /* Type.StringDict */, key, str]);
753
758
  }
754
759
  return key;
755
760
  }
756
761
  clear() {
757
- this.dict = new StringDictionary();
762
+ this.dict = new StringDictionary(this.app.session.getPageNumber);
758
763
  }
759
764
  }
760
765
 
@@ -1743,21 +1748,36 @@ function PerformanceTrack(frames, ticks, totalJSHeapSize, usedJSHeapSize) {
1743
1748
  usedJSHeapSize,
1744
1749
  ];
1745
1750
  }
1746
- function StringDict(key, value) {
1751
+ function StringDictDeprecated(key, value) {
1747
1752
  return [
1748
- 50 /* Messages.Type.StringDict */,
1753
+ 50 /* Messages.Type.StringDictDeprecated */,
1749
1754
  key,
1750
1755
  value,
1751
1756
  ];
1752
1757
  }
1753
- function SetNodeAttributeDict(id, nameKey, valueKey) {
1758
+ function SetNodeAttributeDictDeprecated(id, nameKey, valueKey) {
1754
1759
  return [
1755
- 51 /* Messages.Type.SetNodeAttributeDict */,
1760
+ 51 /* Messages.Type.SetNodeAttributeDictDeprecated */,
1756
1761
  id,
1757
1762
  nameKey,
1758
1763
  valueKey,
1759
1764
  ];
1760
1765
  }
1766
+ function StringDict(key, value) {
1767
+ return [
1768
+ 43 /* Messages.Type.StringDict */,
1769
+ key,
1770
+ value,
1771
+ ];
1772
+ }
1773
+ function SetNodeAttributeDict(id, name, value) {
1774
+ return [
1775
+ 52 /* Messages.Type.SetNodeAttributeDict */,
1776
+ id,
1777
+ name,
1778
+ value,
1779
+ ];
1780
+ }
1761
1781
  function ResourceTimingDeprecated(timestamp, duration, ttfb, headerSize, encodedBodySize, decodedBodySize, url, initiator) {
1762
1782
  return [
1763
1783
  53 /* Messages.Type.ResourceTimingDeprecated */,
@@ -2073,6 +2093,13 @@ function GraphQL(operationKind, operationName, variables, response, duration) {
2073
2093
  duration,
2074
2094
  ];
2075
2095
  }
2096
+ function WebVitals(name, value) {
2097
+ return [
2098
+ 124 /* Messages.Type.WebVitals */,
2099
+ name,
2100
+ value,
2101
+ ];
2102
+ }
2076
2103
 
2077
2104
  var _Messages = /*#__PURE__*/Object.freeze({
2078
2105
  __proto__: null,
@@ -2130,6 +2157,7 @@ var _Messages = /*#__PURE__*/Object.freeze({
2130
2157
  SetInputValue: SetInputValue,
2131
2158
  SetNodeAttribute: SetNodeAttribute,
2132
2159
  SetNodeAttributeDict: SetNodeAttributeDict,
2160
+ SetNodeAttributeDictDeprecated: SetNodeAttributeDictDeprecated,
2133
2161
  SetNodeAttributeURLBased: SetNodeAttributeURLBased,
2134
2162
  SetNodeData: SetNodeData,
2135
2163
  SetNodeFocus: SetNodeFocus,
@@ -2141,6 +2169,7 @@ var _Messages = /*#__PURE__*/Object.freeze({
2141
2169
  SetViewportSize: SetViewportSize,
2142
2170
  StateAction: StateAction,
2143
2171
  StringDict: StringDict,
2172
+ StringDictDeprecated: StringDictDeprecated,
2144
2173
  TabChange: TabChange,
2145
2174
  TabData: TabData,
2146
2175
  TagTrigger: TagTrigger,
@@ -2151,6 +2180,7 @@ var _Messages = /*#__PURE__*/Object.freeze({
2151
2180
  UserID: UserID,
2152
2181
  Vuex: Vuex,
2153
2182
  WSChannel: WSChannel,
2183
+ WebVitals: WebVitals,
2154
2184
  Zustand: Zustand
2155
2185
  });
2156
2186
 
@@ -3594,6 +3624,10 @@ class Nodes {
3594
3624
  this.nodeCallbacks = [];
3595
3625
  this.elementListeners = new Map();
3596
3626
  this.nextNodeId = 0;
3627
+ // Attached once per Tracker instance
3628
+ this.attachNodeCallback = (nodeCallback) => {
3629
+ return this.nodeCallbacks.push(nodeCallback);
3630
+ };
3597
3631
  this.scanTree = (cb) => {
3598
3632
  this.nodes.forEach((node) => (node ? cb(node) : undefined));
3599
3633
  };
@@ -3641,10 +3675,6 @@ class Nodes {
3641
3675
  }
3642
3676
  this.nextNodeId = nextFrameId;
3643
3677
  }
3644
- // Attached once per Tracker instance
3645
- attachNodeCallback(nodeCallback) {
3646
- return this.nodeCallbacks.push(nodeCallback);
3647
- }
3648
3678
  registerNode(node) {
3649
3679
  let id = node[this.node_id];
3650
3680
  const isNew = id === undefined;
@@ -3747,6 +3777,7 @@ class Observer {
3747
3777
  }
3748
3778
  if (type === 'childList') {
3749
3779
  for (let i = 0; i < mutation.removedNodes.length; i++) {
3780
+ // Should be the same as bindTree(mutation.removedNodes[i]), but logic needs to be be untied
3750
3781
  if (isObservable(mutation.removedNodes[i])) {
3751
3782
  this.bindNode(mutation.removedNodes[i]);
3752
3783
  }
@@ -3777,6 +3808,7 @@ class Observer {
3777
3808
  }
3778
3809
  if (type === 'characterData') {
3779
3810
  this.textSet.add(id);
3811
+ continue;
3780
3812
  }
3781
3813
  }
3782
3814
  this.commitNodes();
@@ -4030,7 +4062,7 @@ class Observer {
4030
4062
  }
4031
4063
  commitNode(id) {
4032
4064
  const node = this.app.nodes.getNode(id);
4033
- if (node === undefined) {
4065
+ if (!node) {
4034
4066
  return false;
4035
4067
  }
4036
4068
  const cmt = this.commited[id];
@@ -4378,6 +4410,24 @@ class Session {
4378
4410
  this.userID = null;
4379
4411
  this.callbacks = [];
4380
4412
  this.timestamp = 0;
4413
+ this.getPageNumber = () => {
4414
+ const pageNoStr = this.app.sessionStorage.getItem(this.options.session_pageno_key);
4415
+ if (pageNoStr == null) {
4416
+ return undefined;
4417
+ }
4418
+ return parseInt(pageNoStr);
4419
+ };
4420
+ this.incPageNo = () => {
4421
+ let pageNo = this.getPageNumber();
4422
+ if (pageNo === undefined) {
4423
+ pageNo = 0;
4424
+ }
4425
+ else {
4426
+ pageNo++;
4427
+ }
4428
+ this.app.sessionStorage.setItem(this.options.session_pageno_key, pageNo.toString());
4429
+ return pageNo;
4430
+ };
4381
4431
  this.app = params.app;
4382
4432
  this.options = params.options;
4383
4433
  this.createTabId();
@@ -4424,24 +4474,6 @@ class Session {
4424
4474
  setUserInfo(userInfo) {
4425
4475
  this.userInfo = userInfo;
4426
4476
  }
4427
- getPageNumber() {
4428
- const pageNoStr = this.app.sessionStorage.getItem(this.options.session_pageno_key);
4429
- if (pageNoStr == null) {
4430
- return undefined;
4431
- }
4432
- return parseInt(pageNoStr);
4433
- }
4434
- incPageNo() {
4435
- let pageNo = this.getPageNumber();
4436
- if (pageNo === undefined) {
4437
- pageNo = 0;
4438
- }
4439
- else {
4440
- pageNo++;
4441
- }
4442
- this.app.sessionStorage.setItem(this.options.session_pageno_key, pageNo.toString());
4443
- return pageNo;
4444
- }
4445
4477
  getSessionToken() {
4446
4478
  const token = this.token || this.app.sessionStorage.getItem(this.options.session_token_key);
4447
4479
  return token || undefined;
@@ -4558,7 +4590,7 @@ class Ticker {
4558
4590
  * this value is injected during build time via rollup
4559
4591
  * */
4560
4592
  // @ts-ignore
4561
- const workerBodyFn = "!function(){\"use strict\";class t{constructor(t,s,i,e=10,n=250,h,r){this.onUnauthorised=s,this.onFailure=i,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.onCompress=h,this.pageNo=r,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.lastBatchNum=0,this.ingestURL=t+\"/v1/web/i\",this.isCompressing=void 0!==h}getQueueStatus(){return 0===this.queue.length&&!this.busy}authorise(t){this.token=t,this.busy||this.sendNext()}push(t){if(this.busy||!this.token)this.queue.push(t);else if(this.busy=!0,this.isCompressing&&this.onCompress)this.onCompress(t);else{const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}}sendNext(){const t=this.queue.shift();if(t)if(this.busy=!0,this.isCompressing&&this.onCompress)this.onCompress(t);else{const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}else this.busy=!1}retry(t,s,i){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure(`Failed to send batch after ${this.attemptsCount} attempts.`):(this.attemptsCount++,setTimeout((()=>this.sendBatch(t,s,i)),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t,s,i){var e;const n=null==i?void 0:i.toString().replace(/^([^_]+)_([^_]+).*/,\"$1_$2_$3\");this.busy=!0;const h={Authorization:`Bearer ${this.token}`};s&&(h[\"Content-Encoding\"]=\"gzip\"),null!==this.token?fetch(`${this.ingestURL}?batch=${null!==(e=this.pageNo)&&void 0!==e?e:\"noPageNum\"}_${null!=n?n:\"noBatchNum\"}`,{body:t,method:\"POST\",headers:h,keepalive:t.length<65536}).then((e=>{if(401===e.status)return this.busy=!1,void this.onUnauthorised();e.status>=400?this.retry(t,s,`${null!=i?i:\"noBatchNum\"}_network:${e.status}`):(this.attemptsCount=0,this.sendNext())})).catch((e=>{console.warn(\"OpenReplay:\",e),this.retry(t,s,`${null!=i?i:\"noBatchNum\"}_reject:${e.message}`)})):setTimeout((()=>{this.sendBatch(t,s,`${null!=i?i:\"noBatchNum\"}_newToken`)}),500)}sendCompressed(t){const s=++this.lastBatchNum;this.sendBatch(t,!0,s)}sendUncompressed(t){const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}clean(){this.sendNext(),setTimeout((()=>{this.token=null,this.queue.length=0}),10)}}const s=\"function\"==typeof TextEncoder?new TextEncoder:{encode(t){const s=t.length,i=new Uint8Array(3*s);let e=-1;for(let n=0,h=0,r=0;r!==s;){if(n=t.charCodeAt(r),r+=1,n>=55296&&n<=56319){if(r===s){i[e+=1]=239,i[e+=1]=191,i[e+=1]=189;break}if(h=t.charCodeAt(r),!(h>=56320&&h<=57343)){i[e+=1]=239,i[e+=1]=191,i[e+=1]=189;continue}if(n=1024*(n-55296)+h-56320+65536,r+=1,n>65535){i[e+=1]=240|n>>>18,i[e+=1]=128|n>>>12&63,i[e+=1]=128|n>>>6&63,i[e+=1]=128|63&n;continue}}n<=127?i[e+=1]=0|n:n<=2047?(i[e+=1]=192|n>>>6,i[e+=1]=128|63&n):(i[e+=1]=224|n>>>12,i[e+=1]=128|n>>>6&63,i[e+=1]=128|63&n)}return i.subarray(0,e+1)}};class i{constructor(t){this.size=t,this.offset=0,this.checkpointOffset=0,this.data=new Uint8Array(t)}getCurrentOffset(){return this.offset}checkpoint(){this.checkpointOffset=this.offset}get isEmpty(){return 0===this.offset}skip(t){return this.offset+=t,this.offset<=this.size}set(t,s){this.data.set(t,s)}boolean(t){return this.data[this.offset++]=+t,this.offset<=this.size}uint(t){for((t<0||t>Number.MAX_SAFE_INTEGER)&&(t=0);t>=128;)this.data[this.offset++]=t%256|128,t=Math.floor(t/128);return this.data[this.offset++]=t,this.offset<=this.size}int(t){return t=Math.round(t),this.uint(t>=0?2*t:-2*t-1)}string(t){const i=s.encode(t),e=i.byteLength;return!(!this.uint(e)||this.offset+e>this.size)&&(this.data.set(i,this.offset),this.offset+=e,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}class e extends i{encode(t){switch(t[0]){case 0:case 11:case 114:case 115:return this.uint(t[1]);case 4:case 44:case 47:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 5:case 20:case 38:case 70:case 75:case 76:case 77:case 82:return this.uint(t[1])&&this.uint(t[2]);case 6:return this.int(t[1])&&this.int(t[2]);case 7:return!0;case 8:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.string(t[4])&&this.boolean(t[5]);case 9:case 10:case 24:case 51:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3]);case 12:case 61:case 71:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 13:case 14:case 17:case 50:case 54:return this.uint(t[1])&&this.string(t[2]);case 16:return this.uint(t[1])&&this.int(t[2])&&this.int(t[3]);case 18:return this.uint(t[1])&&this.string(t[2])&&this.int(t[3]);case 19:return this.uint(t[1])&&this.boolean(t[2]);case 21:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8]);case 22:case 27:case 30:case 41:case 45:case 46:case 63:case 64:case 79:return this.string(t[1])&&this.string(t[2]);case 23:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 28:case 29:case 42:case 117:case 118:return this.string(t[1]);case 37:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3]);case 39:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.uint(t[7]);case 40:return this.string(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4]);case 48:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.int(t[5]);case 49:return this.int(t[1])&&this.int(t[2])&&this.uint(t[3])&&this.uint(t[4]);case 53:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.string(t[7])&&this.string(t[8]);case 55:return this.boolean(t[1]);case 57:case 60:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 58:case 120:return this.int(t[1]);case 59:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.string(t[5])&&this.string(t[6])&&this.string(t[7]);case 67:case 73:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.string(t[4]);case 68:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4])&&this.uint(t[5])&&this.uint(t[6]);case 69:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4]);case 78:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 81:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.int(t[4])&&this.string(t[5]);case 83:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 84:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.uint(t[4])&&this.string(t[5])&&this.string(t[6]);case 112:return this.uint(t[1])&&this.string(t[2])&&this.boolean(t[3])&&this.string(t[4])&&this.int(t[5])&&this.int(t[6]);case 113:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3]);case 116:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.string(t[7])&&this.string(t[8])&&this.uint(t[9])&&this.boolean(t[10]);case 119:return this.string(t[1])&&this.uint(t[2]);case 121:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.uint(t[4]);case 122:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.string(t[4]);case 123:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.uint(t[5])}}}class n{constructor(t,s,i,n,h,r){this.pageNo=t,this.timestamp=s,this.url=i,this.onBatch=n,this.tabId=h,this.onOfflineEnd=r,this.nextIndex=0,this.beaconSize=2e5,this.encoder=new e(this.beaconSize),this.sizeBuffer=new Uint8Array(3),this.isEmpty=!0,this.beaconSizeLimit=1e6,this.prepare()}writeType(t){return this.encoder.uint(t[0])}writeFields(t){return this.encoder.encode(t)}writeSizeAt(t,s){for(let s=0;s<3;s++)this.sizeBuffer[s]=t>>8*s;this.encoder.set(this.sizeBuffer,s)}prepare(){if(!this.encoder.isEmpty)return;const t=[81,1,this.pageNo,this.nextIndex,this.timestamp,this.url],s=[118,this.tabId];this.writeType(t),this.writeFields(t),this.writeWithSize(s),this.isEmpty=!0}writeWithSize(t){const s=this.encoder;if(!this.writeType(t)||!s.skip(3))return!1;const i=s.getCurrentOffset(),e=this.writeFields(t);if(e){const e=s.getCurrentOffset()-i;if(e>16777215)return console.warn(\"OpenReplay: max message size overflow.\"),!1;this.writeSizeAt(e,i-3),s.checkpoint(),this.isEmpty=this.isEmpty&&0===t[0],this.nextIndex++}return e}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){if(\"q_end\"===t[0])return this.finaliseBatch(),this.onOfflineEnd();0===t[0]&&(this.timestamp=t[1]),122===t[0]&&(this.url=t[1]),this.writeWithSize(t)||(this.finaliseBatch(),this.writeWithSize(t)||(this.encoder=new e(this.beaconSizeLimit),this.prepare(),this.writeWithSize(t)?this.finaliseBatch():console.warn(\"OpenReplay: beacon size overflow. Skipping large message.\",t,this),this.encoder=new e(this.beaconSize),this.prepare()))}finaliseBatch(){if(this.isEmpty)return;const t=this.encoder.flush();this.onBatch(t),this.prepare()}clean(){this.encoder.reset()}}var h;!function(t){t[t.NotActive=0]=\"NotActive\",t[t.Starting=1]=\"Starting\",t[t.Stopping=2]=\"Stopping\",t[t.Active=3]=\"Active\",t[t.Stopped=4]=\"Stopped\"}(h||(h={}));let r=null,u=null,a=h.NotActive;function o(){u&&u.finaliseBatch()}function c(){return new Promise((t=>{a=h.Stopping,null!==p&&(clearInterval(p),p=null),u&&(u.clean(),u=null),r&&(r.clean(),setTimeout((()=>{r=null}),20)),setTimeout((()=>{a=h.NotActive,t(null)}),100)}))}function g(){[h.Stopped,h.Stopping].includes(a)||(postMessage(\"a_stop\"),c().then((()=>{postMessage(\"a_start\")})))}let l,p=null;self.onmessage=({data:s})=>{if(null!=s){if(\"stop\"===s)return o(),void c().then((()=>{a=h.Stopped}));if(\"forceFlushBatch\"!==s){if(!Array.isArray(s)){if(\"compressed\"===s.type){if(!r)return console.debug(\"OR WebWorker: sender not initialised. Compressed batch.\"),void g();s.batch&&r.sendCompressed(s.batch)}if(\"uncompressed\"===s.type){if(!r)return console.debug(\"OR WebWorker: sender not initialised. Uncompressed batch.\"),void g();s.batch&&r.sendUncompressed(s.batch)}return\"start\"===s.type?(a=h.Starting,r=new t(s.ingestPoint,(()=>{g()}),(t=>{!function(t){postMessage({type:\"failure\",reason:t}),c()}(t)}),s.connAttemptCount,s.connAttemptGap,(t=>{postMessage({type:\"compress\",batch:t},[t.buffer])}),s.pageNo),u=new n(s.pageNo,s.timestamp,s.url,(t=>{r&&r.push(t)}),s.tabId,(()=>postMessage({type:\"queue_empty\"}))),null===p&&(p=setInterval(o,1e4)),a=h.Active):\"auth\"===s.type?r?u?(r.authorise(s.token),void(s.beaconSizeLimit&&u.setBeaconSizeLimit(s.beaconSizeLimit))):(console.debug(\"OR WebWorker: writer not initialised. Received auth.\"),void g()):(console.debug(\"OR WebWorker: sender not initialised. Received auth.\"),void g()):void 0}if(u){const t=u;s.forEach((s=>{55===s[0]&&(s[1]?l=setTimeout((()=>g()),18e5):clearTimeout(l)),t.writeMessage(s)}))}else postMessage(\"not_init\"),g()}else o()}else o()}}();\n";
4593
+ const workerBodyFn = "!function(){\"use strict\";class t{constructor(t,s,i,e=10,n=250,h,r){this.onUnauthorised=s,this.onFailure=i,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.onCompress=h,this.pageNo=r,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.lastBatchNum=0,this.ingestURL=t+\"/v1/web/i\",this.isCompressing=void 0!==h}getQueueStatus(){return 0===this.queue.length&&!this.busy}authorise(t){this.token=t,this.busy||this.sendNext()}push(t){if(this.busy||!this.token)this.queue.push(t);else if(this.busy=!0,this.isCompressing&&this.onCompress)this.onCompress(t);else{const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}}sendNext(){const t=this.queue.shift();if(t)if(this.busy=!0,this.isCompressing&&this.onCompress)this.onCompress(t);else{const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}else this.busy=!1}retry(t,s,i){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure(`Failed to send batch after ${this.attemptsCount} attempts.`):(this.attemptsCount++,setTimeout((()=>this.sendBatch(t,s,i)),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t,s,i){var e;const n=null==i?void 0:i.toString().replace(/^([^_]+)_([^_]+).*/,\"$1_$2_$3\");this.busy=!0;const h={Authorization:`Bearer ${this.token}`};s&&(h[\"Content-Encoding\"]=\"gzip\"),null!==this.token?fetch(`${this.ingestURL}?batch=${null!==(e=this.pageNo)&&void 0!==e?e:\"noPageNum\"}_${null!=n?n:\"noBatchNum\"}`,{body:t,method:\"POST\",headers:h,keepalive:t.length<65536}).then((e=>{if(401===e.status)return this.busy=!1,void this.onUnauthorised();e.status>=400?this.retry(t,s,`${null!=i?i:\"noBatchNum\"}_network:${e.status}`):(this.attemptsCount=0,this.sendNext())})).catch((e=>{console.warn(\"OpenReplay:\",e),this.retry(t,s,`${null!=i?i:\"noBatchNum\"}_reject:${e.message}`)})):setTimeout((()=>{this.sendBatch(t,s,`${null!=i?i:\"noBatchNum\"}_newToken`)}),500)}sendCompressed(t){const s=++this.lastBatchNum;this.sendBatch(t,!0,s)}sendUncompressed(t){const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}clean(){this.sendNext(),setTimeout((()=>{this.token=null,this.queue.length=0}),10)}}const s=\"function\"==typeof TextEncoder?new TextEncoder:{encode(t){const s=t.length,i=new Uint8Array(3*s);let e=-1;for(let n=0,h=0,r=0;r!==s;){if(n=t.charCodeAt(r),r+=1,n>=55296&&n<=56319){if(r===s){i[e+=1]=239,i[e+=1]=191,i[e+=1]=189;break}if(h=t.charCodeAt(r),!(h>=56320&&h<=57343)){i[e+=1]=239,i[e+=1]=191,i[e+=1]=189;continue}if(n=1024*(n-55296)+h-56320+65536,r+=1,n>65535){i[e+=1]=240|n>>>18,i[e+=1]=128|n>>>12&63,i[e+=1]=128|n>>>6&63,i[e+=1]=128|63&n;continue}}n<=127?i[e+=1]=0|n:n<=2047?(i[e+=1]=192|n>>>6,i[e+=1]=128|63&n):(i[e+=1]=224|n>>>12,i[e+=1]=128|n>>>6&63,i[e+=1]=128|63&n)}return i.subarray(0,e+1)}};class i{constructor(t){this.size=t,this.offset=0,this.checkpointOffset=0,this.data=new Uint8Array(t)}getCurrentOffset(){return this.offset}checkpoint(){this.checkpointOffset=this.offset}get isEmpty(){return 0===this.offset}skip(t){return this.offset+=t,this.offset<=this.size}set(t,s){this.data.set(t,s)}boolean(t){return this.data[this.offset++]=+t,this.offset<=this.size}uint(t){for((t<0||t>Number.MAX_SAFE_INTEGER)&&(t=0);t>=128;)this.data[this.offset++]=t%256|128,t=Math.floor(t/128);return this.data[this.offset++]=t,this.offset<=this.size}int(t){return t=Math.round(t),this.uint(t>=0?2*t:-2*t-1)}string(t){const i=s.encode(t),e=i.byteLength;return!(!this.uint(e)||this.offset+e>this.size)&&(this.data.set(i,this.offset),this.offset+=e,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}class e extends i{encode(t){switch(t[0]){case 0:case 11:case 114:case 115:return this.uint(t[1]);case 4:case 44:case 47:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 5:case 20:case 38:case 70:case 75:case 76:case 77:case 82:return this.uint(t[1])&&this.uint(t[2]);case 6:return this.int(t[1])&&this.int(t[2]);case 7:return!0;case 8:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.string(t[4])&&this.boolean(t[5]);case 9:case 10:case 24:case 51:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3]);case 12:case 52:case 61:case 71:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 13:case 14:case 17:case 50:case 54:return this.uint(t[1])&&this.string(t[2]);case 16:return this.uint(t[1])&&this.int(t[2])&&this.int(t[3]);case 18:return this.uint(t[1])&&this.string(t[2])&&this.int(t[3]);case 19:return this.uint(t[1])&&this.boolean(t[2]);case 21:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8]);case 22:case 27:case 30:case 41:case 45:case 46:case 43:case 63:case 64:case 79:case 124:return this.string(t[1])&&this.string(t[2]);case 23:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 28:case 29:case 42:case 117:case 118:return this.string(t[1]);case 37:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3]);case 39:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.uint(t[7]);case 40:return this.string(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4]);case 48:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.int(t[5]);case 49:return this.int(t[1])&&this.int(t[2])&&this.uint(t[3])&&this.uint(t[4]);case 53:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.string(t[7])&&this.string(t[8]);case 55:return this.boolean(t[1]);case 57:case 60:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 58:case 120:return this.int(t[1]);case 59:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.string(t[5])&&this.string(t[6])&&this.string(t[7]);case 67:case 73:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.string(t[4]);case 68:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4])&&this.uint(t[5])&&this.uint(t[6]);case 69:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4]);case 78:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 81:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.int(t[4])&&this.string(t[5]);case 83:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 84:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.uint(t[4])&&this.string(t[5])&&this.string(t[6]);case 112:return this.uint(t[1])&&this.string(t[2])&&this.boolean(t[3])&&this.string(t[4])&&this.int(t[5])&&this.int(t[6]);case 113:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3]);case 116:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.string(t[7])&&this.string(t[8])&&this.uint(t[9])&&this.boolean(t[10]);case 119:return this.string(t[1])&&this.uint(t[2]);case 121:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.uint(t[4]);case 122:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.string(t[4]);case 123:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.uint(t[5])}}}class n{constructor(t,s,i,n,h,r){this.pageNo=t,this.timestamp=s,this.url=i,this.onBatch=n,this.tabId=h,this.onOfflineEnd=r,this.nextIndex=0,this.beaconSize=2e5,this.encoder=new e(this.beaconSize),this.sizeBuffer=new Uint8Array(3),this.isEmpty=!0,this.beaconSizeLimit=1e6,this.prepare()}writeType(t){return this.encoder.uint(t[0])}writeFields(t){return this.encoder.encode(t)}writeSizeAt(t,s){for(let s=0;s<3;s++)this.sizeBuffer[s]=t>>8*s;this.encoder.set(this.sizeBuffer,s)}prepare(){if(!this.encoder.isEmpty)return;const t=[81,1,this.pageNo,this.nextIndex,this.timestamp,this.url],s=[118,this.tabId];this.writeType(t),this.writeFields(t),this.writeWithSize(s),this.isEmpty=!0}writeWithSize(t){const s=this.encoder;if(!this.writeType(t)||!s.skip(3))return!1;const i=s.getCurrentOffset(),e=this.writeFields(t);if(e){const e=s.getCurrentOffset()-i;if(e>16777215)return console.warn(\"OpenReplay: max message size overflow.\"),!1;this.writeSizeAt(e,i-3),s.checkpoint(),this.isEmpty=this.isEmpty&&0===t[0],this.nextIndex++}return e}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){if(\"q_end\"===t[0])return this.finaliseBatch(),this.onOfflineEnd();0===t[0]&&(this.timestamp=t[1]),122===t[0]&&(this.url=t[1]),this.writeWithSize(t)||(this.finaliseBatch(),this.writeWithSize(t)||(this.encoder=new e(this.beaconSizeLimit),this.prepare(),this.writeWithSize(t)?this.finaliseBatch():console.warn(\"OpenReplay: beacon size overflow. Skipping large message.\",t,this),this.encoder=new e(this.beaconSize),this.prepare()))}finaliseBatch(){if(this.isEmpty)return;const t=this.encoder.flush();this.onBatch(t),this.prepare()}clean(){this.encoder.reset()}}var h;!function(t){t[t.NotActive=0]=\"NotActive\",t[t.Starting=1]=\"Starting\",t[t.Stopping=2]=\"Stopping\",t[t.Active=3]=\"Active\",t[t.Stopped=4]=\"Stopped\"}(h||(h={}));let r=null,u=null,a=h.NotActive;function o(){u&&u.finaliseBatch()}function c(){return new Promise((t=>{a=h.Stopping,null!==p&&(clearInterval(p),p=null),u&&(u.clean(),u=null),r&&(r.clean(),setTimeout((()=>{r=null}),20)),setTimeout((()=>{a=h.NotActive,t(null)}),100)}))}function g(){[h.Stopped,h.Stopping].includes(a)||(postMessage(\"a_stop\"),c().then((()=>{postMessage(\"a_start\")})))}let l,p=null;self.onmessage=({data:s})=>{if(null!=s){if(\"stop\"===s)return o(),void c().then((()=>{a=h.Stopped}));if(\"forceFlushBatch\"!==s){if(!Array.isArray(s)){if(\"compressed\"===s.type){if(!r)return console.debug(\"OR WebWorker: sender not initialised. Compressed batch.\"),void g();s.batch&&r.sendCompressed(s.batch)}if(\"uncompressed\"===s.type){if(!r)return console.debug(\"OR WebWorker: sender not initialised. Uncompressed batch.\"),void g();s.batch&&r.sendUncompressed(s.batch)}return\"start\"===s.type?(a=h.Starting,r=new t(s.ingestPoint,(()=>{g()}),(t=>{!function(t){postMessage({type:\"failure\",reason:t}),c()}(t)}),s.connAttemptCount,s.connAttemptGap,(t=>{postMessage({type:\"compress\",batch:t},[t.buffer])}),s.pageNo),u=new n(s.pageNo,s.timestamp,s.url,(t=>{r&&r.push(t)}),s.tabId,(()=>postMessage({type:\"queue_empty\"}))),null===p&&(p=setInterval(o,1e4)),a=h.Active):\"auth\"===s.type?r?u?(r.authorise(s.token),void(s.beaconSizeLimit&&u.setBeaconSizeLimit(s.beaconSizeLimit))):(console.debug(\"OR WebWorker: writer not initialised. Received auth.\"),void g()):(console.debug(\"OR WebWorker: sender not initialised. Received auth.\"),void g()):void 0}if(u){const t=u;s.forEach((s=>{55===s[0]&&(s[1]?l=setTimeout((()=>g()),18e5):clearTimeout(l)),t.writeMessage(s)}))}else postMessage(\"not_init\"),g()}else o()}else o()}}();\n";
4562
4594
  const CANCELED = 'canceled';
4563
4595
  const uxtStorageKey = 'or_uxt_active';
4564
4596
  const bufferStorageKey = 'or_buffer_1';
@@ -4612,7 +4644,7 @@ class App {
4612
4644
  this.stopCallbacks = [];
4613
4645
  this.commitCallbacks = [];
4614
4646
  this.activityState = ActivityState.NotActive;
4615
- this.version = '14.0.14'; // TODO: version compatability check inside each plugin.
4647
+ this.version = '15.0.1'; // TODO: version compatability check inside each plugin.
4616
4648
  this.socketMode = false;
4617
4649
  this.compressionThreshold = 24 * 1000;
4618
4650
  this.bc = null;
@@ -5132,7 +5164,7 @@ class App {
5132
5164
  this.allowAppStart();
5133
5165
  this.start(this.prevOpts, true)
5134
5166
  .then((r) => {
5135
- this.debug.info('Worker restarted, session was too long', r);
5167
+ this.debug.info('Worker restart, session too long', r);
5136
5168
  })
5137
5169
  .catch((e) => {
5138
5170
  this.debug.error('Worker restart failed', e);
@@ -7097,6 +7129,8 @@ function roundNumber(num) {
7097
7129
  return Math.round(num * 1e4);
7098
7130
  }
7099
7131
 
7132
+ var e,o=-1,a=function(e){addEventListener("pageshow",(function(n){n.persisted&&(o=n.timeStamp,e(n));}),!0);},c=function(){var e=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},u=function(){var e=c();return e&&e.activationStart||0},f=function(e,n){var t=c(),r="navigate";o>=0?r="back-forward-cache":t&&(document.prerendering||u()>0?r="prerender":document.wasDiscarded?r="restore":t.type&&(r=t.type.replace(/_/g,"-")));return {name:e,value:void 0===n?-1:n,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:r}},s=function(e,n,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){var r=new PerformanceObserver((function(e){Promise.resolve().then((function(){n(e.getEntries());}));}));return r.observe(Object.assign({type:e,buffered:!0},t||{})),r}}catch(e){}},d=function(e,n,t,r){var i,o;return function(a){n.value>=0&&(a||r)&&((o=n.value-(i||0))||void 0===i)&&(i=n.value,n.delta=o,n.rating=function(e,n){return e>n[1]?"poor":e>n[0]?"needs-improvement":"good"}(n.value,t),e(n));}},l=function(e){requestAnimationFrame((function(){return requestAnimationFrame((function(){return e()}))}));},p=function(e){document.addEventListener("visibilitychange",(function(){"hidden"===document.visibilityState&&e();}));},v=function(e){var n=!1;return function(){n||(e(),n=!0);}},m=-1,h=function(){return "hidden"!==document.visibilityState||document.prerendering?1/0:0},g=function(e){"hidden"===document.visibilityState&&m>-1&&(m="visibilitychange"===e.type?e.timeStamp:0,T());},y=function(){addEventListener("visibilitychange",g,!0),addEventListener("prerenderingchange",g,!0);},T=function(){removeEventListener("visibilitychange",g,!0),removeEventListener("prerenderingchange",g,!0);},E=function(){return m<0&&(m=h(),y(),a((function(){setTimeout((function(){m=h(),y();}),0);}))),{get firstHiddenTime(){return m}}},C=function(e){document.prerendering?addEventListener("prerenderingchange",(function(){return e()}),!0):e();},b=[1800,3e3],S=function(e,n){n=n||{},C((function(){var t,r=E(),i=f("FCP"),o=s("paint",(function(e){e.forEach((function(e){"first-contentful-paint"===e.name&&(o.disconnect(),e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-u(),0),i.entries.push(e),t(!0)));}));}));o&&(t=d(e,i,b,n.reportAllChanges),a((function(r){i=f("FCP"),t=d(e,i,b,n.reportAllChanges),l((function(){i.value=performance.now()-r.timeStamp,t(!0);}));})));}));},L=[.1,.25],w=function(e,n){n=n||{},S(v((function(){var t,r=f("CLS",0),i=0,o=[],c=function(e){e.forEach((function(e){if(!e.hadRecentInput){var n=o[0],t=o[o.length-1];i&&e.startTime-t.startTime<1e3&&e.startTime-n.startTime<5e3?(i+=e.value,o.push(e)):(i=e.value,o=[e]);}})),i>r.value&&(r.value=i,r.entries=o,t());},u=s("layout-shift",c);u&&(t=d(e,r,L,n.reportAllChanges),p((function(){c(u.takeRecords()),t(!0);})),a((function(){i=0,r=f("CLS",0),t=d(e,r,L,n.reportAllChanges),l((function(){return t()}));})),setTimeout(t,0));})));},A=0,I=1/0,P=0,M=function(e){e.forEach((function(e){e.interactionId&&(I=Math.min(I,e.interactionId),P=Math.max(P,e.interactionId),A=P?(P-I)/7+1:0);}));},k=function(){return e?A:performance.interactionCount||0},F=function(){"interactionCount"in performance||e||(e=s("event",M,{type:"event",buffered:!0,durationThreshold:0}));},D=[],x=new Map,R=0,B=function(){var e=Math.min(D.length-1,Math.floor((k()-R)/50));return D[e]},H=[],q=function(e){if(H.forEach((function(n){return n(e)})),e.interactionId||"first-input"===e.entryType){var n=D[D.length-1],t=x.get(e.interactionId);if(t||D.length<10||e.duration>n.latency){if(t)e.duration>t.latency?(t.entries=[e],t.latency=e.duration):e.duration===t.latency&&e.startTime===t.entries[0].startTime&&t.entries.push(e);else {var r={id:e.interactionId,latency:e.duration,entries:[e]};x.set(r.id,r),D.push(r);}D.sort((function(e,n){return n.latency-e.latency})),D.length>10&&D.splice(10).forEach((function(e){return x.delete(e.id)}));}}},O=function(e){var n=self.requestIdleCallback||self.setTimeout,t=-1;return e=v(e),"hidden"===document.visibilityState?e():(t=n(e),p(e)),t},N=[200,500],j=function(e,n){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(n=n||{},C((function(){var t;F();var r,i=f("INP"),o=function(e){O((function(){e.forEach(q);var n=B();n&&n.latency!==i.value&&(i.value=n.latency,i.entries=n.entries,r());}));},c=s("event",o,{durationThreshold:null!==(t=n.durationThreshold)&&void 0!==t?t:40});r=d(e,i,N,n.reportAllChanges),c&&(c.observe({type:"first-input",buffered:!0}),p((function(){o(c.takeRecords()),r(!0);})),a((function(){R=k(),D.length=0,x.clear(),i=f("INP"),r=d(e,i,N,n.reportAllChanges);})));})));},_=[2500,4e3],z={},G=function(e,n){n=n||{},C((function(){var t,r=E(),i=f("LCP"),o=function(e){n.reportAllChanges||(e=e.slice(-1)),e.forEach((function(e){e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-u(),0),i.entries=[e],t());}));},c=s("largest-contentful-paint",o);if(c){t=d(e,i,_,n.reportAllChanges);var m=v((function(){z[i.id]||(o(c.takeRecords()),c.disconnect(),z[i.id]=!0,t(!0));}));["keydown","click"].forEach((function(e){addEventListener(e,(function(){return O(m)}),{once:!0,capture:!0});})),p(m),a((function(r){i=f("LCP"),t=d(e,i,_,n.reportAllChanges),l((function(){i.value=performance.now()-r.timeStamp,z[i.id]=!0,t(!0);}));}));}}));},J=[800,1800],K=function e(n){document.prerendering?C((function(){return e(n)})):"complete"!==document.readyState?addEventListener("load",(function(){return e(n)}),!0):setTimeout(n,0);},Q=function(e,n){n=n||{};var t=f("TTFB"),r=d(e,t,J,n.reportAllChanges);K((function(){var i=c();i&&(t.value=Math.max(i.responseStart-u(),0),t.entries=[i],r(!0),a((function(){t=f("TTFB",0),(r=d(e,t,J,n.reportAllChanges))(!0);})));}));};
7133
+
7100
7134
  function getPaintBlocks(resources) {
7101
7135
  const paintBlocks = [];
7102
7136
  const elements = document.getElementsByTagName('*');
@@ -7185,6 +7219,11 @@ function Timing (app, opts) {
7185
7219
  (entry.responseStatus && entry.responseStatus === 304) || entry.transferSize === 0));
7186
7220
  }
7187
7221
  const observer = new PerformanceObserver((list) => list.getEntries().forEach(resourceTiming));
7222
+ function onVitalsSignal(msg) {
7223
+ if (app.active()) {
7224
+ return app.send(WebVitals(msg.name, String(msg.value)));
7225
+ }
7226
+ }
7188
7227
  let prevSessionID;
7189
7228
  app.attachStartCallback(function ({ sessionID }) {
7190
7229
  if (sessionID !== prevSessionID) {
@@ -7193,6 +7232,17 @@ function Timing (app, opts) {
7193
7232
  prevSessionID = sessionID;
7194
7233
  }
7195
7234
  observer.observe({ entryTypes: ['resource'] });
7235
+ // browser support:
7236
+ // onCLS(): Chromium
7237
+ // onFCP(): Chromium, Firefox, Safari
7238
+ // onFID(): Chromium, Firefox (Deprecated)
7239
+ // onINP(): Chromium
7240
+ // onLCP(): Chromium, Firefox
7241
+ // onTTFB(): Chromium, Firefox, Safari
7242
+ w(onVitalsSignal);
7243
+ j(onVitalsSignal);
7244
+ G(onVitalsSignal);
7245
+ Q(onVitalsSignal);
7196
7246
  });
7197
7247
  app.attachStopCallback(function () {
7198
7248
  observer.disconnect();
@@ -7657,6 +7707,7 @@ function Fonts (app) {
7657
7707
  }
7658
7708
  const docFonts = new Map();
7659
7709
  const patchWindow = (wnd) => {
7710
+ // @ts-ignore
7660
7711
  class FontFaceInterceptor extends wnd.FontFace {
7661
7712
  constructor(...args) {
7662
7713
  //maybe do this on load(). In this case check if the document.fonts.load(...) function calls the font's load()
@@ -9014,7 +9065,7 @@ class API {
9014
9065
  const orig = this.options.ingestPoint || DEFAULT_INGEST_POINT;
9015
9066
  req.open('POST', orig + '/v1/web/not-started');
9016
9067
  req.send(JSON.stringify({
9017
- trackerVersion: '14.0.14',
9068
+ trackerVersion: '15.0.1',
9018
9069
  projectKey: this.options.projectKey,
9019
9070
  doNotTrack,
9020
9071
  reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,
@@ -9044,7 +9095,6 @@ class API {
9044
9095
  };
9045
9096
  this.crossdomainMode = Boolean(inIframe() && options.crossdomain?.enabled);
9046
9097
  if (!IN_BROWSER || !processOptions(options)) {
9047
- console.error('OpenReplay: tracker called in a non-browser environment or with invalid options');
9048
9098
  return;
9049
9099
  }
9050
9100
  if (window.__OPENREPLAY__ ||