noibu-react-native 0.1.1 → 0.1.3

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 (35) hide show
  1. package/dist/api/clientConfig.d.ts +4 -5
  2. package/dist/api/clientConfig.js +21 -15
  3. package/dist/api/inputManager.js +1 -1
  4. package/dist/api/metroplexSocket.d.ts +155 -0
  5. package/dist/api/metroplexSocket.js +667 -804
  6. package/dist/api/storedMetrics.js +2 -1
  7. package/dist/constants.d.ts +11 -0
  8. package/dist/constants.js +15 -2
  9. package/dist/entry/index.js +2 -0
  10. package/dist/entry/init.d.ts +1 -1
  11. package/dist/entry/init.js +9 -2
  12. package/dist/monitors/appNavigationMonitor.js +3 -2
  13. package/dist/monitors/clickMonitor.js +1 -1
  14. package/dist/monitors/errorMonitor.js +2 -2
  15. package/dist/monitors/httpDataBundler.js +62 -15
  16. package/dist/monitors/inputMonitor.js +5 -0
  17. package/dist/monitors/integrations/react-native-navigation-integration.d.ts +1 -2
  18. package/dist/monitors/keyboardInputMonitor.js +1 -1
  19. package/dist/monitors/requestMonitor.js +47 -310
  20. package/dist/pageVisit/pageVisit.js +5 -0
  21. package/dist/pageVisit/{pageVisitEventError/pageVisitEventError.js → pageVisitEventError.js} +18 -19
  22. package/dist/pageVisit/{pageVisitEventHTTP/pageVisitEventHTTP.js → pageVisitEventHTTP.js} +15 -7
  23. package/dist/pageVisit/{userStep/userStep.js → userStep.js} +2 -2
  24. package/dist/types/NavigationIntegration.d.ts +1 -2
  25. package/dist/types/globals.d.ts +6 -3
  26. package/dist/utils/function.d.ts +2 -3
  27. package/dist/utils/function.js +15 -10
  28. package/dist/utils/log.d.ts +5 -0
  29. package/dist/utils/log.js +17 -0
  30. package/dist/utils/object.d.ts +41 -0
  31. package/dist/utils/object.js +85 -108
  32. package/dist/utils/performance.d.ts +6 -0
  33. package/dist/utils/performance.js +1 -2
  34. package/package.json +5 -4
  35. package/dist/pageVisit/pageVisitEventError/blacklistedDomains.js +0 -9
@@ -7,8 +7,8 @@ import { CustomerConfig, StoredConfig } from '../types/Config';
7
7
  * storing and retrieval.
8
8
  */
9
9
  export default class ClientConfig {
10
- private readonly pageVisitId;
11
- private browserId;
10
+ readonly pageVisitId: string;
11
+ browserId: StoredConfig['BrowserId'];
12
12
  private pageVisitSeq;
13
13
  private lastActiveTime;
14
14
  private readonly noibuErrorURL;
@@ -30,17 +30,16 @@ export default class ClientConfig {
30
30
  static configureInstance({ noibuErrorURL, customerConfig, }: {
31
31
  noibuErrorURL: string;
32
32
  customerConfig: CustomerConfig;
33
- }): void;
33
+ }): Promise<void>;
34
34
  /**
35
35
  * gets the singleton instance
36
- * @returns {ClientConfig}
37
36
  */
38
37
  static getInstance(): ClientConfig;
39
38
  /** lockClient will disable the client script for a single pagevisit for
40
39
  * duration given in minuntes */
41
40
  lockClient(duration: number, msg: string): Promise<void>;
42
41
  /** Locks the client until the next page loads */
43
- lockClientUntilNextPage(msg: string): void;
42
+ lockClientUntilNextPage(msg: string): Promise<void>;
44
43
  /** Updates the config object to store the given last active time */
45
44
  updateLastActiveTime(lastActiveTime: Date): Promise<void>;
46
45
  /** Gets the current page visit sequence number that should be used */
@@ -1,7 +1,9 @@
1
1
  import uuid from 'react-native-uuid';
2
- import { MAX_METROPLEX_SOCKET_INNACTIVE_TIME, SEVERITY, NOIBU_BROWSER_ID_KYWRD, PV_SEQ_NUM_RESET_TIME_MINUTES, JS_ENV, MAX_PAGEVISIT_VISITED, CLIENT_LOCK_TIME_MINUTES, GET_SCRIPT_ID, MAX_COLLECT_ERROR_LOG } from '../constants.js';
2
+ import { MAX_METROPLEX_SOCKET_INNACTIVE_TIME, SEVERITY, NOIBU_BROWSER_ID_KYWRD, PV_SEQ_NUM_RESET_TIME_MINUTES, JS_ENV, MAX_PAGEVISIT_VISITED, CLIENT_LOCK_TIME_MINUTES, GET_SCRIPT_ID, GET_DEVICE_ENV, MAX_COLLECT_ERROR_LOG } from '../constants.js';
3
3
  import { stringifyJSON, getMaxSubstringAllowed, getUserAgent, makeRequest } from '../utils/function.js';
4
4
  import Storage from '../storage/storage.js';
5
+ import { noibuLog } from '../utils/log.js';
6
+ import { unwrapNoibuWrapped } from '../utils/object.js';
5
7
 
6
8
  /** @module ClientConfig */
7
9
  /**
@@ -42,8 +44,6 @@ class ClientConfig {
42
44
  this.lastActiveTime = new Date();
43
45
  // error URL to send Noibu errors to
44
46
  this.noibuErrorURL = noibuErrorURL;
45
- // sets up this.browserId, this.isClientDisabled, this.pageVisitSeq
46
- this._setupStorageVars();
47
47
  // error sent to backend counter
48
48
  this.cltErrorPostCounter = 0;
49
49
  // variables for checking if the socket is inactive
@@ -56,18 +56,16 @@ class ClientConfig {
56
56
  this.blockedElements = customerConfig.blockedElements;
57
57
  }
58
58
  /** Configures the singleton instance */
59
- static configureInstance({ noibuErrorURL, customerConfig, }) {
59
+ static async configureInstance({ noibuErrorURL, customerConfig, }) {
60
60
  if (!this.instance) {
61
- // Set this.noibuErrorURL preemptively in case ClientConfig isn't able to be
62
- // configured properly and throws an error.
63
- // This will ensure we get the expected error POST request at the correct URL.
64
61
  ClientConfig.noibuErrorURL = noibuErrorURL;
65
62
  this.instance = new ClientConfig(noibuErrorURL, customerConfig);
63
+ // sets up this.browserId, this.isClientDisabled, this.pageVisitSeq
64
+ await this.instance._setupStorageVars();
66
65
  }
67
66
  }
68
67
  /**
69
68
  * gets the singleton instance
70
- * @returns {ClientConfig}
71
69
  */
72
70
  static getInstance() {
73
71
  if (!this.instance) {
@@ -84,11 +82,11 @@ class ClientConfig {
84
82
  noibuLSObject.DisabledStatus = true;
85
83
  noibuLSObject.ClientUnlockTime = expiryTime;
86
84
  await this._storeBrowserData(noibuLSObject);
87
- this.postNoibuErrorAndOptionallyDisableClient(msg, true, SEVERITY.warn);
85
+ await this.postNoibuErrorAndOptionallyDisableClient(msg, true, SEVERITY.warn);
88
86
  }
89
87
  /** Locks the client until the next page loads */
90
88
  lockClientUntilNextPage(msg) {
91
- this.postNoibuErrorAndOptionallyDisableClient(msg, true, SEVERITY.warn);
89
+ return this.postNoibuErrorAndOptionallyDisableClient(msg, true, SEVERITY.warn);
92
90
  }
93
91
  /** Updates the config object to store the given last active time */
94
92
  async updateLastActiveTime(lastActiveTime) {
@@ -165,7 +163,7 @@ class ClientConfig {
165
163
  async _setupStorageVars() {
166
164
  const storage = Storage.getInstance();
167
165
  if (!(await storage.isAvailable())) {
168
- this.postNoibuErrorAndOptionallyDisableClient(`Storage is unavailable, disabling client. ${await storage.getDiagnoseInfo()}`, true, SEVERITY.error);
166
+ void this.postNoibuErrorAndOptionallyDisableClient(`Storage is unavailable, disabling client. ${await storage.getDiagnoseInfo()}`, true, SEVERITY.error);
169
167
  return;
170
168
  }
171
169
  // getting the current content of the storage
@@ -175,6 +173,7 @@ class ClientConfig {
175
173
  noibuLSObject.CurrentPageVisitCount = 0;
176
174
  }
177
175
  this.browserId = noibuLSObject.BrowserId;
176
+ noibuLog('ClientConfig - _setupStorageVars', { noibuLSObject });
178
177
  this.pageVisitSeq = noibuLSObject.CurrentPageVisitCount;
179
178
  this.isClientDisabled = noibuLSObject.DisabledStatus;
180
179
  // If the client has been disabled just return.
@@ -199,7 +198,7 @@ class ClientConfig {
199
198
  // setting the lock time
200
199
  noibuLSObject.ClientUnlockTime = expiryTime;
201
200
  noibuLSObject.DisabledStatus = true;
202
- this.postNoibuErrorAndOptionallyDisableClient(`Hit max page visits, disabling client for ${CLIENT_LOCK_TIME_MINUTES}mins`, true, SEVERITY.error);
201
+ await this.postNoibuErrorAndOptionallyDisableClient(`Hit max page visits, disabling client for ${CLIENT_LOCK_TIME_MINUTES}mins`, true, SEVERITY.error);
203
202
  }
204
203
  // we now check if we successfully saved the data
205
204
  const savedData = await this._storeBrowserData(noibuLSObject);
@@ -207,7 +206,7 @@ class ClientConfig {
207
206
  // error happened, thus we disable collect.
208
207
  if (!savedData.BrowserId) {
209
208
  // we do not set a lock expiry date here since we cannot store to storage
210
- this.postNoibuErrorAndOptionallyDisableClient(`Null browser in storage, disabling client`, true, SEVERITY.error);
209
+ void this.postNoibuErrorAndOptionallyDisableClient(`Null browser in storage, disabling client`, true, SEVERITY.error);
211
210
  this.browserId = '';
212
211
  }
213
212
  }
@@ -265,7 +264,7 @@ class ClientConfig {
265
264
  return data;
266
265
  }
267
266
  catch (e) {
268
- this.postNoibuErrorAndOptionallyDisableClient(`Error writing browser data to storage, disabling client: ${e.message}, ${await storage.getDiagnoseInfo()}`, true, SEVERITY.error);
267
+ await this.postNoibuErrorAndOptionallyDisableClient(`Error writing browser data to storage, disabling client: ${e.message}, ${await storage.getDiagnoseInfo()}`, true, SEVERITY.error);
269
268
  // sending empty fields if we encountered errors while storing in the LS
270
269
  return this._generateNewBrowserData();
271
270
  }
@@ -292,6 +291,12 @@ class ClientConfig {
292
291
  * severity expects one of the SEVERITY_x level constants, or else error will be used
293
292
  */
294
293
  async postNoibuErrorAndOptionallyDisableClient(errorMsg, disableClient, severity, keepAlive = false) {
294
+ noibuLog('postNoibuErrorAndOptionallyDisableClient', {
295
+ errorMsg,
296
+ disableClient,
297
+ severity,
298
+ keepAlive,
299
+ });
295
300
  if (this.isClientDisabled) {
296
301
  return;
297
302
  }
@@ -307,6 +312,7 @@ class ClientConfig {
307
312
  pageVisitId: this.pageVisitId,
308
313
  scriptId: GET_SCRIPT_ID(),
309
314
  ua: await getUserAgent(),
315
+ deviceEnv: GET_DEVICE_ENV(),
310
316
  error: errorMsg,
311
317
  };
312
318
  // if the page visits sends more errors than the
@@ -339,7 +345,7 @@ class ClientConfig {
339
345
  });
340
346
  }
341
347
  else {
342
- fetch(this.noibuErrorURL, {
348
+ void unwrapNoibuWrapped(fetch)(this.noibuErrorURL, {
343
349
  method: 'POST',
344
350
  headers,
345
351
  body: stringifyJSON(errorContent),
@@ -1,6 +1,6 @@
1
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
2
  import MetroplexSocket from './metroplexSocket.js';
3
- import { saveErrorToPagevisit } from '../pageVisit/pageVisitEventError/pageVisitEventError.js';
3
+ import { saveErrorToPagevisit } from '../pageVisit/pageVisitEventError.js';
4
4
  import HelpCode from './helpCode.js';
5
5
 
6
6
  /** @module InputManager */
@@ -0,0 +1,155 @@
1
+ /// <reference types="react-native" />
2
+ /** Manages the socket to Metroplex */
3
+ export default class MetroplexSocket {
4
+ _initialURL: string;
5
+ ackedOnce: boolean;
6
+ connectionCount: number;
7
+ connectionPromise: Promise<any> | null;
8
+ connectionURL: string;
9
+ currentConnectionAttempts: number;
10
+ forceClosed: boolean;
11
+ helpCodeCb: null | ((...args: any[]) => any);
12
+ initialReferingURL: string;
13
+ static instance: MetroplexSocket;
14
+ instanceId: string | number[];
15
+ isRetryLoopDisabled: boolean;
16
+ latestReceivedSeqNumStoredTime: Date;
17
+ latestReceivedSeqNumber: number;
18
+ messageSequenceNum: number;
19
+ metroRetryFrequencyMS: 30000;
20
+ metroplexTypeLock: Record<any, any>;
21
+ pageVisitInfoSent: boolean;
22
+ postURL: string;
23
+ previousMessageType: string;
24
+ retryMessageQueue: any[];
25
+ retryMetroplexInterval: null | number;
26
+ scriptInstanceId: string | number[] | undefined;
27
+ sessionLength: number;
28
+ sessionStartTime: any;
29
+ sessionTimestamp: Date;
30
+ socket: WebSocket | null;
31
+ socketInstanceId: string | number[] | null;
32
+ socketCloseCodes: string[];
33
+ socketOpens: string[];
34
+ /**
35
+ * Creates an instance of metroplex
36
+ * id of script, to make sure only a single socket is open
37
+ */
38
+ constructor(scriptInstanceId?: string | number[]);
39
+ /**
40
+ * gets the singleton instance
41
+ * @returns {MetroplexSocket}
42
+ */
43
+ static getInstance(scriptInstanceId?: string | number[]): MetroplexSocket;
44
+ /** Starts off the socket connection */
45
+ start(): void;
46
+ /**
47
+ * Adds the seq num field to the given payload depending on whether its
48
+ * a page visit part or video frag
49
+ */
50
+ _addSeqNumToPayload(type: string, payload: any): void;
51
+ /**
52
+ * sets the seq num in the payload for the given key and increments the
53
+ * global seq number
54
+ */
55
+ _setSeqNumInPayloadAndIncrementSeqNum(payloadKey: string, payload: any): void;
56
+ /** requests help code and saves a callback to be called on response */
57
+ requestHelpCode(cb: (typeof this)['helpCodeCb']): Promise<boolean>;
58
+ /**
59
+ * Immediately sends a message to Metroplex over the web socket
60
+ * Queues the message if the connection isn't open yet.
61
+ * returns true if message was sent succefully, false otherwise
62
+ */
63
+ sendMessage(type: string, payload: any): Promise<boolean>;
64
+ /** Updates the latest pv message sent timestamp if events contain any user steps
65
+ */
66
+ _updateLatestPvTimestamp(events: any[]): Promise<void>;
67
+ /** returns true if the socket is either connecting or connected to metroplex */
68
+ isConnected(): boolean;
69
+ /** returns true if we are connecting to the socket */
70
+ isConnecting(): boolean;
71
+ /** close will close the socket opened for video frag transmission */
72
+ close(): void;
73
+ /** Connects the web socket to metroplex and calls callback upon successfully connecting
74
+ */
75
+ handleConnect(forceOpen: boolean): Promise<void>;
76
+ /**
77
+ * connectSocket will establish a websocket connection to the metroplex
78
+ * service
79
+ */
80
+ connectSocket(): Promise<any> | null;
81
+ /** Calculates and sets the end_at field of the payload
82
+ * @param {} payload
83
+ * @param {} isPageVisit
84
+ */
85
+ addEndTimeToPayload(payload: any, isPageVisit: boolean): void;
86
+ /** open handler for socket */
87
+ _onSocketOpen(): Promise<void>;
88
+ /** message handler for socket
89
+ * @param {} event
90
+ */
91
+ _onSocketMessage(event: any): Promise<void>;
92
+ /**
93
+ * Returns true if the message's payload has the payload type given and has a sequence
94
+ * number higher than seqNum
95
+ */
96
+ _messagePayloadHasLargerSeqNum(message: any, payloadType: string, seqNum: number): any;
97
+ /**
98
+ * removes messages from the retry queue that are smaller than the
99
+ * latest stored message in metroplex
100
+ */
101
+ _clearRetryQueue(seqNum: number): void;
102
+ /** will resend everything that is in the retry queue */
103
+ _sendUnconfirmedMessages(socketWasAlreadyOpen: boolean): Promise<void>;
104
+ /** sets up the interval to empty the queue as we receive confirmation messages from metroplex */
105
+ setupRetryMechanism(): void;
106
+ /** sets up events that will trigger the event queue to be emptied */
107
+ _setupOffloadEvents(): void;
108
+ /**
109
+ * will handle the final moments of a page being active. It
110
+ * will try to empty both the queues with beacons.
111
+ */
112
+ _handleUnload(): Promise<void>;
113
+ /**
114
+ * will post full page visit to metroplex. It
115
+ * will try to empty both the queues with beacons.
116
+ */
117
+ postFullPageVisit(maxMessageSize: number): Promise<void>;
118
+ /**
119
+ * will send a message to metroplex via a post request that will outlive the current page
120
+ */
121
+ postMessage(msg: any): Promise<void>;
122
+ /**
123
+ * Stringifies the payload into JSON, sends it to the back end if the session
124
+ * is active and returns true. If inactive the session and socket are closed
125
+ * and this method returns false.
126
+ */
127
+ _sendSocketMessage(payload: any): Promise<void>;
128
+ /**
129
+ * Closes the socket connection if the session is inactive. Returns true if the
130
+ * session is inactive
131
+ */
132
+ closeIfInactive(): Promise<boolean>;
133
+ /** will get page information, calling this will increase the connection count */
134
+ getPageInformation(): Promise<{
135
+ br_id: string;
136
+ pv_id: string;
137
+ v: 5;
138
+ seq: number | null;
139
+ on_url: string;
140
+ ref_url: string;
141
+ start_at: string;
142
+ conc: number;
143
+ cv: 2;
144
+ last: boolean;
145
+ script_id: string;
146
+ script_inst_id: string | number[] | undefined;
147
+ mp_sock_inst_id: string | number[];
148
+ sock_inst_id: string | number[] | null;
149
+ }>;
150
+ /**
151
+ * Try to parse help code response and fire custom event
152
+ * @param {String} response
153
+ */
154
+ _tryProcessHelpCodeResponse(response: any): boolean;
155
+ }