@cloudcare/browser-core 1.1.2 → 1.2.0
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/cjs/{cookie.js → browser/cookie.js} +6 -37
- package/cjs/browser/fetchObservable.js +91 -0
- package/cjs/browser/xhrObservable.js +118 -0
- package/cjs/configuration/configuration.js +70 -0
- package/cjs/configuration/transportConfiguration.js +64 -0
- package/cjs/console/consoleObservable.js +84 -0
- package/cjs/dataMap.js +26 -21
- package/cjs/error/trackRuntimeError.js +27 -0
- package/cjs/helper/catchUserErrors.js +20 -0
- package/cjs/helper/contextHistory.js +134 -0
- package/cjs/helper/createEventRateLimiter.js +47 -0
- package/cjs/helper/deviceInfo.js +8 -25
- package/cjs/helper/display.js +31 -0
- package/cjs/helper/enums.js +28 -2
- package/cjs/helper/errorTools.js +63 -2
- package/cjs/helper/instrumentMethod.js +93 -0
- package/cjs/helper/lifeCycle.js +5 -3
- package/cjs/helper/observable.js +40 -2
- package/cjs/helper/tools.js +217 -11
- package/cjs/index.js +153 -23
- package/cjs/init.js +17 -27
- package/cjs/report/reportObservable.js +112 -0
- package/cjs/session/sessionConstants.js +13 -0
- package/cjs/session/sessionCookieStore.js +188 -0
- package/cjs/session/sessionManagement.js +96 -0
- package/cjs/session/sessionStore.js +150 -0
- package/cjs/synthetics/syntheticsWorkerValues.js +32 -0
- package/cjs/synthetics/usr.js +32 -0
- package/cjs/tracekit/computeStackTrace.js +73 -563
- package/cjs/tracekit/index.js +3 -15
- package/cjs/tracekit/tracekit.js +113 -0
- package/cjs/transport/batch.js +332 -0
- package/cjs/transport/httpRequest.js +112 -0
- package/cjs/transport/index.js +29 -0
- package/cjs/transport/sendWithRetryStrategy.js +177 -0
- package/cjs/transport/startBatchWithReplica.js +24 -0
- package/esm/{cookie.js → browser/cookie.js} +4 -35
- package/esm/browser/fetchObservable.js +77 -0
- package/esm/browser/xhrObservable.js +106 -0
- package/esm/configuration/configuration.js +55 -0
- package/esm/configuration/transportConfiguration.js +54 -0
- package/esm/console/consoleObservable.js +70 -0
- package/esm/dataMap.js +26 -21
- package/esm/error/trackRuntimeError.js +16 -0
- package/esm/helper/catchUserErrors.js +12 -0
- package/esm/helper/contextHistory.js +106 -0
- package/esm/helper/createEventRateLimiter.js +38 -0
- package/esm/helper/deviceInfo.js +6 -25
- package/esm/helper/display.js +21 -0
- package/esm/helper/enums.js +25 -1
- package/esm/helper/errorTools.js +58 -3
- package/esm/helper/instrumentMethod.js +81 -0
- package/esm/helper/lifeCycle.js +5 -3
- package/esm/helper/observable.js +39 -3
- package/esm/helper/tools.js +173 -3
- package/esm/index.js +17 -7
- package/esm/init.js +17 -22
- package/esm/report/reportObservable.js +98 -0
- package/esm/session/sessionConstants.js +3 -0
- package/esm/session/sessionCookieStore.js +168 -0
- package/esm/session/sessionManagement.js +78 -0
- package/esm/session/sessionStore.js +139 -0
- package/esm/synthetics/syntheticsWorkerValues.js +15 -0
- package/esm/synthetics/usr.js +18 -0
- package/esm/tracekit/computeStackTrace.js +73 -557
- package/esm/tracekit/index.js +1 -1
- package/esm/tracekit/tracekit.js +103 -0
- package/esm/transport/batch.js +316 -0
- package/esm/transport/httpRequest.js +104 -0
- package/esm/transport/index.js +3 -0
- package/esm/transport/sendWithRetryStrategy.js +165 -0
- package/esm/transport/startBatchWithReplica.js +15 -0
- package/package.json +2 -2
- package/src/.DS_Store +0 -0
- package/src/{cookie.js → browser/cookie.js} +6 -34
- package/src/browser/fetchObservable.js +86 -0
- package/src/browser/xhrObservable.js +102 -0
- package/src/configuration/configuration.js +61 -0
- package/src/configuration/transportConfiguration.js +42 -0
- package/src/console/consoleObservable.js +65 -0
- package/src/dataMap.js +26 -21
- package/src/error/trackRuntimeError.js +19 -0
- package/src/helper/catchUserErrors.js +12 -0
- package/src/helper/contextHistory.js +85 -0
- package/src/helper/createEventRateLimiter.js +37 -0
- package/src/helper/deviceInfo.js +5 -51
- package/src/helper/display.js +21 -0
- package/src/helper/enums.js +38 -14
- package/src/helper/errorTools.js +76 -12
- package/src/helper/instrumentMethod.js +97 -0
- package/src/helper/lifeCycle.js +5 -3
- package/src/helper/observable.js +33 -2
- package/src/helper/tools.js +159 -5
- package/src/index.js +18 -7
- package/src/init.js +17 -18
- package/src/report/reportObservable.js +113 -0
- package/src/session/sessionConstants.js +3 -0
- package/src/session/sessionCookieStore.js +159 -0
- package/src/session/sessionManagement.js +89 -0
- package/src/session/sessionStore.js +139 -0
- package/src/synthetics/syntheticsWorkerValues.js +22 -0
- package/src/synthetics/usr.js +18 -0
- package/src/tracekit/computeStackTrace.js +75 -551
- package/src/tracekit/index.js +1 -1
- package/src/tracekit/tracekit.js +100 -0
- package/src/transport/batch.js +289 -0
- package/src/transport/httpRequest.js +109 -0
- package/src/transport/index.js +3 -0
- package/src/transport/sendWithRetryStrategy.js +186 -0
- package/src/transport/startBatchWithReplica.js +26 -0
- package/cjs/configuration.js +0 -184
- package/cjs/errorCollection.js +0 -167
- package/cjs/fetchProxy.js +0 -162
- package/cjs/helper/errorFilter.js +0 -47
- package/cjs/sessionManagement.js +0 -221
- package/cjs/tracekit/report.js +0 -289
- package/cjs/transport.js +0 -373
- package/cjs/xhrProxy.js +0 -122
- package/esm/configuration.js +0 -167
- package/esm/errorCollection.js +0 -141
- package/esm/fetchProxy.js +0 -116
- package/esm/helper/errorFilter.js +0 -38
- package/esm/sessionManagement.js +0 -195
- package/esm/tracekit/report.js +0 -273
- package/esm/transport.js +0 -357
- package/esm/xhrProxy.js +0 -110
- package/src/configuration.js +0 -156
- package/src/errorCollection.js +0 -170
- package/src/fetchProxy.js +0 -109
- package/src/helper/errorFilter.js +0 -38
- package/src/sessionManagement.js +0 -224
- package/src/tracekit/report.js +0 -284
- package/src/transport.js +0 -380
- package/src/xhrProxy.js +0 -106
package/src/transport.js
DELETED
|
@@ -1,380 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
addEventListener,
|
|
3
|
-
values,
|
|
4
|
-
findByPath,
|
|
5
|
-
escapeRowData,
|
|
6
|
-
each,
|
|
7
|
-
isNumber,
|
|
8
|
-
isArray,
|
|
9
|
-
extend,
|
|
10
|
-
isString,
|
|
11
|
-
toServerDuration,
|
|
12
|
-
isBoolean,
|
|
13
|
-
isEmptyObject,
|
|
14
|
-
isObject,
|
|
15
|
-
map,
|
|
16
|
-
escapeJsonValue,
|
|
17
|
-
escapeRowField
|
|
18
|
-
} from './helper/tools'
|
|
19
|
-
import { DOM_EVENT, RumEventType } from './helper/enums'
|
|
20
|
-
import { commonTags, dataMap } from './dataMap'
|
|
21
|
-
import { getGlobalObject } from'./init'
|
|
22
|
-
// https://en.wikipedia.org/wiki/UTF-8
|
|
23
|
-
var HAS_MULTI_BYTES_CHARACTERS = /[^\u0000-\u007F]/
|
|
24
|
-
var CUSTOM_KEYS = 'custom_keys'
|
|
25
|
-
function addBatchPrecision(url) {
|
|
26
|
-
if (!url) return url
|
|
27
|
-
return url + (url.indexOf('?') === -1 ? '?' : '&') + 'precision=ms'
|
|
28
|
-
}
|
|
29
|
-
var global = getGlobalObject()
|
|
30
|
-
var httpRequest = function (endpointUrl, bytesLimit, isLineProtocolToJson) {
|
|
31
|
-
this.endpointUrl = endpointUrl
|
|
32
|
-
this.bytesLimit = bytesLimit
|
|
33
|
-
this.isLineProtocolToJson = isLineProtocolToJson
|
|
34
|
-
var isRealNavigator = Object.prototype.toString.call(global && global.navigator) === '[object Navigator]';
|
|
35
|
-
var hasSendBeacon = isRealNavigator && typeof global.navigator.sendBeacon === 'function';
|
|
36
|
-
if (hasSendBeacon) {
|
|
37
|
-
this.sendBeacon = global.navigator.sendBeacon.bind(global.navigator);
|
|
38
|
-
} else {
|
|
39
|
-
this.sendBeacon = undefined
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
httpRequest.prototype = {
|
|
44
|
-
send: function (data, size) {
|
|
45
|
-
|
|
46
|
-
var url = addBatchPrecision(this.endpointUrl)
|
|
47
|
-
|
|
48
|
-
if (this.sendBeacon && size < this.bytesLimit && !this.isLineProtocolToJson) {
|
|
49
|
-
var isQueued = this.sendBeacon(url, data)
|
|
50
|
-
if (isQueued) {
|
|
51
|
-
return
|
|
52
|
-
}
|
|
53
|
-
} else if (this.sendBeacon && size < this.bytesLimit && this.isLineProtocolToJson) {
|
|
54
|
-
const blob = new Blob([JSON.stringify(data)], {
|
|
55
|
-
type: 'application/json',
|
|
56
|
-
});
|
|
57
|
-
var isQueued = this.sendBeacon(url, blob)
|
|
58
|
-
if (isQueued) {
|
|
59
|
-
return
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
var request = new XMLHttpRequest()
|
|
64
|
-
request.open('POST', url, true)
|
|
65
|
-
request.withCredentials = true
|
|
66
|
-
if (this.isLineProtocolToJson) {
|
|
67
|
-
request.setRequestHeader('Content-type', 'application/json')
|
|
68
|
-
request.send(JSON.stringify(data))
|
|
69
|
-
} else {
|
|
70
|
-
|
|
71
|
-
request.setRequestHeader('Content-type', 'text/plain;charset=UTF-8')
|
|
72
|
-
request.send(data)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export var HttpRequest = httpRequest
|
|
81
|
-
|
|
82
|
-
export var processedMessageByDataMap = function (message) {
|
|
83
|
-
if (!message || !message.type) return {
|
|
84
|
-
rowStr: '',
|
|
85
|
-
rowData: undefined
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
var rowData = { tags: {}, fields: {} }
|
|
89
|
-
var hasFileds = false
|
|
90
|
-
var rowStr = ''
|
|
91
|
-
each(dataMap, function (value, key) {
|
|
92
|
-
if (value.type === message.type) {
|
|
93
|
-
rowStr += key + ','
|
|
94
|
-
rowData.measurement = key
|
|
95
|
-
var tagsStr = []
|
|
96
|
-
var tags = extend({}, commonTags, value.tags)
|
|
97
|
-
var filterFileds = ['date', 'type', CUSTOM_KEYS] // 已经在datamap中定义过的fields和tags
|
|
98
|
-
each(tags, function (value_path, _key) {
|
|
99
|
-
var _value = findByPath(message, value_path)
|
|
100
|
-
filterFileds.push(_key)
|
|
101
|
-
if (_value || isNumber(_value)) {
|
|
102
|
-
rowData.tags[_key] = escapeJsonValue(_value)
|
|
103
|
-
tagsStr.push(escapeRowData(_key) + '=' + escapeRowData(_value))
|
|
104
|
-
}
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
var fieldsStr = []
|
|
108
|
-
each(value.fields, function (_value, _key) {
|
|
109
|
-
if (isArray(_value) && _value.length === 2) {
|
|
110
|
-
var type = _value[0],
|
|
111
|
-
value_path = _value[1]
|
|
112
|
-
var _valueData = findByPath(message, value_path)
|
|
113
|
-
filterFileds.push(_key)
|
|
114
|
-
if (_valueData || isNumber(_valueData)) {
|
|
115
|
-
rowData.fields[_key] = _valueData // 这里不需要转译
|
|
116
|
-
// _valueData =
|
|
117
|
-
// type === 'string'
|
|
118
|
-
// ? '"' +
|
|
119
|
-
// _valueData.replace(/[\\]*"/g, '"').replace(/"/g, '\\"') +
|
|
120
|
-
// '"'
|
|
121
|
-
// : escapeRowData(_valueData)
|
|
122
|
-
fieldsStr.push(escapeRowData(_key) + '=' + escapeRowField(_valueData))
|
|
123
|
-
}
|
|
124
|
-
} else if (isString(_value)) {
|
|
125
|
-
var _valueData = findByPath(message, _value)
|
|
126
|
-
filterFileds.push(_key)
|
|
127
|
-
if (_valueData || isNumber(_valueData)) {
|
|
128
|
-
rowData.fields[_key] = _valueData // 这里不需要转译
|
|
129
|
-
fieldsStr.push(escapeRowData(_key) + '=' + escapeRowField(_valueData))
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
})
|
|
133
|
-
if (message.tags && isObject(message.tags) && !isEmptyObject(message.tags)) {
|
|
134
|
-
// 自定义tag, 存储成field
|
|
135
|
-
const _tagKeys = []
|
|
136
|
-
each(message.tags, function (_value, _key) {
|
|
137
|
-
// 如果和之前tag重名,则舍弃
|
|
138
|
-
if (filterFileds.indexOf(_key) > -1) return
|
|
139
|
-
filterFileds.push(_key)
|
|
140
|
-
if (_value || isNumber(_value)) {
|
|
141
|
-
_tagKeys.push(_key)
|
|
142
|
-
rowData.fields[_key] = _value // 这里不需要转译
|
|
143
|
-
fieldsStr.push(escapeRowData(_key) + '=' + escapeRowField(_value))
|
|
144
|
-
}
|
|
145
|
-
})
|
|
146
|
-
if (_tagKeys.length) {
|
|
147
|
-
rowData.fields[CUSTOM_KEYS] = escapeRowField(_tagKeys)
|
|
148
|
-
fieldsStr.push(escapeRowData(CUSTOM_KEYS) + '=' + escapeRowField(_tagKeys))
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
if (message.type === RumEventType.LOGGER) {
|
|
152
|
-
// 这里处理日志类型数据自定义字段
|
|
153
|
-
each(message, function (value, key) {
|
|
154
|
-
if (
|
|
155
|
-
filterFileds.indexOf(key) === -1 &&
|
|
156
|
-
(isNumber(value) || isString(value) || isBoolean(value))
|
|
157
|
-
) {
|
|
158
|
-
rowData.fields[key] = value // 这里不需要转译
|
|
159
|
-
fieldsStr.push(escapeRowData(key) + '=' + escapeRowField(value))
|
|
160
|
-
}
|
|
161
|
-
})
|
|
162
|
-
}
|
|
163
|
-
if (tagsStr.length) {
|
|
164
|
-
rowStr += tagsStr.join(',')
|
|
165
|
-
}
|
|
166
|
-
if (fieldsStr.length) {
|
|
167
|
-
rowStr += ' '
|
|
168
|
-
rowStr += fieldsStr.join(',')
|
|
169
|
-
hasFileds = true
|
|
170
|
-
}
|
|
171
|
-
rowStr = rowStr + ' ' + message.date
|
|
172
|
-
rowData.time = toServerDuration(message.date) // 这里不需要转译
|
|
173
|
-
}
|
|
174
|
-
})
|
|
175
|
-
return {
|
|
176
|
-
rowStr: hasFileds ? rowStr : '',
|
|
177
|
-
rowData: hasFileds ? rowData : undefined
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
var batch = function(
|
|
181
|
-
request,
|
|
182
|
-
maxSize,
|
|
183
|
-
bytesLimit,
|
|
184
|
-
maxMessageSize,
|
|
185
|
-
flushTimeout,
|
|
186
|
-
isLineProtocolToJson,
|
|
187
|
-
beforeUnloadCallback
|
|
188
|
-
) {
|
|
189
|
-
|
|
190
|
-
this.request = request
|
|
191
|
-
this.maxSize = maxSize
|
|
192
|
-
this.bytesLimit = bytesLimit
|
|
193
|
-
this.maxMessageSize = maxMessageSize
|
|
194
|
-
this.flushTimeout = flushTimeout
|
|
195
|
-
this.isLineProtocolToJson = isLineProtocolToJson
|
|
196
|
-
this.beforeUnloadCallback = beforeUnloadCallback
|
|
197
|
-
|
|
198
|
-
this.pushOnlyBuffer = []
|
|
199
|
-
this.upsertBuffer = {}
|
|
200
|
-
this.bufferBytesSize = 0
|
|
201
|
-
this.bufferMessageCount = 0
|
|
202
|
-
|
|
203
|
-
this.flushOnVisibilityHidden()
|
|
204
|
-
this.flushPeriodically()
|
|
205
|
-
}
|
|
206
|
-
batch.prototype = {
|
|
207
|
-
|
|
208
|
-
add: function (message) {
|
|
209
|
-
|
|
210
|
-
this.addOrUpdate(message)
|
|
211
|
-
},
|
|
212
|
-
|
|
213
|
-
upsert: function (message, key) {
|
|
214
|
-
|
|
215
|
-
this.addOrUpdate(message, key)
|
|
216
|
-
},
|
|
217
|
-
|
|
218
|
-
flush: function () {
|
|
219
|
-
|
|
220
|
-
if (this.bufferMessageCount !== 0) {
|
|
221
|
-
var messages = this.pushOnlyBuffer.concat(values(this.upsertBuffer))
|
|
222
|
-
if (messages.length === 0) return
|
|
223
|
-
if (this.isLineProtocolToJson) {
|
|
224
|
-
this.request.send(map(messages, function(rowdataStr) {
|
|
225
|
-
return JSON.parse(rowdataStr)
|
|
226
|
-
}), this.bufferBytesSize)
|
|
227
|
-
} else {
|
|
228
|
-
|
|
229
|
-
this.request.send(messages.join('\n'), this.bufferBytesSize)
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
this.pushOnlyBuffer = []
|
|
233
|
-
this.upsertBuffer = {}
|
|
234
|
-
this.bufferBytesSize = 0
|
|
235
|
-
this.bufferMessageCount = 0
|
|
236
|
-
}
|
|
237
|
-
},
|
|
238
|
-
|
|
239
|
-
processSendData: function (message) {
|
|
240
|
-
if (this.isLineProtocolToJson) {
|
|
241
|
-
return JSON.stringify(processedMessageByDataMap(message).rowData)
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
return processedMessageByDataMap(message).rowStr
|
|
245
|
-
},
|
|
246
|
-
sizeInBytes: function (candidate) {
|
|
247
|
-
// Accurate byte size computations can degrade performances when there is a lot of events to process
|
|
248
|
-
if (!HAS_MULTI_BYTES_CHARACTERS.test(candidate)) {
|
|
249
|
-
return candidate.length
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
if (window.TextEncoder !== undefined) {
|
|
253
|
-
return new TextEncoder().encode(candidate).length
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
return new Blob([candidate]).size
|
|
257
|
-
},
|
|
258
|
-
|
|
259
|
-
addOrUpdate: function (message, key) {
|
|
260
|
-
var process = this.process(message)
|
|
261
|
-
if (!process.processedMessage || process.processedMessage === '') return
|
|
262
|
-
if (process.messageBytesSize >= this.maxMessageSize) {
|
|
263
|
-
console.warn(
|
|
264
|
-
'Discarded a message whose size was bigger than the maximum allowed size' +
|
|
265
|
-
this.maxMessageSize +
|
|
266
|
-
'KB.'
|
|
267
|
-
)
|
|
268
|
-
return
|
|
269
|
-
}
|
|
270
|
-
if (this.hasMessageFor(key)) {
|
|
271
|
-
this.remove(key)
|
|
272
|
-
}
|
|
273
|
-
if (this.willReachedBytesLimitWith(process.messageBytesSize)) {
|
|
274
|
-
this.flush()
|
|
275
|
-
}
|
|
276
|
-
this.push(process.processedMessage, process.messageBytesSize, key)
|
|
277
|
-
if (this.isFull()) {
|
|
278
|
-
this.flush()
|
|
279
|
-
}
|
|
280
|
-
},
|
|
281
|
-
process: function (message) {
|
|
282
|
-
var processedMessage = ''
|
|
283
|
-
|
|
284
|
-
var processedMessage = this.processSendData(message)
|
|
285
|
-
var messageBytesSize = this.sizeInBytes(processedMessage)
|
|
286
|
-
return {
|
|
287
|
-
processedMessage: processedMessage,
|
|
288
|
-
messageBytesSize: messageBytesSize
|
|
289
|
-
}
|
|
290
|
-
},
|
|
291
|
-
|
|
292
|
-
push: function (processedMessage, messageBytesSize, key) {
|
|
293
|
-
if (this.bufferMessageCount > 0) {
|
|
294
|
-
// \n separator at serialization
|
|
295
|
-
this.bufferBytesSize += 1
|
|
296
|
-
}
|
|
297
|
-
if (key !== undefined) {
|
|
298
|
-
this.upsertBuffer[key] = processedMessage
|
|
299
|
-
} else {
|
|
300
|
-
this.pushOnlyBuffer.push(processedMessage)
|
|
301
|
-
}
|
|
302
|
-
this.bufferBytesSize += messageBytesSize
|
|
303
|
-
this.bufferMessageCount += 1
|
|
304
|
-
},
|
|
305
|
-
|
|
306
|
-
remove: function (key) {
|
|
307
|
-
var removedMessage = this.upsertBuffer[key]
|
|
308
|
-
delete this.upsertBuffer[key]
|
|
309
|
-
var messageBytesSize = this.sizeInBytes(removedMessage)
|
|
310
|
-
this.bufferBytesSize -= messageBytesSize
|
|
311
|
-
this.bufferMessageCount -= 1
|
|
312
|
-
if (this.bufferMessageCount > 0) {
|
|
313
|
-
this.bufferBytesSize -= 1
|
|
314
|
-
}
|
|
315
|
-
},
|
|
316
|
-
|
|
317
|
-
hasMessageFor: function (key) {
|
|
318
|
-
return key !== undefined && this.upsertBuffer[key] !== undefined
|
|
319
|
-
},
|
|
320
|
-
|
|
321
|
-
willReachedBytesLimitWith: function (messageBytesSize) {
|
|
322
|
-
// byte of the separator at the end of the message
|
|
323
|
-
return this.bufferBytesSize + messageBytesSize + 1 >= this.bytesLimit
|
|
324
|
-
},
|
|
325
|
-
|
|
326
|
-
isFull: function () {
|
|
327
|
-
return (
|
|
328
|
-
this.bufferMessageCount === this.maxSize ||
|
|
329
|
-
this.bufferBytesSize >= this.bytesLimit
|
|
330
|
-
)
|
|
331
|
-
},
|
|
332
|
-
|
|
333
|
-
flushPeriodically: function () {
|
|
334
|
-
var _this = this
|
|
335
|
-
setTimeout(function () {
|
|
336
|
-
_this.flush()
|
|
337
|
-
_this.flushPeriodically()
|
|
338
|
-
}, _this.flushTimeout)
|
|
339
|
-
},
|
|
340
|
-
|
|
341
|
-
flushOnVisibilityHidden: function () {
|
|
342
|
-
var _this = this
|
|
343
|
-
/**
|
|
344
|
-
* With sendBeacon, requests are guaranteed to be successfully sent during document unload
|
|
345
|
-
*/
|
|
346
|
-
// @ts-ignore this function is not always defined
|
|
347
|
-
if (global.navigator.sendBeacon) {
|
|
348
|
-
/**
|
|
349
|
-
* beforeunload is called before visibilitychange
|
|
350
|
-
* register first to be sure to be called before flush on beforeunload
|
|
351
|
-
* caveat: unload can still be canceled by another listener
|
|
352
|
-
*/
|
|
353
|
-
addEventListener(
|
|
354
|
-
window,
|
|
355
|
-
DOM_EVENT.BEFORE_UNLOAD,
|
|
356
|
-
_this.beforeUnloadCallback
|
|
357
|
-
)
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* Only event that guarantee to fire on mobile devices when the page transitions to background state
|
|
361
|
-
* (e.g. when user switches to a different application, goes to homescreen, etc), or is being unloaded.
|
|
362
|
-
*/
|
|
363
|
-
addEventListener(document, DOM_EVENT.VISIBILITY_CHANGE, function () {
|
|
364
|
-
if (document.visibilityState === 'hidden') {
|
|
365
|
-
_this.flush()
|
|
366
|
-
}
|
|
367
|
-
})
|
|
368
|
-
/**
|
|
369
|
-
* Safari does not support yet to send a request during:
|
|
370
|
-
* - a visibility change during doc unload (cf: https://bugs.webkit.org/show_bug.cgi?id=194897)
|
|
371
|
-
* - a page hide transition (cf: https://bugs.webkit.org/show_bug.cgi?id=188329)
|
|
372
|
-
*/
|
|
373
|
-
addEventListener(window, DOM_EVENT.BEFORE_UNLOAD, function () {
|
|
374
|
-
_this.flush()
|
|
375
|
-
})
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
export var Batch = batch
|
package/src/xhrProxy.js
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { normalizeUrl } from './helper/urlPolyfill'
|
|
2
|
-
import { each, relativeNow, clocksNow, elapsed, extend } from './helper/tools'
|
|
3
|
-
|
|
4
|
-
var xhrProxySingleton
|
|
5
|
-
var beforeSendCallbacks = []
|
|
6
|
-
var onRequestCompleteCallbacks = []
|
|
7
|
-
var originalXhrOpen
|
|
8
|
-
var originalXhrSend
|
|
9
|
-
var originalXhrAbort
|
|
10
|
-
export function startXhrProxy() {
|
|
11
|
-
if (!xhrProxySingleton) {
|
|
12
|
-
proxyXhr()
|
|
13
|
-
xhrProxySingleton = {
|
|
14
|
-
beforeSend: function (callback) {
|
|
15
|
-
beforeSendCallbacks.push(callback)
|
|
16
|
-
},
|
|
17
|
-
onRequestComplete: function (callback) {
|
|
18
|
-
onRequestCompleteCallbacks.push(callback)
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return xhrProxySingleton
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function resetXhrProxy() {
|
|
26
|
-
if (xhrProxySingleton) {
|
|
27
|
-
xhrProxySingleton = undefined
|
|
28
|
-
beforeSendCallbacks.length = 0
|
|
29
|
-
onRequestCompleteCallbacks.length = 0
|
|
30
|
-
XMLHttpRequest.prototype.open = originalXhrOpen
|
|
31
|
-
XMLHttpRequest.prototype.send = originalXhrSend
|
|
32
|
-
XMLHttpRequest.prototype.abort = originalXhrAbort
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function proxyXhr() {
|
|
37
|
-
originalXhrOpen = XMLHttpRequest.prototype.open
|
|
38
|
-
originalXhrSend = XMLHttpRequest.prototype.send
|
|
39
|
-
originalXhrAbort = XMLHttpRequest.prototype.abort
|
|
40
|
-
XMLHttpRequest.prototype.open = function (method, url) {
|
|
41
|
-
// WARN: since this data structure is tied to the instance, it is shared by both logs and rum
|
|
42
|
-
// and can be used by different code versions depending on customer setup
|
|
43
|
-
// so it should stay compatible with older versions
|
|
44
|
-
this._dataflux_xhr = {
|
|
45
|
-
method: method,
|
|
46
|
-
startTime: -1, // computed in send call
|
|
47
|
-
url: normalizeUrl(url)
|
|
48
|
-
}
|
|
49
|
-
return originalXhrOpen.apply(this, arguments)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
XMLHttpRequest.prototype.send = function (body) {
|
|
53
|
-
var _this = this
|
|
54
|
-
if (this._dataflux_xhr) {
|
|
55
|
-
var xhrPendingContext = this._dataflux_xhr
|
|
56
|
-
xhrPendingContext.startTime = relativeNow()
|
|
57
|
-
xhrPendingContext.startClocks = clocksNow()
|
|
58
|
-
xhrPendingContext.isAborted = false
|
|
59
|
-
|
|
60
|
-
var originalOnreadystatechange = this.onreadystatechange
|
|
61
|
-
|
|
62
|
-
this.onreadystatechange = function () {
|
|
63
|
-
if (this.readyState === XMLHttpRequest.DONE) {
|
|
64
|
-
reportXhr()
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (originalOnreadystatechange) {
|
|
68
|
-
originalOnreadystatechange.apply(this, arguments)
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
var hasBeenReported = false
|
|
73
|
-
var reportXhr = function () {
|
|
74
|
-
_this.removeEventListener('loadend', reportXhr)
|
|
75
|
-
if (hasBeenReported) {
|
|
76
|
-
return
|
|
77
|
-
}
|
|
78
|
-
hasBeenReported = true
|
|
79
|
-
var xhrCompleteContext = extend({}, xhrPendingContext, {
|
|
80
|
-
duration: elapsed(
|
|
81
|
-
xhrPendingContext.startClocks.relative,
|
|
82
|
-
relativeNow()
|
|
83
|
-
),
|
|
84
|
-
response: _this.response,
|
|
85
|
-
status: _this.status
|
|
86
|
-
})
|
|
87
|
-
each(onRequestCompleteCallbacks, function (callback) {
|
|
88
|
-
callback(xhrCompleteContext, _this)
|
|
89
|
-
})
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
_this.addEventListener('loadend', reportXhr)
|
|
93
|
-
each(beforeSendCallbacks, function (callback) {
|
|
94
|
-
callback(xhrPendingContext, _this)
|
|
95
|
-
})
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return originalXhrSend.apply(_this, arguments)
|
|
99
|
-
}
|
|
100
|
-
XMLHttpRequest.prototype.abort = function () {
|
|
101
|
-
if (this._dataflux_xhr) {
|
|
102
|
-
this._dataflux_xhr.isAborted = true
|
|
103
|
-
}
|
|
104
|
-
return originalXhrAbort.apply(this, arguments)
|
|
105
|
-
}
|
|
106
|
-
}
|