@openreplay/tracker 3.6.3 → 4.0.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.
Files changed (128) hide show
  1. package/.eslintignore +8 -0
  2. package/.prettierignore +1 -0
  3. package/LICENSE +1 -1
  4. package/cjs/app/guards.d.ts +2 -1
  5. package/cjs/app/guards.js +6 -3
  6. package/cjs/app/index.d.ts +28 -23
  7. package/cjs/app/index.js +101 -83
  8. package/cjs/app/logger.js +6 -3
  9. package/cjs/app/messages.d.ts +52 -0
  10. package/cjs/app/messages.gen.d.ts +57 -0
  11. package/cjs/app/messages.gen.js +493 -0
  12. package/cjs/app/messages.js +234 -0
  13. package/cjs/app/nodes.d.ts +1 -1
  14. package/cjs/app/nodes.js +2 -0
  15. package/cjs/app/observer/iframe_observer.d.ts +1 -1
  16. package/cjs/app/observer/iframe_observer.js +3 -3
  17. package/cjs/app/observer/observer.d.ts +2 -3
  18. package/cjs/app/observer/observer.js +50 -52
  19. package/cjs/app/observer/shadow_root_observer.d.ts +1 -1
  20. package/cjs/app/observer/shadow_root_observer.js +3 -3
  21. package/cjs/app/observer/top_observer.d.ts +13 -2
  22. package/cjs/app/observer/top_observer.js +58 -23
  23. package/cjs/app/sanitizer.d.ts +1 -1
  24. package/cjs/app/sanitizer.js +5 -5
  25. package/cjs/app/session.d.ts +20 -2
  26. package/cjs/app/session.js +65 -6
  27. package/cjs/app/ticker.d.ts +1 -1
  28. package/cjs/common/{webworker.d.ts → interaction.d.ts} +5 -5
  29. package/cjs/common/{types.js → interaction.js} +0 -0
  30. package/cjs/common/messages.gen.d.ts +382 -0
  31. package/cjs/common/{webworker.js → messages.gen.js} +1 -0
  32. package/cjs/index.d.ts +10 -9
  33. package/cjs/index.js +47 -36
  34. package/cjs/modules/adoptedStyleSheets.d.ts +2 -0
  35. package/cjs/modules/adoptedStyleSheets.js +127 -0
  36. package/cjs/modules/connection.d.ts +1 -1
  37. package/cjs/modules/connection.js +2 -2
  38. package/cjs/modules/console.d.ts +1 -1
  39. package/cjs/modules/console.js +7 -21
  40. package/cjs/modules/cssrules.d.ts +1 -1
  41. package/cjs/modules/cssrules.js +18 -14
  42. package/cjs/modules/exception.d.ts +3 -3
  43. package/cjs/modules/exception.js +23 -18
  44. package/cjs/modules/img.d.ts +1 -1
  45. package/cjs/modules/img.js +39 -26
  46. package/cjs/modules/input.d.ts +1 -1
  47. package/cjs/modules/input.js +21 -21
  48. package/cjs/modules/mouse.d.ts +1 -1
  49. package/cjs/modules/mouse.js +50 -43
  50. package/cjs/modules/performance.d.ts +1 -1
  51. package/cjs/modules/performance.js +2 -2
  52. package/cjs/modules/scroll.d.ts +1 -1
  53. package/cjs/modules/scroll.js +16 -7
  54. package/cjs/modules/timing.d.ts +1 -1
  55. package/cjs/modules/timing.js +14 -26
  56. package/cjs/modules/viewport.d.ts +1 -1
  57. package/cjs/modules/viewport.js +4 -4
  58. package/cjs/utils.js +7 -7
  59. package/cjs/vendors/finder/finder.js +53 -48
  60. package/lib/app/guards.d.ts +2 -1
  61. package/lib/app/guards.js +4 -2
  62. package/lib/app/index.d.ts +28 -23
  63. package/lib/app/index.js +109 -91
  64. package/lib/app/logger.js +6 -3
  65. package/lib/app/messages.d.ts +52 -0
  66. package/lib/app/messages.gen.d.ts +57 -0
  67. package/lib/app/messages.gen.js +434 -0
  68. package/lib/app/messages.js +181 -0
  69. package/lib/app/nodes.d.ts +1 -1
  70. package/lib/app/nodes.js +2 -0
  71. package/lib/app/observer/iframe_observer.d.ts +1 -1
  72. package/lib/app/observer/iframe_observer.js +3 -3
  73. package/lib/app/observer/observer.d.ts +2 -3
  74. package/lib/app/observer/observer.js +51 -53
  75. package/lib/app/observer/shadow_root_observer.d.ts +1 -1
  76. package/lib/app/observer/shadow_root_observer.js +3 -3
  77. package/lib/app/observer/top_observer.d.ts +13 -2
  78. package/lib/app/observer/top_observer.js +62 -27
  79. package/lib/app/sanitizer.d.ts +1 -1
  80. package/lib/app/sanitizer.js +7 -7
  81. package/lib/app/session.d.ts +20 -2
  82. package/lib/app/session.js +65 -6
  83. package/lib/app/ticker.d.ts +1 -1
  84. package/lib/common/{webworker.d.ts → interaction.d.ts} +5 -5
  85. package/lib/common/{types.js → interaction.js} +0 -0
  86. package/lib/common/messages.gen.d.ts +382 -0
  87. package/lib/common/messages.gen.js +2 -0
  88. package/lib/common/tsconfig.tsbuildinfo +1 -1
  89. package/lib/index.d.ts +10 -9
  90. package/lib/index.js +60 -49
  91. package/lib/modules/adoptedStyleSheets.d.ts +2 -0
  92. package/lib/modules/adoptedStyleSheets.js +124 -0
  93. package/lib/modules/connection.d.ts +1 -1
  94. package/lib/modules/connection.js +2 -2
  95. package/lib/modules/console.d.ts +1 -1
  96. package/lib/modules/console.js +8 -22
  97. package/lib/modules/cssrules.d.ts +1 -1
  98. package/lib/modules/cssrules.js +19 -15
  99. package/lib/modules/exception.d.ts +3 -3
  100. package/lib/modules/exception.js +23 -18
  101. package/lib/modules/img.d.ts +1 -1
  102. package/lib/modules/img.js +41 -28
  103. package/lib/modules/input.d.ts +1 -1
  104. package/lib/modules/input.js +23 -23
  105. package/lib/modules/mouse.d.ts +1 -1
  106. package/lib/modules/mouse.js +53 -46
  107. package/lib/modules/performance.d.ts +1 -1
  108. package/lib/modules/performance.js +3 -3
  109. package/lib/modules/scroll.d.ts +1 -1
  110. package/lib/modules/scroll.js +17 -8
  111. package/lib/modules/timing.d.ts +1 -1
  112. package/lib/modules/timing.js +16 -28
  113. package/lib/modules/viewport.d.ts +1 -1
  114. package/lib/modules/viewport.js +4 -4
  115. package/lib/utils.js +7 -7
  116. package/lib/vendors/finder/finder.js +53 -48
  117. package/package.json +27 -10
  118. package/cjs/common/messages.d.ts +0 -444
  119. package/cjs/common/messages.js +0 -794
  120. package/cjs/common/types.d.ts +0 -9
  121. package/cjs/modules/longtasks.d.ts +0 -2
  122. package/cjs/modules/longtasks.js +0 -26
  123. package/lib/common/messages.d.ts +0 -444
  124. package/lib/common/messages.js +0 -790
  125. package/lib/common/types.d.ts +0 -9
  126. package/lib/common/webworker.js +0 -1
  127. package/lib/modules/longtasks.d.ts +0 -2
  128. package/lib/modules/longtasks.js +0 -23
package/.eslintignore ADDED
@@ -0,0 +1,8 @@
1
+ node_modules
2
+ npm-debug.log
3
+ lib
4
+ cjs
5
+ build
6
+ .cache
7
+ .eslintrc.cjs
8
+ *.gen.ts
@@ -0,0 +1 @@
1
+ *.gen.ts
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2021 OpenReplay.com <support@openreplay.com>
1
+ Copyright (c) 2022 Asayer, Inc
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
@@ -1,7 +1,8 @@
1
1
  export declare function isSVGElement(node: Element): node is SVGElement;
2
2
  export declare function isElementNode(node: Node): node is Element;
3
3
  export declare function isTextNode(node: Node): node is Text;
4
- export declare function isRootNode(node: Node): boolean;
4
+ export declare function isDocument(node: Node): node is Document;
5
+ export declare function isRootNode(node: Node): node is Document | DocumentFragment;
5
6
  declare type TagTypeMap = {
6
7
  HTML: HTMLHtmlElement;
7
8
  IMG: HTMLImageElement;
package/cjs/app/guards.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasTag = exports.isRootNode = exports.isTextNode = exports.isElementNode = exports.isSVGElement = void 0;
3
+ exports.hasTag = exports.isRootNode = exports.isDocument = exports.isTextNode = exports.isElementNode = exports.isSVGElement = void 0;
4
4
  function isSVGElement(node) {
5
5
  return node.namespaceURI === 'http://www.w3.org/2000/svg';
6
6
  }
@@ -13,9 +13,12 @@ function isTextNode(node) {
13
13
  return node.nodeType === Node.TEXT_NODE;
14
14
  }
15
15
  exports.isTextNode = isTextNode;
16
+ function isDocument(node) {
17
+ return node.nodeType === Node.DOCUMENT_NODE;
18
+ }
19
+ exports.isDocument = isDocument;
16
20
  function isRootNode(node) {
17
- return node.nodeType === Node.DOCUMENT_NODE ||
18
- node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
21
+ return node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
19
22
  }
20
23
  exports.isRootNode = isRootNode;
21
24
  function hasTag(el, tagName) {
@@ -1,17 +1,20 @@
1
- import type Message from "../common/messages.js";
2
- import Nodes from "./nodes.js";
3
- import Sanitizer from "./sanitizer.js";
4
- import Ticker from "./ticker.js";
5
- import Logger from "./logger.js";
6
- import Session from "./session.js";
7
- import type { Options as ObserverOptions } from "./observer/top_observer.js";
8
- import type { Options as SanitizerOptions } from "./sanitizer.js";
9
- import type { Options as LoggerOptions } from "./logger.js";
10
- import type { Options as WebworkerOptions } from "../common/webworker.js";
1
+ import type Message from './messages.gen.js';
2
+ import Nodes from './nodes.js';
3
+ import Observer from './observer/top_observer.js';
4
+ import Sanitizer from './sanitizer.js';
5
+ import Ticker from './ticker.js';
6
+ import Logger from './logger.js';
7
+ import Session from './session.js';
8
+ import type { Options as ObserverOptions } from './observer/top_observer.js';
9
+ import type { Options as SanitizerOptions } from './sanitizer.js';
10
+ import type { Options as LoggerOptions } from './logger.js';
11
+ import type { Options as SessOptions } from './session.js';
12
+ import type { Options as WebworkerOptions } from '../common/interaction.js';
11
13
  export interface StartOptions {
12
14
  userID?: string;
13
15
  metadata?: Record<string, string>;
14
16
  forceNew?: boolean;
17
+ sessionHash?: string;
15
18
  }
16
19
  interface OnStartInfo {
17
20
  sessionID: string;
@@ -34,9 +37,9 @@ declare type CommitCallback = (messages: Array<Message>) => void;
34
37
  declare type AppOptions = {
35
38
  revID: string;
36
39
  node_id: string;
40
+ session_reset_key: string;
37
41
  session_token_key: string;
38
42
  session_pageno_key: string;
39
- session_reset_key: string;
40
43
  local_uuid_key: string;
41
44
  ingestPoint: string;
42
45
  resourceBaseHref: string | null;
@@ -44,10 +47,10 @@ declare type AppOptions = {
44
47
  __is_snippet: boolean;
45
48
  __debug_report_edp: string | null;
46
49
  __debug__?: LoggerOptions;
47
- localStorage: Storage;
48
- sessionStorage: Storage;
50
+ localStorage: Storage | null;
51
+ sessionStorage: Storage | null;
49
52
  onStart?: StartCallback;
50
- } & WebworkerOptions;
53
+ } & WebworkerOptions & SessOptions;
51
54
  export declare type Options = AppOptions & ObserverOptions & SanitizerOptions;
52
55
  export declare const DEFAULT_INGEST_POINT = "https://api.openreplay.com/ingest";
53
56
  export default class App {
@@ -61,39 +64,41 @@ export default class App {
61
64
  readonly localStorage: Storage;
62
65
  readonly sessionStorage: Storage;
63
66
  private readonly messages;
64
- private readonly observer;
67
+ readonly observer: Observer;
65
68
  private readonly startCallbacks;
66
69
  private readonly stopCallbacks;
67
70
  private readonly commitCallbacks;
68
71
  private readonly options;
69
72
  private readonly revID;
70
73
  private activityState;
71
- private version;
74
+ private readonly version;
72
75
  private readonly worker?;
73
- constructor(projectKey: string, sessionToken: string | null | undefined, options: Partial<Options>);
76
+ constructor(projectKey: string, sessionToken: string | undefined, options: Partial<Options>);
74
77
  private _debug;
75
78
  send(message: Message, urgent?: boolean): void;
76
79
  private commit;
77
80
  safe<T extends (...args: any[]) => void>(fn: T): T;
78
81
  attachCommitCallback(cb: CommitCallback): void;
79
- attachStartCallback(cb: StartCallback): void;
80
- attachStopCallback(cb: Function): void;
82
+ attachStartCallback(cb: StartCallback, useSafe?: boolean): void;
83
+ attachStopCallback(cb: () => any, useSafe?: boolean): void;
81
84
  attachEventListener(target: EventTarget, type: string, listener: EventListener, useSafe?: boolean, useCapture?: boolean): void;
82
85
  checkRequiredVersion(version: string): boolean;
83
- private getStartInfo;
86
+ private getTrackerInfo;
84
87
  getSessionInfo(): {
85
88
  userUUID: string | null;
86
89
  projectKey: string;
87
90
  revID: string;
88
- timestamp: number;
89
91
  trackerVersion: string;
90
92
  isSnippet: boolean;
91
- sessionID: string | null;
93
+ sessionID: string | undefined;
92
94
  metadata: Record<string, string>;
93
95
  userID: string | null;
96
+ timestamp: number;
97
+ projectID?: string | undefined;
94
98
  };
95
99
  getSessionToken(): string | undefined;
96
100
  getSessionID(): string | undefined;
101
+ getSessionURL(): string | undefined;
97
102
  getHost(): string;
98
103
  getProjectKey(): string;
99
104
  getBaseHref(): string;
@@ -103,7 +108,7 @@ export default class App {
103
108
  resetNextPageSession(flag: boolean): void;
104
109
  private _start;
105
110
  start(options?: StartOptions): Promise<StartPromiseReturn>;
106
- stop(calledFromAPI?: boolean, restarting?: boolean): void;
111
+ stop(stopWorker?: boolean): void;
107
112
  restart(): void;
108
113
  }
109
114
  export {};
package/cjs/app/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DEFAULT_INGEST_POINT = void 0;
4
- const messages_js_1 = require("../common/messages.js");
4
+ const messages_gen_js_1 = require("./messages.gen.js");
5
5
  const utils_js_1 = require("../utils.js");
6
6
  const nodes_js_1 = require("./nodes.js");
7
7
  const top_observer_js_1 = require("./observer/top_observer.js");
@@ -10,8 +10,8 @@ const ticker_js_1 = require("./ticker.js");
10
10
  const logger_js_1 = require("./logger.js");
11
11
  const session_js_1 = require("./session.js");
12
12
  const performance_js_1 = require("../modules/performance.js");
13
- const CANCELED = "canceled";
14
- const START_ERROR = ":(";
13
+ const CANCELED = 'canceled';
14
+ const START_ERROR = ':(';
15
15
  const UnsuccessfulStart = (reason) => ({ reason, success: false });
16
16
  const SuccessfulStart = (body) => (Object.assign(Object.assign({}, body), { success: true }));
17
17
  var ActivityState;
@@ -32,7 +32,7 @@ class App {
32
32
  this.stopCallbacks = [];
33
33
  this.commitCallbacks = [];
34
34
  this.activityState = ActivityState.NotActive;
35
- this.version = '3.6.3'; // TODO: version compatability check inside each plugin.
35
+ this.version = '4.0.0'; // TODO: version compatability check inside each plugin.
36
36
  this.projectKey = projectKey;
37
37
  this.options = Object.assign({
38
38
  revID: '',
@@ -46,8 +46,8 @@ class App {
46
46
  verbose: false,
47
47
  __is_snippet: false,
48
48
  __debug_report_edp: null,
49
- localStorage: window.localStorage,
50
- sessionStorage: window.sessionStorage,
49
+ localStorage: window === null || window === void 0 ? void 0 : window.localStorage,
50
+ sessionStorage: window === null || window === void 0 ? void 0 : window.sessionStorage,
51
51
  }, options);
52
52
  this.revID = this.options.revID;
53
53
  this.sanitizer = new sanitizer_js_1.default(this, options);
@@ -57,32 +57,33 @@ class App {
57
57
  this.ticker.attach(() => this.commit());
58
58
  this.debug = new logger_js_1.default(this.options.__debug__);
59
59
  this.notify = new logger_js_1.default(this.options.verbose ? logger_js_1.LogLevel.Warnings : logger_js_1.LogLevel.Silent);
60
- this.session = new session_js_1.default();
60
+ this.localStorage = this.options.localStorage || window.localStorage;
61
+ this.sessionStorage = this.options.sessionStorage || window.sessionStorage;
62
+ this.session = new session_js_1.default(this, this.options);
61
63
  this.session.attachUpdateCallback(({ userID, metadata }) => {
62
- if (userID != null) { // TODO: nullable userID
63
- this.send(new messages_js_1.UserID(userID));
64
+ if (userID != null) {
65
+ // TODO: nullable userID
66
+ this.send((0, messages_gen_js_1.UserID)(userID));
64
67
  }
65
68
  if (metadata != null) {
66
- Object.entries(metadata).forEach(([key, value]) => this.send(new messages_js_1.Metadata(key, value)));
69
+ Object.entries(metadata).forEach(([key, value]) => this.send((0, messages_gen_js_1.Metadata)(key, value)));
67
70
  }
68
71
  });
69
- this.localStorage = this.options.localStorage;
70
- this.sessionStorage = this.options.sessionStorage;
72
+ // @depricated (use sessionHash on start instead)
71
73
  if (sessionToken != null) {
72
- this.sessionStorage.setItem(this.options.session_token_key, sessionToken);
74
+ this.session.applySessionHash(sessionToken);
73
75
  }
74
76
  try {
75
- this.worker = new Worker(URL.createObjectURL(new Blob([`"use strict";function t(t){function i(...i){return new t(...i)}return i.prototype=t.prototype,i}const i=new Map;const s=t(class{constructor(t,i,s){this.pageNo=t,this.firstIndex=i,this.timestamp=s,this._id=80}encode(t){return t.uint(80)&&t.uint(this.pageNo)&&t.uint(this.firstIndex)&&t.int(this.timestamp)}});i.set(80,s);const e=t(class{constructor(t){this.timestamp=t,this._id=0}encode(t){return t.uint(0)&&t.uint(this.timestamp)}});i.set(0,e);const n=t(class{constructor(t,i,s){this.url=t,this.referrer=i,this.navigationStart=s,this._id=4}encode(t){return t.uint(4)&&t.string(this.url)&&t.string(this.referrer)&&t.uint(this.navigationStart)}});i.set(4,n);const r=t(class{constructor(t,i){this.width=t,this.height=i,this._id=5}encode(t){return t.uint(5)&&t.uint(this.width)&&t.uint(this.height)}});i.set(5,r);const h=t(class{constructor(t,i){this.x=t,this.y=i,this._id=6}encode(t){return t.uint(6)&&t.int(this.x)&&t.int(this.y)}});i.set(6,h);const o=t(class{constructor(){this._id=7}encode(t){return t.uint(7)}});i.set(7,o);const c=t(class{constructor(t,i,s,e,n){this.id=t,this.parentID=i,this.index=s,this.tag=e,this.svg=n,this._id=8}encode(t){return t.uint(8)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)&&t.string(this.tag)&&t.boolean(this.svg)}});i.set(8,c);const a=t(class{constructor(t,i,s){this.id=t,this.parentID=i,this.index=s,this._id=9}encode(t){return t.uint(9)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});i.set(9,a);const u=t(class{constructor(t,i,s){this.id=t,this.parentID=i,this.index=s,this._id=10}encode(t){return t.uint(10)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});i.set(10,u);const d=t(class{constructor(t){this.id=t,this._id=11}encode(t){return t.uint(11)&&t.uint(this.id)}});i.set(11,d);const l=t(class{constructor(t,i,s){this.id=t,this.name=i,this.value=s,this._id=12}encode(t){return t.uint(12)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)}});i.set(12,l);const p=t(class{constructor(t,i){this.id=t,this.name=i,this._id=13}encode(t){return t.uint(13)&&t.uint(this.id)&&t.string(this.name)}});i.set(13,p);const g=t(class{constructor(t,i){this.id=t,this.data=i,this._id=14}encode(t){return t.uint(14)&&t.uint(this.id)&&t.string(this.data)}});i.set(14,g);const m=t(class{constructor(t,i,s){this.id=t,this.x=i,this.y=s,this._id=16}encode(t){return t.uint(16)&&t.uint(this.id)&&t.int(this.x)&&t.int(this.y)}});i.set(16,m);const f=t(class{constructor(t,i){this.id=t,this.label=i,this._id=17}encode(t){return t.uint(17)&&t.uint(this.id)&&t.string(this.label)}});i.set(17,f);const y=t(class{constructor(t,i,s){this.id=t,this.value=i,this.mask=s,this._id=18}encode(t){return t.uint(18)&&t.uint(this.id)&&t.string(this.value)&&t.int(this.mask)}});i.set(18,y);const _=t(class{constructor(t,i){this.id=t,this.checked=i,this._id=19}encode(t){return t.uint(19)&&t.uint(this.id)&&t.boolean(this.checked)}});i.set(19,_);const v=t(class{constructor(t,i){this.x=t,this.y=i,this._id=20}encode(t){return t.uint(20)&&t.uint(this.x)&&t.uint(this.y)}});i.set(20,v);const S=t(class{constructor(t,i){this.level=t,this.value=i,this._id=22}encode(t){return t.uint(22)&&t.string(this.level)&&t.string(this.value)}});i.set(22,S);const b=t(class{constructor(t,i,s,e,n,r,h,o,c){this.requestStart=t,this.responseStart=i,this.responseEnd=s,this.domContentLoadedEventStart=e,this.domContentLoadedEventEnd=n,this.loadEventStart=r,this.loadEventEnd=h,this.firstPaint=o,this.firstContentfulPaint=c,this._id=23}encode(t){return t.uint(23)&&t.uint(this.requestStart)&&t.uint(this.responseStart)&&t.uint(this.responseEnd)&&t.uint(this.domContentLoadedEventStart)&&t.uint(this.domContentLoadedEventEnd)&&t.uint(this.loadEventStart)&&t.uint(this.loadEventEnd)&&t.uint(this.firstPaint)&&t.uint(this.firstContentfulPaint)}});i.set(23,b);const w=t(class{constructor(t,i,s){this.speedIndex=t,this.visuallyComplete=i,this.timeToInteractive=s,this._id=24}encode(t){return t.uint(24)&&t.uint(this.speedIndex)&&t.uint(this.visuallyComplete)&&t.uint(this.timeToInteractive)}});i.set(24,w);const E=t(class{constructor(t,i,s){this.name=t,this.message=i,this.payload=s,this._id=25}encode(t){return t.uint(25)&&t.string(this.name)&&t.string(this.message)&&t.string(this.payload)}});i.set(25,E);const x=t(class{constructor(t,i){this.name=t,this.payload=i,this._id=27}encode(t){return t.uint(27)&&t.string(this.name)&&t.string(this.payload)}});i.set(27,x);const T=t(class{constructor(t){this.id=t,this._id=28}encode(t){return t.uint(28)&&t.string(this.id)}});i.set(28,T);const z=t(class{constructor(t){this.id=t,this._id=29}encode(t){return t.uint(29)&&t.string(this.id)}});i.set(29,z);const k=t(class{constructor(t,i){this.key=t,this.value=i,this._id=30}encode(t){return t.uint(30)&&t.string(this.key)&&t.string(this.value)}});i.set(30,k);const A=t(class{constructor(t,i,s){this.id=t,this.rule=i,this.index=s,this._id=37}encode(t){return t.uint(37)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)}});i.set(37,A);const I=t(class{constructor(t,i){this.id=t,this.index=i,this._id=38}encode(t){return t.uint(38)&&t.uint(this.id)&&t.uint(this.index)}});i.set(38,I);const L=t(class{constructor(t,i,s,e,n,r,h){this.method=t,this.url=i,this.request=s,this.response=e,this.status=n,this.timestamp=r,this.duration=h,this._id=39}encode(t){return t.uint(39)&&t.string(this.method)&&t.string(this.url)&&t.string(this.request)&&t.string(this.response)&&t.uint(this.status)&&t.uint(this.timestamp)&&t.uint(this.duration)}});i.set(39,L);const C=t(class{constructor(t,i,s,e){this.name=t,this.duration=i,this.args=s,this.result=e,this._id=40}encode(t){return t.uint(40)&&t.string(this.name)&&t.uint(this.duration)&&t.string(this.args)&&t.string(this.result)}});i.set(40,C);const M=t(class{constructor(t,i){this.key=t,this.value=i,this._id=41}encode(t){return t.uint(41)&&t.string(this.key)&&t.string(this.value)}});i.set(41,M);const N=t(class{constructor(t){this.type=t,this._id=42}encode(t){return t.uint(42)&&t.string(this.type)}});i.set(42,N);const B=t(class{constructor(t,i,s){this.action=t,this.state=i,this.duration=s,this._id=44}encode(t){return t.uint(44)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});i.set(44,B);const U=t(class{constructor(t,i){this.mutation=t,this.state=i,this._id=45}encode(t){return t.uint(45)&&t.string(this.mutation)&&t.string(this.state)}});i.set(45,U);const R=t(class{constructor(t,i){this.type=t,this.payload=i,this._id=46}encode(t){return t.uint(46)&&t.string(this.type)&&t.string(this.payload)}});i.set(46,R);const O=t(class{constructor(t,i,s){this.action=t,this.state=i,this.duration=s,this._id=47}encode(t){return t.uint(47)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});i.set(47,O);const P=t(class{constructor(t,i,s,e){this.operationKind=t,this.operationName=i,this.variables=s,this.response=e,this._id=48}encode(t){return t.uint(48)&&t.string(this.operationKind)&&t.string(this.operationName)&&t.string(this.variables)&&t.string(this.response)}});i.set(48,P);const q=t(class{constructor(t,i,s,e){this.frames=t,this.ticks=i,this.totalJSHeapSize=s,this.usedJSHeapSize=e,this._id=49}encode(t){return t.uint(49)&&t.int(this.frames)&&t.int(this.ticks)&&t.uint(this.totalJSHeapSize)&&t.uint(this.usedJSHeapSize)}});i.set(49,q);const D=t(class{constructor(t,i,s,e,n,r,h,o){this.timestamp=t,this.duration=i,this.ttfb=s,this.headerSize=e,this.encodedBodySize=n,this.decodedBodySize=r,this.url=h,this.initiator=o,this._id=53}encode(t){return t.uint(53)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.ttfb)&&t.uint(this.headerSize)&&t.uint(this.encodedBodySize)&&t.uint(this.decodedBodySize)&&t.string(this.url)&&t.string(this.initiator)}});i.set(53,D);const W=t(class{constructor(t,i){this.downlink=t,this.type=i,this._id=54}encode(t){return t.uint(54)&&t.uint(this.downlink)&&t.string(this.type)}});i.set(54,W);const H=t(class{constructor(t){this.hidden=t,this._id=55}encode(t){return t.uint(55)&&t.boolean(this.hidden)}});i.set(55,H);const J=t(class{constructor(t,i,s,e,n,r,h){this.timestamp=t,this.duration=i,this.context=s,this.containerType=e,this.containerSrc=n,this.containerId=r,this.containerName=h,this._id=59}encode(t){return t.uint(59)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.context)&&t.uint(this.containerType)&&t.string(this.containerSrc)&&t.string(this.containerId)&&t.string(this.containerName)}});i.set(59,J);const F=t(class{constructor(t,i,s,e){this.id=t,this.name=i,this.value=s,this.baseURL=e,this._id=60}encode(t){return t.uint(60)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)&&t.string(this.baseURL)}});i.set(60,F);const X=t(class{constructor(t,i,s){this.id=t,this.data=i,this.baseURL=s,this._id=61}encode(t){return t.uint(61)&&t.uint(this.id)&&t.string(this.data)&&t.string(this.baseURL)}});i.set(61,X);const G=t(class{constructor(t,i){this.type=t,this.value=i,this._id=63}encode(t){return t.uint(63)&&t.string(this.type)&&t.string(this.value)}});i.set(63,G);const K=t(class{constructor(t,i){this.name=t,this.payload=i,this._id=64}encode(t){return t.uint(64)&&t.string(this.name)&&t.string(this.payload)}});i.set(64,K);const j=t(class{constructor(){this._id=65}encode(t){return t.uint(65)}});i.set(65,j);const Q=t(class{constructor(t,i,s,e){this.id=t,this.rule=i,this.index=s,this.baseURL=e,this._id=67}encode(t){return t.uint(67)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)&&t.string(this.baseURL)}});i.set(67,Q);const V=t(class{constructor(t,i,s,e){this.id=t,this.hesitationTime=i,this.label=s,this.selector=e,this._id=69}encode(t){return t.uint(69)&&t.uint(this.id)&&t.uint(this.hesitationTime)&&t.string(this.label)&&t.string(this.selector)}});i.set(69,V);const Y=t(class{constructor(t,i){this.frameID=t,this.id=i,this._id=70}encode(t){return t.uint(70)&&t.uint(this.frameID)&&t.uint(this.id)}});i.set(70,Y);class Z{constructor(t,i,s,e=10,n=1e3){this.onUnauthorised=i,this.onFailure=s,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.ingestURL=t+"/v1/web/i"}authorise(t){this.token=t}push(t){this.busy||!this.token?this.queue.push(t):this.sendBatch(t)}retry(t){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure():(this.attemptsCount++,setTimeout(()=>this.sendBatch(t),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t){this.busy=!0,fetch(this.ingestURL,{body:t,method:"POST",headers:{Authorization:"Bearer "+this.token},keepalive:t.length<65536}).then(i=>{if(401===i.status)return this.busy=!1,void this.onUnauthorised();if(i.status>=400)return void this.retry(t);this.attemptsCount=0;const s=this.queue.shift();s?this.sendBatch(s):this.busy=!1}).catch(i=>{console.warn("OpenReplay:",i),this.retry(t)})}clean(){this.queue.length=0}}const tt="function"==typeof TextEncoder?new TextEncoder:{encode(t){const i=t.length,s=new Uint8Array(3*i);let e=-1;for(var n=0,r=0,h=0;h!==i;){if(n=t.charCodeAt(h),h+=1,n>=55296&&n<=56319){if(h===i){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;break}if(!((r=t.charCodeAt(h))>=56320&&r<=57343)){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;continue}if(h+=1,(n=1024*(n-55296)+r-56320+65536)>65535){s[e+=1]=240|n>>>18,s[e+=1]=128|n>>>12&63,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n;continue}}n<=127?s[e+=1]=0|n:n<=2047?(s[e+=1]=192|n>>>6,s[e+=1]=128|63&n):(s[e+=1]=224|n>>>12,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n)}return s.subarray(0,e+1)}};class it{constructor(t){this.size=t,this.offset=0,this.checkpointOffset=0,this.data=new Uint8Array(t)}checkpoint(){this.checkpointOffset=this.offset}isEmpty(){return 0===this.offset}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=tt.encode(t),s=i.byteLength;return!(!this.uint(s)||this.offset+s>this.size)&&(this.data.set(i,this.offset),this.offset+=s,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}class st{constructor(t,i,s){this.pageNo=t,this.timestamp=i,this.onBatch=s,this.nextIndex=0,this.beaconSize=2e5,this.writer=new it(this.beaconSize),this.isEmpty=!0,this.beaconSizeLimit=1e6,this.prepare()}prepare(){this.writer.isEmpty()&&new s(this.pageNo,this.nextIndex,this.timestamp).encode(this.writer)}write(t){const i=t.encode(this.writer);return i&&(this.isEmpty=!1,this.writer.checkpoint(),this.nextIndex++),i}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){for(t instanceof e&&(this.timestamp=t.timestamp);!this.write(t);){if(this.finaliseBatch(),this.beaconSize===this.beaconSizeLimit)return console.warn("OpenReplay: beacon size overflow. Skipping large message."),this.writer.reset(),this.prepare(),void(this.isEmpty=!0);this.beaconSize=Math.min(2*this.beaconSize,this.beaconSizeLimit),this.writer=new it(this.beaconSize),this.prepare(),this.isEmpty=!0}}finaliseBatch(){this.isEmpty||(this.onBatch(this.writer.flush()),this.prepare(),this.isEmpty=!0)}clean(){this.writer.reset()}}var et;!function(t){t[t.NotActive=0]="NotActive",t[t.Starting=1]="Starting",t[t.Stopping=2]="Stopping",t[t.Active=3]="Active"}(et||(et={}));let nt=null,rt=null;function ht(){rt&&rt.finaliseBatch()}function ot(){et.Stopping,null!==at&&(clearInterval(at),at=null),rt&&(rt.clean(),rt=null),et.NotActive}et.NotActive;let ct,at=null;self.onmessage=({data:t})=>{if(null!=t){if("stop"===t)return ht(),void ot();if(Array.isArray(t)){if(!rt)throw new Error("WebWorker: writer not initialised. Service Should be Started.");const s=rt;t.forEach(t=>{const e=new(i.get(t._id));Object.assign(e,t),e instanceof H&&(e.hidden?ct=setTimeout(()=>self.postMessage("restart"),18e5):clearTimeout(ct)),s.writeMessage(e)})}else{if("start"===t.type)return et.Starting,nt=new Z(t.ingestPoint,()=>{self.postMessage("restart")},()=>{nt&&(nt.clean(),nt=null),ot(),self.postMessage("failed")},t.connAttemptCount,t.connAttemptGap),rt=new st(t.pageNo,t.timestamp,t=>nt&&nt.push(t)),null===at&&(at=setInterval(ht,1e4)),et.Active;if("auth"===t.type){if(!nt)throw new Error("WebWorker: sender not initialised. Received auth.");if(!rt)throw new Error("WebWorker: writer not initialised. Received auth.");return nt.authorise(t.token),void(t.beaconSizeLimit&&rt.setBeaconSizeLimit(t.beaconSizeLimit))}}}else ht()};
76
- `], { type: 'text/javascript' })));
77
- this.worker.onerror = e => {
78
- this._debug("webworker_error", e);
77
+ this.worker = new Worker(URL.createObjectURL(new Blob(['"use strict";class t{constructor(t,i,s,e=10,n=1e3){this.onUnauthorised=i,this.onFailure=s,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.ingestURL=t+"/v1/web/i"}authorise(t){this.token=t}push(t){this.busy||!this.token?this.queue.push(t):this.sendBatch(t)}retry(t){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure():(this.attemptsCount++,setTimeout(()=>this.sendBatch(t),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t){this.busy=!0,fetch(this.ingestURL,{body:t,method:"POST",headers:{Authorization:"Bearer "+this.token},keepalive:t.length<65536}).then(i=>{if(401===i.status)return this.busy=!1,void this.onUnauthorised();if(i.status>=400)return void this.retry(t);this.attemptsCount=0;const s=this.queue.shift();s?this.sendBatch(s):this.busy=!1}).catch(i=>{console.warn("OpenReplay:",i),this.retry(t)})}clean(){this.queue.length=0}}const i="function"==typeof TextEncoder?new TextEncoder:{encode(t){const i=t.length,s=new Uint8Array(3*i);let e=-1;for(let n=0,r=0,h=0;h!==i;){if(n=t.charCodeAt(h),h+=1,n>=55296&&n<=56319){if(h===i){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;break}if(r=t.charCodeAt(h),!(r>=56320&&r<=57343)){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;continue}if(n=1024*(n-55296)+r-56320+65536,h+=1,n>65535){s[e+=1]=240|n>>>18,s[e+=1]=128|n>>>12&63,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n;continue}}n<=127?s[e+=1]=0|n:n<=2047?(s[e+=1]=192|n>>>6,s[e+=1]=128|63&n):(s[e+=1]=224|n>>>12,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n)}return s.subarray(0,e+1)}};class s extends class{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}isEmpty(){return 0===this.offset}skip(t){return this.offset+=t,this.offset<=this.size}set(t,i){this.data.set(t,i)}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 s=i.encode(t),e=s.byteLength;return!(!this.uint(e)||this.offset+e>this.size)&&(this.data.set(s,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}}{encode(t){switch(t[0]){case 81:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.int(t[4])&&this.string(t[5]);case 82:return this.uint(t[1])&&this.uint(t[2]);case 0:return this.uint(t[1]);case 4:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 5: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:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3]);case 11:return this.uint(t[1]);case 12:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 13:case 14: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 17:return this.uint(t[1])&&this.string(t[2]);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 20:return this.uint(t[1])&&this.uint(t[2]);case 22: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 24:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3]);case 25:return this.string(t[1])&&this.string(t[2])&&this.string(t[3]);case 27:return this.string(t[1])&&this.string(t[2]);case 28:case 29:return this.string(t[1]);case 30:return this.string(t[1])&&this.string(t[2]);case 37:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3]);case 38:return this.uint(t[1])&&this.uint(t[2]);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 41:return this.string(t[1])&&this.string(t[2]);case 42:return this.string(t[1]);case 44:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 45:case 46:return this.string(t[1])&&this.string(t[2]);case 47:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 48:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);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 54:return this.uint(t[1])&&this.string(t[2]);case 55:return this.boolean(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 60:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 61:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 63:case 64:return this.string(t[1])&&this.string(t[2]);case 67:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.string(t[4]);case 69:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4]);case 70:return this.uint(t[1])&&this.uint(t[2]);case 71:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 73:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.string(t[4]);case 75:case 76:case 77:return this.uint(t[1])&&this.uint(t[2])}}}class e{constructor(t,i,e,n){this.pageNo=t,this.timestamp=i,this.url=e,this.onBatch=n,this.nextIndex=0,this.beaconSize=2e5,this.encoder=new s(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,i){for(let i=0;i<3;i++)this.sizeBuffer[i]=t>>8*i;this.encoder.set(this.sizeBuffer,i)}prepare(){if(!this.encoder.isEmpty())return;const t=[81,1,this.pageNo,this.nextIndex,this.timestamp,this.url];this.writeType(t),this.writeFields(t),this.isEmpty=!0}writeWithSize(t){const i=this.encoder;if(!this.writeType(t)||!i.skip(3))return!1;const s=i.getCurrentOffset(),e=this.writeFields(t);if(e){const e=i.getCurrentOffset()-s;if(e>16777215)return console.warn("OpenReplay: max message size overflow."),!1;this.writeSizeAt(e,s-3),i.checkpoint(),this.isEmpty=this.isEmpty&&0===t[0],this.nextIndex++}return e}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){if(0===t[0]&&(this.timestamp=t[1]),4===t[0]&&(this.url=t[1]),!this.writeWithSize(t))for(this.finaliseBatch();!this.writeWithSize(t);){if(this.beaconSize===this.beaconSizeLimit)return console.warn("OpenReplay: beacon size overflow. Skipping large message.",t,this),this.encoder.reset(),void this.prepare();this.beaconSize=Math.min(2*this.beaconSize,this.beaconSizeLimit),this.encoder=new s(this.beaconSize),this.prepare()}}finaliseBatch(){this.isEmpty||(this.onBatch(this.encoder.flush()),this.prepare())}clean(){this.encoder.reset()}}var n;!function(t){t[t.NotActive=0]="NotActive",t[t.Starting=1]="Starting",t[t.Stopping=2]="Stopping",t[t.Active=3]="Active"}(n||(n={}));let r=null,h=null;function u(){h&&h.finaliseBatch()}function a(){n.Stopping,null!==c&&(clearInterval(c),c=null),h&&(h.clean(),h=null),n.NotActive}n.NotActive;let o,c=null;self.onmessage=({data:i})=>{if(null!=i){if("stop"===i)return u(),void a();if(Array.isArray(i)){if(!h)throw new Error("WebWorker: writer not initialised. Service Should be Started.");const t=h;i.forEach(i=>{55===i[0]&&(i[1]?o=setTimeout(()=>self.postMessage("restart"),18e5):clearTimeout(o)),t.writeMessage(i)})}else{if("start"===i.type)return n.Starting,r=new t(i.ingestPoint,()=>{self.postMessage("restart")},()=>{r&&(r.clean(),r=null),a(),self.postMessage("failed")},i.connAttemptCount,i.connAttemptGap),h=new e(i.pageNo,i.timestamp,i.url,t=>r&&r.push(t)),null===c&&(c=setInterval(u,1e4)),n.Active;if("auth"===i.type){if(!r)throw new Error("WebWorker: sender not initialised. Received auth.");if(!h)throw new Error("WebWorker: writer not initialised. Received auth.");return r.authorise(i.token),void(i.beaconSizeLimit&&h.setBeaconSizeLimit(i.beaconSizeLimit))}}}else u()};'], { type: 'text/javascript' })));
78
+ this.worker.onerror = (e) => {
79
+ this._debug('webworker_error', e);
79
80
  };
80
81
  this.worker.onmessage = ({ data }) => {
81
- if (data === "failed") {
82
+ if (data === 'failed') {
82
83
  this.stop();
83
- this._debug("worker_failed", {}); // add context (from worker)
84
+ this._debug('worker_failed', {}); // add context (from worker)
84
85
  }
85
- else if (data === "restart") {
86
+ else if (data === 'restart') {
86
87
  this.stop();
87
88
  this.start({ forceNew: true });
88
89
  }
@@ -99,7 +100,7 @@ class App {
99
100
  this.attachEventListener(document, 'visibilitychange', alertWorker, false);
100
101
  }
101
102
  catch (e) {
102
- this._debug("worker_start", e);
103
+ this._debug('worker_start', e);
103
104
  }
104
105
  }
105
106
  _debug(context, e) {
@@ -109,11 +110,11 @@ class App {
109
110
  headers: { 'Content-Type': 'application/json' },
110
111
  body: JSON.stringify({
111
112
  context,
112
- error: `${e}`
113
- })
113
+ error: `${e}`,
114
+ }),
114
115
  });
115
116
  }
116
- this.debug.error("OpenReplay error: ", context, e);
117
+ this.debug.error('OpenReplay error: ', context, e);
117
118
  }
118
119
  send(message, urgent = false) {
119
120
  if (this.activityState === ActivityState.NotActive) {
@@ -130,9 +131,9 @@ class App {
130
131
  }
131
132
  commit() {
132
133
  if (this.worker && this.messages.length) {
133
- this.messages.unshift(new messages_js_1.Timestamp((0, utils_js_1.timestamp)()));
134
+ this.messages.unshift((0, messages_gen_js_1.Timestamp)((0, utils_js_1.timestamp)()));
134
135
  this.worker.postMessage(this.messages);
135
- this.commitCallbacks.forEach(cb => cb(this.messages));
136
+ this.commitCallbacks.forEach((cb) => cb(this.messages));
136
137
  this.messages.length = 0;
137
138
  }
138
139
  }
@@ -143,8 +144,8 @@ class App {
143
144
  fn.apply(this, args);
144
145
  }
145
146
  catch (e) {
146
- app._debug("safe_fn_call", e);
147
- // time: timestamp(),
147
+ app._debug('safe_fn_call', e);
148
+ // time: now(),
148
149
  // name: e.name,
149
150
  // message: e.message,
150
151
  // stack: e.stack
@@ -152,57 +153,72 @@ class App {
152
153
  }; // TODO: correct typing
153
154
  }
154
155
  attachCommitCallback(cb) {
156
+ // TODO!: what if start callback added when activityState === Active ?
157
+ // For example - attachEventListener() called during dynamic <iframe> appearance
155
158
  this.commitCallbacks.push(cb);
156
159
  }
157
- attachStartCallback(cb) {
160
+ attachStartCallback(cb, useSafe = false) {
161
+ if (useSafe) {
162
+ cb = this.safe(cb);
163
+ }
158
164
  this.startCallbacks.push(cb);
159
165
  }
160
- attachStopCallback(cb) {
166
+ attachStopCallback(cb, useSafe = false) {
167
+ if (useSafe) {
168
+ cb = this.safe(cb);
169
+ }
161
170
  this.stopCallbacks.push(cb);
162
171
  }
163
172
  attachEventListener(target, type, listener, useSafe = true, useCapture = true) {
164
173
  if (useSafe) {
165
174
  listener = this.safe(listener);
166
175
  }
167
- this.attachStartCallback(() => target.addEventListener(type, listener, useCapture));
168
- this.attachStopCallback(() => target.removeEventListener(type, listener, useCapture));
176
+ this.attachStartCallback(() => target.addEventListener(type, listener, useCapture), useSafe);
177
+ this.attachStopCallback(() => target.removeEventListener(type, listener, useCapture), useSafe);
169
178
  }
170
179
  // TODO: full correct semantic
171
180
  checkRequiredVersion(version) {
172
181
  const reqVer = version.split(/[.-]/);
173
182
  const ver = this.version.split(/[.-]/);
174
183
  for (let i = 0; i < 3; i++) {
184
+ if (isNaN(Number(ver[i])) || isNaN(Number(reqVer[i]))) {
185
+ return false;
186
+ }
175
187
  if (Number(ver[i]) > Number(reqVer[i])) {
176
188
  return true;
177
189
  }
178
- if (Number(ver[i]) < Number(reqVer[i]) || isNaN(Number(ver[i])) || isNaN(Number(reqVer[i]))) {
190
+ if (Number(ver[i]) < Number(reqVer[i])) {
179
191
  return false;
180
192
  }
181
193
  }
182
194
  return true;
183
195
  }
184
- getStartInfo() {
196
+ getTrackerInfo() {
185
197
  return {
186
198
  userUUID: this.localStorage.getItem(this.options.local_uuid_key),
187
199
  projectKey: this.projectKey,
188
200
  revID: this.revID,
189
- timestamp: (0, utils_js_1.timestamp)(),
190
201
  trackerVersion: this.version,
191
202
  isSnippet: this.options.__is_snippet,
192
203
  };
193
204
  }
194
205
  getSessionInfo() {
195
- return Object.assign(Object.assign({}, this.session.getInfo()), this.getStartInfo());
206
+ return Object.assign(Object.assign({}, this.session.getInfo()), this.getTrackerInfo());
196
207
  }
197
208
  getSessionToken() {
198
- const token = this.sessionStorage.getItem(this.options.session_token_key);
199
- if (token !== null) {
200
- return token;
201
- }
209
+ return this.session.getSessionToken();
202
210
  }
203
211
  getSessionID() {
204
212
  return this.session.getInfo().sessionID || undefined;
205
213
  }
214
+ getSessionURL() {
215
+ const { projectID, sessionID } = this.session.getInfo();
216
+ if (!projectID || !sessionID) {
217
+ this.debug.error('OpenReplay error: Unable to build session URL');
218
+ return undefined;
219
+ }
220
+ return this.options.ingestPoint.replace(/ingest$/, `${projectID}/session/${sessionID}`);
221
+ }
206
222
  getHost() {
207
223
  return new URL(this.options.ingestPoint).hostname;
208
224
  }
@@ -215,18 +231,19 @@ class App {
215
231
  return this.options.resourceBaseHref;
216
232
  }
217
233
  else if (typeof this.options.resourceBaseHref === 'object') {
218
- //switch between types
234
+ //TODO: switch between types
219
235
  }
220
236
  if (document.baseURI) {
221
237
  return document.baseURI;
222
238
  }
223
239
  // IE only
224
- return ((_b = (_a = document.head) === null || _a === void 0 ? void 0 : _a.getElementsByTagName("base")[0]) === null || _b === void 0 ? void 0 : _b.getAttribute("href")) || location.origin + location.pathname;
240
+ return (((_b = (_a = document.head) === null || _a === void 0 ? void 0 : _a.getElementsByTagName('base')[0]) === null || _b === void 0 ? void 0 : _b.getAttribute('href')) ||
241
+ location.origin + location.pathname);
225
242
  }
226
243
  resolveResourceURL(resourceURL) {
227
244
  const base = new URL(this.getBaseHref());
228
- base.pathname += "/" + new URL(resourceURL).pathname;
229
- base.pathname.replace(/\/+/g, "/");
245
+ base.pathname += '/' + new URL(resourceURL).pathname;
246
+ base.pathname.replace(/\/+/g, '/');
230
247
  return base.toString();
231
248
  }
232
249
  isServiceURL(url) {
@@ -245,30 +262,28 @@ class App {
245
262
  }
246
263
  _start(startOpts) {
247
264
  if (!this.worker) {
248
- return Promise.resolve(UnsuccessfulStart("No worker found: perhaps, CSP is not set."));
265
+ return Promise.resolve(UnsuccessfulStart('No worker found: perhaps, CSP is not set.'));
249
266
  }
250
267
  if (this.activityState !== ActivityState.NotActive) {
251
- return Promise.resolve(UnsuccessfulStart("OpenReplay: trying to call `start()` on the instance that has been started already."));
268
+ return Promise.resolve(UnsuccessfulStart('OpenReplay: trying to call `start()` on the instance that has been started already.'));
252
269
  }
253
270
  this.activityState = ActivityState.Starting;
254
- let pageNo = 0;
255
- const pageNoStr = this.sessionStorage.getItem(this.options.session_pageno_key);
256
- if (pageNoStr != null) {
257
- pageNo = parseInt(pageNoStr);
258
- pageNo++;
271
+ if (startOpts.sessionHash) {
272
+ this.session.applySessionHash(startOpts.sessionHash);
259
273
  }
260
- this.sessionStorage.setItem(this.options.session_pageno_key, pageNo.toString());
261
- const startInfo = this.getStartInfo();
274
+ const timestamp = (0, utils_js_1.timestamp)();
262
275
  const startWorkerMsg = {
263
- type: "start",
264
- pageNo,
276
+ type: 'start',
277
+ pageNo: this.session.incPageNo(),
265
278
  ingestPoint: this.options.ingestPoint,
266
- timestamp: startInfo.timestamp,
279
+ timestamp,
280
+ url: document.URL,
267
281
  connAttemptCount: this.options.connAttemptCount,
268
282
  connAttemptGap: this.options.connAttemptGap,
269
283
  };
270
284
  this.worker.postMessage(startWorkerMsg);
271
285
  this.session.update({
286
+ // TODO: transparent "session" module logic AND explicit internal api for plugins.
272
287
  // "updating" with old metadata in order to trigger session's UpdateCallbacks.
273
288
  // (for the case of internal .start() calls, like on "restart" webworker signal or assistent connection in tracker-assist )
274
289
  metadata: startOpts.metadata || this.session.getInfo().metadata,
@@ -276,63 +291,69 @@ class App {
276
291
  });
277
292
  const sReset = this.sessionStorage.getItem(this.options.session_reset_key);
278
293
  this.sessionStorage.removeItem(this.options.session_reset_key);
279
- return window.fetch(this.options.ingestPoint + '/v1/web/start', {
294
+ return window
295
+ .fetch(this.options.ingestPoint + '/v1/web/start', {
280
296
  method: 'POST',
281
297
  headers: {
282
298
  'Content-Type': 'application/json',
283
299
  },
284
- body: JSON.stringify(Object.assign(Object.assign({}, startInfo), { userID: this.session.getInfo().userID, token: this.sessionStorage.getItem(this.options.session_token_key), deviceMemory: performance_js_1.deviceMemory,
300
+ body: JSON.stringify(Object.assign(Object.assign({}, this.getTrackerInfo()), { timestamp, userID: this.session.getInfo().userID, token: this.session.getSessionToken(), deviceMemory: performance_js_1.deviceMemory,
285
301
  jsHeapSizeLimit: performance_js_1.jsHeapSizeLimit, reset: startOpts.forceNew || sReset !== null })),
286
302
  })
287
- .then(r => {
303
+ .then((r) => {
288
304
  if (r.status === 200) {
289
305
  return r.json();
290
306
  }
291
307
  else {
292
- return r.text().then(text => text === CANCELED
308
+ return r
309
+ .text()
310
+ .then((text) => text === CANCELED
293
311
  ? Promise.reject(CANCELED)
294
312
  : Promise.reject(`Server error: ${r.status}. ${text}`));
295
313
  }
296
314
  })
297
- .then(r => {
315
+ .then((r) => {
298
316
  if (!this.worker) {
299
- return Promise.reject("no worker found after start request (this might not happen)");
317
+ return Promise.reject('no worker found after start request (this might not happen)');
300
318
  }
301
- const { token, userUUID, sessionID, beaconSizeLimit } = r;
319
+ const { token, userUUID, sessionID, projectID, beaconSizeLimit, startTimestamp, // real startTS, derived from sessionID
320
+ } = r;
302
321
  if (typeof token !== 'string' ||
303
322
  typeof userUUID !== 'string' ||
323
+ //typeof startTimestamp !== 'number' ||
324
+ //typeof sessionID !== 'string' ||
304
325
  (typeof beaconSizeLimit !== 'number' && typeof beaconSizeLimit !== 'undefined')) {
305
326
  return Promise.reject(`Incorrect server response: ${JSON.stringify(r)}`);
306
327
  }
307
- this.sessionStorage.setItem(this.options.session_token_key, token);
328
+ this.session.setSessionToken(token);
308
329
  this.localStorage.setItem(this.options.local_uuid_key, userUUID);
309
- this.session.update({ sessionID }); // TODO: no no-explicit 'any'
330
+ this.session.update({ sessionID, timestamp: startTimestamp || timestamp, projectID }); // TODO: no no-explicit 'any'
310
331
  const startWorkerMsg = {
311
- type: "auth",
332
+ type: 'auth',
312
333
  token,
313
- beaconSizeLimit
334
+ beaconSizeLimit,
314
335
  };
315
336
  this.worker.postMessage(startWorkerMsg);
316
- this.activityState = ActivityState.Active;
317
337
  const onStartInfo = { sessionToken: token, userUUID, sessionID };
318
338
  this.startCallbacks.forEach((cb) => cb(onStartInfo)); // TODO: start as early as possible (before receiving the token)
319
339
  this.observer.observe();
320
340
  this.ticker.start();
321
- this.notify.log("OpenReplay tracking started.");
341
+ this.activityState = ActivityState.Active;
342
+ this.notify.log('OpenReplay tracking started.');
322
343
  // get rid of onStart ?
323
344
  if (typeof this.options.onStart === 'function') {
324
345
  this.options.onStart(onStartInfo);
325
346
  }
326
347
  return SuccessfulStart(onStartInfo);
327
348
  })
328
- .catch(reason => {
329
- this.sessionStorage.removeItem(this.options.session_token_key);
349
+ .catch((reason) => {
330
350
  this.stop();
351
+ this.session.reset();
331
352
  if (reason === CANCELED) {
332
353
  return UnsuccessfulStart(CANCELED);
333
354
  }
334
- this.notify.log("OpenReplay was unable to start. ", reason);
335
- this._debug("session_start", reason);
355
+ this.notify.log('OpenReplay was unable to start. ', reason);
356
+ this._debug('session_start', reason);
336
357
  return UnsuccessfulStart(START_ERROR);
337
358
  });
338
359
  }
@@ -344,15 +365,15 @@ class App {
344
365
  return new Promise((resolve) => {
345
366
  const onVisibilityChange = () => {
346
367
  if (!document.hidden) {
347
- document.removeEventListener("visibilitychange", onVisibilityChange);
368
+ document.removeEventListener('visibilitychange', onVisibilityChange);
348
369
  resolve(this._start(options));
349
370
  }
350
371
  };
351
- document.addEventListener("visibilitychange", onVisibilityChange);
372
+ document.addEventListener('visibilitychange', onVisibilityChange);
352
373
  });
353
374
  }
354
375
  }
355
- stop(calledFromAPI = false, restarting = false) {
376
+ stop(stopWorker = true) {
356
377
  if (this.activityState !== ActivityState.NotActive) {
357
378
  try {
358
379
  this.sanitizer.clear();
@@ -360,12 +381,9 @@ class App {
360
381
  this.nodes.clear();
361
382
  this.ticker.stop();
362
383
  this.stopCallbacks.forEach((cb) => cb());
363
- if (calledFromAPI) {
364
- this.session.reset();
365
- }
366
- this.notify.log("OpenReplay tracking stopped.");
367
- if (this.worker && !restarting) {
368
- this.worker.postMessage("stop");
384
+ this.notify.log('OpenReplay tracking stopped.');
385
+ if (this.worker && stopWorker) {
386
+ this.worker.postMessage('stop');
369
387
  }
370
388
  }
371
389
  finally {
@@ -374,7 +392,7 @@ class App {
374
392
  }
375
393
  }
376
394
  restart() {
377
- this.stop(false, true);
395
+ this.stop(false);
378
396
  this.start({ forceNew: false });
379
397
  }
380
398
  }