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,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { PageVisitManager } from './PageVisitManager.js';
|
|
2
|
+
import { MAX_TIME_FOR_UNSENT_DATA_MILLIS } from '../constants.js';
|
|
3
|
+
import { getOccurredNow } from '../utils/date.js';
|
|
4
4
|
import { addSafeEventListener } from '../utils/eventlistener.js';
|
|
5
|
-
import ClientConfig from '../api/clientConfig.js';
|
|
6
5
|
import { Singleton } from '../monitors/BaseMonitor.js';
|
|
7
6
|
|
|
8
7
|
/** @module EventDebouncer */
|
|
@@ -11,42 +10,35 @@ import { Singleton } from '../monitors/BaseMonitor.js';
|
|
|
11
10
|
* that are registered
|
|
12
11
|
*/
|
|
13
12
|
class EventDebouncer extends Singleton {
|
|
14
|
-
/**
|
|
15
|
-
* Creates an instance of EventDebouncer
|
|
16
|
-
*/
|
|
13
|
+
/** Creates an instance of EventDebouncer */
|
|
17
14
|
constructor() {
|
|
18
15
|
super();
|
|
19
|
-
this.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
[
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
[
|
|
45
|
-
timeout: null,
|
|
46
|
-
events: [],
|
|
47
|
-
debouncePeriod: MAX_TIME_FOR_UNSENT_DATA_MILLIS,
|
|
48
|
-
eventName: KEYBOARD_EVENT_TYPE,
|
|
49
|
-
},
|
|
16
|
+
this.debouncePeriods = {
|
|
17
|
+
app_nav: 0,
|
|
18
|
+
page: MAX_TIME_FOR_UNSENT_DATA_MILLIS,
|
|
19
|
+
err: MAX_TIME_FOR_UNSENT_DATA_MILLIS,
|
|
20
|
+
http: MAX_TIME_FOR_UNSENT_DATA_MILLIS,
|
|
21
|
+
userstep: MAX_TIME_FOR_UNSENT_DATA_MILLIS,
|
|
22
|
+
};
|
|
23
|
+
this.timeouts = {
|
|
24
|
+
app_nav: null,
|
|
25
|
+
page: null,
|
|
26
|
+
err: null,
|
|
27
|
+
http: null,
|
|
28
|
+
userstep: null,
|
|
29
|
+
};
|
|
30
|
+
this.events = {
|
|
31
|
+
app_nav: [],
|
|
32
|
+
page: [],
|
|
33
|
+
err: [],
|
|
34
|
+
http: [],
|
|
35
|
+
userstep: [],
|
|
36
|
+
};
|
|
37
|
+
/** Debounce function to be executed once the debounce period is completed */
|
|
38
|
+
this.sendEvents = (type) => {
|
|
39
|
+
this.timeouts[type] = null;
|
|
40
|
+
PageVisitManager.getInstance().addPageVisitEvents(this.events[type]);
|
|
41
|
+
this.events[type] = [];
|
|
50
42
|
};
|
|
51
43
|
this._setupUnloadHandler();
|
|
52
44
|
}
|
|
@@ -54,45 +46,22 @@ class EventDebouncer extends Singleton {
|
|
|
54
46
|
* Creates an event object with the event and the time it was added then pushes
|
|
55
47
|
* that event object to the queue of events waiting to be debounced.
|
|
56
48
|
*/
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
this.eventsToDebounce[type].events.push({
|
|
66
|
-
event,
|
|
67
|
-
occurredAt: new Date(timestampWrapper(occurredAt)).toISOString(),
|
|
68
|
-
});
|
|
69
|
-
this._debouncePvEvents(type);
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Adds the events from the object to the page visit and sets up a timer
|
|
73
|
-
* to send the events if no more are received without the timeout
|
|
74
|
-
*/
|
|
75
|
-
_debouncePvEvents(type) {
|
|
76
|
-
/**
|
|
77
|
-
* Debounce function to be executed once the debounce period is completed
|
|
78
|
-
*/
|
|
79
|
-
const later = () => {
|
|
80
|
-
this.eventsToDebounce[type].timeout = null;
|
|
81
|
-
PageVisit.getInstance().addPageVisitEvents(this.eventsToDebounce[type].events, this.eventsToDebounce[type].eventName);
|
|
82
|
-
this.eventsToDebounce[type].events = [];
|
|
83
|
-
};
|
|
84
|
-
if (this.eventsToDebounce[type].timeout !== null) {
|
|
85
|
-
clearTimeout(this.eventsToDebounce[type].timeout);
|
|
86
|
-
}
|
|
87
|
-
this.eventsToDebounce[type].timeout = setTimeout(later, this.eventsToDebounce[type].debouncePeriod);
|
|
49
|
+
debounce(event) {
|
|
50
|
+
const type = event.type;
|
|
51
|
+
const withTimestamp = Object.assign(Object.assign({}, event), { occ_at: getOccurredNow() });
|
|
52
|
+
const debouncePeriod = this.debouncePeriods[type];
|
|
53
|
+
this.events[type].push(withTimestamp);
|
|
54
|
+
clearTimeout(this.timeouts[type]);
|
|
55
|
+
this.timeouts[event.type] = setTimeout(() => this.sendEvents(type), debouncePeriod);
|
|
88
56
|
}
|
|
89
57
|
/** Sets up the page hide handler to try to push remaining events in the queues */
|
|
90
58
|
_setupUnloadHandler() {
|
|
91
|
-
addSafeEventListener(window, 'pagehide', () =>
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
59
|
+
addSafeEventListener(window, 'pagehide', () => Object.keys(this.debouncePeriods).forEach((key) => this.sendEvents(key)));
|
|
60
|
+
}
|
|
61
|
+
destroy() {
|
|
62
|
+
Object.values(this.timeouts)
|
|
63
|
+
.filter(t => !!t)
|
|
64
|
+
.forEach(clearTimeout);
|
|
96
65
|
}
|
|
97
66
|
}
|
|
98
67
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { NoSeq } from '../types/Metroplex';
|
|
2
|
+
import { PageVisitEventHTTP, RawHttpData } from '@noibu/metroplex-ts-bindings';
|
|
3
|
+
/** Saves the HTTP event to the pageVisit Queue */
|
|
4
|
+
export declare function saveHTTPEvent(httpEvent: Partial<PageVisitEventHTTP>, httpData?: NoSeq<RawHttpData> | null, isGqlError?: boolean): number | undefined;
|
|
5
|
+
/** Determines if a response is a failure */
|
|
6
|
+
export declare function isHttpCodeFailure(code: unknown): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Checks if sending data is allowed based on the HTTP status code and count.
|
|
9
|
+
* status - The HTTP status code to evaluate.
|
|
10
|
+
* count - The count of events to consider.
|
|
11
|
+
* isGqlError - Whether the context is considered as a GQL error.
|
|
12
|
+
* Returns `true` if sending data is allowed, `false` otherwise.
|
|
13
|
+
*/
|
|
14
|
+
export declare function isSendAllowed(status: number, count: number, isGqlError?: boolean): boolean;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { PageVisitManager } from './PageVisitManager.js';
|
|
2
|
+
import StoredMetrics from '../api/StoredMetrics.js';
|
|
3
|
+
import MetroplexSocket from '../api/MetroplexSocket.js';
|
|
4
|
+
import { safeTrim, getMaxSubstringAllowed, asString } from '../utils/function.js';
|
|
5
|
+
import { EventDebouncer } from './EventDebouncer.js';
|
|
6
|
+
import '../node_modules/@noibu/metroplex-ts-bindings/dist/index.js';
|
|
7
|
+
import { WebsocketMessageType } from '../node_modules/@noibu/metroplex-ts-bindings/dist/WebsocketMessageType.js';
|
|
8
|
+
import { EventType } from '../node_modules/@noibu/metroplex-ts-bindings/dist/EventType.js';
|
|
9
|
+
|
|
10
|
+
/** @module PageVisitEventHTTP */
|
|
11
|
+
/** http event manager */
|
|
12
|
+
// maximum number of HTTP data events including errors to collect per page visit
|
|
13
|
+
const MAX_HTTP_DATA_IF_ERROR_EVENT_COUNT = 120;
|
|
14
|
+
// maximum number of HTTP data events to collect per page visit
|
|
15
|
+
const MAX_HTTP_DATA_EVENT_COUNT = 100;
|
|
16
|
+
/** if no value or it's less than 0, fallback to 0 */
|
|
17
|
+
const validate = (value) => (!value || value < 0 ? 0 : value);
|
|
18
|
+
/** Saves the HTTP event to the pageVisit Queue */
|
|
19
|
+
function saveHTTPEvent(httpEvent, httpData, isGqlError = false) {
|
|
20
|
+
if (!httpEvent) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const url = safeTrim(getMaxSubstringAllowed(asString(httpEvent.url)));
|
|
24
|
+
// we do not store http events that have empty urls
|
|
25
|
+
if (!url) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const validatedEvent = {
|
|
29
|
+
code: validate(httpEvent.code),
|
|
30
|
+
r_time: validate(httpEvent.r_time),
|
|
31
|
+
mtd: (httpEvent.mtd || 'get').toUpperCase(),
|
|
32
|
+
url,
|
|
33
|
+
};
|
|
34
|
+
// we register an http event
|
|
35
|
+
StoredMetrics.getInstance().addHttpEvent();
|
|
36
|
+
// send http data down to metroplex
|
|
37
|
+
if (httpData) {
|
|
38
|
+
// add the sequence number to both events
|
|
39
|
+
const sequenceNumber = StoredMetrics.getInstance().httpSequenceNumber;
|
|
40
|
+
// restrict total number of events collected per page visit to ensure we don't
|
|
41
|
+
// blow up memory and storage usage
|
|
42
|
+
if (isSendAllowed(validatedEvent.code, sequenceNumber, isGqlError)) {
|
|
43
|
+
const httpDataWithSeq = Object.assign(Object.assign({}, httpData), { seq: sequenceNumber });
|
|
44
|
+
validatedEvent.seq = sequenceNumber;
|
|
45
|
+
// increment the count
|
|
46
|
+
StoredMetrics.getInstance().addHttpData();
|
|
47
|
+
MetroplexSocket.getInstance().sendMessage({ type: WebsocketMessageType.PageVisitHttp, payload: httpDataWithSeq });
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
// have collected more than the max number of http requests for this
|
|
51
|
+
// page visit, so increment the over request limit count
|
|
52
|
+
StoredMetrics.getInstance().addHttpDataOverLimit();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const pve = {
|
|
56
|
+
type: EventType.Http,
|
|
57
|
+
http: validatedEvent,
|
|
58
|
+
};
|
|
59
|
+
// if this was an error, send immediately, so we don't lose it, delay otherwise
|
|
60
|
+
if (isAnError(validatedEvent.code, isGqlError)) {
|
|
61
|
+
PageVisitManager.getInstance().addPageVisitEvent(pve);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
EventDebouncer.getInstance().debounce(pve);
|
|
65
|
+
}
|
|
66
|
+
return validatedEvent.seq;
|
|
67
|
+
}
|
|
68
|
+
/** utility function to determine if status/flags combo is an error */
|
|
69
|
+
function isAnError(status, isGqlError) {
|
|
70
|
+
return isHttpCodeFailure(status) || isGqlError;
|
|
71
|
+
}
|
|
72
|
+
/** Determines if a response is a failure */
|
|
73
|
+
function isHttpCodeFailure(code) {
|
|
74
|
+
return typeof code !== 'number' ? true : code >= 400 || code <= 0;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Checks if sending data is allowed based on the HTTP status code and count.
|
|
78
|
+
* status - The HTTP status code to evaluate.
|
|
79
|
+
* count - The count of events to consider.
|
|
80
|
+
* isGqlError - Whether the context is considered as a GQL error.
|
|
81
|
+
* Returns `true` if sending data is allowed, `false` otherwise.
|
|
82
|
+
*/
|
|
83
|
+
function isSendAllowed(status, count, isGqlError = false) {
|
|
84
|
+
const threshold = isAnError(status, isGqlError) ? MAX_HTTP_DATA_IF_ERROR_EVENT_COUNT : MAX_HTTP_DATA_EVENT_COUNT;
|
|
85
|
+
return count < threshold;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export { isHttpCodeFailure, isSendAllowed, saveHTTPEvent };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Singleton } from '../monitors/BaseMonitor';
|
|
2
|
+
import { PageVisitEvent } from '@noibu/metroplex-ts-bindings';
|
|
3
|
+
/**
|
|
4
|
+
* Singleton class to hold all the information
|
|
5
|
+
* about the gathered errors throught the session
|
|
6
|
+
*/
|
|
7
|
+
export declare class PageVisitManager extends Singleton {
|
|
8
|
+
partCounter: number;
|
|
9
|
+
pvEvents: PageVisitEvent[];
|
|
10
|
+
pvEventLength: number;
|
|
11
|
+
visibilityChangedCounter: number;
|
|
12
|
+
totalPvEventLength: number;
|
|
13
|
+
/** adds page visit events into the current page visit map and then sends a page visit message
|
|
14
|
+
*/
|
|
15
|
+
addPageVisitEvents(eventObjects: PageVisitEvent[]): void;
|
|
16
|
+
/**
|
|
17
|
+
* adds the page visit event into the current page visit map and then sends a page visit message
|
|
18
|
+
* returns the key to access this event in the map
|
|
19
|
+
*/
|
|
20
|
+
addPageVisitEvent(eventObj: Omit<PageVisitEvent, 'occ_at'>): void;
|
|
21
|
+
/**
|
|
22
|
+
* adds a new page visit event into the current page visit map and returns the
|
|
23
|
+
* the key to access this event in the map
|
|
24
|
+
*/
|
|
25
|
+
_addPageVisitEvent(pvEvent: PageVisitEvent): void;
|
|
26
|
+
/**
|
|
27
|
+
* _sendPageVisitMessage will reset the buffer and post the current
|
|
28
|
+
* content to metroplex
|
|
29
|
+
*/
|
|
30
|
+
_sendPageVisitMessage(): void;
|
|
31
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import ClientConfig from '../api/ClientConfig.js';
|
|
2
|
+
import MetroplexSocket from '../api/MetroplexSocket.js';
|
|
3
|
+
import StoredMetrics from '../api/StoredMetrics.js';
|
|
4
|
+
import { noibuLog } from '../utils/log.js';
|
|
5
|
+
import { Singleton } from '../monitors/BaseMonitor.js';
|
|
6
|
+
import { getOccurredNow } from '../utils/date.js';
|
|
7
|
+
import '../node_modules/@noibu/metroplex-ts-bindings/dist/index.js';
|
|
8
|
+
import { WebsocketMessageType } from '../node_modules/@noibu/metroplex-ts-bindings/dist/WebsocketMessageType.js';
|
|
9
|
+
|
|
10
|
+
/** @module Pagevisit */
|
|
11
|
+
const MAX_PAGEVISIT_EVENTS = 200;
|
|
12
|
+
const MAX_PAGEVISIT_PARTS = 10000;
|
|
13
|
+
/**
|
|
14
|
+
* Singleton class to hold all the information
|
|
15
|
+
* about the gathered errors throught the session
|
|
16
|
+
*/
|
|
17
|
+
class PageVisitManager extends Singleton {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(...arguments);
|
|
20
|
+
this.partCounter = 0;
|
|
21
|
+
this.pvEvents = [];
|
|
22
|
+
this.pvEventLength = 0;
|
|
23
|
+
// variables used for monitoring our posting frequency
|
|
24
|
+
this.visibilityChangedCounter = 0;
|
|
25
|
+
this.totalPvEventLength = 0;
|
|
26
|
+
}
|
|
27
|
+
/** adds page visit events into the current page visit map and then sends a page visit message
|
|
28
|
+
*/
|
|
29
|
+
addPageVisitEvents(eventObjects) {
|
|
30
|
+
eventObjects.forEach(eventObj => this._addPageVisitEvent(eventObj));
|
|
31
|
+
this._sendPageVisitMessage();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* adds the page visit event into the current page visit map and then sends a page visit message
|
|
35
|
+
* returns the key to access this event in the map
|
|
36
|
+
*/
|
|
37
|
+
addPageVisitEvent(eventObj) {
|
|
38
|
+
const withTimestamp = Object.assign(Object.assign({}, eventObj), { occ_at: getOccurredNow() });
|
|
39
|
+
noibuLog('addPageVisitEvent', withTimestamp);
|
|
40
|
+
this._addPageVisitEvent(withTimestamp);
|
|
41
|
+
this._sendPageVisitMessage();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* adds a new page visit event into the current page visit map and returns the
|
|
45
|
+
* the key to access this event in the map
|
|
46
|
+
*/
|
|
47
|
+
_addPageVisitEvent(pvEvent) {
|
|
48
|
+
// if we are over the limit set by the Beacon API limit, we need to
|
|
49
|
+
// send what we currently have in the buffer to metroplex
|
|
50
|
+
if (this.pvEventLength >= MAX_PAGEVISIT_EVENTS) {
|
|
51
|
+
this._sendPageVisitMessage();
|
|
52
|
+
}
|
|
53
|
+
// updating sizes
|
|
54
|
+
this.pvEvents.push(pvEvent);
|
|
55
|
+
this.pvEventLength += 1;
|
|
56
|
+
this.totalPvEventLength += 1;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* _sendPageVisitMessage will reset the buffer and post the current
|
|
60
|
+
* content to metroplex
|
|
61
|
+
*/
|
|
62
|
+
_sendPageVisitMessage() {
|
|
63
|
+
if (this.pvEvents.length === 0) {
|
|
64
|
+
/**
|
|
65
|
+
* don't send to metroplex if the event buffer is empty.
|
|
66
|
+
* Target previous call to this function from visibilityChange
|
|
67
|
+
* would have sent it as a final post. Another reason it would be empty is
|
|
68
|
+
* if the user has not done anything on the page and switched tabs,
|
|
69
|
+
* or closed the browser etc
|
|
70
|
+
*/
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (this.partCounter >= MAX_PAGEVISIT_PARTS) {
|
|
74
|
+
/**
|
|
75
|
+
* if we are attempting to send over the MAX_PAGEVISIT_PARTS
|
|
76
|
+
* number of parts then we block any subsequent part post to not
|
|
77
|
+
* overwhelm our back end. We lock the client for 10 minute, something
|
|
78
|
+
* must be going bad.
|
|
79
|
+
*/
|
|
80
|
+
ClientConfig.getInstance().lockClientUntilNextPage({
|
|
81
|
+
msg: 'NoibuJS will stop processing parts because we reached max parts',
|
|
82
|
+
MAX_PAGEVISIT_PARTS,
|
|
83
|
+
totalPvEventLength: this.totalPvEventLength,
|
|
84
|
+
visibilityChangedCounter: this.visibilityChangedCounter,
|
|
85
|
+
});
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const pvp = MetroplexSocket.getInstance().addEndTimeToPayload({ events: this.pvEvents, pc: this.partCounter }, true);
|
|
89
|
+
StoredMetrics.getInstance().setPvPart(this.partCounter);
|
|
90
|
+
MetroplexSocket.getInstance().sendMessage({ payload: pvp, type: WebsocketMessageType.PageVisitPart });
|
|
91
|
+
// since we sent the content of the buffer to metroplex, we reset
|
|
92
|
+
// all variables that contained information about the past buffer.
|
|
93
|
+
this.pvEvents = [];
|
|
94
|
+
this.pvEventLength = 0;
|
|
95
|
+
this.partCounter += 1;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export { PageVisitManager };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Option, PageVisitEventError } from '@noibu/metroplex-ts-bindings';
|
|
2
|
+
import { EventInput, PageVisitErrorInput } from '../types/PageVisitErrors';
|
|
3
|
+
/**
|
|
4
|
+
* gets the onURL of a string, defaulting to the location of the webpage
|
|
5
|
+
*/
|
|
6
|
+
export declare function getOnURL(realOnURL: unknown): string;
|
|
7
|
+
/**
|
|
8
|
+
* determines if an error is a collect error
|
|
9
|
+
*/
|
|
10
|
+
export declare function isErrorCollectedByNoibu(pvError: PageVisitEventError): Promise<false | void>;
|
|
11
|
+
/** Saves the error to the Error queue */
|
|
12
|
+
export declare function saveErrorToPagevisit<T extends PageVisitErrorInput | EventInput>(payload: T, httpDataSeqNum?: Option<number>): void;
|