noibu-react-native 0.2.6 → 0.2.7
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.
- package/README.md +15 -15
- package/dist/api/{clientConfig.js → ClientConfig.js} +69 -52
- package/dist/api/{helpCode.js → HelpCode.js} +6 -13
- package/dist/api/InputManager.js +156 -0
- package/dist/api/{metroplexSocket.js → MetroplexSocket.js} +189 -178
- package/dist/api/StoredMetrics.js +158 -0
- package/dist/api/{storedPageVisit.js → StoredPageVisit.js} +61 -48
- package/dist/const_matchers.js +1 -5
- package/dist/constants.js +15 -390
- package/dist/entry/index.js +3 -4
- package/dist/entry/init.js +33 -19
- package/dist/monitors/AppNavigationMonitor.js +19 -19
- package/dist/monitors/BaseMonitor.js +9 -4
- package/dist/monitors/ClickMonitor.js +72 -76
- package/dist/monitors/ErrorMonitor.js +45 -55
- package/dist/monitors/KeyboardInputMonitor.js +13 -11
- package/dist/monitors/PageMonitor.js +25 -2
- package/dist/monitors/RequestMonitor.js +46 -57
- package/dist/monitors/http-tools/GqlErrorValidator.js +39 -69
- package/dist/monitors/http-tools/HTTPDataBundler.js +71 -66
- package/dist/monitors/integrations/{react-native-navigation-integration.js → ReactNativeNavigationIntegration.js} +15 -12
- package/dist/pageVisit/EventDebouncer.js +43 -74
- package/dist/pageVisit/HttpEventManager.js +88 -0
- package/dist/pageVisit/PageVisitManager.js +99 -0
- package/dist/pageVisit/pageVisitEventError.js +170 -280
- package/dist/react/ErrorBoundary.js +3 -6
- package/dist/sessionRecorder/{sessionRecorder.js → SessionRecorder.js} +58 -70
- package/dist/sessionRecorder/nativeSessionRecorderSubscription.js +3 -5
- package/dist/storage/{rnStorageProvider.js → RNStorageProvider.js} +3 -7
- package/dist/storage/{storage.js → Storage.js} +17 -30
- package/dist/storage/{storageProvider.js → StorageProvider.js} +7 -8
- package/dist/utils/date.js +39 -50
- package/dist/utils/eventlistener.js +5 -12
- package/dist/utils/function.js +42 -113
- package/dist/utils/log.js +5 -5
- package/dist/utils/object.js +12 -12
- package/dist/utils/piiRedactor.js +31 -3
- package/dist/utils/stacktrace-parser.js +29 -21
- package/package.json +14 -14
- package/dist/api/inputManager.js +0 -227
- package/dist/api/storedMetrics.js +0 -198
- package/dist/pageVisit/pageVisit.js +0 -181
- package/dist/pageVisit/pageVisitEventHTTP.js +0 -98
- package/dist/pageVisit/userStep.js +0 -20
- package/dist/src/api/clientConfig.d.ts +0 -100
- package/dist/src/api/clientConfig.test.d.ts +0 -1
- package/dist/src/api/helpCode.d.ts +0 -23
- package/dist/src/api/inputManager.d.ts +0 -87
- package/dist/src/api/metroplexSocket.d.ts +0 -137
- package/dist/src/api/storedMetrics.d.ts +0 -73
- package/dist/src/api/storedPageVisit.d.ts +0 -40
- package/dist/src/const_matchers.d.ts +0 -1
- package/dist/src/constants.d.ts +0 -290
- package/dist/src/entry/index.d.ts +0 -14
- package/dist/src/entry/init.d.ts +0 -5
- package/dist/src/monitors/AppNavigationMonitor.d.ts +0 -18
- package/dist/src/monitors/BaseMonitor.d.ts +0 -13
- package/dist/src/monitors/BaseMonitor.test.d.ts +0 -1
- package/dist/src/monitors/ClickMonitor.d.ts +0 -31
- package/dist/src/monitors/ErrorMonitor.d.ts +0 -63
- package/dist/src/monitors/KeyboardInputMonitor.d.ts +0 -20
- package/dist/src/monitors/PageMonitor.d.ts +0 -20
- package/dist/src/monitors/RequestMonitor.d.ts +0 -94
- package/dist/src/monitors/http-tools/GqlErrorValidator.d.ts +0 -59
- package/dist/src/monitors/http-tools/HTTPDataBundler.d.ts +0 -112
- package/dist/src/monitors/integrations/react-native-navigation-integration.d.ts +0 -20
- package/dist/src/pageVisit/EventDebouncer.d.ts +0 -24
- package/dist/src/pageVisit/pageVisit.d.ts +0 -52
- package/dist/src/pageVisit/pageVisitEventError.d.ts +0 -15
- package/dist/src/pageVisit/pageVisitEventHTTP.d.ts +0 -25
- package/dist/src/pageVisit/userStep.d.ts +0 -5
- package/dist/src/react/ErrorBoundary.d.ts +0 -72
- package/dist/src/sessionRecorder/nativeSessionRecorderSubscription.d.ts +0 -79
- package/dist/src/sessionRecorder/sessionRecorder.d.ts +0 -60
- package/dist/src/sessionRecorder/types.d.ts +0 -91
- package/dist/src/storage/rnStorageProvider.d.ts +0 -23
- package/dist/src/storage/storage.d.ts +0 -39
- package/dist/src/storage/storageProvider.d.ts +0 -26
- package/dist/src/utils/date.d.ts +0 -6
- package/dist/src/utils/eventlistener.d.ts +0 -8
- package/dist/src/utils/function.d.ts +0 -102
- package/dist/src/utils/log.d.ts +0 -4
- package/dist/src/utils/object.d.ts +0 -44
- package/dist/src/utils/performance.d.ts +0 -6
- package/dist/src/utils/piiRedactor.d.ts +0 -11
- package/dist/src/utils/polyfills.d.ts +0 -4
- package/dist/src/utils/stacktrace-parser.d.ts +0 -7
- package/dist/types/Config.d.ts +0 -31
- package/dist/types/Metroplex.types.d.ts +0 -73
- package/dist/types/NavigationIntegration.d.ts +0 -6
- package/dist/types/PageVisit.types.d.ts +0 -8
- package/dist/types/PageVisitErrors.types.d.ts +0 -114
- package/dist/types/PageVisitEvents.types.d.ts +0 -91
- package/dist/types/PageVisitMetrics.types.d.ts +0 -27
- package/dist/types/Storage.d.ts +0 -14
- package/dist/types/StoredPageVisit.types.d.ts +0 -11
- package/dist/types/WrappedObjects.d.ts +0 -6
package/README.md
CHANGED
|
@@ -27,7 +27,8 @@ Install using favourite node package manager (npm, yarn, etc.):
|
|
|
27
27
|
npm install noibu-react-native --save
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
Additionally, for iOS target do:
|
|
30
|
+
Additionally, for iOS target do:
|
|
31
|
+
|
|
31
32
|
```bash
|
|
32
33
|
npx pod-install
|
|
33
34
|
```
|
|
@@ -65,22 +66,21 @@ That's it! First time the module is set up, it runs an init and starts listening
|
|
|
65
66
|
## Configuration
|
|
66
67
|
|
|
67
68
|
`setupNoibu(config): void` method accepts following parameters:
|
|
68
|
-
- `config` which consists of
|
|
69
|
-
- `@property domain {string}` - indicates which Noibu dashboard session recordings should go to ([learn more about domains](https://help.noibu.com/hc/en-us/articles/4846518088845-Domains-Overview))
|
|
70
|
-
- `@property [blockedElements] {string[]}` - lets you specify component ids to be ignored by SDK when collecting error information
|
|
71
|
-
- `@property [enableHttpDataCollection] {boolean}` - indicates whether SDK should collect HTTP information like headers or body from requests
|
|
72
|
-
- `@property [listOfUrlsToCollectHttpDataFrom] {string[]}` - is an allow list of URLs to allow HTTP data collection from, works best with `enableHttpDataCollection` enabled
|
|
73
69
|
|
|
74
|
-
|
|
70
|
+
- `config` which consists of
|
|
71
|
+
- `@property domain {string}` - indicates which Noibu dashboard session recordings should go to ([learn more about domains](https://help.noibu.com/hc/en-us/articles/4846518088845-Domains-Overview))
|
|
72
|
+
- `@property [blockedElements] {string[]}` - lets you specify component ids to be ignored by SDK when collecting error information
|
|
73
|
+
- `@property [enableHttpDataCollection] {boolean}` - indicates whether SDK should collect HTTP information like headers or body from requests
|
|
74
|
+
- `@property [listOfUrlsToCollectHttpDataFrom] {string[]}` - is an allow list of URLs to allow HTTP data collection from, works best with `enableHttpDataCollection` enabled
|
|
75
|
+
|
|
76
|
+
Example:
|
|
77
|
+
|
|
75
78
|
```js
|
|
76
79
|
setupNoibu({
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
'https://example.com/some-path/',
|
|
82
|
-
],
|
|
83
|
-
blockedElements: ['sensitive-info']
|
|
80
|
+
domain: 'react-native-app.myshop.com',
|
|
81
|
+
enableHttpDataCollection: true,
|
|
82
|
+
listOfUrlsToCollectHttpDataFrom: ['https://react-native-app.myshop.com/backend', 'https://example.com/some-path/'],
|
|
83
|
+
blockedElements: ['sensitive-info'],
|
|
84
84
|
});
|
|
85
85
|
```
|
|
86
86
|
|
|
@@ -101,7 +101,7 @@ Requests a help code from the HelpCode instance. To read more about help codes,
|
|
|
101
101
|
```jsx
|
|
102
102
|
import { NoibuJS } from 'noibu-react-native';
|
|
103
103
|
import { useCallback, useState } from 'react';
|
|
104
|
-
import { Alert, Text, Pressable, View} from 'react-native';
|
|
104
|
+
import { Alert, Text, Pressable, View } from 'react-native';
|
|
105
105
|
|
|
106
106
|
const AlertHelpCode = () => {
|
|
107
107
|
const triggerHelpCodeAlert = useCallback(async () => {
|
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import { __awaiter } from 'tslib';
|
|
2
2
|
import uuid from 'react-native-uuid';
|
|
3
|
-
import {
|
|
4
|
-
import { stringifyJSON, getMaxSubstringAllowed, getUserAgent,
|
|
5
|
-
import Storage from '../storage/
|
|
6
|
-
import { noibuLog } from '../utils/log.js';
|
|
3
|
+
import { SEVERITY, MAX_METROPLEX_SOCKET_INNACTIVE_TIME, GET_SCRIPT_ID, GET_DEVICE_ENV } from '../constants.js';
|
|
4
|
+
import { stringifyJSON, getMaxSubstringAllowed, getUserAgent, postRequest } from '../utils/function.js';
|
|
5
|
+
import Storage from '../storage/Storage.js';
|
|
6
|
+
import { noibuLog, noibuErr } from '../utils/log.js';
|
|
7
7
|
import { unwrapNoibuWrapped } from '../utils/object.js';
|
|
8
8
|
import { Singleton } from '../monitors/BaseMonitor.js';
|
|
9
9
|
|
|
10
|
+
// maximum number of page visits assigned to a single browser id
|
|
11
|
+
const MAX_PAGEVISIT_VISITED = 300;
|
|
12
|
+
// The amount of time to lock the client for if they have exceeded things
|
|
13
|
+
// like the maximum number of pagevisits
|
|
14
|
+
const CLIENT_LOCK_TIME_MINUTES = 45;
|
|
15
|
+
// The amount of inactive time required for us to reset the page visit sequence numbers
|
|
16
|
+
const PV_SEQ_NUM_RESET_TIME_MINUTES = 45;
|
|
17
|
+
// number of errors that collect can send to metroplex before shutting himself off.
|
|
18
|
+
const MAX_COLLECT_ERROR_LOG = 50;
|
|
19
|
+
const NOIBU_BROWSER_ID_KYWRD = 'n_browser_data';
|
|
10
20
|
/**
|
|
11
21
|
* Singleton class to manage the client configuration
|
|
12
22
|
* this class will be responsible for controlling the disabled
|
|
@@ -14,9 +24,18 @@ import { Singleton } from '../monitors/BaseMonitor.js';
|
|
|
14
24
|
* storing and retrieval.
|
|
15
25
|
*/
|
|
16
26
|
class ClientConfig extends Singleton {
|
|
17
|
-
/**
|
|
18
|
-
|
|
19
|
-
|
|
27
|
+
/** Error handling for constructor */
|
|
28
|
+
handleConstructorError(noibuErrorURL, customerConfig) {
|
|
29
|
+
const reason = {
|
|
30
|
+
msg: 'ClientConfig was not properly configured',
|
|
31
|
+
noibuErrorURL,
|
|
32
|
+
customerConfig,
|
|
33
|
+
globalUrl: this.globalUrl,
|
|
34
|
+
};
|
|
35
|
+
void this.postInternalError(reason, true, SEVERITY.error);
|
|
36
|
+
this.configurationPromise = Promise.reject(reason);
|
|
37
|
+
}
|
|
38
|
+
/** Creates a ClientConfig singleton instance */
|
|
20
39
|
constructor(noibuErrorURL, customerConfig) {
|
|
21
40
|
super();
|
|
22
41
|
this.pageVisitId = uuid.v4();
|
|
@@ -33,26 +52,25 @@ class ClientConfig extends Singleton {
|
|
|
33
52
|
this.maxSocketInactiveTime = MAX_METROPLEX_SOCKET_INNACTIVE_TIME;
|
|
34
53
|
this.locationBreadcrumbs = [];
|
|
35
54
|
this.isClientDisabled = false;
|
|
55
|
+
if (!noibuErrorURL || !customerConfig) {
|
|
56
|
+
this.handleConstructorError(noibuErrorURL, customerConfig);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
36
59
|
this.noibuErrorURL = noibuErrorURL;
|
|
37
60
|
this.customerDomain = customerConfig.domain;
|
|
38
|
-
this.
|
|
39
|
-
customerConfig
|
|
40
|
-
this.enableHttpDataCollection = customerConfig.enableHttpDataCollection;
|
|
41
|
-
this.blockedElements = customerConfig.blockedElements;
|
|
42
|
-
if (!noibuErrorURL || !this.hasAllNecessaryArgs()) {
|
|
43
|
-
const reason = Object.assign({ msg: 'ClientConfig was not properly configured' }, customerConfig);
|
|
44
|
-
void this.postNoibuErrorAndOptionallyDisableClient(reason, true, SEVERITY.error);
|
|
45
|
-
this.configurationPromise = Promise.reject(reason);
|
|
61
|
+
if (!this.hasAllNecessaryArgs(customerConfig)) {
|
|
62
|
+
this.handleConstructorError(noibuErrorURL, customerConfig);
|
|
46
63
|
return;
|
|
47
64
|
}
|
|
65
|
+
this.listOfUrlsToCollectHttpDataFrom = customerConfig.listOfUrlsToCollectHttpDataFrom;
|
|
66
|
+
this.enableHttpDataCollection = customerConfig.enableHttpDataCollection;
|
|
67
|
+
this.blockedElements = customerConfig.blockedElements;
|
|
48
68
|
// sets up this.browserId, this.isClientDisabled, this.pageVisitSeq
|
|
49
69
|
this.configurationPromise = this._setupStorageVars();
|
|
50
70
|
}
|
|
51
|
-
/**
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
hasAllNecessaryArgs() {
|
|
55
|
-
return (!!this.customerDomain && this.globalUrl.includes(this.customerDomain));
|
|
71
|
+
/** Convenience method to check correct setup */
|
|
72
|
+
hasAllNecessaryArgs(customerConfig) {
|
|
73
|
+
return !!customerConfig.domain && this.globalUrl.includes(customerConfig.domain);
|
|
56
74
|
}
|
|
57
75
|
/** lockClient will disable the client script for a single pagevisit for
|
|
58
76
|
* duration given in minuntes */
|
|
@@ -64,12 +82,12 @@ class ClientConfig extends Singleton {
|
|
|
64
82
|
noibuLSObject.DisabledStatus = true;
|
|
65
83
|
noibuLSObject.ClientUnlockTime = expiryTime;
|
|
66
84
|
yield this._storeBrowserData(noibuLSObject);
|
|
67
|
-
yield this.
|
|
85
|
+
yield this.postInternalError(msg, true, SEVERITY.warn);
|
|
68
86
|
});
|
|
69
87
|
}
|
|
70
88
|
/** Locks the client until the next page loads */
|
|
71
89
|
lockClientUntilNextPage(msg) {
|
|
72
|
-
return this.
|
|
90
|
+
return this.postInternalError(msg, true, SEVERITY.warn);
|
|
73
91
|
}
|
|
74
92
|
/** Updates the config object to store the given last active time */
|
|
75
93
|
updateLastActiveTime(lastActiveTime) {
|
|
@@ -133,9 +151,7 @@ class ClientConfig extends Singleton {
|
|
|
133
151
|
return parsedConfig;
|
|
134
152
|
});
|
|
135
153
|
}
|
|
136
|
-
/**
|
|
137
|
-
* Check if we have surpassed the last active time and the page visit seq number needs resetting
|
|
138
|
-
*/
|
|
154
|
+
/** Check if we have surpassed the last active time and the page visit seq number needs resetting */
|
|
139
155
|
_pageVisitSeqNeedsReset() {
|
|
140
156
|
return __awaiter(this, void 0, void 0, function* () {
|
|
141
157
|
const noibuLSObject = yield this._getClientState();
|
|
@@ -155,7 +171,7 @@ class ClientConfig extends Singleton {
|
|
|
155
171
|
return __awaiter(this, void 0, void 0, function* () {
|
|
156
172
|
const storage = Storage.getInstance();
|
|
157
173
|
if (!(yield storage.isAvailable())) {
|
|
158
|
-
void this.
|
|
174
|
+
void this.postInternalError({ msg: `Storage is unavailable, disabling client.`, diagnosis: yield storage.getDiagnoseInfo() }, true, SEVERITY.error);
|
|
159
175
|
return;
|
|
160
176
|
}
|
|
161
177
|
// getting the current content of the storage
|
|
@@ -175,11 +191,6 @@ class ClientConfig extends Singleton {
|
|
|
175
191
|
// Update the LS object values before storing it for the next page visit
|
|
176
192
|
noibuLSObject.CurrentPageVisitCount += 1;
|
|
177
193
|
noibuLSObject.LastActive = new Date();
|
|
178
|
-
// Expose page visit ID in storage for use by Trailbreaker video tests
|
|
179
|
-
// This will be done for the testvideo and lambdavideo bundles used by Trailbreaker
|
|
180
|
-
if (JS_ENV().includes('video')) {
|
|
181
|
-
noibuLSObject.pvId = this.pageVisitId;
|
|
182
|
-
}
|
|
183
194
|
// if we have reached the max page visits for a browser id then
|
|
184
195
|
// we disabled collect for 45 minutes
|
|
185
196
|
if (noibuLSObject.CurrentPageVisitCount >= MAX_PAGEVISIT_VISITED) {
|
|
@@ -190,7 +201,7 @@ class ClientConfig extends Singleton {
|
|
|
190
201
|
// setting the lock time
|
|
191
202
|
noibuLSObject.ClientUnlockTime = expiryTime;
|
|
192
203
|
noibuLSObject.DisabledStatus = true;
|
|
193
|
-
yield this.
|
|
204
|
+
yield this.postInternalError({ msg: `Hit max page visits, disabling client for ${CLIENT_LOCK_TIME_MINUTES}mins` }, true, SEVERITY.error);
|
|
194
205
|
}
|
|
195
206
|
// we now check if we successfully saved the data
|
|
196
207
|
const savedData = yield this._storeBrowserData(noibuLSObject);
|
|
@@ -198,7 +209,7 @@ class ClientConfig extends Singleton {
|
|
|
198
209
|
// error happened, thus we disable collect.
|
|
199
210
|
if (!savedData.BrowserId) {
|
|
200
211
|
// we do not set a lock expiry date here since we cannot store to storage
|
|
201
|
-
void this.
|
|
212
|
+
void this.postInternalError({ msg: `Null browser in storage, disabling client` }, true, SEVERITY.error);
|
|
202
213
|
this.browserId = '';
|
|
203
214
|
}
|
|
204
215
|
});
|
|
@@ -213,8 +224,7 @@ class ClientConfig extends Singleton {
|
|
|
213
224
|
return __awaiter(this, void 0, void 0, function* () {
|
|
214
225
|
const newConfigData = yield this._getLsObject();
|
|
215
226
|
// if the lock expired, we remove the lock period and enable the client
|
|
216
|
-
if (newConfigData.ClientUnlockTime &&
|
|
217
|
-
new Date(newConfigData.ClientUnlockTime) <= new Date()) {
|
|
227
|
+
if (newConfigData.ClientUnlockTime && new Date(newConfigData.ClientUnlockTime) <= new Date()) {
|
|
218
228
|
newConfigData.ClientUnlockTime = undefined;
|
|
219
229
|
newConfigData.DisabledStatus = false;
|
|
220
230
|
yield this._storeBrowserData(newConfigData);
|
|
@@ -237,18 +247,12 @@ class ClientConfig extends Singleton {
|
|
|
237
247
|
* and persisted throughout a session
|
|
238
248
|
*/
|
|
239
249
|
_generateNewBrowserData() {
|
|
240
|
-
|
|
250
|
+
return {
|
|
241
251
|
DisabledStatus: false,
|
|
242
252
|
BrowserId: uuid.v4(),
|
|
243
253
|
CurrentPageVisitCount: 0,
|
|
244
254
|
LastActive: new Date(),
|
|
245
255
|
};
|
|
246
|
-
// Expose page visit ID in storage for use by Trailbreaker video tests
|
|
247
|
-
// This will be done for the testvideo and lambdavideo bundles used by Trailbreaker
|
|
248
|
-
if (JS_ENV().includes('video')) {
|
|
249
|
-
noibuBrowserData.pvId = this.pageVisitId;
|
|
250
|
-
}
|
|
251
|
-
return noibuBrowserData;
|
|
252
256
|
}
|
|
253
257
|
/**
|
|
254
258
|
* _storeBrowserData will store the passed object in storage.
|
|
@@ -262,7 +266,10 @@ class ClientConfig extends Singleton {
|
|
|
262
266
|
return data;
|
|
263
267
|
}
|
|
264
268
|
catch (e) {
|
|
265
|
-
yield this.
|
|
269
|
+
yield this.postInternalError({
|
|
270
|
+
msg: 'Error writing browser data to storage, disabling client: ' + e.message,
|
|
271
|
+
diagnosis: yield storage.getDiagnoseInfo(),
|
|
272
|
+
}, true, SEVERITY.error);
|
|
266
273
|
// sending empty fields if we encountered errors while storing in the LS
|
|
267
274
|
return this._generateNewBrowserData();
|
|
268
275
|
}
|
|
@@ -285,13 +292,13 @@ class ClientConfig extends Singleton {
|
|
|
285
292
|
return getMaxSubstringAllowed(globalUrl.toString());
|
|
286
293
|
}
|
|
287
294
|
/**
|
|
288
|
-
*
|
|
295
|
+
* postInternalError will post errors that were thrown by collect
|
|
289
296
|
* and disable the client if required
|
|
290
297
|
* severity expects one of the SEVERITY_x level constants, or else error will be used
|
|
291
298
|
*/
|
|
292
|
-
|
|
299
|
+
postInternalError(errorMsg_1) {
|
|
293
300
|
return __awaiter(this, arguments, void 0, function* (errorMsg, disableClient = false, severity = SEVERITY.error, keepAlive = false) {
|
|
294
|
-
|
|
301
|
+
noibuErr('postInternalError', {
|
|
295
302
|
errorMsg,
|
|
296
303
|
disableClient,
|
|
297
304
|
severity,
|
|
@@ -313,7 +320,7 @@ class ClientConfig extends Singleton {
|
|
|
313
320
|
scriptId: GET_SCRIPT_ID(),
|
|
314
321
|
ua: yield getUserAgent(),
|
|
315
322
|
deviceEnv: GET_DEVICE_ENV(),
|
|
316
|
-
|
|
323
|
+
msg: stringifyJSON(errorMsg),
|
|
317
324
|
};
|
|
318
325
|
// if the page visits sends more errors than the
|
|
319
326
|
// allowed threshold we disable the client
|
|
@@ -329,7 +336,7 @@ class ClientConfig extends Singleton {
|
|
|
329
336
|
this.isClientDisabled = true;
|
|
330
337
|
// end of lock
|
|
331
338
|
// overriding the message to be an alert that we are shutting collect off.
|
|
332
|
-
collectError.
|
|
339
|
+
collectError.msg = `Shutting collect off, we reached the maximum limit of collect errors sent.`;
|
|
333
340
|
}
|
|
334
341
|
const errorContent = {
|
|
335
342
|
url: this.globalUrl,
|
|
@@ -340,7 +347,7 @@ class ClientConfig extends Singleton {
|
|
|
340
347
|
'content-type': 'application/json',
|
|
341
348
|
};
|
|
342
349
|
if (!keepAlive) {
|
|
343
|
-
|
|
350
|
+
postRequest(this.noibuErrorURL, errorContent, headers, false, 2000).catch(() => {
|
|
344
351
|
// we do nothing and let this error silently fail
|
|
345
352
|
});
|
|
346
353
|
}
|
|
@@ -359,14 +366,24 @@ class ClientConfig extends Singleton {
|
|
|
359
366
|
}
|
|
360
367
|
});
|
|
361
368
|
}
|
|
362
|
-
/**
|
|
363
|
-
* Returns true if the page visit is considered to be inactive
|
|
364
|
-
*/
|
|
369
|
+
/** Returns true if the page visit is considered to be inactive */
|
|
365
370
|
isInactive() {
|
|
366
371
|
const someTimeAgo = new Date();
|
|
367
372
|
someTimeAgo.setSeconds(someTimeAgo.getSeconds() - this.maxSocketInactiveTime);
|
|
368
373
|
return this.lastActiveTime < someTimeAgo;
|
|
369
374
|
}
|
|
375
|
+
/**
|
|
376
|
+
* Wraps a function in a try catch block and posts the error if one is thrown
|
|
377
|
+
* explanation will be inserted into the error message as 'Error in {explanation}'
|
|
378
|
+
*/
|
|
379
|
+
wrapInternal(explanation, fun) {
|
|
380
|
+
try {
|
|
381
|
+
fun();
|
|
382
|
+
}
|
|
383
|
+
catch (error) {
|
|
384
|
+
this.postInternalError({ msg: `Error in ${explanation}`, error }, false, SEVERITY.error);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
370
387
|
}
|
|
371
388
|
|
|
372
389
|
export { ClientConfig as default };
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { __awaiter } from 'tslib';
|
|
2
|
-
import MetroplexSocket from './
|
|
2
|
+
import MetroplexSocket from './MetroplexSocket.js';
|
|
3
3
|
import { SEVERITY } from '../constants.js';
|
|
4
|
-
import ClientConfig from './
|
|
4
|
+
import ClientConfig from './ClientConfig.js';
|
|
5
5
|
import { Singleton } from '../monitors/BaseMonitor.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* HelpCode class is responsible for help code feature related functionality
|
|
9
9
|
*/
|
|
10
10
|
class HelpCode extends Singleton {
|
|
11
|
-
/**
|
|
12
|
-
* Constructs instance and sets up event listeners
|
|
13
|
-
*/
|
|
11
|
+
/** Constructs instance and sets up event listeners */
|
|
14
12
|
constructor() {
|
|
15
13
|
super();
|
|
16
14
|
this.requestContext = null;
|
|
@@ -19,9 +17,6 @@ class HelpCode extends Singleton {
|
|
|
19
17
|
/**
|
|
20
18
|
* Requests a help code and returns a Promise that resolves when the help code is obtained
|
|
21
19
|
* or rejects if the noibu connection is unavailable.
|
|
22
|
-
|
|
23
|
-
* @returns {Promise<string>} Promise object representing the help code request.
|
|
24
|
-
* @throws {string} Throws an error if the noibu connection is unavailable.
|
|
25
20
|
*/
|
|
26
21
|
requestHelpCode() {
|
|
27
22
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -46,16 +41,14 @@ class HelpCode extends Singleton {
|
|
|
46
41
|
return this.requestContext.promise;
|
|
47
42
|
});
|
|
48
43
|
}
|
|
49
|
-
/**
|
|
50
|
-
* Handles the received help code event.
|
|
51
|
-
*/
|
|
44
|
+
/** Handles the received help code event. */
|
|
52
45
|
receiveHelpCode(event) {
|
|
53
46
|
var _a, _b;
|
|
54
47
|
if (this.requestContext === null) {
|
|
55
48
|
const { success, data } = event.detail;
|
|
56
49
|
if (!success) {
|
|
57
|
-
const
|
|
58
|
-
ClientConfig.getInstance().
|
|
50
|
+
const msg = `Noibu help code is not available due to ${data}`;
|
|
51
|
+
ClientConfig.getInstance().postInternalError({ msg }, false, SEVERITY.error);
|
|
59
52
|
}
|
|
60
53
|
return;
|
|
61
54
|
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { __awaiter } from 'tslib';
|
|
2
|
+
import MetroplexSocket from './MetroplexSocket.js';
|
|
3
|
+
import { saveErrorToPagevisit } from '../pageVisit/pageVisitEventError.js';
|
|
4
|
+
import HelpCode from './HelpCode.js';
|
|
5
|
+
import { Singleton } from '../monitors/BaseMonitor.js';
|
|
6
|
+
import '../node_modules/@noibu/metroplex-ts-bindings/dist/index.js';
|
|
7
|
+
import { PageVisitErrorSource } from '../node_modules/@noibu/metroplex-ts-bindings/dist/PageVisitErrorSource.js';
|
|
8
|
+
import { WebsocketMessageType } from '../node_modules/@noibu/metroplex-ts-bindings/dist/WebsocketMessageType.js';
|
|
9
|
+
|
|
10
|
+
// maximum ids that a user can add to a pagevisit
|
|
11
|
+
const MAX_CUSTOM_IDS_PER_PAGEVISIT = 10;
|
|
12
|
+
const MAX_CUSTOM_ERRORS_PER_PAGEVISIT = 500;
|
|
13
|
+
const TOO_MANY_IDS_ADDED_MSG = 'TOO_MANY_IDS_ADDED';
|
|
14
|
+
const ID_NAME_ALREADY_ADDED_MSG = 'ID_NAME_ALREADY_ADDED';
|
|
15
|
+
const NAME_TOO_LONG_MSG = 'NAME_TOO_LONG';
|
|
16
|
+
const VALUE_TOO_LONG_MSG = 'VALUE_TOO_LONG';
|
|
17
|
+
const INVALID_NAME_TYPE_MSG = 'INVALID_NAME_TYPE';
|
|
18
|
+
const INVALID_VALUE_TYPE_MSG = 'INVALID_VALUE_TYPE';
|
|
19
|
+
const NAME_HAS_NO_LENGTH_MSG = 'NAME_HAS_NO_LENGTH';
|
|
20
|
+
const VALUE_HAS_NO_LENGTH_MSG = 'VALUE_HAS_NO_LENGTH';
|
|
21
|
+
const SUCCESS_MSG = 'SUCCESS';
|
|
22
|
+
const ERROR_HAS_NO_MSG_MSG = 'ERROR_HAS_NO_MSG';
|
|
23
|
+
const ERROR_HAS_NO_STACK_MSG = 'ERROR_HAS_NO_STACK';
|
|
24
|
+
const NULL_CUSTOM_ERR_MSG = 'NULL_CUSTOM_ERROR';
|
|
25
|
+
const TOO_MANY_ERRORS_RECEIVED_PER_PAGEVISIT_MSG = 'TOO_MANY_ERRORS_RECEIVED_PER_PAGEVISIT';
|
|
26
|
+
/** this class controls the input that customers can inject into
|
|
27
|
+
* our script via the NoibuJS SDK
|
|
28
|
+
*/
|
|
29
|
+
class InputManager extends Singleton {
|
|
30
|
+
constructor() {
|
|
31
|
+
super(...arguments);
|
|
32
|
+
this.customIDs = {};
|
|
33
|
+
this.customErrorsCount = 0;
|
|
34
|
+
}
|
|
35
|
+
/** exposes functions to the window of the browser for the clients
|
|
36
|
+
* to interact with on their end
|
|
37
|
+
*/
|
|
38
|
+
exposeFunctions() {
|
|
39
|
+
return {
|
|
40
|
+
// adding all the functions and binding the current context
|
|
41
|
+
// so that we can use the exposed function as if they are running`
|
|
42
|
+
// in the noibujs script
|
|
43
|
+
requestHelpCode: this._requestHelpCode.bind(this),
|
|
44
|
+
addCustomAttribute: this._addCustomAttribute.bind(this),
|
|
45
|
+
addError: this._addCustomError.bind(this),
|
|
46
|
+
addJsSdkError: this._addErrorFromJSSdk.bind(this),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** validates the custom error that was passed */
|
|
50
|
+
getErrorValidationError(customError) {
|
|
51
|
+
if (!customError) {
|
|
52
|
+
return NULL_CUSTOM_ERR_MSG;
|
|
53
|
+
}
|
|
54
|
+
if (!customError.message) {
|
|
55
|
+
return ERROR_HAS_NO_MSG_MSG;
|
|
56
|
+
}
|
|
57
|
+
if (!customError.stack) {
|
|
58
|
+
return ERROR_HAS_NO_STACK_MSG;
|
|
59
|
+
}
|
|
60
|
+
return SUCCESS_MSG;
|
|
61
|
+
}
|
|
62
|
+
/** Validates and sets the custom error to our internal trackers */
|
|
63
|
+
_validateAndSetCustomError(customError) {
|
|
64
|
+
// we cap the number of errors allowed to be sent
|
|
65
|
+
if (this.customErrorsCount >= MAX_CUSTOM_ERRORS_PER_PAGEVISIT) {
|
|
66
|
+
return TOO_MANY_ERRORS_RECEIVED_PER_PAGEVISIT_MSG;
|
|
67
|
+
}
|
|
68
|
+
// need to validate first before we start operating with the received
|
|
69
|
+
// data
|
|
70
|
+
const validationResult = this.getErrorValidationError(customError);
|
|
71
|
+
if (validationResult !== SUCCESS_MSG) {
|
|
72
|
+
return validationResult;
|
|
73
|
+
}
|
|
74
|
+
this.customErrorsCount += 1;
|
|
75
|
+
return SUCCESS_MSG;
|
|
76
|
+
}
|
|
77
|
+
/** adds an error from a JS Sdk to the session */
|
|
78
|
+
_addErrorFromJSSdk(customError, errorSource) {
|
|
79
|
+
const validationAndSettingResult = this._validateAndSetCustomError(customError);
|
|
80
|
+
if (validationAndSettingResult !== SUCCESS_MSG) {
|
|
81
|
+
return validationAndSettingResult;
|
|
82
|
+
}
|
|
83
|
+
saveErrorToPagevisit({ error: customError, type: `${errorSource}` });
|
|
84
|
+
return validationAndSettingResult;
|
|
85
|
+
}
|
|
86
|
+
/** adds a custom Error to the session */
|
|
87
|
+
_addCustomError(customError) {
|
|
88
|
+
const validationAndSettingResult = this._validateAndSetCustomError(customError);
|
|
89
|
+
if (validationAndSettingResult !== SUCCESS_MSG) {
|
|
90
|
+
return validationAndSettingResult;
|
|
91
|
+
}
|
|
92
|
+
// customError is validated at this point
|
|
93
|
+
saveErrorToPagevisit({ type: PageVisitErrorSource.CustomError, error: customError });
|
|
94
|
+
return validationAndSettingResult;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* adds a custom id to the session
|
|
98
|
+
* todo wrong param types, should be unknown
|
|
99
|
+
*/
|
|
100
|
+
_addCustomAttribute(name, value) {
|
|
101
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
102
|
+
// we return if we are over the limit of ids
|
|
103
|
+
if (Object.keys(this.customIDs).length >= MAX_CUSTOM_IDS_PER_PAGEVISIT) {
|
|
104
|
+
return TOO_MANY_IDS_ADDED_MSG;
|
|
105
|
+
}
|
|
106
|
+
// need to validate first before we start operating with the received
|
|
107
|
+
// data
|
|
108
|
+
const validationResult = this.getValidationError(name, value);
|
|
109
|
+
if (validationResult !== SUCCESS_MSG) {
|
|
110
|
+
return validationResult;
|
|
111
|
+
}
|
|
112
|
+
// we do not want to keep sending something that was already sent
|
|
113
|
+
if (name in this.customIDs) {
|
|
114
|
+
return ID_NAME_ALREADY_ADDED_MSG;
|
|
115
|
+
}
|
|
116
|
+
this.customIDs[name] = value;
|
|
117
|
+
yield MetroplexSocket.getInstance().sendMessage({
|
|
118
|
+
type: WebsocketMessageType.PageVisitMeta,
|
|
119
|
+
payload: {
|
|
120
|
+
id_name: name,
|
|
121
|
+
id_val: value,
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
return SUCCESS_MSG;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/** validation function for customer input */
|
|
128
|
+
getValidationError(name, value) {
|
|
129
|
+
// all ids need to be strings and less than 50 chars and more than 0 chars
|
|
130
|
+
if (typeof name !== 'string') {
|
|
131
|
+
return INVALID_NAME_TYPE_MSG;
|
|
132
|
+
}
|
|
133
|
+
if (typeof value !== 'string') {
|
|
134
|
+
return INVALID_VALUE_TYPE_MSG;
|
|
135
|
+
}
|
|
136
|
+
if (value.length > 50) {
|
|
137
|
+
return VALUE_TOO_LONG_MSG;
|
|
138
|
+
}
|
|
139
|
+
if (name.length > 50) {
|
|
140
|
+
return NAME_TOO_LONG_MSG;
|
|
141
|
+
}
|
|
142
|
+
if (value.length === 0) {
|
|
143
|
+
return VALUE_HAS_NO_LENGTH_MSG;
|
|
144
|
+
}
|
|
145
|
+
if (name.length === 0) {
|
|
146
|
+
return NAME_HAS_NO_LENGTH_MSG;
|
|
147
|
+
}
|
|
148
|
+
return SUCCESS_MSG;
|
|
149
|
+
}
|
|
150
|
+
/** Requests a help code from the HelpCode instance. */
|
|
151
|
+
_requestHelpCode() {
|
|
152
|
+
return HelpCode.getInstance().requestHelpCode();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export { InputManager as default };
|