noibu-react-native 0.0.1

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 (40) hide show
  1. package/README.md +155 -0
  2. package/dist/api/clientConfig.js +416 -0
  3. package/dist/api/helpCode.js +106 -0
  4. package/dist/api/inputManager.js +233 -0
  5. package/dist/api/metroplexSocket.js +882 -0
  6. package/dist/api/storedMetrics.js +201 -0
  7. package/dist/api/storedPageVisit.js +235 -0
  8. package/dist/const_matchers.js +260 -0
  9. package/dist/constants.d.ts +264 -0
  10. package/dist/constants.js +528 -0
  11. package/dist/entry/index.d.ts +8 -0
  12. package/dist/entry/index.js +15 -0
  13. package/dist/entry/init.js +91 -0
  14. package/dist/monitors/clickMonitor.js +284 -0
  15. package/dist/monitors/elementMonitor.js +174 -0
  16. package/dist/monitors/errorMonitor.js +295 -0
  17. package/dist/monitors/gqlErrorValidator.js +306 -0
  18. package/dist/monitors/httpDataBundler.js +665 -0
  19. package/dist/monitors/inputMonitor.js +130 -0
  20. package/dist/monitors/keyboardInputMonitor.js +67 -0
  21. package/dist/monitors/locationChangeMonitor.js +30 -0
  22. package/dist/monitors/pageMonitor.js +119 -0
  23. package/dist/monitors/requestMonitor.js +679 -0
  24. package/dist/pageVisit/pageVisit.js +172 -0
  25. package/dist/pageVisit/pageVisitEventError/pageVisitEventError.js +313 -0
  26. package/dist/pageVisit/pageVisitEventHTTP/pageVisitEventHTTP.js +115 -0
  27. package/dist/pageVisit/userStep/userStep.js +20 -0
  28. package/dist/react/ErrorBoundary.d.ts +72 -0
  29. package/dist/react/ErrorBoundary.js +102 -0
  30. package/dist/storage/localStorageProvider.js +23 -0
  31. package/dist/storage/rnStorageProvider.js +62 -0
  32. package/dist/storage/sessionStorageProvider.js +23 -0
  33. package/dist/storage/storage.js +119 -0
  34. package/dist/storage/storageProvider.js +83 -0
  35. package/dist/utils/date.js +62 -0
  36. package/dist/utils/eventlistener.js +67 -0
  37. package/dist/utils/function.js +398 -0
  38. package/dist/utils/object.js +144 -0
  39. package/dist/utils/performance.js +21 -0
  40. package/package.json +57 -0
@@ -0,0 +1,130 @@
1
+ import { PageVisit } from '../pageVisit/pageVisit.js';
2
+ import { LOCATION_EVENT_TYPE, PAGE_EVENT_TYPE, MAX_TIME_FOR_UNSENT_DATA_MILLIS, ERROR_EVENT_TYPE, HTTP_EVENT_TYPE, KEYBOARD_EVENT_TYPE, USERSTEP_EVENT_TYPE } from '../constants.js';
3
+ import { timestampWrapper } from '../utils/date.js';
4
+ import { addSafeEventListener } from '../utils/eventlistener.js';
5
+
6
+ /** @module InputMonitor */
7
+
8
+ /**
9
+ * Singleton class to manage the client configuration
10
+ * this class will be responsible for debouncing all events
11
+ * that are registered
12
+ */
13
+ class InputMonitor {
14
+ /**
15
+ * Creates an instance of InputMonitor
16
+ */
17
+ constructor() {
18
+ // events are stored in queues that are debounced seperatly
19
+ // each object in this map is
20
+ // type: {
21
+ // timeout: timeout,
22
+ // events: [...],
23
+ // debouncePeriod: period at which we debounce events,
24
+ // eventName: name of the event, could be different than type
25
+ // (clicks and keyboards are usersteps)
26
+ // }
27
+ this.eventsToDebounce = {};
28
+
29
+ // setting up debouncers for all events
30
+ // we send clicks directly to the socket so they aren't registered here
31
+ // we dont wait to send location changes, they happen at most once per second.
32
+ this.registerInputType(LOCATION_EVENT_TYPE, 0);
33
+ this.registerInputType(PAGE_EVENT_TYPE, MAX_TIME_FOR_UNSENT_DATA_MILLIS);
34
+ this.registerInputType(ERROR_EVENT_TYPE, MAX_TIME_FOR_UNSENT_DATA_MILLIS);
35
+ this.registerInputType(HTTP_EVENT_TYPE, MAX_TIME_FOR_UNSENT_DATA_MILLIS);
36
+ this.registerInputType(
37
+ KEYBOARD_EVENT_TYPE,
38
+ MAX_TIME_FOR_UNSENT_DATA_MILLIS,
39
+ USERSTEP_EVENT_TYPE,
40
+ );
41
+
42
+ this._setupUnloadHandler();
43
+ }
44
+
45
+ /** gets the instance of InputMonitor */
46
+ static getInstance() {
47
+ if (!this.instance) {
48
+ this.instance = new InputMonitor();
49
+ }
50
+
51
+ return this.instance;
52
+ }
53
+
54
+ /** will debounce all events that are of this type by the debounce period
55
+ * @param {} type
56
+ * @param {} debouncePeriod
57
+ * @param {} eventName=type
58
+ */
59
+ registerInputType(type, debouncePeriod, eventName = type) {
60
+ if (type in this.eventsToDebounce) {
61
+ return;
62
+ }
63
+
64
+ // registering this event type as a debouncable
65
+ this.eventsToDebounce[type] = {
66
+ timeout: null,
67
+ events: [],
68
+ debouncePeriod,
69
+ eventName,
70
+ };
71
+ }
72
+
73
+ /**
74
+ * Creates an event object with the event and the time it was added then pushes
75
+ * that event object to the queue of events waiting to be debounced.
76
+ * @param {} event
77
+ * @param {} type
78
+ */
79
+ addEvent(event, type) {
80
+ if (!(type in this.eventsToDebounce)) {
81
+ throw new Error(`Type: ${type} is not in eventsToDebounce`);
82
+ }
83
+
84
+ this.eventsToDebounce[type].events.push({
85
+ event,
86
+ occurredAt: new Date(timestampWrapper(Date.now())).toISOString(),
87
+ });
88
+
89
+ this._debouncePvEvents(type);
90
+ }
91
+
92
+ /**
93
+ * Adds the events from the object to the page visit and sets up a timer
94
+ * to send the events if no more are received without the timeout
95
+ * @param {} type
96
+ */
97
+ _debouncePvEvents(type) {
98
+ /**
99
+ * Debounce function to be executed once the debounce period is completed
100
+ */
101
+ const later = () => {
102
+ this.eventsToDebounce[type].timeout = null;
103
+ PageVisit.getInstance().addPageVisitEvents(
104
+ this.eventsToDebounce[type].events,
105
+ this.eventsToDebounce[type].eventName,
106
+ );
107
+ this.eventsToDebounce[type].events = [];
108
+ };
109
+
110
+ clearTimeout(this.eventsToDebounce[type].timeout);
111
+ this.eventsToDebounce[type].timeout = setTimeout(
112
+ later,
113
+ this.eventsToDebounce[type].debouncePeriod,
114
+ );
115
+ }
116
+
117
+ /** Sets up the page hide handler to try to push remaining events in the queues */
118
+ _setupUnloadHandler() {
119
+ addSafeEventListener(window, 'pagehide', () => {
120
+ Object.values(this.eventsToDebounce).forEach(eventObject => {
121
+ PageVisit.getInstance().addPageVisitEvents(
122
+ eventObject.events,
123
+ eventObject.eventName,
124
+ );
125
+ });
126
+ });
127
+ }
128
+ }
129
+
130
+ export { InputMonitor };
@@ -0,0 +1,67 @@
1
+ import { TextInput } from 'react-native';
2
+ import { updatePayload } from '../pageVisit/userStep/userStep.js';
3
+ import { InputMonitor } from './inputMonitor.js';
4
+ import { SOURCE_ATT_NAME, TEXT_ATT_NAME, TAGNAME_ATT_NAME, TYPE_ATT_NAME, KEYBOARD_EVENT_TYPE } from '../constants.js';
5
+
6
+ /** @module KeyboardInputMonitor */
7
+
8
+ /**
9
+ * KeyboardInputMonitor is a listener class that attaches a
10
+ * keyboard input listener of the document object.
11
+ */
12
+ class KeyboardInputMonitor {
13
+ /**
14
+ * Begins the monitoring process
15
+ * we currently only monitor two input locations: textarea and input
16
+ */
17
+ monitor() {
18
+ const handler = this._handle.bind(this);
19
+ // addSafeEventListener(window, 'input', handler);
20
+
21
+ if (!TextInput.originalRender) {
22
+ TextInput.originalRender = TextInput.render;
23
+ TextInput.render = function (props, ...args) {
24
+ const onChange = event => {
25
+ const currentText = event.nativeEvent.text;
26
+ handler(event.target.viewConfig.uiViewClassName, props);
27
+ if (props.onChange) props.onChange(event);
28
+ if (props.onChangeText) props.onChangeText(currentText);
29
+ };
30
+ const newProps = {
31
+ ...props,
32
+ onChange,
33
+ };
34
+ return TextInput.originalRender(newProps, ...args);
35
+ };
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Validates an event
41
+ * @param uiViewClassName
42
+ * @param props
43
+ */
44
+ _handle(uiViewClassName, props) {
45
+ if (!/(text|input)/i.test(uiViewClassName)) {
46
+ return;
47
+ }
48
+
49
+ const name = props.placeholder || props.testID;
50
+
51
+ if (!name) {
52
+ return;
53
+ }
54
+
55
+ InputMonitor.getInstance().addEvent(
56
+ updatePayload({
57
+ [SOURCE_ATT_NAME]: '',
58
+ [TEXT_ATT_NAME]: name,
59
+ [TAGNAME_ATT_NAME]: uiViewClassName.toLowerCase(),
60
+ [TYPE_ATT_NAME]: KEYBOARD_EVENT_TYPE,
61
+ }),
62
+ KEYBOARD_EVENT_TYPE,
63
+ );
64
+ }
65
+ }
66
+
67
+ export { KeyboardInputMonitor };
@@ -0,0 +1,30 @@
1
+ import { getProperGlobalUrl } from '../utils/function.js';
2
+ import { InputMonitor } from './inputMonitor.js';
3
+ import { URL_ATT_NAME, LOCATION_EVENT_TYPE } from '../constants.js';
4
+
5
+ /** @module LocationMonitor */
6
+
7
+ let currentLocation = (window.location && window.location.href) || '';
8
+
9
+ /**
10
+ * will poll the url on a 1 second basis to see if it has changed
11
+ * there is currently no alternative to getting an accurate url
12
+ * change listener
13
+ */
14
+ function monitorLocation() {
15
+ setInterval(() => {
16
+ if (currentLocation !== ((window.location && window.location.href) || '')) {
17
+ // updating the current url to be the new one
18
+ currentLocation = (window.location && window.location.href) || '';
19
+
20
+ const payload = {
21
+ [URL_ATT_NAME]: getProperGlobalUrl(),
22
+ };
23
+
24
+ // storing the location change in the page visit queue
25
+ InputMonitor.getInstance().addEvent(payload, LOCATION_EVENT_TYPE);
26
+ }
27
+ }, 1000);
28
+ }
29
+
30
+ export { monitorLocation };
@@ -0,0 +1,119 @@
1
+ import { PAGE_EVENTS_WINDOW, PAGE_EVENTS_DOCUMENT, PAGE_EVENT_TYPE } from '../constants.js';
2
+ import { InputMonitor } from './inputMonitor.js';
3
+ import { addSafeEventListener } from '../utils/eventlistener.js';
4
+
5
+ /** @module PageMonitor */
6
+
7
+ /** Monitors the page events which we capture and later process */
8
+ class PageMonitor {
9
+ /** gets the singleton instance */
10
+ static getInstance() {
11
+ if (!this.instance) {
12
+ this.instance = new PageMonitor();
13
+ }
14
+
15
+ return this.instance;
16
+ }
17
+
18
+ /** Starts monitoring page events on the document */
19
+ monitor() {
20
+ PAGE_EVENTS_WINDOW.forEach(pageEvent => {
21
+ addSafeEventListener(
22
+ window,
23
+ pageEvent,
24
+ this._onPageEventHandle.bind(this),
25
+ true,
26
+ );
27
+ });
28
+ if (global.document) {
29
+ PAGE_EVENTS_DOCUMENT.forEach(pageEvent => {
30
+ addSafeEventListener(
31
+ document,
32
+ pageEvent,
33
+ this._onPageEventHandle.bind(this),
34
+ true,
35
+ );
36
+ });
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Handles a single page event
42
+ * @param {} event
43
+ */
44
+ _onPageEventHandle(event) {
45
+ if (!event || !event.type) {
46
+ return;
47
+ }
48
+
49
+ const payload = {
50
+ type: event.type,
51
+ };
52
+
53
+ // Add data if applicable for the event type
54
+ switch (event.type) {
55
+ case 'visibilitychange':
56
+ payload.data = `state: ${this.getDocumentState()}`;
57
+ break;
58
+ case 'readystatechange':
59
+ payload.data = `state: ${document.readyState}`;
60
+ break;
61
+ case 'pagehide':
62
+ case 'pageshow':
63
+ case 'load':
64
+ if (event.persisted) {
65
+ payload.data = `persisted: ${event.persisted}`;
66
+ }
67
+ break;
68
+ case 'storage':
69
+ if (event.key) {
70
+ payload.data = `key: ${event.key}`;
71
+ }
72
+ break;
73
+ case 'message':
74
+ case 'messageerror':
75
+ if (event.data && event.origin) {
76
+ payload.data = `origin: ${event.origin} size: ${this.getSizeInBytes(
77
+ event.data,
78
+ )}`;
79
+ }
80
+ break;
81
+ case 'hashchange':
82
+ if (event.newURL) {
83
+ payload.data = `newURL: ${event.newURL}`;
84
+ }
85
+ break;
86
+ // do nothing
87
+ }
88
+
89
+ // storing the page event in the page visit queue
90
+ InputMonitor.getInstance().addEvent(payload, PAGE_EVENT_TYPE);
91
+ }
92
+
93
+ /** Returns document state */
94
+ getDocumentState() {
95
+ if (document.visibilityState === 'hidden') {
96
+ return 'hidden';
97
+ }
98
+ if (document.hasFocus()) {
99
+ return 'active';
100
+ }
101
+ return 'passive';
102
+ }
103
+
104
+ /**
105
+ * Returns object size in bytes
106
+ * @param {} obj
107
+ */
108
+ getSizeInBytes(obj) {
109
+ let str = obj;
110
+ if (typeof obj !== 'string') {
111
+ // Else, make obj into a string
112
+ str = JSON.stringify(obj);
113
+ }
114
+ // 2B per character in the string
115
+ return str.length * 2;
116
+ }
117
+ }
118
+
119
+ export { PageMonitor };