noibu-react-native 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -0
- package/dist/api/clientConfig.js +416 -0
- package/dist/api/helpCode.js +106 -0
- package/dist/api/inputManager.js +233 -0
- package/dist/api/metroplexSocket.js +882 -0
- package/dist/api/storedMetrics.js +201 -0
- package/dist/api/storedPageVisit.js +235 -0
- package/dist/const_matchers.js +260 -0
- package/dist/constants.d.ts +264 -0
- package/dist/constants.js +528 -0
- package/dist/entry/index.d.ts +8 -0
- package/dist/entry/index.js +15 -0
- package/dist/entry/init.js +91 -0
- package/dist/monitors/clickMonitor.js +284 -0
- package/dist/monitors/elementMonitor.js +174 -0
- package/dist/monitors/errorMonitor.js +295 -0
- package/dist/monitors/gqlErrorValidator.js +306 -0
- package/dist/monitors/httpDataBundler.js +665 -0
- package/dist/monitors/inputMonitor.js +130 -0
- package/dist/monitors/keyboardInputMonitor.js +67 -0
- package/dist/monitors/locationChangeMonitor.js +30 -0
- package/dist/monitors/pageMonitor.js +119 -0
- package/dist/monitors/requestMonitor.js +679 -0
- package/dist/pageVisit/pageVisit.js +172 -0
- package/dist/pageVisit/pageVisitEventError/pageVisitEventError.js +313 -0
- package/dist/pageVisit/pageVisitEventHTTP/pageVisitEventHTTP.js +115 -0
- package/dist/pageVisit/userStep/userStep.js +20 -0
- package/dist/react/ErrorBoundary.d.ts +72 -0
- package/dist/react/ErrorBoundary.js +102 -0
- package/dist/storage/localStorageProvider.js +23 -0
- package/dist/storage/rnStorageProvider.js +62 -0
- package/dist/storage/sessionStorageProvider.js +23 -0
- package/dist/storage/storage.js +119 -0
- package/dist/storage/storageProvider.js +83 -0
- package/dist/utils/date.js +62 -0
- package/dist/utils/eventlistener.js +67 -0
- package/dist/utils/function.js +398 -0
- package/dist/utils/object.js +144 -0
- package/dist/utils/performance.js +21 -0
- package/package.json +57 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { BROWSER_ID_ATT_NAME, PV_ID_ATT_NAME, COLLECT_VER_ATT_NAME, CURRENT_NOIBUJS_VERSION, VER_ATT_NAME, CURRENT_METRICS_VERSION, EXP_VIDEO_LENGTH_ATT_NAME, PV_EXP_VF_SEQ_ATT_NAME, PV_EXP_PART_COUNTER_ATT_NAME, PV_EXP_HTTP_DATA_SEQ_ATT_NAME, PV_HTTP_PAYLOADS_COLLECTED_ATT_NAME, PV_HTTP_PAYLOADS_DROPPED_OVERSIZE_ATT_NAME, PV_HTTP_PAYLOADS_DROPPED_TYPE_ATT_NAME, PV_HTTP_REQUESTS_DROPPED_OVER_LIMIT, VIDEO_CLICKS_ATT_NAME, PV_CLICKS_ATT_NAME, DID_CUT_PV_ATT_NAME, DID_CUT_VID_ATT_NAME, DID_START_VID_ATT_NAME, HTTP_COUNT_EXPECTED_ATT_NAME, ERR_COUNT_EXPECTED_ATT_NAME, ON_URL_ATT_NAME, GET_METROPLEX_METRICS_URL } from '../constants.js';
|
|
2
|
+
import ClientConfig from './clientConfig.js';
|
|
3
|
+
import { stringifyJSON } from '../utils/function.js';
|
|
4
|
+
import { addSafeEventListener } from '../utils/eventlistener.js';
|
|
5
|
+
|
|
6
|
+
/** @module StoredMetrics */
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* This class holds the final page visit and video frag metrics. It flushes
|
|
10
|
+
* them to local storage and then finally sends them to Metroplex via the post
|
|
11
|
+
* route when the next page is loaded
|
|
12
|
+
*/
|
|
13
|
+
class StoredMetrics {
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new StoredMetrics instance
|
|
16
|
+
*/
|
|
17
|
+
constructor() {
|
|
18
|
+
this.expectedVideoLength = 0;
|
|
19
|
+
this.expectedVfSeq = 0;
|
|
20
|
+
this.httpSequenceNumber = 0;
|
|
21
|
+
this.httpOverLimitCount = 0;
|
|
22
|
+
this.httpDroppedPayloadByTypeCount = 0;
|
|
23
|
+
this.httpDroppedPayloadByLengthCount = 0;
|
|
24
|
+
this.httpPayloadCount = 0;
|
|
25
|
+
this.expectedPvPart = 0;
|
|
26
|
+
this.videoClicks = 0;
|
|
27
|
+
this.pvClicks = 0;
|
|
28
|
+
this.errCount = 0;
|
|
29
|
+
this.httpCount = 0;
|
|
30
|
+
this.didCutPv = false;
|
|
31
|
+
this.didCutVideo = false;
|
|
32
|
+
this.writeTimeout = null;
|
|
33
|
+
this.didStartVideo = false;
|
|
34
|
+
|
|
35
|
+
this._setupListeners();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** gets the singleton instance */
|
|
39
|
+
static getInstance() {
|
|
40
|
+
if (!this.instance) {
|
|
41
|
+
this.instance = new StoredMetrics();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return this.instance;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Add video frag payload data to the stored metrics
|
|
48
|
+
* @param {} expectedVfSeq
|
|
49
|
+
* @param {} expectedVideoLength
|
|
50
|
+
*/
|
|
51
|
+
addVideoFragData(expectedVfSeq, expectedVideoLength) {
|
|
52
|
+
this.expectedVfSeq = expectedVfSeq;
|
|
53
|
+
this.expectedVideoLength = expectedVideoLength;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Set the amount of page visit parts
|
|
57
|
+
* @param {} expectedPvPart
|
|
58
|
+
*/
|
|
59
|
+
setPvPart(expectedPvPart) {
|
|
60
|
+
this.expectedPvPart = expectedPvPart;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Increase the amount of video clicks seen in the session */
|
|
64
|
+
addVideoClick() {
|
|
65
|
+
this.videoClicks += 1;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Increase the amount of page visit clicks */
|
|
69
|
+
addPvClick() {
|
|
70
|
+
this.pvClicks += 1;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Increments the error count by 1 */
|
|
74
|
+
addError() {
|
|
75
|
+
this.errCount += 1;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Increments the http count by 1 */
|
|
79
|
+
addHttpEvent() {
|
|
80
|
+
this.httpCount += 1;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Increments the http data sequence count by 1 */
|
|
84
|
+
addHttpData() {
|
|
85
|
+
this.httpSequenceNumber += 1;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Increments the http data over limit count by 1 */
|
|
89
|
+
addHttpDataOverLimit() {
|
|
90
|
+
this.httpOverLimitCount += 1;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Increments the http data drop count by content type */
|
|
94
|
+
addHttpDataDropByType() {
|
|
95
|
+
this.httpDroppedPayloadByTypeCount += 1;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Increments the http data drop count by content length */
|
|
99
|
+
addHttpDataDropByLength() {
|
|
100
|
+
this.httpDroppedPayloadByLengthCount += 1;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Increments the http data payload collected count */
|
|
104
|
+
addHttpDataPayloadCount() {
|
|
105
|
+
this.httpPayloadCount += 1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Set that the video was cut/blocked due to size constraints */
|
|
109
|
+
setDidCutVideo() {
|
|
110
|
+
this.didCutVideo = true;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Set that the video was started */
|
|
114
|
+
setDidStartVideo() {
|
|
115
|
+
this.didStartVideo = true;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Set that the page visit was cut/blocked due to size constraints */
|
|
119
|
+
setDidCutPv() {
|
|
120
|
+
this.didCutPv = true;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Sets up all the listeners that noibujs should listen to before storing
|
|
125
|
+
* our metrics to localstorage
|
|
126
|
+
*/
|
|
127
|
+
_setupListeners() {
|
|
128
|
+
// Add the window event handlers to post the data to the metrics endpoint
|
|
129
|
+
const evt = 'pagehide';
|
|
130
|
+
addSafeEventListener(window, evt, () => {
|
|
131
|
+
this._postMetricsIfActive(evt);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** posts the metrics to metroplex if client is active
|
|
136
|
+
* @param {} eventName
|
|
137
|
+
*/
|
|
138
|
+
_postMetricsIfActive(eventName) {
|
|
139
|
+
if (ClientConfig.getInstance().isClientDisabled) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
// Don't send the metrics if the session has become inactive
|
|
143
|
+
// already sent when went inactive
|
|
144
|
+
if (ClientConfig.getInstance().isInactive()) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
this.postMetrics(eventName);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** posts the metrics to metroplex using the beacon API
|
|
151
|
+
* @param {} eventName
|
|
152
|
+
*/
|
|
153
|
+
postMetrics(eventName) {
|
|
154
|
+
// Create a new object to write to local storage that doesnt have the timeout and flush members.
|
|
155
|
+
const lsMetrics = {
|
|
156
|
+
// metadata
|
|
157
|
+
[BROWSER_ID_ATT_NAME]: ClientConfig.getInstance().browserId,
|
|
158
|
+
[PV_ID_ATT_NAME]: ClientConfig.getInstance().pageVisitId,
|
|
159
|
+
[COLLECT_VER_ATT_NAME]: CURRENT_NOIBUJS_VERSION,
|
|
160
|
+
[VER_ATT_NAME]: CURRENT_METRICS_VERSION,
|
|
161
|
+
|
|
162
|
+
// metrics
|
|
163
|
+
[EXP_VIDEO_LENGTH_ATT_NAME]: this.expectedVideoLength,
|
|
164
|
+
[PV_EXP_VF_SEQ_ATT_NAME]: this.expectedVfSeq,
|
|
165
|
+
[PV_EXP_PART_COUNTER_ATT_NAME]: this.expectedPvPart,
|
|
166
|
+
[PV_EXP_HTTP_DATA_SEQ_ATT_NAME]: this.httpSequenceNumber,
|
|
167
|
+
[PV_HTTP_PAYLOADS_COLLECTED_ATT_NAME]: this.httpPayloadCount,
|
|
168
|
+
[PV_HTTP_PAYLOADS_DROPPED_OVERSIZE_ATT_NAME]:
|
|
169
|
+
this.httpDroppedPayloadByLengthCount,
|
|
170
|
+
[PV_HTTP_PAYLOADS_DROPPED_TYPE_ATT_NAME]:
|
|
171
|
+
this.httpDroppedPayloadByTypeCount,
|
|
172
|
+
[PV_HTTP_REQUESTS_DROPPED_OVER_LIMIT]: this.httpOverLimitCount,
|
|
173
|
+
[VIDEO_CLICKS_ATT_NAME]: this.videoClicks,
|
|
174
|
+
[PV_CLICKS_ATT_NAME]: this.pvClicks,
|
|
175
|
+
[DID_CUT_PV_ATT_NAME]: this.didCutPv,
|
|
176
|
+
[DID_CUT_VID_ATT_NAME]: this.didCutVideo,
|
|
177
|
+
[DID_START_VID_ATT_NAME]: this.didStartVideo,
|
|
178
|
+
[HTTP_COUNT_EXPECTED_ATT_NAME]: this.httpCount,
|
|
179
|
+
[ERR_COUNT_EXPECTED_ATT_NAME]: this.errCount,
|
|
180
|
+
[ON_URL_ATT_NAME]:
|
|
181
|
+
(global.document &&
|
|
182
|
+
global.document.location &&
|
|
183
|
+
global.document.location.href) ||
|
|
184
|
+
'http://localhost',
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
if (global.fetch) {
|
|
188
|
+
global.fetch(GET_METROPLEX_METRICS_URL(), {
|
|
189
|
+
method: 'POST',
|
|
190
|
+
headers: {
|
|
191
|
+
'content-type': 'application/json',
|
|
192
|
+
},
|
|
193
|
+
body: stringifyJSON(lsMetrics),
|
|
194
|
+
// keep alive outlives the current page, its the same as beacon
|
|
195
|
+
keepalive: true,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export { StoredMetrics as default };
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { PV_METROPLEX_TYPE, PAGE_VISIT_PART_ATT_NAME, PV_EVENTS_ATT_NAME, TYPE_ATT_NAME, USERSTEP_EVENT_TYPE, ERROR_EVENT_TYPE, LOCATION_EVENT_TYPE, NOIBU_STORED_PAGE_VISIT, SEVERITY_ERROR, MAX_METROPLEX_SOCKET_INNACTIVE_TIME, PAGE_VISIT_INFORMATION_ATT_NAME, PAGE_VISIT_VID_FRAG_ATT_NAME, IS_LAST_ATT_NAME, GET_METROPLEX_POST_URL } from '../constants.js';
|
|
2
|
+
import ClientConfig from './clientConfig.js';
|
|
3
|
+
import { stringifyJSON, makeRequest } from '../utils/function.js';
|
|
4
|
+
import Storage from '../storage/storage.js';
|
|
5
|
+
|
|
6
|
+
/** @module StoredPageVisit */
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* This class holds the final page visit. It flushes it to storage and then
|
|
10
|
+
* finally sends it to Metroplex via the post route when the next page is loaded
|
|
11
|
+
*/
|
|
12
|
+
class StoredPageVisit {
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new instance of StoredPageVisit
|
|
15
|
+
*/
|
|
16
|
+
constructor() {
|
|
17
|
+
this.latestPageVisitFrag = null;
|
|
18
|
+
this.writeTimeout = null;
|
|
19
|
+
this.flushedStorage = false;
|
|
20
|
+
|
|
21
|
+
const storage = Storage.getInstance();
|
|
22
|
+
if (storage.isAvailable()) {
|
|
23
|
+
this._postPreviousPageVisit();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** gets the singleton instance */
|
|
28
|
+
static getInstance() {
|
|
29
|
+
if (!this.instance) {
|
|
30
|
+
this.instance = new StoredPageVisit();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return this.instance;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Check if the events contain a click or location change. If they do then write the retry
|
|
38
|
+
* queue (which contains the metroplex msg sent above) to storage
|
|
39
|
+
* @param {} retryMessageQueue
|
|
40
|
+
* @param {} pvInfo
|
|
41
|
+
*/
|
|
42
|
+
checkAndStoreRetryQueue(retryMessageQueue, pvInfo) {
|
|
43
|
+
// Get the events from the last message
|
|
44
|
+
const { type, payload } = retryMessageQueue[retryMessageQueue.length - 1];
|
|
45
|
+
|
|
46
|
+
// Only store page visit payloads
|
|
47
|
+
if (type !== PV_METROPLEX_TYPE || !payload[PAGE_VISIT_PART_ATT_NAME]) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const events = payload[PAGE_VISIT_PART_ATT_NAME][PV_EVENTS_ATT_NAME]
|
|
51
|
+
? payload[PAGE_VISIT_PART_ATT_NAME][PV_EVENTS_ATT_NAME]
|
|
52
|
+
: [];
|
|
53
|
+
|
|
54
|
+
const filteredEvents = events.filter(
|
|
55
|
+
event =>
|
|
56
|
+
// Return true if the event is a userstep, error, or location event
|
|
57
|
+
// Any userstep is used rather than just mouse clicks because we shouldn't
|
|
58
|
+
// assume mouse clicks are the only way for any activity to happen
|
|
59
|
+
event[TYPE_ATT_NAME] === USERSTEP_EVENT_TYPE ||
|
|
60
|
+
event[TYPE_ATT_NAME] === ERROR_EVENT_TYPE ||
|
|
61
|
+
event[TYPE_ATT_NAME] === LOCATION_EVENT_TYPE,
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
// Only write the retry queue if it contains a user step or location change
|
|
65
|
+
if (filteredEvents.length > 0) {
|
|
66
|
+
this.writePageVisitsFromRetryQueue(retryMessageQueue, pvInfo);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Writes the page visit frags in the retry queue to storage
|
|
71
|
+
* @param {} retryMessageQueue
|
|
72
|
+
* @param {} pvInfo
|
|
73
|
+
*/
|
|
74
|
+
writePageVisitsFromRetryQueue(retryMessageQueue, pvInfo) {
|
|
75
|
+
const pageVisitFrags = [];
|
|
76
|
+
for (let i = 0; i < retryMessageQueue.length; i += 1) {
|
|
77
|
+
const { type, payload } = retryMessageQueue[i];
|
|
78
|
+
if (type === PV_METROPLEX_TYPE) {
|
|
79
|
+
const frag = payload[PAGE_VISIT_PART_ATT_NAME];
|
|
80
|
+
pageVisitFrags.push(frag);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
this._writePageVisitFrags(pageVisitFrags, pvInfo);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Write the given page visit frags to storage
|
|
88
|
+
* @param {} pageVisitFrags
|
|
89
|
+
* @param {} pvInfo
|
|
90
|
+
*/
|
|
91
|
+
_writePageVisitFrags(pageVisitFrags, pvInfo) {
|
|
92
|
+
// Create a new object to write to storage that doesnt have the timeout and flush members
|
|
93
|
+
const lsPageVisit = {
|
|
94
|
+
pageVisitFrags,
|
|
95
|
+
pageVisitInfo: pvInfo,
|
|
96
|
+
timestamp: new Date(),
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const storage = Storage.getInstance();
|
|
100
|
+
|
|
101
|
+
const json = stringifyJSON(lsPageVisit);
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
storage.save(NOIBU_STORED_PAGE_VISIT, json);
|
|
105
|
+
} catch (err) {
|
|
106
|
+
storage.remove(NOIBU_STORED_PAGE_VISIT);
|
|
107
|
+
|
|
108
|
+
// Calculate current storage size
|
|
109
|
+
const size = storage.calculateUsedSize();
|
|
110
|
+
|
|
111
|
+
ClientConfig.getInstance().postNoibuErrorAndOptionallyDisableClient(
|
|
112
|
+
`Error writing pv to storage: ${err}, ` +
|
|
113
|
+
`json size: ${json.length}, storage size: ${size}, ` +
|
|
114
|
+
`${storage.getDiagnoseInfo()}`,
|
|
115
|
+
false,
|
|
116
|
+
SEVERITY_ERROR,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Read the stored page visit from storage, create a complete page visit object
|
|
123
|
+
* and then post that to Metroplex
|
|
124
|
+
*/
|
|
125
|
+
_getPostData() {
|
|
126
|
+
const storage = Storage.getInstance();
|
|
127
|
+
|
|
128
|
+
// Read the storedPageVisit from storage
|
|
129
|
+
const data = storage.load(NOIBU_STORED_PAGE_VISIT);
|
|
130
|
+
if (!data) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
let storedPageVisit = {};
|
|
135
|
+
try {
|
|
136
|
+
storedPageVisit = JSON.parse(data);
|
|
137
|
+
} catch (e) {
|
|
138
|
+
// Remove the item since there is something corrupted
|
|
139
|
+
storage.remove(NOIBU_STORED_PAGE_VISIT);
|
|
140
|
+
ClientConfig.getInstance().postNoibuErrorAndOptionallyDisableClient(
|
|
141
|
+
`Error parsing page visit string '${data}': ${e}`,
|
|
142
|
+
false,
|
|
143
|
+
SEVERITY_ERROR,
|
|
144
|
+
);
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// making sure we have the timestamp attribute since we added this logic after initially
|
|
149
|
+
// releasing the storedPageVisit
|
|
150
|
+
if (storedPageVisit.timestamp) {
|
|
151
|
+
// checking how long the page visit was in storage
|
|
152
|
+
const someTimeAgo = new Date();
|
|
153
|
+
someTimeAgo.setSeconds(
|
|
154
|
+
someTimeAgo.getSeconds() - MAX_METROPLEX_SOCKET_INNACTIVE_TIME,
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
// if the user leaves the page for more than 35 minutes, we do not attempt
|
|
158
|
+
// to send the page visit since we can assume that this will create another pagevisit
|
|
159
|
+
if (someTimeAgo >= Date.parse(storedPageVisit.timestamp)) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Copy the page visit information from storage into a new complete PV
|
|
165
|
+
const completePv = {
|
|
166
|
+
[PAGE_VISIT_INFORMATION_ATT_NAME]: storedPageVisit.pageVisitInfo,
|
|
167
|
+
[PAGE_VISIT_PART_ATT_NAME]: [],
|
|
168
|
+
[PAGE_VISIT_VID_FRAG_ATT_NAME]: [],
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
// Set is last to be true on the page visit information
|
|
172
|
+
completePv[PAGE_VISIT_INFORMATION_ATT_NAME][IS_LAST_ATT_NAME] = true;
|
|
173
|
+
|
|
174
|
+
// Add the page visit frags to the complete PV
|
|
175
|
+
for (let i = 0; i < storedPageVisit.pageVisitFrags.length; i += 1) {
|
|
176
|
+
completePv[PAGE_VISIT_PART_ATT_NAME].push(
|
|
177
|
+
storedPageVisit.pageVisitFrags[i],
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return completePv;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Creates and tries to resolve a promise that posts the previous page visit
|
|
186
|
+
* to Metroplex from storage
|
|
187
|
+
*/
|
|
188
|
+
_postPreviousPageVisit() {
|
|
189
|
+
// Whether the post promise resolves or not we need to finally
|
|
190
|
+
// clear the storage item and set flushed
|
|
191
|
+
this._getPostPageVisitPromise()
|
|
192
|
+
.then(() => {
|
|
193
|
+
this._updateStorageFlushed();
|
|
194
|
+
})
|
|
195
|
+
.catch(() => {
|
|
196
|
+
this._updateStorageFlushed();
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Remove the storage item and set flushed to true after they have
|
|
202
|
+
* been posted to metroplex
|
|
203
|
+
*/
|
|
204
|
+
_updateStorageFlushed() {
|
|
205
|
+
this.flushedStorage = true;
|
|
206
|
+
const storage = Storage.getInstance();
|
|
207
|
+
storage.remove(NOIBU_STORED_PAGE_VISIT);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** Returns a promise that resolves to post the page visit in storage to Metroplex */
|
|
211
|
+
_getPostPageVisitPromise() {
|
|
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(() => {
|
|
226
|
+
resolve();
|
|
227
|
+
})
|
|
228
|
+
.catch(e => {
|
|
229
|
+
reject(new Error('Page visit post request rejected due to: ', e));
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export { StoredPageVisit as default };
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/* eslint-disable require-jsdoc */
|
|
2
|
+
// This file is generated by wsmatchers. Don't directly edit this file
|
|
3
|
+
const addToCartTextRegexArray = [
|
|
4
|
+
'\\b(view|add|my)\\b.*\\b(cart|bag|basket|bucket|box)\\b',
|
|
5
|
+
|
|
6
|
+
'\\b(buy now)\\b',
|
|
7
|
+
|
|
8
|
+
'^backorder$',
|
|
9
|
+
|
|
10
|
+
'\\b(acquista ora)\\b',
|
|
11
|
+
|
|
12
|
+
'\\b(buy this)\\b',
|
|
13
|
+
|
|
14
|
+
'\\b(ajouter|mon)\\b.*\\b(panier)\\b',
|
|
15
|
+
|
|
16
|
+
'\\b(aggiungi)\\b.*\\b(cart|borsa|carrello)\\b',
|
|
17
|
+
|
|
18
|
+
'^ajouter à la shopping bag$',
|
|
19
|
+
|
|
20
|
+
'^aggiungi$',
|
|
21
|
+
|
|
22
|
+
'^aggiungi alla shopping bag$',
|
|
23
|
+
|
|
24
|
+
'\\b(warenkorb)\\b',
|
|
25
|
+
|
|
26
|
+
'(^kaufen$)',
|
|
27
|
+
|
|
28
|
+
'^купить$',
|
|
29
|
+
|
|
30
|
+
'\\b(agregar)\\b.*\\b(carrito)\\b',
|
|
31
|
+
|
|
32
|
+
'\\b(adicionar)\\b.*\\b(carrinho)\\b',
|
|
33
|
+
|
|
34
|
+
'^carrinho$',
|
|
35
|
+
|
|
36
|
+
'^añadir al carrito de compras$',
|
|
37
|
+
|
|
38
|
+
'(^añadir al carrito$)',
|
|
39
|
+
|
|
40
|
+
'(add another)',
|
|
41
|
+
|
|
42
|
+
'(in winkelmand)',
|
|
43
|
+
|
|
44
|
+
'(sepete ekle)',
|
|
45
|
+
|
|
46
|
+
'(Lagg I Varukorgen)',
|
|
47
|
+
|
|
48
|
+
'(ΠΡΟΣΘΗΚΗ ΣΤΟ ΚΑΛΑΘΙ)',
|
|
49
|
+
|
|
50
|
+
'(Lägg i varukorgen)',
|
|
51
|
+
|
|
52
|
+
'(Köp)',
|
|
53
|
+
|
|
54
|
+
'(カートに追加)',
|
|
55
|
+
|
|
56
|
+
'^添加至购物袋$',
|
|
57
|
+
|
|
58
|
+
'^购买$',
|
|
59
|
+
|
|
60
|
+
'^購入する$',
|
|
61
|
+
|
|
62
|
+
'(أضف الى السلة)',
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
const checkoutStartedTextRegexArray = [
|
|
66
|
+
'(paypal)',
|
|
67
|
+
|
|
68
|
+
'(checkout|payment|check out)',
|
|
69
|
+
|
|
70
|
+
'(l.?achat|règlement|paiement|la commande)',
|
|
71
|
+
|
|
72
|
+
'(passer).*(commande)',
|
|
73
|
+
|
|
74
|
+
'valider mon panier',
|
|
75
|
+
|
|
76
|
+
'(acheter maintenant)',
|
|
77
|
+
|
|
78
|
+
'^caisse$',
|
|
79
|
+
|
|
80
|
+
'(gå vidare till kassan)',
|
|
81
|
+
|
|
82
|
+
'(cassa|acquisto)',
|
|
83
|
+
|
|
84
|
+
'^vai alla cassa$',
|
|
85
|
+
|
|
86
|
+
'^procedi all.?acquisto$',
|
|
87
|
+
|
|
88
|
+
'^procedi al checkout$',
|
|
89
|
+
|
|
90
|
+
'^siguiente$',
|
|
91
|
+
|
|
92
|
+
'(kasse)',
|
|
93
|
+
|
|
94
|
+
'^zur kasse gehen$',
|
|
95
|
+
|
|
96
|
+
'^bezahlen$',
|
|
97
|
+
|
|
98
|
+
'^weiter zum checkout$',
|
|
99
|
+
|
|
100
|
+
'(comprar ahora)',
|
|
101
|
+
|
|
102
|
+
'^comprar$',
|
|
103
|
+
|
|
104
|
+
'(prosseguir com a compra)',
|
|
105
|
+
|
|
106
|
+
'^pasar por la caja$',
|
|
107
|
+
|
|
108
|
+
'^afrekenen$',
|
|
109
|
+
|
|
110
|
+
'^compre$',
|
|
111
|
+
|
|
112
|
+
'(continue to pay)',
|
|
113
|
+
|
|
114
|
+
'(naar de kassa)',
|
|
115
|
+
|
|
116
|
+
'Перейти к оформлению заказа',
|
|
117
|
+
|
|
118
|
+
'^купить сейчас$',
|
|
119
|
+
|
|
120
|
+
'^bestellen$',
|
|
121
|
+
|
|
122
|
+
'(Alışverişi Tamamla)',
|
|
123
|
+
|
|
124
|
+
'^Till kassan$',
|
|
125
|
+
|
|
126
|
+
'(チェックアウトに進む)',
|
|
127
|
+
|
|
128
|
+
'^去结算$',
|
|
129
|
+
|
|
130
|
+
'^付款。$',
|
|
131
|
+
|
|
132
|
+
'^お支払い$',
|
|
133
|
+
|
|
134
|
+
'(تاكيد الطلب)',
|
|
135
|
+
];
|
|
136
|
+
|
|
137
|
+
const checkoutPlaceOrderRegexArray = [
|
|
138
|
+
'(checkout|continue) (with paypal)',
|
|
139
|
+
|
|
140
|
+
'^continue to paypal$',
|
|
141
|
+
|
|
142
|
+
'^weiter zu paypal$',
|
|
143
|
+
|
|
144
|
+
'^continue to afterpay$',
|
|
145
|
+
|
|
146
|
+
'^braintree_paypal$',
|
|
147
|
+
|
|
148
|
+
'^pay and place order$',
|
|
149
|
+
|
|
150
|
+
'^mit paypal bezahlen$',
|
|
151
|
+
|
|
152
|
+
'^continue to payment securely$',
|
|
153
|
+
|
|
154
|
+
'(continua su paypal)',
|
|
155
|
+
|
|
156
|
+
'(apple pay|applepay)',
|
|
157
|
+
|
|
158
|
+
'(amazon pay|amazonpay|continue with amazon)',
|
|
159
|
+
|
|
160
|
+
'(sezzlepay)',
|
|
161
|
+
|
|
162
|
+
'(place order)',
|
|
163
|
+
|
|
164
|
+
'(place your order)',
|
|
165
|
+
|
|
166
|
+
'(order confirmation)',
|
|
167
|
+
|
|
168
|
+
'(complete purchase)',
|
|
169
|
+
|
|
170
|
+
'submit.*order',
|
|
171
|
+
|
|
172
|
+
'(pay now)',
|
|
173
|
+
|
|
174
|
+
'(^pay it now$)',
|
|
175
|
+
|
|
176
|
+
'(make payment)',
|
|
177
|
+
|
|
178
|
+
'(^make payment$)',
|
|
179
|
+
|
|
180
|
+
'(complete order)',
|
|
181
|
+
|
|
182
|
+
'^complete your order$',
|
|
183
|
+
|
|
184
|
+
'(fazer pedido)',
|
|
185
|
+
|
|
186
|
+
'^encomendar$',
|
|
187
|
+
|
|
188
|
+
'((realizar) (pedido|pago))',
|
|
189
|
+
|
|
190
|
+
'^finalizar compra$',
|
|
191
|
+
|
|
192
|
+
'^pagar$',
|
|
193
|
+
|
|
194
|
+
'^jetzt kaufen$',
|
|
195
|
+
|
|
196
|
+
'^bestellung aufgeben$',
|
|
197
|
+
|
|
198
|
+
'^bestellung prüfen$',
|
|
199
|
+
|
|
200
|
+
'^auftragsbestätigung$',
|
|
201
|
+
|
|
202
|
+
'^bestelling plaatsen$',
|
|
203
|
+
|
|
204
|
+
'^passer la commande$',
|
|
205
|
+
|
|
206
|
+
'(je confirme et je paye)',
|
|
207
|
+
|
|
208
|
+
'(accéder au paiement)',
|
|
209
|
+
|
|
210
|
+
'^passer au paiement$',
|
|
211
|
+
|
|
212
|
+
'(Valider et continuer)',
|
|
213
|
+
|
|
214
|
+
'^valider la commande$',
|
|
215
|
+
|
|
216
|
+
'(^passez la commande$)',
|
|
217
|
+
|
|
218
|
+
'^invia ordine$',
|
|
219
|
+
|
|
220
|
+
'(effettua ordine)',
|
|
221
|
+
|
|
222
|
+
'^effettua l.?ordine$',
|
|
223
|
+
|
|
224
|
+
'(conferma acquisto)',
|
|
225
|
+
|
|
226
|
+
'^conferma l.?acquisto$',
|
|
227
|
+
|
|
228
|
+
'^confirmation de commande$',
|
|
229
|
+
|
|
230
|
+
'^confirma l.?ordine$',
|
|
231
|
+
|
|
232
|
+
'^conferma l.?ordine$',
|
|
233
|
+
|
|
234
|
+
'^conferma ordine$',
|
|
235
|
+
|
|
236
|
+
'(SİPARİŞİ TAMAMLA)',
|
|
237
|
+
|
|
238
|
+
'^Разместить заказ$',
|
|
239
|
+
|
|
240
|
+
'(Slutför köp)',
|
|
241
|
+
|
|
242
|
+
'(注文する)',
|
|
243
|
+
|
|
244
|
+
'(إنشاء الطلب)',
|
|
245
|
+
|
|
246
|
+
'(注文を確定)',
|
|
247
|
+
|
|
248
|
+
'^お支払いへ進む$',
|
|
249
|
+
|
|
250
|
+
'^确认下单$',
|
|
251
|
+
];
|
|
252
|
+
|
|
253
|
+
function WHITELIST_TEXT_REGEX_STRING() {
|
|
254
|
+
return addToCartTextRegexArray
|
|
255
|
+
.concat(checkoutStartedTextRegexArray)
|
|
256
|
+
.concat(checkoutPlaceOrderRegexArray)
|
|
257
|
+
.join('|');
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export { WHITELIST_TEXT_REGEX_STRING };
|