noibu-react-native 0.2.6 → 0.2.8
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/android/build.gradle +1 -1
- package/dist/{src/api/clientConfig.d.ts → api/ClientConfig.d.ts} +19 -20
- package/dist/api/{clientConfig.js → ClientConfig.js} +82 -63
- package/dist/{src/api/helpCode.d.ts → api/HelpCode.d.ts} +3 -10
- package/dist/api/{helpCode.js → HelpCode.js} +8 -14
- package/dist/api/InputManager.d.ts +39 -0
- package/dist/api/InputManager.js +156 -0
- package/dist/{src/api/metroplexSocket.d.ts → api/MetroplexSocket.d.ts} +33 -38
- package/dist/api/{metroplexSocket.js → MetroplexSocket.js} +190 -178
- package/dist/{src/api/storedMetrics.d.ts → api/StoredMetrics.d.ts} +10 -20
- package/dist/api/StoredMetrics.js +158 -0
- package/dist/{src/api/storedPageVisit.d.ts → api/StoredPageVisit.d.ts} +11 -8
- package/dist/api/{storedPageVisit.js → StoredPageVisit.js} +62 -48
- package/dist/const_matchers.js +1 -5
- package/dist/constants.d.ts +48 -0
- package/dist/constants.js +15 -397
- package/dist/{src/entry → entry}/index.d.ts +5 -6
- package/dist/entry/index.js +3 -4
- package/dist/entry/init.d.ts +8 -0
- package/dist/entry/init.js +34 -19
- package/dist/monitors/AppNavigationMonitor.d.ts +10 -0
- package/dist/monitors/AppNavigationMonitor.js +19 -19
- package/dist/monitors/AppNavigationMonitor.test.d.ts +1 -0
- package/dist/{src/monitors → monitors}/BaseMonitor.d.ts +5 -5
- package/dist/monitors/BaseMonitor.js +9 -4
- package/dist/monitors/BaseMonitor.test.d.ts +1 -0
- package/dist/{src/monitors → monitors}/ClickMonitor.d.ts +10 -13
- package/dist/monitors/ClickMonitor.js +72 -76
- package/dist/monitors/ClickMonitor.test.d.ts +1 -0
- package/dist/{src/monitors → monitors}/ErrorMonitor.d.ts +4 -28
- package/dist/monitors/ErrorMonitor.js +45 -55
- package/dist/{src/monitors → monitors}/KeyboardInputMonitor.d.ts +1 -3
- package/dist/monitors/KeyboardInputMonitor.js +13 -11
- package/dist/{src/monitors → monitors}/PageMonitor.d.ts +1 -1
- package/dist/monitors/PageMonitor.js +25 -2
- package/dist/{src/monitors → monitors}/RequestMonitor.d.ts +9 -29
- package/dist/monitors/RequestMonitor.js +46 -57
- package/dist/monitors/http-tools/GqlErrorValidator.d.ts +35 -0
- package/dist/monitors/http-tools/GqlErrorValidator.js +42 -70
- package/dist/{src/monitors → monitors}/http-tools/HTTPDataBundler.d.ts +9 -15
- package/dist/monitors/http-tools/HTTPDataBundler.js +74 -67
- package/dist/monitors/integrations/ReactNativeNavigationIntegration.d.ts +17 -0
- package/dist/monitors/integrations/{react-native-navigation-integration.js → ReactNativeNavigationIntegration.js} +15 -12
- package/dist/{src/pageVisit → pageVisit}/EventDebouncer.d.ts +9 -10
- package/dist/pageVisit/EventDebouncer.js +43 -74
- package/dist/pageVisit/HttpEventManager.d.ts +14 -0
- package/dist/pageVisit/HttpEventManager.js +88 -0
- package/dist/pageVisit/PageVisitManager.d.ts +31 -0
- package/dist/pageVisit/PageVisitManager.js +99 -0
- package/dist/pageVisit/pageVisitEventError.d.ts +12 -0
- package/dist/pageVisit/pageVisitEventError.js +170 -280
- package/dist/{src/react → react}/ErrorBoundary.d.ts +4 -9
- package/dist/react/ErrorBoundary.js +3 -6
- package/dist/{src/sessionRecorder/sessionRecorder.d.ts → sessionRecorder/SessionRecorder.d.ts} +7 -17
- package/dist/sessionRecorder/{sessionRecorder.js → SessionRecorder.js} +60 -71
- package/dist/{src/sessionRecorder → sessionRecorder}/nativeSessionRecorderSubscription.d.ts +4 -6
- package/dist/sessionRecorder/nativeSessionRecorderSubscription.js +3 -5
- package/dist/{src/storage/rnStorageProvider.d.ts → storage/RNStorageProvider.d.ts} +4 -8
- package/dist/storage/{rnStorageProvider.js → RNStorageProvider.js} +3 -7
- package/dist/{src/storage/storage.d.ts → storage/Storage.d.ts} +8 -18
- package/dist/storage/{storage.js → Storage.js} +17 -30
- package/dist/{src/storage/storageProvider.d.ts → storage/StorageProvider.d.ts} +5 -8
- package/dist/storage/{storageProvider.js → StorageProvider.js} +7 -8
- package/dist/types/NavigationIntegration.d.ts +1 -1
- package/dist/utils/date.d.ts +7 -0
- package/dist/utils/date.js +41 -51
- package/dist/utils/eventlistener.js +6 -14
- package/dist/{src/utils → utils}/function.d.ts +13 -43
- package/dist/utils/function.js +42 -113
- package/dist/utils/log.d.ts +4 -0
- package/dist/utils/log.js +2 -4
- package/dist/{src/utils → utils}/object.d.ts +10 -8
- package/dist/utils/object.js +12 -12
- package/dist/{src/utils → utils}/performance.d.ts +1 -1
- package/dist/utils/piiRedactor.js +31 -3
- package/dist/utils/stacktrace-parser.d.ts +8 -0
- package/dist/utils/stacktrace-parser.js +29 -21
- package/dist/utils/stacktrace-parser.test.d.ts +1 -0
- 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/inputManager.d.ts +0 -87
- package/dist/src/constants.d.ts +0 -290
- package/dist/src/entry/init.d.ts +0 -5
- package/dist/src/monitors/AppNavigationMonitor.d.ts +0 -18
- package/dist/src/monitors/http-tools/GqlErrorValidator.d.ts +0 -59
- package/dist/src/monitors/integrations/react-native-navigation-integration.d.ts +0 -20
- 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/utils/date.d.ts +0 -6
- package/dist/src/utils/log.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/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/dist/{src/api/clientConfig.test.d.ts → api/ClientConfig.test.d.ts} +0 -0
- /package/dist/{src/monitors/BaseMonitor.test.d.ts → api/MetroplexSocket.test.d.ts} +0 -0
- /package/dist/{src/const_matchers.d.ts → const_matchers.d.ts} +0 -0
- /package/dist/{src/sessionRecorder → sessionRecorder}/types.d.ts +0 -0
- /package/dist/{src/utils → utils}/eventlistener.d.ts +0 -0
- /package/dist/{src/utils → utils}/piiRedactor.d.ts +0 -0
- /package/dist/{src/utils → utils}/polyfills.d.ts +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MAX_STRING_LENGTH } from '../constants.js';
|
|
2
2
|
|
|
3
3
|
/* eslint-disable require-jsdoc,prefer-destructuring,camelcase */
|
|
4
4
|
// This is a loose copy of ravenjs code
|
|
@@ -15,13 +15,14 @@ import { MAX_FRAMES_IN_ARRAY, MAX_STRING_LENGTH } from '../constants.js';
|
|
|
15
15
|
// or substantial portions of the Software.
|
|
16
16
|
//
|
|
17
17
|
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
18
|
-
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
|
|
18
|
+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR Target
|
|
19
19
|
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
20
20
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
21
21
|
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
|
22
22
|
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
// global reference to slice
|
|
24
24
|
const UNKNOWN_FUNCTION = '<unknown>';
|
|
25
|
+
const MAX_FRAMES_IN_ARRAY = 15;
|
|
25
26
|
/**
|
|
26
27
|
* Safari web extensions, starting version unknown, can produce "frames-only" stacktraces.
|
|
27
28
|
* What it means, is that instead of format like:
|
|
@@ -48,9 +49,7 @@ const extractSafariExtensionDetails = (func, filename) => {
|
|
|
48
49
|
return isSafariExtension || isSafariWebExtension
|
|
49
50
|
? [
|
|
50
51
|
func.indexOf('@') !== -1 ? func.split('@')[0] : UNKNOWN_FUNCTION,
|
|
51
|
-
isSafariExtension
|
|
52
|
-
? `safari-extension:${filename}`
|
|
53
|
-
: `safari-web-extension:${filename}`,
|
|
52
|
+
isSafariExtension ? `safari-extension:${filename}` : `safari-web-extension:${filename}`,
|
|
54
53
|
]
|
|
55
54
|
: [func, filename];
|
|
56
55
|
};
|
|
@@ -68,8 +67,8 @@ function createFrame(filename, func, lineno, colno) {
|
|
|
68
67
|
return frame;
|
|
69
68
|
}
|
|
70
69
|
// Chromium based browsers: Chrome, Brave, new Opera, new Edge
|
|
71
|
-
const chromeRegex = /^\s*at (?:(.+?\)(?: \[
|
|
72
|
-
const chromeEvalRegex = /\((\S*)(
|
|
70
|
+
const chromeRegex = /^\s*at (?:(.+?\)(?: \[.+])?|.*?) ?\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
|
|
71
|
+
const chromeEvalRegex = /\((\S*):(\d+):(\d+)\)/;
|
|
73
72
|
const chrome = (line) => {
|
|
74
73
|
const parts = chromeRegex.exec(line);
|
|
75
74
|
if (parts) {
|
|
@@ -89,20 +88,29 @@ const chrome = (line) => {
|
|
|
89
88
|
return undefined;
|
|
90
89
|
};
|
|
91
90
|
function parseStack(stackString) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
if (typeof stackString === 'string') {
|
|
92
|
+
return stackString
|
|
93
|
+
.split('\n')
|
|
94
|
+
.slice(0, MAX_FRAMES_IN_ARRAY + 1)
|
|
95
|
+
.reduce((stack, line) => {
|
|
96
|
+
if (line.length > MAX_STRING_LENGTH) {
|
|
97
|
+
return stack;
|
|
98
|
+
}
|
|
99
|
+
const parseResult = chrome(line);
|
|
100
|
+
if (parseResult) {
|
|
101
|
+
stack.push(parseResult);
|
|
102
|
+
}
|
|
98
103
|
return stack;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
}, []);
|
|
105
|
+
}
|
|
106
|
+
if (stackString.length && stackString[0].file) {
|
|
107
|
+
return stackString.map(frame => ({
|
|
108
|
+
file: frame.file || '<unknown>',
|
|
109
|
+
line: frame.lineNumber,
|
|
110
|
+
mname: `${frame.class}.${frame.methodName}`,
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
return [];
|
|
106
114
|
}
|
|
107
115
|
|
|
108
|
-
export { parseStack };
|
|
116
|
+
export { MAX_FRAMES_IN_ARRAY, parseStack };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "noibu-react-native",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"targetNjsVersion": "1.0.104",
|
|
5
5
|
"description": "React-Native SDK for NoibuJS to collect errors in React-Native applications",
|
|
6
6
|
"main": "dist/entry/index.js",
|
|
@@ -16,12 +16,10 @@
|
|
|
16
16
|
"clean": "rimraf ./dist/*",
|
|
17
17
|
"build": "node ./build.js",
|
|
18
18
|
"build:dev": "node ./build.watch.js",
|
|
19
|
-
"
|
|
19
|
+
"prepack": "npm run clean; npm run build;",
|
|
20
20
|
"test": "jest --coverage",
|
|
21
21
|
"tsc": "tsc",
|
|
22
|
-
"lint": "eslint
|
|
23
|
-
"lint_output": "eslint src -c .eslintrc.json --ext js,ts,jsx,tsx -f json > eslint_report.json",
|
|
24
|
-
"codecov": "codecov"
|
|
22
|
+
"lint": "tsc eslint.config.ts && eslint ."
|
|
25
23
|
},
|
|
26
24
|
"peerDependenciesMeta": {
|
|
27
25
|
"react-native-navigation": {
|
|
@@ -42,13 +40,16 @@
|
|
|
42
40
|
"react-native": ">=0.63.0",
|
|
43
41
|
"react-native-navigation": ">=2.29.0",
|
|
44
42
|
"react-native-url-polyfill": "^1.3.0",
|
|
45
|
-
"react-native-uuid": "^2.0.1"
|
|
43
|
+
"react-native-uuid": "^2.0.1",
|
|
44
|
+
"whatwg-fetch": "^3.6.20"
|
|
46
45
|
},
|
|
47
46
|
"devDependencies": {
|
|
48
47
|
"@babel/core": "^7.26.0",
|
|
49
48
|
"@babel/preset-env": "^7.26.0",
|
|
50
49
|
"@babel/preset-typescript": "^7.26.0",
|
|
50
|
+
"@eslint/eslintrc": "^3.2.0",
|
|
51
51
|
"@jest/globals": "^29.7.0",
|
|
52
|
+
"@noibu/metroplex-ts-bindings": "1.0.25",
|
|
52
53
|
"@react-native-async-storage/async-storage": "^1.19.0",
|
|
53
54
|
"@rollup/plugin-commonjs": "^25.0.0",
|
|
54
55
|
"@rollup/plugin-json": "^6.0.0",
|
|
@@ -60,20 +61,19 @@
|
|
|
60
61
|
"@types/node": "^20.2.3",
|
|
61
62
|
"@types/react": "16.14.62",
|
|
62
63
|
"@types/react-test-renderer": "^18.0.0",
|
|
63
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
64
|
-
"@typescript-eslint/parser": "^
|
|
64
|
+
"@typescript-eslint/eslint-plugin": "^8.19.1",
|
|
65
|
+
"@typescript-eslint/parser": "^8.19.1",
|
|
65
66
|
"babel-jest": "^29.7.0",
|
|
66
67
|
"babel-plugin-transform-flow-strip-types": "^6.22.0",
|
|
67
68
|
"codecov": "^3.8.3",
|
|
68
69
|
"dotenv": "^16.1.3",
|
|
69
|
-
"eslint": "^
|
|
70
|
-
"eslint-
|
|
71
|
-
"eslint-
|
|
72
|
-
"eslint-plugin-
|
|
73
|
-
"eslint-plugin-prettier": "^4.2.1",
|
|
70
|
+
"eslint": "^9.17.0",
|
|
71
|
+
"eslint-plugin-jsdoc": "^50.6.1",
|
|
72
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
73
|
+
"eslint-plugin-react": "^7.37.3",
|
|
74
74
|
"fflate": "0.8.2",
|
|
75
75
|
"jest": "^29.7.0",
|
|
76
|
-
"prettier": "^
|
|
76
|
+
"prettier": "^3.4.2",
|
|
77
77
|
"react": "16.13.1",
|
|
78
78
|
"react-native": "0.63.0",
|
|
79
79
|
"react-native-navigation": "^7.40.3",
|
package/dist/api/inputManager.js
DELETED
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
import { NOIBUJS_SDK_REQUEST_HELP_CODE, NOIBUJS_SDK_ADD_ID_FUNCTION, NOIBUJS_SDK_ADD_ERROR_FUNCTION, NOIBUJS_SDK_ADD_ERROR_FROM_JS_FMW_FUNCTION, MAX_CUSTOM_ERRORS_PER_PAGEVISIT, MAX_CUSTOM_IDS_PER_PAGEVISIT, META_DATA_METROPLEX_TYPE, PAGE_VISIT_META_DATA_ATT_NAME, CUSTOM_ID_NAME_TYPE, CUSTOM_ID_VALUE_TYPE, CUSTOM_ERROR_EVENT_TYPE } from '../constants.js';
|
|
2
|
-
import MetroplexSocket from './metroplexSocket.js';
|
|
3
|
-
import { saveErrorToPagevisit } from '../pageVisit/pageVisitEventError.js';
|
|
4
|
-
import HelpCode from './helpCode.js';
|
|
5
|
-
|
|
6
|
-
/** @module InputManager */
|
|
7
|
-
|
|
8
|
-
/** this class controls the input that customers can inject into
|
|
9
|
-
* our script via the NoibuJS SDK
|
|
10
|
-
*/
|
|
11
|
-
class InputManager {
|
|
12
|
-
/**
|
|
13
|
-
* Creates a new InputManager
|
|
14
|
-
*/
|
|
15
|
-
constructor() {
|
|
16
|
-
this.customIDs = {};
|
|
17
|
-
this.customErrorsCount = 0;
|
|
18
|
-
|
|
19
|
-
this.TOO_MANY_IDS_ADDED_MSG = 'TOO_MANY_IDS_ADDED';
|
|
20
|
-
this.ID_NAME_ALREADY_ADDED_MSG = 'ID_NAME_ALREADY_ADDED';
|
|
21
|
-
this.NAME_TOO_LONG_MSG = 'NAME_TOO_LONG';
|
|
22
|
-
this.VALUE_TOO_LONG_MSG = 'VALUE_TOO_LONG';
|
|
23
|
-
this.INVALID_NAME_TYPE_MSG = 'INVALID_NAME_TYPE';
|
|
24
|
-
this.INVALID_VALUE_TYPE_MSG = 'INVALID_VALUE_TYPE';
|
|
25
|
-
this.NAME_HAS_NO_LENGTH_MSG = 'NAME_HAS_NO_LENGTH';
|
|
26
|
-
this.VALUE_HAS_NO_LENGTH_MSG = 'VALUE_HAS_NO_LENGTH';
|
|
27
|
-
this.SUCCESS_MSG = 'SUCCESS';
|
|
28
|
-
this.ERROR_HAS_NO_MSG_MSG = 'ERROR_HAS_NO_MSG';
|
|
29
|
-
this.ERROR_HAS_NO_STACK_MSG = 'ERROR_HAS_NO_STACK';
|
|
30
|
-
this.NULL_CUSTOM_ERR_MSG = 'NULL_CUSTOM_ERROR';
|
|
31
|
-
this.ERROR_ALREADY_RECEIVED_MSG = 'ERROR_ALREADY_RECEIVED';
|
|
32
|
-
this.INVALID_ERROR_SOURCE_MSG = 'INVALID_ERROR_SOURCE_MSG';
|
|
33
|
-
this.TOO_MANY_ERRORS_RECEIVED_PER_PAGEVISIT_MSG =
|
|
34
|
-
'TOO_MANY_ERRORS_RECEIVED_PER_PAGEVISIT';
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** gets the singleton instance */
|
|
38
|
-
static getInstance() {
|
|
39
|
-
if (!this.instance) {
|
|
40
|
-
this.instance = new InputManager();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return this.instance;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** exposes functions to the window of the browser for the clients
|
|
47
|
-
* to interact with on their end
|
|
48
|
-
*/
|
|
49
|
-
exposeFunctions() {
|
|
50
|
-
return this._getSDKWindowObject();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* gets the sdk object that will be assigned to a window variable
|
|
55
|
-
* @returns {{
|
|
56
|
-
* requestHelpCode: (alert?: boolean) => Promise<string>,
|
|
57
|
-
* addCustomAttribute: (name: string, value: string) => Promise<string>,
|
|
58
|
-
* addError: (customError: Error) => string,
|
|
59
|
-
* addJsSdkError: (customError: string, errorSource: string) => string
|
|
60
|
-
* }}
|
|
61
|
-
*/
|
|
62
|
-
_getSDKWindowObject() {
|
|
63
|
-
return {
|
|
64
|
-
// adding all the functions and binding the current context
|
|
65
|
-
// so that we can use the exposed function as if they are running`
|
|
66
|
-
// in the noibujs script
|
|
67
|
-
[NOIBUJS_SDK_REQUEST_HELP_CODE]: this._requestHelpCode.bind(this),
|
|
68
|
-
[NOIBUJS_SDK_ADD_ID_FUNCTION]: this._addCustomAttribute.bind(this),
|
|
69
|
-
[NOIBUJS_SDK_ADD_ERROR_FUNCTION]: this._addCustomError.bind(this),
|
|
70
|
-
[NOIBUJS_SDK_ADD_ERROR_FROM_JS_FMW_FUNCTION]:
|
|
71
|
-
this._addErrorFromJSSdk.bind(this),
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* validates the custom error that was passed
|
|
77
|
-
* @param {} customError
|
|
78
|
-
*/
|
|
79
|
-
_validateCustomError(customError) {
|
|
80
|
-
// customError cannot be null
|
|
81
|
-
if (!customError) {
|
|
82
|
-
return this.NULL_CUSTOM_ERR_MSG;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// making sure we have the message and stack to create an error signature
|
|
86
|
-
if (!customError.message) {
|
|
87
|
-
return this.ERROR_HAS_NO_MSG_MSG;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (!customError.stack) {
|
|
91
|
-
return this.ERROR_HAS_NO_STACK_MSG;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return this.SUCCESS_MSG;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Validates and sets the custom error to our internal trackers
|
|
99
|
-
* @param {} customError
|
|
100
|
-
*/
|
|
101
|
-
_validateAndSetCustomError(customError) {
|
|
102
|
-
// we cap the number of errors allowed to be sent
|
|
103
|
-
if (this.customErrorsCount >= MAX_CUSTOM_ERRORS_PER_PAGEVISIT) {
|
|
104
|
-
return this.TOO_MANY_ERRORS_RECEIVED_PER_PAGEVISIT_MSG;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// need to validate first before we start operating with the received
|
|
108
|
-
// data
|
|
109
|
-
const validationResult = this._validateCustomError(customError);
|
|
110
|
-
if (validationResult !== this.SUCCESS_MSG) {
|
|
111
|
-
return validationResult;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
this.customErrorsCount += 1;
|
|
115
|
-
return this.SUCCESS_MSG;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* adds an error from a JS Sdk to the session
|
|
120
|
-
* @param {} customError
|
|
121
|
-
* @param {string} errorSource
|
|
122
|
-
*/
|
|
123
|
-
_addErrorFromJSSdk(customError, errorSource) {
|
|
124
|
-
const validationAndSettingResult =
|
|
125
|
-
this._validateAndSetCustomError(customError);
|
|
126
|
-
|
|
127
|
-
if (validationAndSettingResult !== this.SUCCESS_MSG) {
|
|
128
|
-
return validationAndSettingResult;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
saveErrorToPagevisit(errorSource, { error: customError });
|
|
132
|
-
return validationAndSettingResult;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* adds a custom Error to the session
|
|
137
|
-
* @param {} customError
|
|
138
|
-
*/
|
|
139
|
-
_addCustomError(customError) {
|
|
140
|
-
const validationAndSettingResult =
|
|
141
|
-
this._validateAndSetCustomError(customError);
|
|
142
|
-
if (validationAndSettingResult !== this.SUCCESS_MSG) {
|
|
143
|
-
return validationAndSettingResult;
|
|
144
|
-
}
|
|
145
|
-
saveErrorToPagevisit(CUSTOM_ERROR_EVENT_TYPE, { error: customError });
|
|
146
|
-
return validationAndSettingResult;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* adds a custom id to the session
|
|
151
|
-
* @param {} name
|
|
152
|
-
* @param {} value
|
|
153
|
-
*/
|
|
154
|
-
async _addCustomAttribute(name, value) {
|
|
155
|
-
// we return if we are over the limit of ids
|
|
156
|
-
if (Object.keys(this.customIDs).length >= MAX_CUSTOM_IDS_PER_PAGEVISIT) {
|
|
157
|
-
return this.TOO_MANY_IDS_ADDED_MSG;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// need to validate first before we start operating with the received
|
|
161
|
-
// data
|
|
162
|
-
const validationResult = this._validateCustomIDInput(name, value);
|
|
163
|
-
if (validationResult !== this.SUCCESS_MSG) {
|
|
164
|
-
return validationResult;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// we do not want to keep sending something that was already sent
|
|
168
|
-
if (name in this.customIDs) {
|
|
169
|
-
return this.ID_NAME_ALREADY_ADDED_MSG;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
this.customIDs[name] = value;
|
|
173
|
-
await MetroplexSocket.getInstance().sendMessage(META_DATA_METROPLEX_TYPE, {
|
|
174
|
-
[PAGE_VISIT_META_DATA_ATT_NAME]: {
|
|
175
|
-
[CUSTOM_ID_NAME_TYPE]: name,
|
|
176
|
-
[CUSTOM_ID_VALUE_TYPE]: value,
|
|
177
|
-
},
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
return this.SUCCESS_MSG;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* validation function for customer input
|
|
185
|
-
* @param {} name
|
|
186
|
-
* @param {} value
|
|
187
|
-
*/
|
|
188
|
-
_validateCustomIDInput(name, value) {
|
|
189
|
-
// all ids need to be strings and less than 50 chars and more than 0 chars
|
|
190
|
-
if (typeof name !== 'string') {
|
|
191
|
-
return this.INVALID_NAME_TYPE_MSG;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (typeof value !== 'string') {
|
|
195
|
-
return this.INVALID_VALUE_TYPE_MSG;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
if (value.length > 50) {
|
|
199
|
-
return this.VALUE_TOO_LONG_MSG;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
if (name.length > 50) {
|
|
203
|
-
return this.NAME_TOO_LONG_MSG;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (value.length === 0) {
|
|
207
|
-
return this.VALUE_HAS_NO_LENGTH_MSG;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (name.length === 0) {
|
|
211
|
-
return this.NAME_HAS_NO_LENGTH_MSG;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return this.SUCCESS_MSG;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Requests a help code from the HelpCode instance.
|
|
219
|
-
* @param {boolean} [alertUser=true] - Whether to alert the user about the help code request.
|
|
220
|
-
* @returns {Promise<string>} A promise that resolves with the requested help code.
|
|
221
|
-
*/
|
|
222
|
-
_requestHelpCode() {
|
|
223
|
-
return HelpCode.getInstance().requestHelpCode();
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
export { InputManager as default };
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import { BROWSER_ID_ATT_NAME, PV_ID_ATT_NAME, COLLECT_VER_ATT_NAME, CURRENT_NOIBUJS_VERSION, VER_ATT_NAME, CURRENT_METRICS_VERSION, EXP_VIDEO_LENGTH_ATT_NAME, PV_EXP_VF_SEQ_ATT_NAME, PV_EXP_PART_COUNTER_ATT_NAME, PV_EXP_HTTP_DATA_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, VIDEO_CLICKS_ATT_NAME, PV_CLICKS_ATT_NAME, DID_CUT_PV_ATT_NAME, DID_CUT_VID_ATT_NAME, DID_START_VID_ATT_NAME, HTTP_COUNT_EXPECTED_ATT_NAME, ERR_COUNT_EXPECTED_ATT_NAME, ON_URL_ATT_NAME, GET_METROPLEX_METRICS_URL } from '../constants.js';
|
|
2
|
-
import ClientConfig from './clientConfig.js';
|
|
3
|
-
import { getUserAgent, stringifyJSON } from '../utils/function.js';
|
|
4
|
-
import { addSafeEventListener } from '../utils/eventlistener.js';
|
|
5
|
-
import { unwrapNoibuWrapped } from '../utils/object.js';
|
|
6
|
-
|
|
7
|
-
/** @module StoredMetrics */
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* This class holds the final page visit and video frag metrics. It flushes
|
|
11
|
-
* them to storage and then finally sends them to Metroplex via the post
|
|
12
|
-
* route when the next page is loaded
|
|
13
|
-
*/
|
|
14
|
-
class StoredMetrics {
|
|
15
|
-
/**
|
|
16
|
-
* Creates a new StoredMetrics instance
|
|
17
|
-
*/
|
|
18
|
-
constructor() {
|
|
19
|
-
this.expectedVideoLength = 0;
|
|
20
|
-
this.expectedVfSeq = 0;
|
|
21
|
-
this.httpSequenceNumber = 0;
|
|
22
|
-
this.httpOverLimitCount = 0;
|
|
23
|
-
this.httpDroppedPayloadByTypeCount = 0;
|
|
24
|
-
this.httpDroppedPayloadByLengthCount = 0;
|
|
25
|
-
this.httpPayloadCount = 0;
|
|
26
|
-
this.expectedPvPart = 0;
|
|
27
|
-
this.videoClicks = 0;
|
|
28
|
-
this.pvClicks = 0;
|
|
29
|
-
this.errCount = 0;
|
|
30
|
-
this.httpCount = 0;
|
|
31
|
-
this.didCutPv = false;
|
|
32
|
-
this.didCutVideo = false;
|
|
33
|
-
this.writeTimeout = null;
|
|
34
|
-
this.didStartVideo = false;
|
|
35
|
-
|
|
36
|
-
this._setupListeners();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* gets the singleton instance
|
|
41
|
-
* @returns {StoredMetrics}
|
|
42
|
-
*/
|
|
43
|
-
static getInstance() {
|
|
44
|
-
if (!this.instance) {
|
|
45
|
-
this.instance = new StoredMetrics();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return this.instance;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** Add video frag payload data to the stored metrics
|
|
52
|
-
* @param {} expectedVfSeq
|
|
53
|
-
* @param {} expectedVideoLength
|
|
54
|
-
*/
|
|
55
|
-
addVideoFragData(expectedVfSeq, expectedVideoLength) {
|
|
56
|
-
this.expectedVfSeq = expectedVfSeq;
|
|
57
|
-
this.expectedVideoLength = expectedVideoLength;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** Set the amount of page visit parts
|
|
61
|
-
* @param {} expectedPvPart
|
|
62
|
-
*/
|
|
63
|
-
setPvPart(expectedPvPart) {
|
|
64
|
-
this.expectedPvPart = expectedPvPart;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/** Increase the amount of video clicks seen in the session */
|
|
68
|
-
addVideoClick() {
|
|
69
|
-
this.videoClicks += 1;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** Increase the amount of page visit clicks */
|
|
73
|
-
addPvClick() {
|
|
74
|
-
this.pvClicks += 1;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/** Increments the error count by 1 */
|
|
78
|
-
addError() {
|
|
79
|
-
this.errCount += 1;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/** Increments the http count by 1 */
|
|
83
|
-
addHttpEvent() {
|
|
84
|
-
this.httpCount += 1;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/** Increments the http data sequence count by 1 */
|
|
88
|
-
addHttpData() {
|
|
89
|
-
this.httpSequenceNumber += 1;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/** Increments the http data over limit count by 1 */
|
|
93
|
-
addHttpDataOverLimit() {
|
|
94
|
-
this.httpOverLimitCount += 1;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/** Increments the http data drop count by content type */
|
|
98
|
-
addHttpDataDropByType() {
|
|
99
|
-
this.httpDroppedPayloadByTypeCount += 1;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/** Increments the http data drop count by content length */
|
|
103
|
-
addHttpDataDropByLength() {
|
|
104
|
-
this.httpDroppedPayloadByLengthCount += 1;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/** Increments the http data payload collected count */
|
|
108
|
-
addHttpDataPayloadCount() {
|
|
109
|
-
this.httpPayloadCount += 1;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/** Set that the video was cut/blocked due to size constraints */
|
|
113
|
-
setDidCutVideo() {
|
|
114
|
-
this.didCutVideo = true;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/** Set that the video was started */
|
|
118
|
-
setDidStartVideo() {
|
|
119
|
-
this.didStartVideo = true;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/** Set that the page visit was cut/blocked due to size constraints */
|
|
123
|
-
setDidCutPv() {
|
|
124
|
-
this.didCutPv = true;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Sets up all the listeners that noibujs should listen to before storing
|
|
129
|
-
* our metrics to localstorage
|
|
130
|
-
*/
|
|
131
|
-
_setupListeners() {
|
|
132
|
-
// Add the window event handlers to post the data to the metrics endpoint
|
|
133
|
-
const evt = 'pagehide';
|
|
134
|
-
addSafeEventListener(window, evt, () => {
|
|
135
|
-
this._postMetricsIfActive(evt);
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/** posts the metrics to metroplex if client is active
|
|
140
|
-
* @param {} eventName
|
|
141
|
-
*/
|
|
142
|
-
_postMetricsIfActive(eventName) {
|
|
143
|
-
if (ClientConfig.getInstance().isClientDisabled) {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
// Don't send the metrics if the session has become inactive
|
|
147
|
-
// already sent when went inactive
|
|
148
|
-
if (ClientConfig.getInstance().isInactive()) {
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
this.postMetrics(eventName);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/** posts the metrics to metroplex using the beacon API
|
|
155
|
-
*/
|
|
156
|
-
async postMetrics() {
|
|
157
|
-
// Create a new object to write to local storage that doesnt have the timeout and flush members.
|
|
158
|
-
const lsMetrics = {
|
|
159
|
-
// metadata
|
|
160
|
-
[BROWSER_ID_ATT_NAME]: ClientConfig.getInstance().browserId,
|
|
161
|
-
[PV_ID_ATT_NAME]: ClientConfig.getInstance().pageVisitId,
|
|
162
|
-
[COLLECT_VER_ATT_NAME]: CURRENT_NOIBUJS_VERSION,
|
|
163
|
-
[VER_ATT_NAME]: CURRENT_METRICS_VERSION,
|
|
164
|
-
|
|
165
|
-
// metrics
|
|
166
|
-
[EXP_VIDEO_LENGTH_ATT_NAME]: this.expectedVideoLength,
|
|
167
|
-
[PV_EXP_VF_SEQ_ATT_NAME]: this.expectedVfSeq,
|
|
168
|
-
[PV_EXP_PART_COUNTER_ATT_NAME]: this.expectedPvPart,
|
|
169
|
-
[PV_EXP_HTTP_DATA_SEQ_ATT_NAME]: this.httpSequenceNumber,
|
|
170
|
-
[PV_HTTP_PAYLOADS_COLLECTED_ATT_NAME]: this.httpPayloadCount,
|
|
171
|
-
[PV_HTTP_PAYLOADS_DROPPED_OVERSIZE_ATT_NAME]:
|
|
172
|
-
this.httpDroppedPayloadByLengthCount,
|
|
173
|
-
[PV_HTTP_PAYLOADS_DROPPED_TYPE_ATT_NAME]:
|
|
174
|
-
this.httpDroppedPayloadByTypeCount,
|
|
175
|
-
[PV_HTTP_REQUESTS_DROPPED_OVER_LIMIT]: this.httpOverLimitCount,
|
|
176
|
-
[VIDEO_CLICKS_ATT_NAME]: this.videoClicks,
|
|
177
|
-
[PV_CLICKS_ATT_NAME]: this.pvClicks,
|
|
178
|
-
[DID_CUT_PV_ATT_NAME]: this.didCutPv,
|
|
179
|
-
[DID_CUT_VID_ATT_NAME]: this.didCutVideo,
|
|
180
|
-
[DID_START_VID_ATT_NAME]: this.didStartVideo,
|
|
181
|
-
[HTTP_COUNT_EXPECTED_ATT_NAME]: this.httpCount,
|
|
182
|
-
[ERR_COUNT_EXPECTED_ATT_NAME]: this.errCount,
|
|
183
|
-
[ON_URL_ATT_NAME]: ClientConfig.getInstance().globalUrl,
|
|
184
|
-
};
|
|
185
|
-
unwrapNoibuWrapped(fetch)(GET_METROPLEX_METRICS_URL(), {
|
|
186
|
-
method: 'POST',
|
|
187
|
-
headers: {
|
|
188
|
-
'content-type': 'application/json',
|
|
189
|
-
'User-Agent': await getUserAgent(),
|
|
190
|
-
},
|
|
191
|
-
body: stringifyJSON(lsMetrics),
|
|
192
|
-
// keep alive outlives the current page, its the same as beacon
|
|
193
|
-
keepalive: true,
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
export { StoredMetrics as default };
|