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 +4 -4
- package/dist/api/clientConfig.js +31 -33
- package/dist/api/helpCode.js +3 -3
- package/dist/api/inputManager.js +5 -5
- package/dist/api/metroplexSocket.js +16 -18
- package/dist/api/storedPageVisit.js +27 -29
- package/dist/constants.d.ts +0 -1
- package/dist/constants.js +5 -14
- package/dist/entry/index.d.ts +1 -1
- package/dist/monitors/errorMonitor.js +1 -1
- package/dist/monitors/locationChangeMonitor.js +1 -0
- package/dist/storage/rnStorageProvider.d.ts +23 -0
- package/dist/storage/rnStorageProvider.js +23 -52
- package/dist/storage/storage.d.ts +38 -0
- package/dist/storage/storage.js +69 -103
- package/dist/storage/storageProvider.d.ts +25 -0
- package/dist/storage/storageProvider.js +38 -70
- package/package.json +2 -1
- package/dist/storage/localStorageProvider.js +0 -23
- package/dist/storage/sessionStorageProvider.js +0 -23
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`
|
package/dist/api/clientConfig.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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.
|
package/dist/api/helpCode.js
CHANGED
|
@@ -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
|
|
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;
|
package/dist/api/inputManager.js
CHANGED
|
@@ -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(
|
|
229
|
-
return HelpCode.getInstance().requestHelpCode(
|
|
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] =
|
|
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]:
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
229
|
-
|
|
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
|
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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';
|
package/dist/entry/index.d.ts
CHANGED
|
@@ -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
|
};
|
|
@@ -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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
+
}
|
package/dist/storage/storage.js
CHANGED
|
@@ -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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
9
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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.
|
|
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 };
|