noibu-react-native 0.2.3 → 0.2.5

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 (71) hide show
  1. package/dist/api/clientConfig.js +20 -27
  2. package/dist/api/helpCode.js +61 -87
  3. package/dist/api/metroplexSocket.js +72 -65
  4. package/dist/api/storedPageVisit.js +150 -208
  5. package/dist/constants.js +3 -7
  6. package/dist/entry/init.js +13 -15
  7. package/dist/monitors/{appNavigationMonitor.js → AppNavigationMonitor.js} +10 -19
  8. package/dist/monitors/BaseMonitor.js +23 -0
  9. package/dist/monitors/ClickMonitor.js +198 -0
  10. package/dist/monitors/ErrorMonitor.js +206 -0
  11. package/dist/monitors/KeyboardInputMonitor.js +60 -0
  12. package/dist/monitors/PageMonitor.js +98 -0
  13. package/dist/monitors/RequestMonitor.js +390 -0
  14. package/dist/monitors/http-tools/GqlErrorValidator.js +259 -0
  15. package/dist/monitors/{httpDataBundler.js → http-tools/HTTPDataBundler.js} +23 -102
  16. package/dist/pageVisit/{eventDebouncer.js → EventDebouncer.js} +36 -47
  17. package/dist/pageVisit/pageVisitEventError.js +3 -3
  18. package/dist/pageVisit/pageVisitEventHTTP.js +5 -4
  19. package/dist/sessionRecorder/nativeSessionRecorderSubscription.js +22 -5
  20. package/dist/sessionRecorder/sessionRecorder.js +5 -2
  21. package/dist/src/api/clientConfig.d.ts +8 -13
  22. package/dist/src/api/clientConfig.test.d.ts +1 -0
  23. package/dist/src/api/helpCode.d.ts +10 -16
  24. package/dist/src/api/metroplexSocket.d.ts +52 -71
  25. package/dist/src/api/storedPageVisit.d.ts +12 -21
  26. package/dist/src/constants.d.ts +1 -0
  27. package/dist/src/monitors/AppNavigationMonitor.d.ts +18 -0
  28. package/dist/src/monitors/BaseMonitor.d.ts +13 -0
  29. package/dist/src/monitors/BaseMonitor.test.d.ts +1 -0
  30. package/dist/src/monitors/ClickMonitor.d.ts +31 -0
  31. package/dist/src/monitors/ErrorMonitor.d.ts +63 -0
  32. package/dist/src/monitors/{keyboardInputMonitor.d.ts → KeyboardInputMonitor.d.ts} +7 -4
  33. package/dist/src/monitors/{pageMonitor.d.ts → PageMonitor.d.ts} +6 -8
  34. package/dist/src/monitors/RequestMonitor.d.ts +94 -0
  35. package/dist/src/monitors/http-tools/GqlErrorValidator.d.ts +59 -0
  36. package/dist/src/monitors/{httpDataBundler.d.ts → http-tools/HTTPDataBundler.d.ts} +13 -28
  37. package/dist/src/monitors/integrations/react-native-navigation-integration.d.ts +3 -2
  38. package/dist/src/pageVisit/{eventDebouncer.d.ts → EventDebouncer.d.ts} +3 -10
  39. package/dist/src/pageVisit/pageVisit.d.ts +1 -1
  40. package/dist/src/pageVisit/pageVisitEventHTTP.d.ts +3 -3
  41. package/dist/src/sessionRecorder/nativeSessionRecorderSubscription.d.ts +15 -0
  42. package/dist/src/storage/rnStorageProvider.d.ts +1 -1
  43. package/dist/src/storage/storage.d.ts +1 -1
  44. package/dist/src/storage/storageProvider.d.ts +2 -2
  45. package/dist/src/utils/function.d.ts +4 -5
  46. package/dist/src/utils/object.d.ts +3 -5
  47. package/dist/src/utils/polyfills.d.ts +1 -4
  48. package/dist/types/Metroplex.types.d.ts +73 -0
  49. package/dist/types/PageVisit.types.d.ts +2 -145
  50. package/dist/types/PageVisitErrors.types.d.ts +114 -0
  51. package/dist/types/PageVisitEvents.types.d.ts +91 -0
  52. package/dist/types/Storage.d.ts +1 -1
  53. package/dist/types/StoredPageVisit.types.d.ts +4 -45
  54. package/dist/utils/function.js +0 -1
  55. package/dist/utils/object.js +1 -0
  56. package/package.json +11 -7
  57. package/dist/monitors/clickMonitor.js +0 -258
  58. package/dist/monitors/errorMonitor.js +0 -202
  59. package/dist/monitors/gqlErrorValidator.js +0 -306
  60. package/dist/monitors/inputMonitor.js +0 -138
  61. package/dist/monitors/keyboardInputMonitor.js +0 -66
  62. package/dist/monitors/pageMonitor.js +0 -122
  63. package/dist/monitors/requestMonitor.js +0 -386
  64. package/dist/src/monitors/appNavigationMonitor.d.ts +0 -22
  65. package/dist/src/monitors/clickMonitor.d.ts +0 -44
  66. package/dist/src/monitors/errorMonitor.d.ts +0 -28
  67. package/dist/src/monitors/gqlErrorValidator.d.ts +0 -82
  68. package/dist/src/monitors/inputMonitor.d.ts +0 -34
  69. package/dist/src/monitors/requestMonitor.d.ts +0 -10
  70. package/dist/types/RRWeb.d.ts +0 -48
  71. package/dist/types/ReactNative.d.ts +0 -4
@@ -1,232 +1,174 @@
1
+ import { __awaiter } from 'tslib';
1
2
  import { PV_METROPLEX_TYPE, PAGE_VISIT_PART_ATT_NAME, PV_EVENTS_ATT_NAME, TYPE_ATT_NAME, USERSTEP_EVENT_TYPE, ERROR_EVENT_TYPE, NOIBU_STORED_PAGE_VISIT, SEVERITY, MAX_METROPLEX_SOCKET_INNACTIVE_TIME, PAGE_VISIT_INFORMATION_ATT_NAME, PAGE_VISIT_VID_FRAG_ATT_NAME, IS_LAST_ATT_NAME, GET_METROPLEX_POST_URL } from '../constants.js';
2
3
  import ClientConfig from './clientConfig.js';
3
4
  import { stringifyJSON, makeRequest } from '../utils/function.js';
4
5
  import Storage from '../storage/storage.js';
5
-
6
- /** @module StoredPageVisit */
6
+ import { Singleton } from '../monitors/BaseMonitor.js';
7
7
 
8
8
  /**
9
9
  * This class holds the final page visit. It flushes it to storage and then
10
10
  * finally sends it to Metroplex via the post route when the next page is loaded
11
11
  */
12
- class StoredPageVisit {
13
- /**
14
- * Creates a new instance of StoredPageVisit
15
- */
16
- constructor() {
17
- this.latestPageVisitFrag = null;
18
- this.writeTimeout = null;
19
- this.flushedStorage = false;
20
-
21
- const storage = Storage.getInstance();
22
- storage.isAvailable().then(isAvailable => {
23
- if (isAvailable) this._postPreviousPageVisit();
24
- });
25
- }
26
-
27
- /** gets the singleton instance */
28
- static getInstance() {
29
- if (!this.instance) {
30
- this.instance = new StoredPageVisit();
12
+ class StoredPageVisit extends Singleton {
13
+ /**
14
+ * Creates a new instance of StoredPageVisit
15
+ */
16
+ constructor() {
17
+ super();
18
+ const storage = Storage.getInstance();
19
+ storage.isAvailable().then(isAvailable => {
20
+ if (isAvailable)
21
+ this._postPreviousPageVisit();
22
+ });
31
23
  }
32
-
33
- return this.instance;
34
- }
35
-
36
- /**
37
- * Check if the events contain a click or location change. If they do then write the retry
38
- * queue (which contains the metroplex msg sent above) to storage
39
- * @param {} retryMessageQueue
40
- * @param {} pvInfo
41
- */
42
- checkAndStoreRetryQueue(retryMessageQueue, pvInfo) {
43
- // Get the events from the last message
44
- const { type, payload } = retryMessageQueue[retryMessageQueue.length - 1];
45
-
46
- // Only store page visit payloads
47
- if (type !== PV_METROPLEX_TYPE || !payload[PAGE_VISIT_PART_ATT_NAME]) {
48
- return;
49
- }
50
- const events = payload[PAGE_VISIT_PART_ATT_NAME][PV_EVENTS_ATT_NAME]
51
- ? payload[PAGE_VISIT_PART_ATT_NAME][PV_EVENTS_ATT_NAME]
52
- : [];
53
-
54
- const filteredEvents = events.filter(
55
- event =>
24
+ /**
25
+ * Check if the events contain a click or location change. If they do then write the retry
26
+ * queue (which contains the metroplex msg sent above) to storage
27
+ */
28
+ checkAndStoreRetryQueue(retryMessageQueue, pvInfo) {
29
+ // Get the events from the last message
30
+ const { type, payload } = retryMessageQueue[retryMessageQueue.length - 1];
31
+ // Only store page visit payloads
32
+ if (type !== PV_METROPLEX_TYPE || !payload[PAGE_VISIT_PART_ATT_NAME]) {
33
+ return;
34
+ }
35
+ const events = payload[PAGE_VISIT_PART_ATT_NAME][PV_EVENTS_ATT_NAME]
36
+ ? payload[PAGE_VISIT_PART_ATT_NAME][PV_EVENTS_ATT_NAME]
37
+ : [];
38
+ const filteredEvents = events.filter(event =>
56
39
  // Return true if the event is a userstep, error, or location event
57
40
  // Any userstep is used rather than just mouse clicks because we shouldn't
58
41
  // assume mouse clicks are the only way for any activity to happen
59
42
  event[TYPE_ATT_NAME] === USERSTEP_EVENT_TYPE ||
60
- event[TYPE_ATT_NAME] === ERROR_EVENT_TYPE,
61
- );
62
-
63
- // Only write the retry queue if it contains a user step or location change
64
- if (filteredEvents.length > 0) {
65
- this.writePageVisitsFromRetryQueue(retryMessageQueue, pvInfo);
43
+ event[TYPE_ATT_NAME] === ERROR_EVENT_TYPE);
44
+ // Only write the retry queue if it contains a user step or location change
45
+ if (filteredEvents.length > 0) {
46
+ this.writePageVisitsFromRetryQueue(retryMessageQueue, pvInfo);
47
+ }
66
48
  }
67
- }
68
-
69
- /** Writes the page visit frags in the retry queue to storage
70
- * @param {} retryMessageQueue
71
- * @param {} pvInfo
72
- */
73
- writePageVisitsFromRetryQueue(retryMessageQueue, pvInfo) {
74
- const pageVisitFrags = [];
75
- for (let i = 0; i < retryMessageQueue.length; i += 1) {
76
- const { type, payload } = retryMessageQueue[i];
77
- if (type === PV_METROPLEX_TYPE) {
78
- const frag = payload[PAGE_VISIT_PART_ATT_NAME];
79
- pageVisitFrags.push(frag);
80
- }
49
+ /** Writes the page visit frags in the retry queue to storage
50
+ */
51
+ writePageVisitsFromRetryQueue(retryMessageQueue, pvInfo) {
52
+ const pageVisitFrags = [];
53
+ for (let i = 0; i < retryMessageQueue.length; i += 1) {
54
+ const { type, payload } = retryMessageQueue[i];
55
+ if (type === PV_METROPLEX_TYPE) {
56
+ const frag = payload[PAGE_VISIT_PART_ATT_NAME];
57
+ pageVisitFrags.push(frag);
58
+ }
59
+ }
60
+ this._writePageVisitFrags(pageVisitFrags, pvInfo);
81
61
  }
82
-
83
- this._writePageVisitFrags(pageVisitFrags, pvInfo);
84
- }
85
-
86
- /** Write the given page visit frags to storage
87
- * @param {} pageVisitFrags
88
- * @param {} pvInfo
89
- */
90
- async _writePageVisitFrags(pageVisitFrags, pvInfo) {
91
- // Create a new object to write to storage that doesn't have the timeout and flush members
92
- const lsPageVisit = {
93
- pageVisitFrags,
94
- pageVisitInfo: pvInfo,
95
- timestamp: new Date(),
96
- };
97
-
98
- const storage = Storage.getInstance();
99
-
100
- const json = stringifyJSON(lsPageVisit);
101
-
102
- try {
103
- await storage.save(NOIBU_STORED_PAGE_VISIT, json);
104
- } catch (err) {
105
- await storage.remove(NOIBU_STORED_PAGE_VISIT);
106
-
107
- // Calculate current storage size
108
- const size = await storage.calculateUsedSize();
109
-
110
- ClientConfig.getInstance().postNoibuErrorAndOptionallyDisableClient(
111
- `Error writing pv to storage: ${err}, ` +
112
- `json size: ${json.length}, storage size: ${size}, ` +
113
- `${await storage.getDiagnoseInfo()}`,
114
- false,
115
- SEVERITY.error,
116
- );
62
+ /** Write the given page visit frags to storage
63
+ */
64
+ _writePageVisitFrags(pageVisitFrags, pvInfo) {
65
+ return __awaiter(this, void 0, void 0, function* () {
66
+ // Create a new object to write to storage that doesn't have the timeout and flush members
67
+ const lsPageVisit = {
68
+ pageVisitFrags,
69
+ pageVisitInfo: pvInfo,
70
+ timestamp: new Date(),
71
+ };
72
+ const storage = Storage.getInstance();
73
+ const json = stringifyJSON(lsPageVisit);
74
+ try {
75
+ yield storage.save(NOIBU_STORED_PAGE_VISIT, json);
76
+ }
77
+ catch (err) {
78
+ yield storage.remove(NOIBU_STORED_PAGE_VISIT);
79
+ // Calculate current storage size
80
+ const size = yield storage.calculateUsedSize();
81
+ ClientConfig.getInstance().postNoibuErrorAndOptionallyDisableClient(`Error writing pv to storage: ${err}, ` +
82
+ `json size: ${json.length}, storage size: ${size}, ` +
83
+ `${yield storage.getDiagnoseInfo()}`, false, SEVERITY.error);
84
+ }
85
+ });
117
86
  }
118
- }
119
-
120
- /**
121
- * Read the stored page visit from storage, create a complete page visit object
122
- * and then post that to Metroplex
123
- */
124
- async _getPostData() {
125
- const storage = Storage.getInstance();
126
-
127
- // Read the storedPageVisit from storage
128
- const data = await storage.load(NOIBU_STORED_PAGE_VISIT);
129
- if (!data) {
130
- return null;
87
+ /**
88
+ * Read the stored page visit from storage, create a complete page visit object
89
+ * and then post that to Metroplex
90
+ */
91
+ _getPostData() {
92
+ return __awaiter(this, void 0, void 0, function* () {
93
+ const storage = Storage.getInstance();
94
+ // Read the storedPageVisit from storage
95
+ const data = yield storage.load(NOIBU_STORED_PAGE_VISIT);
96
+ if (!data) {
97
+ return null;
98
+ }
99
+ let storedPageVisit = {};
100
+ try {
101
+ storedPageVisit = JSON.parse(data);
102
+ }
103
+ catch (e) {
104
+ // Remove the item since there is something corrupted
105
+ yield storage.remove(NOIBU_STORED_PAGE_VISIT);
106
+ ClientConfig.getInstance().postNoibuErrorAndOptionallyDisableClient(`Error parsing page visit string '${data}': ${e}`, false, SEVERITY.error);
107
+ return null;
108
+ }
109
+ // making sure we have the timestamp attribute since we added this logic after initially
110
+ // releasing the storedPageVisit
111
+ if (storedPageVisit.timestamp) {
112
+ // checking how long the page visit was in storage
113
+ const someTimeAgo = new Date();
114
+ someTimeAgo.setSeconds(someTimeAgo.getSeconds() - MAX_METROPLEX_SOCKET_INNACTIVE_TIME);
115
+ // if the user leaves the page for more than 35 minutes, we do not attempt
116
+ // to send the page visit since we can assume that this will create another pagevisit
117
+ if (+someTimeAgo >= Date.parse(storedPageVisit.timestamp)) {
118
+ return null;
119
+ }
120
+ }
121
+ // Copy the page visit information from storage into a new complete PV
122
+ const completePv = {
123
+ [PAGE_VISIT_INFORMATION_ATT_NAME]: storedPageVisit.pageVisitInfo,
124
+ [PAGE_VISIT_PART_ATT_NAME]: [],
125
+ [PAGE_VISIT_VID_FRAG_ATT_NAME]: [],
126
+ };
127
+ // Set is last to be true on the page visit information
128
+ completePv[PAGE_VISIT_INFORMATION_ATT_NAME][IS_LAST_ATT_NAME] = true;
129
+ // Add the page visit frags to the complete PV
130
+ for (let i = 0; i < storedPageVisit.pageVisitFrags.length; i += 1) {
131
+ completePv[PAGE_VISIT_PART_ATT_NAME].push(storedPageVisit.pageVisitFrags[i]);
132
+ }
133
+ return completePv;
134
+ });
131
135
  }
132
-
133
- let storedPageVisit = {};
134
- try {
135
- storedPageVisit = JSON.parse(data);
136
- } catch (e) {
137
- // Remove the item since there is something corrupted
138
- await storage.remove(NOIBU_STORED_PAGE_VISIT);
139
- ClientConfig.getInstance().postNoibuErrorAndOptionallyDisableClient(
140
- `Error parsing page visit string '${data}': ${e}`,
141
- false,
142
- SEVERITY.error,
143
- );
144
- return null;
136
+ /**
137
+ * Creates and tries to resolve a promise that posts the previous page visit
138
+ * to Metroplex from storage
139
+ */
140
+ _postPreviousPageVisit() {
141
+ // Whether the post promise resolves or not we need to finally
142
+ // clear the storage item and set flushed
143
+ this._getPostPageVisitPromise().finally(() => this._updateStorageFlushed());
145
144
  }
146
-
147
- // making sure we have the timestamp attribute since we added this logic after initially
148
- // releasing the storedPageVisit
149
- if (storedPageVisit.timestamp) {
150
- // checking how long the page visit was in storage
151
- const someTimeAgo = new Date();
152
- someTimeAgo.setSeconds(
153
- someTimeAgo.getSeconds() - MAX_METROPLEX_SOCKET_INNACTIVE_TIME,
154
- );
155
-
156
- // if the user leaves the page for more than 35 minutes, we do not attempt
157
- // to send the page visit since we can assume that this will create another pagevisit
158
- if (someTimeAgo >= Date.parse(storedPageVisit.timestamp)) {
159
- return null;
160
- }
145
+ /**
146
+ * Remove the storage item and set flushed to true after they have
147
+ * been posted to metroplex
148
+ */
149
+ _updateStorageFlushed() {
150
+ const storage = Storage.getInstance();
151
+ storage.remove(NOIBU_STORED_PAGE_VISIT);
161
152
  }
162
-
163
- // Copy the page visit information from storage into a new complete PV
164
- const completePv = {
165
- [PAGE_VISIT_INFORMATION_ATT_NAME]: storedPageVisit.pageVisitInfo,
166
- [PAGE_VISIT_PART_ATT_NAME]: [],
167
- [PAGE_VISIT_VID_FRAG_ATT_NAME]: [],
168
- };
169
-
170
- // Set is last to be true on the page visit information
171
- completePv[PAGE_VISIT_INFORMATION_ATT_NAME][IS_LAST_ATT_NAME] = true;
172
-
173
- // Add the page visit frags to the complete PV
174
- for (let i = 0; i < storedPageVisit.pageVisitFrags.length; i += 1) {
175
- completePv[PAGE_VISIT_PART_ATT_NAME].push(
176
- storedPageVisit.pageVisitFrags[i],
177
- );
153
+ /** Returns a promise that resolves to post the page visit in storage to Metroplex */
154
+ _getPostPageVisitPromise() {
155
+ return new Promise((resolve, reject) => {
156
+ this._getPostData().then(data => {
157
+ if (!data) {
158
+ resolve();
159
+ return;
160
+ }
161
+ const headers = {
162
+ 'content-type': 'application/json',
163
+ };
164
+ makeRequest('POST', GET_METROPLEX_POST_URL(), data, headers, 2000, true)
165
+ .then(resolve)
166
+ .catch(e => {
167
+ reject(new Error('Page visit post request rejected due to: ', e));
168
+ });
169
+ });
170
+ });
178
171
  }
179
-
180
- return completePv;
181
- }
182
-
183
- /**
184
- * Creates and tries to resolve a promise that posts the previous page visit
185
- * to Metroplex from storage
186
- */
187
- _postPreviousPageVisit() {
188
- // Whether the post promise resolves or not we need to finally
189
- // clear the storage item and set flushed
190
- this._getPostPageVisitPromise()
191
- .then(() => {
192
- this._updateStorageFlushed();
193
- })
194
- .catch(() => {
195
- this._updateStorageFlushed();
196
- });
197
- }
198
-
199
- /**
200
- * Remove the storage item and set flushed to true after they have
201
- * been posted to metroplex
202
- */
203
- _updateStorageFlushed() {
204
- this.flushedStorage = true;
205
- const storage = Storage.getInstance();
206
- storage.remove(NOIBU_STORED_PAGE_VISIT);
207
- }
208
-
209
- /** Returns a promise that resolves to post the page visit in storage to Metroplex */
210
- _getPostPageVisitPromise() {
211
- return new Promise((resolve, reject) => {
212
- this._getPostData().then(data => {
213
- if (!data) {
214
- resolve();
215
- return;
216
- }
217
-
218
- const headers = {
219
- 'content-type': 'application/json',
220
- };
221
-
222
- makeRequest('POST', GET_METROPLEX_POST_URL(), data, headers, 2000, true)
223
- .then(resolve)
224
- .catch(e => {
225
- reject(new Error('Page visit post request rejected due to: ', e));
226
- });
227
- });
228
- });
229
- }
230
172
  }
231
173
 
232
174
  export { StoredPageVisit as default };
package/dist/constants.js CHANGED
@@ -241,6 +241,7 @@ const VIDEO_PART_COUNT_ATT_NAME = 'vpnum';
241
241
  // max size that can be sent from a beacon
242
242
  // set to be 59kb right now
243
243
  const MAX_BEACON_PAYLOAD_SIZE = 59000;
244
+ const MAX_RETRY_MSG_Q_SIZE = 500;
244
245
  // maximum number of connection a single page visit can reach
245
246
  const MAX_METROPLEX_CONNECTION_COUNT = 100;
246
247
  // All urls that NoibuJS may talk to
@@ -320,7 +321,7 @@ const CONTENT_LENGTH = 'content-length';
320
321
  * Gets the script id from the cookie object, returns default if cannot be found
321
322
  */
322
323
  function GET_SCRIPT_ID() {
323
- return "1.0.104-rn-sdk-0.2.3" ;
324
+ return "1.0.104-rn-sdk-0.2.5" ;
324
325
  }
325
326
  /**
326
327
  *
@@ -455,10 +456,5 @@ const MAX_HTTP_DATA_IF_ERROR_EVENT_COUNT = 120;
455
456
  // the maximum size of http data payload that will be capture for success, otherwise it is dropped
456
457
  // this is 64k
457
458
  const MAX_SUCCESS_HTTP_DATA_PAYLOAD_LENGTH = 65536;
458
- const LOCATION_EVENT_TYPE = 'loc';
459
- const ECOMMERCE_EVENT_TYPE = 'ecommerce';
460
- const NETWORK_STATS_EVENT_TYPE = 'network';
461
- const TITLE_EVENT_TYPE = 'title';
462
- const PAGE_TYPE_EVENT_TYPE = 'page_type';
463
459
 
464
- export { APP_NAVIGATION_EVENT_TYPE, BLOCKED_HTTP_HEADER_KEYS, BLOCKLISTED_DOMAINS, BLOCK_SOCKET_MESSAGE, BODY_USED_ERROR, BROWSER_ID_ATT_NAME, CLICK_EVENT_TYPE, CLIENT_LOCK_TIME_MINUTES, CLOSE_CONNECTION_FORCEFULLY, COLLECT_VER_ATT_NAME, CONN_COUNT_ATT_NAME, CONSOLE_FUNCTION_OVERRIDES, CONTENT_LENGTH, CONTENT_TYPE, CSS_CLASS_ATT_NAME, CSS_URLS_ATT_NAME, CURRENT_METRICS_VERSION, CURRENT_NOIBUJS_VERSION, CURRENT_PV_VERSION, CUSTOM_ERROR_EVENT_TYPE, CUSTOM_ID_NAME_TYPE, CUSTOM_ID_VALUE_TYPE, DEFAULT_STACK_FRAME_FIELD_VALUE, DEFAULT_WEBSITE_SUBDOMAIN_PATTERN, DID_CUT_PV_ATT_NAME, DID_CUT_VID_ATT_NAME, DID_START_VID_ATT_NAME, ECOMMERCE_EVENT_TYPE, END_AT_ATT_NAME, ERROR_EVENT_ERROR_TYPE, ERROR_EVENT_TYPE, ERROR_EVENT_UNHANDLED_REJECTION_TYPE, ERROR_LOG_EVENT_ERROR_TYPE, ERROR_SOURCE_ATT_NAME, ERR_COUNT_EXPECTED_ATT_NAME, EVENT_ERROR_TYPE, EXP_VIDEO_LENGTH_ATT_NAME, FETCH_EXCEPTION_ERROR_TYPE, GET_DEVICE_ENV, GET_MAX_METROPLEX_RECONNECTION_NUMBER, GET_METROPLEX_BASE_HTTP_URL, GET_METROPLEX_BASE_SOCKET_URL, GET_METROPLEX_CONSECUTIVE_CONNECTION_DELAY, GET_METROPLEX_METRICS_URL, GET_METROPLEX_POST_URL, GET_SCRIPT_ID, GQL_ERROR_ATT_NAME, GQL_ERROR_TYPE, GQL_EVENT_TYPE, HELP_CODE_ATT_NAME, HTMLID_ATT_NAME, HTTP_BODY_DROPPED_LENGTH_MSG, HTTP_BODY_DROPPED_TYPE_MSG, HTTP_BODY_NULL_STRING, HTTP_CODE_ATT_NAME, HTTP_COUNT_EXPECTED_ATT_NAME, HTTP_DATA_METROPLEX_TYPE, HTTP_DATA_PAYLOAD_ATT_NAME, HTTP_DATA_REQ_HEADERS_ATT_NAME, HTTP_DATA_RESP_HEADERS_ATT_NAME, HTTP_DATA_RESP_PAYLOAD_ATT_NAME, HTTP_EVENT_TYPE, HTTP_METHOD_ATT_NAME, HTTP_PII_BLOCKING_PATTERNS, HTTP_RESP_CODE_ATT_NAME, HTTP_RESP_LENGTH_ATT_NAME, HTTP_RESP_TIME_ATT_NAME, HUMAN_READABLE_CONTENT_TYPE_REGEX, IS_LAST_ATT_NAME, IS_NJS_VERSION_BETA, JS_ENV, JS_ERROR_ATT_NAME, JS_EVENT_TYPE, JS_STACK_FILE_ATT_NAME, JS_STACK_FRAMES_ATT_NAME, JS_STACK_LINE_ATT_NAME, JS_STACK_MESSAGE_ATT_NAME, JS_STACK_METHOD_ATT_NAME, KEYBOARD_EVENT_TYPE, LENGTH_ATT_NAME, LOCATION_EVENT_TYPE, MAX_BEACON_PAYLOAD_SIZE, MAX_COLLECT_ERROR_LOG, MAX_CUSTOM_ERRORS_PER_PAGEVISIT, MAX_CUSTOM_IDS_PER_PAGEVISIT, MAX_FRAMES_IN_ARRAY, MAX_HTTP_DATA_EVENT_COUNT, MAX_HTTP_DATA_IF_ERROR_EVENT_COUNT, MAX_HTTP_DATA_PAYLOAD_LENGTH, MAX_METROPLEX_CONNECTION_COUNT, MAX_METROPLEX_SOCKET_INNACTIVE_TIME, MAX_PAGEVISIT_EVENTS, MAX_PAGEVISIT_PARTS, MAX_PAGEVISIT_VISITED, MAX_RECORDER_EVENT_BUFFER, MAX_STRING_LENGTH, MAX_SUCCESS_HTTP_DATA_PAYLOAD_LENGTH, MAX_TIME_FOR_RECORDER_USER_EVENTS, MAX_TIME_FOR_UNSENT_DATA_MILLIS, META_DATA_METROPLEX_TYPE, METROPLEX_ERROR_ROUTE, METROPLEX_FRAG_ROUTE, METROPLEX_FULL_PV_ROUTE, METROPLEX_METRICS_ROUTE, METROPLEX_RETRY_FREQUENCY, METROPLEX_SOCKET_INSTANCE_ID_ATT_NAME, NETWORK_STATS_EVENT_TYPE, NOIBUJS_SDK_ADD_ERROR_FROM_JS_FMW_FUNCTION, NOIBUJS_SDK_ADD_ERROR_FUNCTION, NOIBUJS_SDK_ADD_ID_FUNCTION, NOIBUJS_SDK_REQUEST_HELP_CODE, NOIBU_BROWSER_ID_KYWRD, NOIBU_INPUT_URLS, NOIBU_LOCAL_STORAGE_TEST_KEY, NOIBU_STORED_PAGE_VISIT, OCCURRED_AT_ATT_NAME, OK_SOCKET_MESSAGE, ON_URL_ATT_NAME, PAGE_EVENTS_DOCUMENT, PAGE_EVENTS_WINDOW, PAGE_EVENT_TYPE, PAGE_TYPE_EVENT_TYPE, PAGE_VISIT_HTTP_DATA_ATT_NAME, PAGE_VISIT_INFORMATION_ATT_NAME, PAGE_VISIT_META_DATA_ATT_NAME, PAGE_VISIT_PART_ATT_NAME, PAGE_VISIT_VID_FRAG_ATT_NAME, PII_DIGIT_PATTERN, PII_EMAIL_PATTERN, PII_REDACTION_REPLACEMENT_STRING, POST_METRICS_EVENT_NAME, PV_CLICKS_ATT_NAME, PV_EVENTS_ATT_NAME, PV_EXP_HTTP_DATA_SEQ_ATT_NAME, PV_EXP_PART_COUNTER_ATT_NAME, PV_EXP_VF_SEQ_ATT_NAME, PV_HTTP_PAYLOADS_COLLECTED_ATT_NAME, PV_HTTP_PAYLOADS_DROPPED_OVERSIZE_ATT_NAME, PV_HTTP_PAYLOADS_DROPPED_TYPE_ATT_NAME, PV_HTTP_REQUESTS_DROPPED_OVER_LIMIT, PV_ID_ATT_NAME, PV_METROPLEX_TYPE, PV_PART_COUNTER_ATT_NAME, PV_SEQ_ATT_NAME, PV_SEQ_NUM_RESET_TIME_MINUTES, REF_URL_ATT_NAME, REQUIRED_DATA_PROCESSING_URLS, RESPONSE_ERROR_TYPE, SCRIPT_ID_ATT_NAME, SCRIPT_INSTANCE_ID_ATT_NAME, SEQ_NUM_ATT_NAME, SEVERITY, SOCKET_INSTANCE_ID_ATT_NAME, SOURCE_ATT_NAME, STACK_TRACE_SANITIZE_REGEXP, STARTED_AT_ATT_NAME, STOP_STORING_PV_SOCKET_MESSAGE, STOP_STORING_VID_SOCKET_MESSAGE, TAGNAME_ATT_NAME, TEXT_ATT_NAME, TITLE_EVENT_TYPE, TYPE_ATT_NAME, URL_ATT_NAME, USERSTEP_EVENT_TYPE, VER_ATT_NAME, VIDEO_CLICKS_ATT_NAME, VIDEO_FRAG_ATT_NAME, VIDEO_METROPLEX_TYPE, VIDEO_PART_COUNT_ATT_NAME, VIDEO_RECORDER_ATT_NAME, WHITELIST_HTML_ID_TEXT_REGEX, WORK_REQUEST_ATT_NAME, WRAPPED_EXCEPTION_ERROR_TYPE, XML_HTTP_REQUEST_ERROR_TYPE };
460
+ export { APP_NAVIGATION_EVENT_TYPE, BLOCKED_HTTP_HEADER_KEYS, BLOCKLISTED_DOMAINS, BLOCK_SOCKET_MESSAGE, BODY_USED_ERROR, BROWSER_ID_ATT_NAME, CLICK_EVENT_TYPE, CLIENT_LOCK_TIME_MINUTES, CLOSE_CONNECTION_FORCEFULLY, COLLECT_VER_ATT_NAME, CONN_COUNT_ATT_NAME, CONSOLE_FUNCTION_OVERRIDES, CONTENT_LENGTH, CONTENT_TYPE, CSS_CLASS_ATT_NAME, CSS_URLS_ATT_NAME, CURRENT_METRICS_VERSION, CURRENT_NOIBUJS_VERSION, CURRENT_PV_VERSION, CUSTOM_ERROR_EVENT_TYPE, CUSTOM_ID_NAME_TYPE, CUSTOM_ID_VALUE_TYPE, DEFAULT_STACK_FRAME_FIELD_VALUE, DEFAULT_WEBSITE_SUBDOMAIN_PATTERN, DID_CUT_PV_ATT_NAME, DID_CUT_VID_ATT_NAME, DID_START_VID_ATT_NAME, END_AT_ATT_NAME, ERROR_EVENT_ERROR_TYPE, ERROR_EVENT_TYPE, ERROR_EVENT_UNHANDLED_REJECTION_TYPE, ERROR_LOG_EVENT_ERROR_TYPE, ERROR_SOURCE_ATT_NAME, ERR_COUNT_EXPECTED_ATT_NAME, EVENT_ERROR_TYPE, EXP_VIDEO_LENGTH_ATT_NAME, FETCH_EXCEPTION_ERROR_TYPE, GET_DEVICE_ENV, GET_MAX_METROPLEX_RECONNECTION_NUMBER, GET_METROPLEX_BASE_HTTP_URL, GET_METROPLEX_BASE_SOCKET_URL, GET_METROPLEX_CONSECUTIVE_CONNECTION_DELAY, GET_METROPLEX_METRICS_URL, GET_METROPLEX_POST_URL, GET_SCRIPT_ID, GQL_ERROR_ATT_NAME, GQL_ERROR_TYPE, GQL_EVENT_TYPE, HELP_CODE_ATT_NAME, HTMLID_ATT_NAME, HTTP_BODY_DROPPED_LENGTH_MSG, HTTP_BODY_DROPPED_TYPE_MSG, HTTP_BODY_NULL_STRING, HTTP_CODE_ATT_NAME, HTTP_COUNT_EXPECTED_ATT_NAME, HTTP_DATA_METROPLEX_TYPE, HTTP_DATA_PAYLOAD_ATT_NAME, HTTP_DATA_REQ_HEADERS_ATT_NAME, HTTP_DATA_RESP_HEADERS_ATT_NAME, HTTP_DATA_RESP_PAYLOAD_ATT_NAME, HTTP_EVENT_TYPE, HTTP_METHOD_ATT_NAME, HTTP_PII_BLOCKING_PATTERNS, HTTP_RESP_CODE_ATT_NAME, HTTP_RESP_LENGTH_ATT_NAME, HTTP_RESP_TIME_ATT_NAME, HUMAN_READABLE_CONTENT_TYPE_REGEX, IS_LAST_ATT_NAME, IS_NJS_VERSION_BETA, JS_ENV, JS_ERROR_ATT_NAME, JS_EVENT_TYPE, JS_STACK_FILE_ATT_NAME, JS_STACK_FRAMES_ATT_NAME, JS_STACK_LINE_ATT_NAME, JS_STACK_MESSAGE_ATT_NAME, JS_STACK_METHOD_ATT_NAME, KEYBOARD_EVENT_TYPE, LENGTH_ATT_NAME, MAX_BEACON_PAYLOAD_SIZE, MAX_COLLECT_ERROR_LOG, MAX_CUSTOM_ERRORS_PER_PAGEVISIT, MAX_CUSTOM_IDS_PER_PAGEVISIT, MAX_FRAMES_IN_ARRAY, MAX_HTTP_DATA_EVENT_COUNT, MAX_HTTP_DATA_IF_ERROR_EVENT_COUNT, MAX_HTTP_DATA_PAYLOAD_LENGTH, MAX_METROPLEX_CONNECTION_COUNT, MAX_METROPLEX_SOCKET_INNACTIVE_TIME, MAX_PAGEVISIT_EVENTS, MAX_PAGEVISIT_PARTS, MAX_PAGEVISIT_VISITED, MAX_RECORDER_EVENT_BUFFER, MAX_RETRY_MSG_Q_SIZE, MAX_STRING_LENGTH, MAX_SUCCESS_HTTP_DATA_PAYLOAD_LENGTH, MAX_TIME_FOR_RECORDER_USER_EVENTS, MAX_TIME_FOR_UNSENT_DATA_MILLIS, META_DATA_METROPLEX_TYPE, METROPLEX_ERROR_ROUTE, METROPLEX_FRAG_ROUTE, METROPLEX_FULL_PV_ROUTE, METROPLEX_METRICS_ROUTE, METROPLEX_RETRY_FREQUENCY, METROPLEX_SOCKET_INSTANCE_ID_ATT_NAME, NOIBUJS_SDK_ADD_ERROR_FROM_JS_FMW_FUNCTION, NOIBUJS_SDK_ADD_ERROR_FUNCTION, NOIBUJS_SDK_ADD_ID_FUNCTION, NOIBUJS_SDK_REQUEST_HELP_CODE, NOIBU_BROWSER_ID_KYWRD, NOIBU_INPUT_URLS, NOIBU_LOCAL_STORAGE_TEST_KEY, NOIBU_STORED_PAGE_VISIT, OCCURRED_AT_ATT_NAME, OK_SOCKET_MESSAGE, ON_URL_ATT_NAME, PAGE_EVENTS_DOCUMENT, PAGE_EVENTS_WINDOW, PAGE_EVENT_TYPE, PAGE_VISIT_HTTP_DATA_ATT_NAME, PAGE_VISIT_INFORMATION_ATT_NAME, PAGE_VISIT_META_DATA_ATT_NAME, PAGE_VISIT_PART_ATT_NAME, PAGE_VISIT_VID_FRAG_ATT_NAME, PII_DIGIT_PATTERN, PII_EMAIL_PATTERN, PII_REDACTION_REPLACEMENT_STRING, POST_METRICS_EVENT_NAME, PV_CLICKS_ATT_NAME, PV_EVENTS_ATT_NAME, PV_EXP_HTTP_DATA_SEQ_ATT_NAME, PV_EXP_PART_COUNTER_ATT_NAME, PV_EXP_VF_SEQ_ATT_NAME, PV_HTTP_PAYLOADS_COLLECTED_ATT_NAME, PV_HTTP_PAYLOADS_DROPPED_OVERSIZE_ATT_NAME, PV_HTTP_PAYLOADS_DROPPED_TYPE_ATT_NAME, PV_HTTP_REQUESTS_DROPPED_OVER_LIMIT, PV_ID_ATT_NAME, PV_METROPLEX_TYPE, PV_PART_COUNTER_ATT_NAME, PV_SEQ_ATT_NAME, PV_SEQ_NUM_RESET_TIME_MINUTES, REF_URL_ATT_NAME, REQUIRED_DATA_PROCESSING_URLS, RESPONSE_ERROR_TYPE, SCRIPT_ID_ATT_NAME, SCRIPT_INSTANCE_ID_ATT_NAME, SEQ_NUM_ATT_NAME, SEVERITY, SOCKET_INSTANCE_ID_ATT_NAME, SOURCE_ATT_NAME, STACK_TRACE_SANITIZE_REGEXP, STARTED_AT_ATT_NAME, STOP_STORING_PV_SOCKET_MESSAGE, STOP_STORING_VID_SOCKET_MESSAGE, TAGNAME_ATT_NAME, TEXT_ATT_NAME, TYPE_ATT_NAME, URL_ATT_NAME, USERSTEP_EVENT_TYPE, VER_ATT_NAME, VIDEO_CLICKS_ATT_NAME, VIDEO_FRAG_ATT_NAME, VIDEO_METROPLEX_TYPE, VIDEO_PART_COUNT_ATT_NAME, VIDEO_RECORDER_ATT_NAME, WHITELIST_HTML_ID_TEXT_REGEX, WORK_REQUEST_ATT_NAME, WRAPPED_EXCEPTION_ERROR_TYPE, XML_HTTP_REQUEST_ERROR_TYPE };
@@ -1,11 +1,7 @@
1
1
  import { __awaiter } from 'tslib';
2
2
  import uuid from 'react-native-uuid';
3
- import { KeyboardInputMonitor } from '../monitors/keyboardInputMonitor.js';
4
- import { ClickMonitor } from '../monitors/clickMonitor.js';
5
- import { PageMonitor } from '../monitors/pageMonitor.js';
6
- import { HTTPDataBundler } from '../monitors/httpDataBundler.js';
7
- import { monitorErrors } from '../monitors/errorMonitor.js';
8
- import { monitorRequests } from '../monitors/requestMonitor.js';
3
+ import { KeyboardInputMonitor } from '../monitors/KeyboardInputMonitor.js';
4
+ import { PageMonitor } from '../monitors/PageMonitor.js';
9
5
  import { GET_METROPLEX_BASE_SOCKET_URL, GET_METROPLEX_BASE_HTTP_URL, METROPLEX_ERROR_ROUTE, SEVERITY } from '../constants.js';
10
6
  import ClientConfig from '../api/clientConfig.js';
11
7
  import { isInvalidURLConfig, isNoibuJSAlreadyLoaded } from '../utils/function.js';
@@ -13,9 +9,13 @@ import { PageVisit } from '../pageVisit/pageVisit.js';
13
9
  import MetroplexSocket from '../api/metroplexSocket.js';
14
10
  import StoredPageVisit from '../api/storedPageVisit.js';
15
11
  import HelpCode from '../api/helpCode.js';
16
- import { AppNavigationMonitor } from '../monitors/appNavigationMonitor.js';
12
+ import { AppNavigationMonitor } from '../monitors/AppNavigationMonitor.js';
17
13
  import { noibuLog } from '../utils/log.js';
18
14
  import SessionRecorder from '../sessionRecorder/sessionRecorder.js';
15
+ import { ClickMonitor } from '../monitors/ClickMonitor.js';
16
+ import { ErrorMonitor } from '../monitors/ErrorMonitor.js';
17
+ import { HTTPDataBundler } from '../monitors/http-tools/HTTPDataBundler.js';
18
+ import RequestMonitor from '../monitors/RequestMonitor.js';
19
19
 
20
20
  // these are set via rollup
21
21
  const urlConfig = {
@@ -41,10 +41,8 @@ function globalInit(customerConfig) {
41
41
  const noibuErrorURL = `${urlConfig.metroplexHTTPBase}/${METROPLEX_ERROR_ROUTE}`;
42
42
  // catch any errors that happened during initialization and send collect error
43
43
  try {
44
- yield ClientConfig.configureInstance({
45
- noibuErrorURL,
46
- customerConfig,
47
- });
44
+ yield ClientConfig.getInstance(noibuErrorURL, customerConfig)
45
+ .configurationPromise;
48
46
  // create an instance ID for this script
49
47
  const instanceId = uuid.v4();
50
48
  // verifying if collect was disabled by other microservices
@@ -63,12 +61,12 @@ function globalInit(customerConfig) {
63
61
  const keyboardInputMonitor = new KeyboardInputMonitor();
64
62
  const clickMonitor = ClickMonitor.getInstance();
65
63
  const pageMonitor = PageMonitor.getInstance();
66
- AppNavigationMonitor.getInstance();
64
+ AppNavigationMonitor.getInstance().monitor();
67
65
  HTTPDataBundler.getInstance();
68
66
  // monitoring calls
69
- monitorErrors();
70
- monitorRequests();
71
- clickMonitor.monitorClicks();
67
+ ErrorMonitor.getInstance().monitor();
68
+ RequestMonitor.getInstance().monitor();
69
+ clickMonitor.monitor();
72
70
  keyboardInputMonitor.monitor();
73
71
  pageMonitor.monitor();
74
72
  SessionRecorder.getInstance().recordUserSession();
@@ -1,23 +1,23 @@
1
1
  import { SEVERITY, APP_NAVIGATION_EVENT_TYPE } from '../constants.js';
2
- import { InputMonitor } from './inputMonitor.js';
3
2
  import { ReactNativeNavigationIntegration } from './integrations/react-native-navigation-integration.js';
4
3
  import ClientConfig from '../api/clientConfig.js';
4
+ import { EventDebouncer } from '../pageVisit/EventDebouncer.js';
5
+ import { Singleton } from './BaseMonitor.js';
5
6
 
6
7
  /**
7
8
  * Attaches corresponding listener to the passed navigation integration
8
9
  */
9
- class AppNavigationMonitor {
10
+ class AppNavigationMonitor extends Singleton {
10
11
  /**
11
- * guesses which navigation is used in app, and registers a listener if found
12
+ * Main method for starting the monitoring
12
13
  */
13
- constructor() {
14
- this.onNavigation = this.onNavigation.bind(this);
14
+ monitor() {
15
15
  try {
16
16
  // eslint-disable-next-line @typescript-eslint/no-var-requires
17
17
  const Navigation = require('react-native-navigation');
18
18
  const rnNavigation = Navigation === null || Navigation === void 0 ? void 0 : Navigation.Navigation;
19
19
  if (rnNavigation) {
20
- new ReactNativeNavigationIntegration().register(rnNavigation, this.onNavigation);
20
+ new ReactNativeNavigationIntegration().register(rnNavigation, AppNavigationMonitor.onNavigation);
21
21
  }
22
22
  }
23
23
  catch (e) {
@@ -27,25 +27,16 @@ class AppNavigationMonitor {
27
27
  /**
28
28
  * handler for updating navigation breadcrumbs and notifying metro of location change
29
29
  */
30
- onNavigation(breadcrumbs) {
30
+ static onNavigation(breadcrumbs) {
31
31
  ClientConfig.getInstance().currentLocationBreadcrumbs = breadcrumbs;
32
- this.reportLocationChange(breadcrumbs.pop());
33
- }
34
- /**
35
- * Gets the singleton instance
36
- */
37
- static getInstance() {
38
- if (!AppNavigationMonitor.instance) {
39
- AppNavigationMonitor.instance = new AppNavigationMonitor();
40
- }
41
- return AppNavigationMonitor.instance;
32
+ AppNavigationMonitor.reportLocationChange(breadcrumbs.pop());
42
33
  }
43
34
  /**
44
35
  * Called when the event needs to be emitted
45
36
  */
46
- reportLocationChange(currentLocation) {
37
+ static reportLocationChange(currentLocation) {
47
38
  const payload = { location: currentLocation || '' };
48
- InputMonitor.getInstance().addEvent(payload, APP_NAVIGATION_EVENT_TYPE);
39
+ EventDebouncer.getInstance().addEvent(payload, APP_NAVIGATION_EVENT_TYPE);
49
40
  }
50
41
  }
51
42
 
@@ -0,0 +1,23 @@
1
+ import { noibuLog } from '../utils/log.js';
2
+
3
+ /**
4
+ * Singleton pattern with our flavor
5
+ */
6
+ class Singleton {
7
+ /** returns singleton instance */
8
+ static getInstance(...args) {
9
+ // Use 'this' to reference the current class constructor
10
+ if (!Singleton.instances.has(this)) {
11
+ noibuLog('Creating new Singleton instance:', this.name);
12
+ Singleton.instances.set(this, new this(...(args !== null && args !== void 0 ? args : [])));
13
+ }
14
+ return Singleton.instances.get(this);
15
+ }
16
+ /** used for testing only */
17
+ resetInstances() {
18
+ Singleton.instances.clear();
19
+ }
20
+ }
21
+ Singleton.instances = new Map();
22
+
23
+ export { Singleton };