noibu-react-native 0.0.2 → 0.0.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.
package/README.md CHANGED
@@ -97,19 +97,19 @@ const AlertHelpCode = () => {
97
97
  };
98
98
  ```
99
99
 
100
- #### `addCustomAttribute(name: string, value: string) => string`
100
+ #### `addCustomAttribute(name: string, value: string) => Promise<string>`
101
101
 
102
102
  Adds a custom attribute to the session.
103
103
 
104
104
  - `@param {string} name` - Name of a custom attribute.
105
105
  - `@param {any} value` - It's value, should be a JSON.stringify-able type.
106
- - `@returns {string}` - A success message, or validation failure cause.
106
+ - `@returns {Promise<string>}` - A success message, or validation failure cause.
107
107
 
108
108
  ```js
109
109
  import { NoibuJS } from 'noibu-react-native';
110
110
 
111
- NoibuJS.addCustomAttribute('myNameIs', 'Jeff'); // SUCCESS
112
- NoibuJS.addCustomAttribute('veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong', 'Jeff'); // NAME_TOO_LONG
111
+ NoibuJS.addCustomAttribute('myNameIs', 'Jeff'); // Promise<SUCCESS>
112
+ NoibuJS.addCustomAttribute('veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong', 'Jeff'); // Promise<NAME_TOO_LONG>
113
113
  ```
114
114
 
115
115
  #### `addError(customError: Error) => string`
@@ -67,14 +67,14 @@ class ClientConfig {
67
67
 
68
68
  /** lockClient will disable the client script for a single pagevisit for
69
69
  * duration given in minuntes */
70
- lockClient(duration, msg) {
70
+ async lockClient(duration, msg) {
71
71
  const expiryTime = new Date();
72
72
  expiryTime.setMinutes(expiryTime.getMinutes() + duration);
73
73
 
74
- const noibuLSObject = this._getClientState();
74
+ const noibuLSObject = await this._getClientState();
75
75
  noibuLSObject[DISABLED_STATUS_KEY] = true;
76
76
  noibuLSObject[CLIENT_UNLOCK_TIME_KEY] = expiryTime;
77
- this._storeBrowserData(noibuLSObject);
77
+ await this._storeBrowserData(noibuLSObject);
78
78
  this.postNoibuErrorAndOptionallyDisableClient(msg, true, SEVERITY_WARN);
79
79
  }
80
80
 
@@ -84,23 +84,23 @@ class ClientConfig {
84
84
  }
85
85
 
86
86
  /** Updates the config object to store the given last active time */
87
- updateLastActiveTime(lastActiveTime) {
87
+ async updateLastActiveTime(lastActiveTime) {
88
88
  this.lastActiveTime = lastActiveTime;
89
- const newConfigData = this._getLsObject();
89
+ const newConfigData = await this._getLsObject();
90
90
  newConfigData[LAST_ACTIVE_TIME_KEY] = lastActiveTime;
91
- this._storeBrowserData(newConfigData);
91
+ await this._storeBrowserData(newConfigData);
92
92
  }
93
93
 
94
94
  /** Gets the current page visit sequence number that should be used */
95
- getPageVisitSeq() {
96
- if (this._pageVisitSeqNeedsReset()) {
95
+ async getPageVisitSeq() {
96
+ if (await this._pageVisitSeqNeedsReset()) {
97
97
  // Reset the page visit sequence number to zero and store the next seq number in storage
98
98
  this.pageVisitSeq = 0;
99
- const newConfigData = this._getLsObject();
99
+ const newConfigData = await this._getLsObject();
100
100
  newConfigData[CURRENT_PAGE_VISIT_COUNT_KEY] = this.pageVisitSeq + 1;
101
101
  // Update the last active time since we are actively requesting the seq
102
102
  newConfigData[LAST_ACTIVE_TIME_KEY] = new Date();
103
- this._storeBrowserData(newConfigData);
103
+ await this._storeBrowserData(newConfigData);
104
104
  }
105
105
 
106
106
  return this.pageVisitSeq;
@@ -118,9 +118,9 @@ class ClientConfig {
118
118
  * LastActiveTime: DATE OBJ
119
119
  * }
120
120
  */
121
- _getLsObject() {
121
+ async _getLsObject() {
122
122
  const storage = Storage.getInstance();
123
- const storedConfig = storage.load(NOIBU_BROWSER_ID_KYWRD);
123
+ const storedConfig = await storage.load(NOIBU_BROWSER_ID_KYWRD);
124
124
 
125
125
  // first time browsing since noibu was installed
126
126
  if (!storedConfig) {
@@ -151,8 +151,8 @@ class ClientConfig {
151
151
  /**
152
152
  * Check if we have surpased the last active time and the page visit seq number needs resetting
153
153
  */
154
- _pageVisitSeqNeedsReset() {
155
- const noibuLSObject = this._getClientState();
154
+ async _pageVisitSeqNeedsReset() {
155
+ const noibuLSObject = await this._getClientState();
156
156
  const someTimeAgo = new Date();
157
157
  someTimeAgo.setMinutes(
158
158
  someTimeAgo.getMinutes() - PV_SEQ_NUM_RESET_TIME_MINUTES,
@@ -164,11 +164,11 @@ class ClientConfig {
164
164
  * _setupStorageVars will set all class variables that depend
165
165
  * on the storage's value.
166
166
  */
167
- _setupStorageVars() {
167
+ async _setupStorageVars() {
168
168
  const storage = Storage.getInstance();
169
- if (!storage.isAvailable()) {
169
+ if (!(await storage.isAvailable())) {
170
170
  this.postNoibuErrorAndOptionallyDisableClient(
171
- `Storage is unavailable, disabling client. ${storage.getDiagnoseInfo()}`,
171
+ `Storage is unavailable, disabling client. ${await storage.getDiagnoseInfo()}`,
172
172
  true,
173
173
  SEVERITY_ERROR,
174
174
  );
@@ -176,10 +176,10 @@ class ClientConfig {
176
176
  }
177
177
 
178
178
  // getting the current content of the storage
179
- const noibuLSObject = this._getClientState();
179
+ const noibuLSObject = await this._getClientState();
180
180
 
181
181
  // Check if we have surpased the last active time and reset the sequence number if so
182
- if (this._pageVisitSeqNeedsReset()) {
182
+ if (await this._pageVisitSeqNeedsReset()) {
183
183
  noibuLSObject[CURRENT_PAGE_VISIT_COUNT_KEY] = 0;
184
184
  }
185
185
 
@@ -219,7 +219,7 @@ class ClientConfig {
219
219
  }
220
220
 
221
221
  // we now check if we successfully saved the data
222
- const savedData = this._storeBrowserData(noibuLSObject);
222
+ const savedData = await this._storeBrowserData(noibuLSObject);
223
223
 
224
224
  // if the browser is null, we cannot access the storage or an
225
225
  // error happened, thus we disable collect.
@@ -240,8 +240,8 @@ class ClientConfig {
240
240
  * Get it from storage if the expiry date is not in the past
241
241
  * Generate a brand new one if the expiry date is in the past
242
242
  */
243
- _getClientState() {
244
- const newConfigData = this._getLsObject();
243
+ async _getClientState() {
244
+ const newConfigData = await this._getLsObject();
245
245
 
246
246
  // if the lock expired, we remove the lock period and enable the client
247
247
  if (
@@ -250,7 +250,7 @@ class ClientConfig {
250
250
  ) {
251
251
  newConfigData[CLIENT_UNLOCK_TIME_KEY] = null;
252
252
  newConfigData[DISABLED_STATUS_KEY] = false;
253
- this._storeBrowserData(newConfigData);
253
+ await this._storeBrowserData(newConfigData);
254
254
  }
255
255
  // return the stored browserId
256
256
  return newConfigData;
@@ -260,9 +260,8 @@ class ClientConfig {
260
260
  * _generateAndStoreData generates brand new data and then proceeds to store
261
261
  * it.
262
262
  */
263
- _generateAndStoreData() {
264
- const data = this._storeBrowserData(this._generateNewBrowserData());
265
- return data;
263
+ async _generateAndStoreData() {
264
+ return this._storeBrowserData(this._generateNewBrowserData());
266
265
  }
267
266
 
268
267
  /**
@@ -291,25 +290,24 @@ class ClientConfig {
291
290
  * _storeBrowserData will store the passed object in storage.
292
291
  * @param {} data the data to be stored
293
292
  */
294
- _storeBrowserData(data) {
293
+ async _storeBrowserData(data) {
295
294
  const storage = Storage.getInstance();
296
295
  try {
297
- storage.save(NOIBU_BROWSER_ID_KYWRD, stringifyJSON(data));
296
+ await storage.save(NOIBU_BROWSER_ID_KYWRD, stringifyJSON(data));
298
297
  return data;
299
298
  } catch (e) {
300
299
  this.postNoibuErrorAndOptionallyDisableClient(
301
300
  `Error writing browser data to storage, disabling client: ${e.message}, ` +
302
- `${storage.getDiagnoseInfo()}`,
301
+ `${await storage.getDiagnoseInfo()}`,
303
302
  true,
304
303
  SEVERITY_ERROR,
305
304
  );
306
305
  // sending empty fields if we encountered errors while storing in the LS
307
- const invalidData = {
306
+ return {
308
307
  [DISABLED_STATUS_KEY]: true,
309
308
  [BROWSER_ID_KEY]: null,
310
309
  [CURRENT_PAGE_VISIT_COUNT_KEY]: 0,
311
310
  };
312
- return invalidData;
313
311
  }
314
312
  }
315
313
 
@@ -355,10 +353,10 @@ class ClientConfig {
355
353
  const expiryTime = new Date();
356
354
  expiryTime.setMinutes(expiryTime.getMinutes() + 10); // 10 minutes lock
357
355
 
358
- const noibuLSObject = this._getClientState();
356
+ const noibuLSObject = await this._getClientState();
359
357
  noibuLSObject[DISABLED_STATUS_KEY] = true;
360
358
  noibuLSObject[CLIENT_UNLOCK_TIME_KEY] = expiryTime;
361
- this._storeBrowserData(noibuLSObject);
359
+ await this._storeBrowserData(noibuLSObject);
362
360
  this.isClientDisabled = true;
363
361
  // end of lock
364
362
  // overriding the message to be an alert that we are shutting collect off.
@@ -32,8 +32,8 @@ class HelpCode {
32
32
  * @returns {Promise<string>} Promise object representing the help code request.
33
33
  * @throws {string} Throws an error if the noibu connection is unavailable.
34
34
  */
35
- requestHelpCode() {
36
- if (this.requestContext != null) {
35
+ async requestHelpCode() {
36
+ if (this.requestContext !== null) {
37
37
  return this.requestContext.promise;
38
38
  }
39
39
 
@@ -50,7 +50,7 @@ class HelpCode {
50
50
 
51
51
  this.requestContext = context;
52
52
 
53
- const result = this._sendRequest();
53
+ const result = await this._sendRequest();
54
54
 
55
55
  if (result === false) {
56
56
  this.requestContext = null;
@@ -54,7 +54,7 @@ class InputManager {
54
54
  * gets the sdk object that will be assigned to a window variable
55
55
  * @returns {{
56
56
  * requestHelpCode: (alert?: boolean) => Promise<string>,
57
- * addCustomAttribute: (name: string, value: string) => string,
57
+ * addCustomAttribute: (name: string, value: string) => Promise<string>,
58
58
  * addError: (customError: Error) => string,
59
59
  * addJsSdkError: (customError: string, errorSource: string) => string
60
60
  * }}
@@ -157,7 +157,7 @@ class InputManager {
157
157
  * @param {} name
158
158
  * @param {} value
159
159
  */
160
- _addCustomAttribute(name, value) {
160
+ async _addCustomAttribute(name, value) {
161
161
  // we return if we are over the limit of ids
162
162
  if (Object.keys(this.customIDs).length >= MAX_CUSTOM_IDS_PER_PAGEVISIT) {
163
163
  return this.TOO_MANY_IDS_ADDED_MSG;
@@ -176,7 +176,7 @@ class InputManager {
176
176
  }
177
177
 
178
178
  this.customIDs[name] = value;
179
- MetroplexSocket.getInstance().sendMessage(META_DATA_METROPLEX_TYPE, {
179
+ await MetroplexSocket.getInstance().sendMessage(META_DATA_METROPLEX_TYPE, {
180
180
  [PAGE_VISIT_META_DATA_ATT_NAME]: {
181
181
  [CUSTOM_ID_NAME_TYPE]: name,
182
182
  [CUSTOM_ID_VALUE_TYPE]: value,
@@ -225,8 +225,8 @@ class InputManager {
225
225
  * @param {boolean} [alertUser=true] - Whether to alert the user about the help code request.
226
226
  * @returns {Promise<string>} A promise that resolves with the requested help code.
227
227
  */
228
- _requestHelpCode(alertUser = true) {
229
- return HelpCode.getInstance().requestHelpCode(alertUser);
228
+ _requestHelpCode() {
229
+ return HelpCode.getInstance().requestHelpCode();
230
230
  }
231
231
  }
232
232
 
@@ -161,9 +161,9 @@ class MetroplexSocket {
161
161
  * Queues the message if the connection isn't open yet.
162
162
  * @param {} type
163
163
  * @param {} payload
164
- * @returns {boolean} true if message was sent succefully, false otherwise
164
+ * @returns {Promise<boolean>} true if message was sent succefully, false otherwise
165
165
  */
166
- sendMessage(type, payload) {
166
+ async sendMessage(type, payload) {
167
167
  // if we have a lock on this specific type, we dont send it
168
168
  if (
169
169
  type in this.metroplexTypeLock ||
@@ -183,7 +183,7 @@ class MetroplexSocket {
183
183
  this.retryMessageQueue.push({ payload: payloadData, type });
184
184
  StoredPageVisit.getInstance().checkAndStoreRetryQueue(
185
185
  this.retryMessageQueue,
186
- this.getPageInformation(),
186
+ await this.getPageInformation(),
187
187
  );
188
188
  }
189
189
 
@@ -261,7 +261,7 @@ class MetroplexSocket {
261
261
  });
262
262
  this.socketInstanceId = uuid.v4();
263
263
 
264
- this.socket.onerror = () => {
264
+ this.socket.onerror = e => {
265
265
  // use for metrics
266
266
  // there is no useful error message/description from this event
267
267
  };
@@ -392,23 +392,21 @@ class MetroplexSocket {
392
392
  this.sessionLength = delta;
393
393
  }
394
394
 
395
- const endTime = new Date(
396
- this.sessionTimestamp.getTime() + delta,
397
- ).toISOString();
398
-
399
395
  // Assigning this value here is much better than copying the whole object.
400
396
  // eslint-disable-next-line no-param-reassign
401
- payload[END_AT_ATT_NAME] = endTime;
397
+ payload[END_AT_ATT_NAME] = new Date(
398
+ this.sessionTimestamp.getTime() + delta,
399
+ ).toISOString();
402
400
  }
403
401
 
404
402
  /** open handler for socket */
405
- _onSocketOpen() {
403
+ async _onSocketOpen() {
406
404
  // if we are not connected, we do not send any messages
407
405
  if (!this.isConnected() || ClientConfig.getInstance().isClientDisabled) {
408
406
  return;
409
407
  }
410
408
 
411
- this._sendSocketMessage(this.getPageInformation());
409
+ this._sendSocketMessage(await this.getPageInformation());
412
410
  // Set this to allow normal page visit and video frag messages to be sent
413
411
  this.pageVisitInfoSent = true;
414
412
  this.currentConnectionAttempts = 0;
@@ -628,7 +626,7 @@ class MetroplexSocket {
628
626
  * will try to empty both the queues with beacons.
629
627
  * @param {} maxMessageSize
630
628
  */
631
- postFullPageVisit(maxMessageSize) {
629
+ async postFullPageVisit(maxMessageSize) {
632
630
  if (this.retryMessageQueue.length === 0) {
633
631
  return;
634
632
  }
@@ -642,14 +640,14 @@ class MetroplexSocket {
642
640
 
643
641
  let currentMsgPayloadSize = 0;
644
642
  let currentCompletePv = {
645
- [PAGE_VISIT_INFORMATION_ATT_NAME]: this.getPageInformation(),
643
+ [PAGE_VISIT_INFORMATION_ATT_NAME]: await this.getPageInformation(),
646
644
  [PAGE_VISIT_PART_ATT_NAME]: [],
647
645
  [PAGE_VISIT_VID_FRAG_ATT_NAME]: [],
648
646
  [PAGE_VISIT_HTTP_DATA_ATT_NAME]: [],
649
647
  [VIDEO_PART_COUNT_ATT_NAME]: this.connectionCount,
650
648
  };
651
649
  currentCompletePv[PAGE_VISIT_INFORMATION_ATT_NAME][IS_LAST_ATT_NAME] = true;
652
-
650
+ const pageInfo = await this.getPageInformation();
653
651
  this.retryMessageQueue.forEach(msg => {
654
652
  // can't use two variables types in obj deconstruction
655
653
  // eslint-disable-next-line prefer-const
@@ -674,9 +672,9 @@ class MetroplexSocket {
674
672
 
675
673
  // resetting currentCompletePv, since we need to keep adding
676
674
  // events to a blank object to send to metroplex.
677
- // retain the video part count so we don't overwrite anything
675
+ // retain the video part count, so we don't overwrite anything
678
676
  currentCompletePv = {
679
- [PAGE_VISIT_INFORMATION_ATT_NAME]: this.getPageInformation(),
677
+ [PAGE_VISIT_INFORMATION_ATT_NAME]: pageInfo,
680
678
  [PAGE_VISIT_PART_ATT_NAME]: [],
681
679
  [PAGE_VISIT_VID_FRAG_ATT_NAME]: [],
682
680
  [PAGE_VISIT_HTTP_DATA_ATT_NAME]: [],
@@ -822,12 +820,12 @@ class MetroplexSocket {
822
820
  }
823
821
 
824
822
  /** will get page information, calling this will increase the connection count */
825
- getPageInformation() {
823
+ async getPageInformation() {
826
824
  const pvi = {
827
825
  [BROWSER_ID_ATT_NAME]: ClientConfig.getInstance().browserId,
828
826
  [PV_ID_ATT_NAME]: ClientConfig.getInstance().pageVisitId,
829
827
  [VER_ATT_NAME]: CURRENT_PV_VERSION,
830
- [PV_SEQ_ATT_NAME]: ClientConfig.getInstance().getPageVisitSeq(),
828
+ [PV_SEQ_ATT_NAME]: await ClientConfig.getInstance().getPageVisitSeq(),
831
829
  [ON_URL_ATT_NAME]: this.initialURL,
832
830
  [REF_URL_ATT_NAME]: this.initialReferingURL,
833
831
  [STARTED_AT_ATT_NAME]: this.sessionTimestamp.toISOString(),
@@ -19,9 +19,9 @@ class StoredPageVisit {
19
19
  this.flushedStorage = false;
20
20
 
21
21
  const storage = Storage.getInstance();
22
- if (storage.isAvailable()) {
23
- this._postPreviousPageVisit();
24
- }
22
+ storage.isAvailable().then(isAvailable => {
23
+ if (isAvailable) this._postPreviousPageVisit();
24
+ });
25
25
  }
26
26
 
27
27
  /** gets the singleton instance */
@@ -88,8 +88,8 @@ class StoredPageVisit {
88
88
  * @param {} pageVisitFrags
89
89
  * @param {} pvInfo
90
90
  */
91
- _writePageVisitFrags(pageVisitFrags, pvInfo) {
92
- // Create a new object to write to storage that doesnt have the timeout and flush members
91
+ async _writePageVisitFrags(pageVisitFrags, pvInfo) {
92
+ // Create a new object to write to storage that doesn't have the timeout and flush members
93
93
  const lsPageVisit = {
94
94
  pageVisitFrags,
95
95
  pageVisitInfo: pvInfo,
@@ -101,17 +101,17 @@ class StoredPageVisit {
101
101
  const json = stringifyJSON(lsPageVisit);
102
102
 
103
103
  try {
104
- storage.save(NOIBU_STORED_PAGE_VISIT, json);
104
+ await storage.save(NOIBU_STORED_PAGE_VISIT, json);
105
105
  } catch (err) {
106
- storage.remove(NOIBU_STORED_PAGE_VISIT);
106
+ await storage.remove(NOIBU_STORED_PAGE_VISIT);
107
107
 
108
108
  // Calculate current storage size
109
- const size = storage.calculateUsedSize();
109
+ const size = await storage.calculateUsedSize();
110
110
 
111
111
  ClientConfig.getInstance().postNoibuErrorAndOptionallyDisableClient(
112
112
  `Error writing pv to storage: ${err}, ` +
113
113
  `json size: ${json.length}, storage size: ${size}, ` +
114
- `${storage.getDiagnoseInfo()}`,
114
+ `${await storage.getDiagnoseInfo()}`,
115
115
  false,
116
116
  SEVERITY_ERROR,
117
117
  );
@@ -122,11 +122,11 @@ class StoredPageVisit {
122
122
  * Read the stored page visit from storage, create a complete page visit object
123
123
  * and then post that to Metroplex
124
124
  */
125
- _getPostData() {
125
+ async _getPostData() {
126
126
  const storage = Storage.getInstance();
127
127
 
128
128
  // Read the storedPageVisit from storage
129
- const data = storage.load(NOIBU_STORED_PAGE_VISIT);
129
+ const data = await storage.load(NOIBU_STORED_PAGE_VISIT);
130
130
  if (!data) {
131
131
  return null;
132
132
  }
@@ -136,7 +136,7 @@ class StoredPageVisit {
136
136
  storedPageVisit = JSON.parse(data);
137
137
  } catch (e) {
138
138
  // Remove the item since there is something corrupted
139
- storage.remove(NOIBU_STORED_PAGE_VISIT);
139
+ await storage.remove(NOIBU_STORED_PAGE_VISIT);
140
140
  ClientConfig.getInstance().postNoibuErrorAndOptionallyDisableClient(
141
141
  `Error parsing page visit string '${data}': ${e}`,
142
142
  false,
@@ -210,24 +210,22 @@ class StoredPageVisit {
210
210
  /** Returns a promise that resolves to post the page visit in storage to Metroplex */
211
211
  _getPostPageVisitPromise() {
212
212
  return new Promise((resolve, reject) => {
213
- const data = this._getPostData();
214
-
215
- if (!data) {
216
- resolve();
217
- return;
218
- }
219
-
220
- const headers = {
221
- 'content-type': 'application/json',
222
- };
223
-
224
- makeRequest('POST', GET_METROPLEX_POST_URL(), data, headers, 2000, true)
225
- .then(() => {
213
+ this._getPostData().then(data => {
214
+ if (!data) {
226
215
  resolve();
227
- })
228
- .catch(e => {
229
- reject(new Error('Page visit post request rejected due to: ', e));
230
- });
216
+ return;
217
+ }
218
+
219
+ const headers = {
220
+ 'content-type': 'application/json',
221
+ };
222
+
223
+ makeRequest('POST', GET_METROPLEX_POST_URL(), data, headers, 2000, true)
224
+ .then(resolve)
225
+ .catch(e => {
226
+ reject(new Error('Page visit post request rejected due to: ', e));
227
+ });
228
+ });
231
229
  });
232
230
  }
233
231
  }
@@ -46,7 +46,6 @@ export declare const MAX_PAGEVISIT_VISITED: 300;
46
46
  export declare const IMG_EXTENSIONS: readonly ["jpg", "jpeg", "bmp", "gif", "png"];
47
47
  export declare const MAX_PAGEVISIT_EVENTS: 200;
48
48
  export declare const POSSIBLE_HTML_ATTRIBUTES_FOR_TEXT_VALUES: string[];
49
- export declare const debug: (...m: any[]) => void;
50
49
  export declare const MAX_CUSTOM_IDS_PER_PAGEVISIT: 10;
51
50
  export declare const MAX_CUSTOM_ERRORS_PER_PAGEVISIT: 500;
52
51
  export declare const NOIBUJS_SDK_NAME: "NOIBUJS";
package/dist/constants.js CHANGED
@@ -379,13 +379,10 @@ function IS_NJS_VERSION_BETA() {
379
379
  */
380
380
  function GET_MAX_METROPLEX_RECONNECTION_NUMBER() {
381
381
  try {
382
- // webpack variable
383
- // eslint-disable-next-line no-undef
384
- const maxConnNum = "20";
385
- return maxConnNum;
382
+ return "20";
386
383
  }
387
384
  catch (err) {
388
- // during testing we only try to connect twice before abandoning
385
+ // during testing, we only try to connect twice before abandoning
389
386
  return 2;
390
387
  }
391
388
  }
@@ -396,13 +393,10 @@ function GET_MAX_METROPLEX_RECONNECTION_NUMBER() {
396
393
  */
397
394
  function GET_METROPLEX_CONSECUTIVE_CONNECTION_DELAY() {
398
395
  try {
399
- // webpack variable
400
- // eslint-disable-next-line no-undef
401
- const consecConnDelay = "1000";
402
- return consecConnDelay;
396
+ return "1000";
403
397
  }
404
398
  catch (err) {
405
- // during testing we only delay by 1 second
399
+ // during testing, we only delay by 1 second
406
400
  return 1000;
407
401
  }
408
402
  }
@@ -481,10 +475,7 @@ function GET_METROPLEX_METRICS_URL() {
481
475
  */
482
476
  function JS_ENV() {
483
477
  try {
484
- // webpack variable
485
- // eslint-disable-next-line no-undef
486
- const currEnv = CURR_ENV;
487
- return currEnv;
478
+ return CURR_ENV;
488
479
  }
489
480
  catch (err) {
490
481
  return 'test';
@@ -8,7 +8,7 @@ export declare const setupNoibu: (config: {
8
8
  }) => void;
9
9
  export declare const NoibuJS: {
10
10
  requestHelpCode: (alert?: boolean | undefined) => Promise<string>;
11
- addCustomAttribute: (name: string, value: string) => string;
11
+ addCustomAttribute: (name: string, value: string) => Promise<string>;
12
12
  addError: (customError: Error) => string;
13
13
  addJsSdkError: (customError: string, errorSource: string) => string;
14
14
  };
@@ -126,7 +126,7 @@ function monitorErrors() {
126
126
  saveErrorToPagevisit(ERROR_EVENT_ERROR_TYPE, {
127
127
  error,
128
128
  });
129
- }, true);
129
+ });
130
130
  if (global.HermesInternal) {
131
131
  global.HermesInternal.enablePromiseRejectionTracker({
132
132
  allRejections: true,
@@ -1,6 +1,7 @@
1
1
  import 'react-native-device-info';
2
2
  import 'react-native-localize';
3
3
  import 'react-native-uuid';
4
+ import '@react-native-async-storage/async-storage';
4
5
 
5
6
  /** @module LocationMonitor */
6
7
 
@@ -0,0 +1,23 @@
1
+ import StorageProvider from './storageProvider';
2
+ /**
3
+ * React native storage provider implementation
4
+ */
5
+ export default class RNStorageProvider extends StorageProvider {
6
+ /**
7
+ * Creates new instance
8
+ */
9
+ constructor();
10
+ /**
11
+ * Checks if storage is available
12
+ * @returns {Object}
13
+ */
14
+ static isAvailable(): Promise<{
15
+ result: boolean;
16
+ error: unknown;
17
+ }>;
18
+ /**
19
+ * Calculates used scape
20
+ * @returns {Number}
21
+ */
22
+ calculateUsedSize(): Promise<number>;
23
+ }
@@ -1,62 +1,33 @@
1
+ import AsyncStorage from '@react-native-async-storage/async-storage';
1
2
  import StorageProvider from './storageProvider.js';
2
3
 
3
4
  // eslint-disable-next-line max-classes-per-file
4
-
5
- /**
6
- * React native storage implementation: temporary
7
- */
8
- class RNStorageTmp {
9
- /** */
10
- constructor() {
11
- this._map = new Map();
12
- }
13
-
14
- /**
15
- * @param key
16
- * @returns {string}
17
- */
18
- getItem(key) {
19
- return this._map.get(key);
20
- }
21
-
22
- /**
23
- * @param key
24
- * @param value
25
- * @returns {Map<string, string>}
26
- */
27
- setItem(key, value) {
28
- return this._map.set(key, value);
29
- }
30
-
31
- /**
32
- * @param key
33
- * @returns {boolean}
34
- */
35
- removeItem(key) {
36
- return this._map.delete(key);
37
- }
38
- }
39
-
40
5
  /**
41
6
  * React native storage provider implementation
42
7
  */
43
8
  class RNStorageProvider extends StorageProvider {
44
- static storage = new RNStorageTmp();
45
-
46
- /**
47
- * Creates new instance
48
- */
49
- constructor() {
50
- super(RNStorageProvider.storage);
51
- }
52
-
53
- /**
54
- * Checks if storage is available
55
- * @returns {Object}
56
- */
57
- static isAvailable() {
58
- return StorageProvider.isAvailable(() => RNStorageProvider.storage);
59
- }
9
+ /**
10
+ * Creates new instance
11
+ */
12
+ constructor() {
13
+ super(AsyncStorage);
14
+ }
15
+ /**
16
+ * Checks if storage is available
17
+ * @returns {Object}
18
+ */
19
+ static isAvailable() {
20
+ return StorageProvider.isAvailable(() => AsyncStorage);
21
+ }
22
+ /**
23
+ * Calculates used scape
24
+ * @returns {Number}
25
+ */
26
+ async calculateUsedSize() {
27
+ const keys = await AsyncStorage.getAllKeys();
28
+ const items = await AsyncStorage.multiGet(keys);
29
+ return items.reduce((sum, [key, item]) => sum + key.length + (item || '').length, 0);
30
+ }
60
31
  }
61
32
 
62
33
  export { RNStorageProvider as default };
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Encapsulates storage api
3
+ */
4
+ export default class Storage implements Noibu.Storage {
5
+ private readonly _isRNStorageAvailable;
6
+ private readonly _rnStorageError;
7
+ private static _instance;
8
+ private readonly _provider;
9
+ private readonly _type;
10
+ /**
11
+ * Creates new instance assessing available options
12
+ */
13
+ constructor();
14
+ /**
15
+ * Singleton
16
+ * @returns {Storage}
17
+ */
18
+ static getInstance(): Storage;
19
+ /** Checks if storage is available */
20
+ isAvailable(): Promise<boolean>;
21
+ /** Loads value from storage */
22
+ load<R = unknown>(key: string): Promise<R | null>;
23
+ /** Saves value to storage */
24
+ save(key: string, value: Noibu.StorageValue): Promise<void>;
25
+ /**
26
+ * Removes value from storage
27
+ * @param {String} key
28
+ */
29
+ remove(key: string): Promise<void>;
30
+ /** Calculates used scape */
31
+ calculateUsedSize(): Promise<number>;
32
+ /**
33
+ * Returns string indicating current provider type
34
+ * and availability for other storage types
35
+ * @returns {String}
36
+ */
37
+ getDiagnoseInfo(): Promise<string>;
38
+ }
@@ -1,118 +1,84 @@
1
- import LocalStorageProvider from './localStorageProvider.js';
2
- import SessionStorageProvider from './sessionStorageProvider.js';
3
1
  import RNStorageProvider from './rnStorageProvider.js';
4
2
 
5
3
  /**
6
4
  * Encapsulates storage api
7
5
  */
8
6
  class Storage {
9
- /**
10
- * Creates new instance assessing available options
11
- */
12
- constructor() {
13
- const localStorageAvailability = LocalStorageProvider.isAvailable();
14
- const sessionStorageAvailability = SessionStorageProvider.isAvailable();
15
- const rnStorageAvailability = RNStorageProvider.isAvailable();
16
- this._isLocalStorageAvailable = localStorageAvailability.result;
17
- this._isSessionStorageAvailable = sessionStorageAvailability.result;
18
- this._isRNStorageAvailable = rnStorageAvailability.result;
19
- this._localStorageError = localStorageAvailability.error;
20
- this._sessionStorageError = sessionStorageAvailability.error;
21
- this._rnStorageError = rnStorageAvailability.error;
22
- this._provider = null;
23
- this._type = 'unavailable';
24
-
25
- if (this._isLocalStorageAvailable) {
26
- this._provider = new LocalStorageProvider();
27
- this._type = 'LocalStorage';
28
- } else if (this._isSessionStorageAvailable) {
29
- this._provider = new SessionStorageProvider();
30
- this._type = 'SessionStorage';
31
- } else if (this._isRNStorageAvailable) {
32
- this._provider = new RNStorageProvider();
33
- this._type = 'RNStorage';
7
+ _isRNStorageAvailable;
8
+ _rnStorageError;
9
+ static _instance;
10
+ _provider;
11
+ _type;
12
+ /**
13
+ * Creates new instance assessing available options
14
+ */
15
+ constructor() {
16
+ // todo replace with promise all if more storage available
17
+ const rnStorageAvailability = RNStorageProvider.isAvailable();
18
+ this._provider = rnStorageAvailability.then(({ result }) => result ? new RNStorageProvider() : null);
19
+ this._type = rnStorageAvailability.then(({ result }) => result ? 'RNStorage' : 'unavailable');
20
+ this._isRNStorageAvailable = rnStorageAvailability.then(({ result }) => result);
21
+ this._rnStorageError = rnStorageAvailability.then(({ error }) => error);
34
22
  }
35
- }
36
-
37
- /**
38
- * Singleton
39
- * @returns {Storage}
40
- */
41
- static getInstance() {
42
- if (!this._instance) {
43
- this._instance = new Storage();
23
+ /**
24
+ * Singleton
25
+ * @returns {Storage}
26
+ */
27
+ static getInstance() {
28
+ if (!this._instance) {
29
+ this._instance = new Storage();
30
+ }
31
+ return this._instance;
44
32
  }
45
- return this._instance;
46
- }
47
-
48
- /**
49
- * Checks if storage is available
50
- * @returns {Boolean}
51
- */
52
- isAvailable() {
53
- return this._provider != null;
54
- }
55
-
56
- /**
57
- * Loads value from storage
58
- * @param {String} key
59
- * @returns {String}
60
- */
61
- load(key) {
62
- if (this.isAvailable()) {
63
- return this._provider.load(key);
33
+ /** Checks if storage is available */
34
+ async isAvailable() {
35
+ return (await this._provider) !== null;
64
36
  }
65
- return null;
66
- }
67
-
68
- /**
69
- * Saves value to storage
70
- * @param {String} key
71
- * @param {String} value
72
- */
73
- save(key, value) {
74
- if (this.isAvailable()) {
75
- this._provider.save(key, value);
37
+ /** Loads value from storage */
38
+ async load(key) {
39
+ const provider = await this._provider;
40
+ if (provider !== null) {
41
+ return provider.load(key);
42
+ }
43
+ return null;
76
44
  }
77
- }
78
-
79
- /**
80
- * Removes value from storage
81
- * @param {String} key
82
- */
83
- remove(key) {
84
- if (this.isAvailable()) {
85
- this._provider.remove(key);
45
+ /** Saves value to storage */
46
+ async save(key, value) {
47
+ const provider = await this._provider;
48
+ if (provider !== null) {
49
+ return provider.save(key, value);
50
+ }
51
+ return undefined;
86
52
  }
87
- }
88
-
89
- /**
90
- * Calculates used scape
91
- * @returns {Number}
92
- */
93
- calculateUsedSize() {
94
- if (this.isAvailable()) {
95
- return this._provider.calculateUsedSize();
53
+ /**
54
+ * Removes value from storage
55
+ * @param {String} key
56
+ */
57
+ async remove(key) {
58
+ const provider = await this._provider;
59
+ if (provider !== null) {
60
+ return provider.remove(key);
61
+ }
62
+ return undefined;
63
+ }
64
+ /** Calculates used scape */
65
+ async calculateUsedSize() {
66
+ const provider = await this._provider;
67
+ if (provider !== null) {
68
+ return provider.calculateUsedSize();
69
+ }
70
+ return 0;
71
+ }
72
+ /**
73
+ * Returns string indicating current provider type
74
+ * and availability for other storage types
75
+ * @returns {String}
76
+ */
77
+ async getDiagnoseInfo() {
78
+ return `storage provider: ${await this
79
+ ._type} (rnStorage available: ${await this
80
+ ._isRNStorageAvailable}, error: ${await this._rnStorageError})`;
96
81
  }
97
- return 0;
98
- }
99
-
100
- /**
101
- * Returns string indicating current provider type
102
- * and availability for other storage types
103
- * @returns {String}
104
- */
105
- getDiagnoseInfo() {
106
- return (
107
- `storage provider: ${this._type} ` +
108
- `(localStorage available: ${this._isLocalStorageAvailable}, ` +
109
- `error: ${this._localStorageError}) ` +
110
- `(sessionStorage available: ${this._isSessionStorageAvailable}, ` +
111
- `error: ${this._sessionStorageError})` +
112
- `(rnStorage available: ${this._isRNStorageAvailable}, ` +
113
- `error: ${this._rnStorageError})`
114
- );
115
- }
116
82
  }
117
83
 
118
84
  export { Storage as default };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Base implementation for LocalStorage and SessionStorage
3
+ */
4
+ export default abstract class StorageProvider {
5
+ _provider: Noibu.Provider;
6
+ /** Creates new instance based on provided provider type */
7
+ constructor(provider: Noibu.Provider);
8
+ /** Checks if provider is available */
9
+ static isAvailable(resolver: () => Noibu.Provider): Promise<{
10
+ result: boolean;
11
+ error: unknown;
12
+ }>;
13
+ /**
14
+ * Loads value from storage
15
+ */
16
+ load<R = Noibu.StorageValue>(key: string): Promise<R | null>;
17
+ /** Saves value to storage */
18
+ save(key: string, value: Noibu.StorageValue): Promise<void>;
19
+ /**
20
+ * Removes value from storage
21
+ * @param {String} key
22
+ */
23
+ remove(key: string): Promise<void>;
24
+ abstract calculateUsedSize(): Promise<number>;
25
+ }
@@ -4,79 +4,47 @@ import { NOIBU_LOCAL_STORAGE_TEST_KEY } from '../constants.js';
4
4
  * Base implementation for LocalStorage and SessionStorage
5
5
  */
6
6
  class StorageProvider {
7
- /**
8
- * Creates new instance based on provided provider type
9
- * @param {WindowLocalStorage|WindowSessionStorage|RNStorageTmp} provider
10
- */
11
- constructor(provider) {
12
- this._provider = provider;
13
- }
14
-
15
- /**
16
- * Checks if provider is available
17
- * @param {Function} function that returns storage instance
18
- * @return {Object} { result: true|false, error: null|Error }
19
- */
20
- static isAvailable(resolver) {
21
- let result = true;
22
- let error = null;
23
- try {
24
- // access to localStorage/sessionStorage may throw an error
25
- // so use function to resolve it wrapped with try/catch
26
- const provider = resolver();
27
- provider.setItem(NOIBU_LOCAL_STORAGE_TEST_KEY, 0);
28
- provider.removeItem(NOIBU_LOCAL_STORAGE_TEST_KEY);
29
- } catch (e) {
30
- result = false;
31
- error = e;
7
+ _provider;
8
+ /** Creates new instance based on provided provider type */
9
+ constructor(provider) {
10
+ this._provider = provider;
32
11
  }
33
- return { result, error };
34
- }
35
-
36
- /**
37
- * Loads value from storage
38
- * @param {String} key
39
- * @returns {String}
40
- */
41
- load(key) {
42
- return this._provider.getItem(key);
43
- }
44
-
45
- /**
46
- * Saves value to storage
47
- * @param {String} key
48
- * @param {String} value
49
- */
50
- save(key, value) {
51
- this._provider.setItem(key, value);
52
- }
53
-
54
- /**
55
- * Removes value from storage
56
- * @param {String} key
57
- */
58
- remove(key) {
59
- this._provider.removeItem(key);
60
- }
61
-
62
- /**
63
- * Calculates used scape
64
- * @returns {Number}
65
- */
66
- calculateUsedSize() {
67
- let size = 0;
68
- for (let i = 0; i < this._provider.length; i++) {
69
- const key = this._provider.key(i);
70
- if (key) {
71
- size += key.length;
72
- const value = this._provider.getItem(key);
73
- if (value) {
74
- size += value.length;
12
+ /** Checks if provider is available */
13
+ static async isAvailable(resolver) {
14
+ let result = true;
15
+ let error = null;
16
+ try {
17
+ const provider = resolver();
18
+ await provider.setItem(NOIBU_LOCAL_STORAGE_TEST_KEY, '0');
19
+ await provider.removeItem(NOIBU_LOCAL_STORAGE_TEST_KEY);
75
20
  }
76
- }
21
+ catch (e) {
22
+ result = false;
23
+ error = e;
24
+ }
25
+ return { result, error };
26
+ }
27
+ /**
28
+ * Loads value from storage
29
+ */
30
+ async load(key) {
31
+ const value = await this._provider.getItem(key);
32
+ if (value !== null) {
33
+ return value;
34
+ }
35
+ return value;
36
+ }
37
+ /** Saves value to storage */
38
+ save(key, value) {
39
+ return this._provider.setItem(key, `${value}`);
40
+ }
41
+ /**
42
+ * Removes value from storage
43
+ * @param {String} key
44
+ */
45
+ remove(key) {
46
+ return this._provider.removeItem(key);
77
47
  }
78
- return size;
79
- }
80
48
  }
81
49
 
82
50
  export { StorageProvider as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noibu-react-native",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "React-Native SDK for NoibuJS to collect errors in React-Native applications",
5
5
  "main": "dist/entry/index.js",
6
6
  "types": "dist/entry/index.d.ts",
@@ -23,6 +23,7 @@
23
23
  "dependencies": {
24
24
  "react": ">=16.11.0",
25
25
  "react-native": ">=0.63.0",
26
+ "@react-native-async-storage/async-storage": "^1.19.0",
26
27
  "react-native-device-info": "^10.6.0",
27
28
  "react-native-url-polyfill": "^1.3.0",
28
29
  "react-native-uuid": "^2.0.1",
@@ -1,23 +0,0 @@
1
- import StorageProvider from './storageProvider.js';
2
-
3
- /**
4
- * Local storage provider implementation
5
- */
6
- class LocalStorageProvider extends StorageProvider {
7
- /**
8
- * Creates new instance
9
- */
10
- constructor() {
11
- super(window.localStorage);
12
- }
13
-
14
- /**
15
- * Checks if storage is available
16
- * @returns {Object}
17
- */
18
- static isAvailable() {
19
- return StorageProvider.isAvailable(() => window.localStorage);
20
- }
21
- }
22
-
23
- export { LocalStorageProvider as default };
@@ -1,23 +0,0 @@
1
- import StorageProvider from './storageProvider.js';
2
-
3
- /**
4
- * Session storage provider implementation
5
- */
6
- class SessionStorageProvider extends StorageProvider {
7
- /**
8
- * Creates new instance
9
- */
10
- constructor() {
11
- super(window.sessionStorage);
12
- }
13
-
14
- /**
15
- * Checks if storage is available
16
- * @returns {Object}
17
- */
18
- static isAvailable() {
19
- return StorageProvider.isAvailable(() => window.sessionStorage);
20
- }
21
- }
22
-
23
- export { SessionStorageProvider as default };