@cloudcare/browser-core 3.1.1 → 3.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/cjs/browser/htmlDomUtils.js +13 -4
  2. package/cjs/browser/htmlDomUtils.js.map +1 -1
  3. package/cjs/configuration/configuration.js +3 -1
  4. package/cjs/configuration/configuration.js.map +1 -1
  5. package/cjs/dataMap.js +7 -3
  6. package/cjs/dataMap.js.map +1 -1
  7. package/cjs/helper/enums.js +2 -1
  8. package/cjs/helper/enums.js.map +1 -1
  9. package/cjs/helper/errorTools.js +2 -1
  10. package/cjs/helper/errorTools.js.map +1 -1
  11. package/cjs/helper/monitor.js +1 -0
  12. package/cjs/helper/monitor.js.map +1 -1
  13. package/cjs/helper/serialisation/contextManager.js +20 -5
  14. package/cjs/helper/serialisation/contextManager.js.map +1 -1
  15. package/cjs/helper/serialisation/rowData.js +7 -5
  16. package/cjs/helper/serialisation/rowData.js.map +1 -1
  17. package/cjs/helper/serialisation/storedContextManager.js +47 -0
  18. package/cjs/helper/serialisation/storedContextManager.js.map +1 -0
  19. package/cjs/helper/tools.js +19 -3
  20. package/cjs/helper/tools.js.map +1 -1
  21. package/cjs/index.js +11 -0
  22. package/cjs/index.js.map +1 -1
  23. package/cjs/transport/batch.js +23 -10
  24. package/cjs/transport/batch.js.map +1 -1
  25. package/cjs/transport/httpRequest.js +31 -12
  26. package/cjs/transport/httpRequest.js.map +1 -1
  27. package/cjs/transport/startBatchWithReplica.js +2 -2
  28. package/cjs/transport/startBatchWithReplica.js.map +1 -1
  29. package/esm/browser/htmlDomUtils.js +11 -3
  30. package/esm/browser/htmlDomUtils.js.map +1 -1
  31. package/esm/configuration/configuration.js +3 -1
  32. package/esm/configuration/configuration.js.map +1 -1
  33. package/esm/dataMap.js +7 -3
  34. package/esm/dataMap.js.map +1 -1
  35. package/esm/helper/enums.js +2 -1
  36. package/esm/helper/enums.js.map +1 -1
  37. package/esm/helper/errorTools.js +1 -0
  38. package/esm/helper/errorTools.js.map +1 -1
  39. package/esm/helper/monitor.js +1 -0
  40. package/esm/helper/monitor.js.map +1 -1
  41. package/esm/helper/serialisation/contextManager.js +21 -6
  42. package/esm/helper/serialisation/contextManager.js.map +1 -1
  43. package/esm/helper/serialisation/rowData.js +8 -6
  44. package/esm/helper/serialisation/rowData.js.map +1 -1
  45. package/esm/helper/serialisation/storedContextManager.js +39 -0
  46. package/esm/helper/serialisation/storedContextManager.js.map +1 -0
  47. package/esm/helper/tools.js +18 -3
  48. package/esm/helper/tools.js.map +1 -1
  49. package/esm/index.js +1 -0
  50. package/esm/index.js.map +1 -1
  51. package/esm/transport/batch.js +24 -11
  52. package/esm/transport/batch.js.map +1 -1
  53. package/esm/transport/httpRequest.js +31 -12
  54. package/esm/transport/httpRequest.js.map +1 -1
  55. package/esm/transport/startBatchWithReplica.js +2 -2
  56. package/esm/transport/startBatchWithReplica.js.map +1 -1
  57. package/package.json +2 -2
  58. package/src/browser/htmlDomUtils.js +11 -4
  59. package/src/configuration/configuration.js +3 -1
  60. package/src/dataMap.js +9 -3
  61. package/src/helper/enums.js +2 -1
  62. package/src/helper/errorTools.js +1 -0
  63. package/src/helper/monitor.js +1 -0
  64. package/src/helper/serialisation/contextManager.js +21 -6
  65. package/src/helper/serialisation/rowData.js +9 -6
  66. package/src/helper/serialisation/storedContextManager.js +56 -0
  67. package/src/helper/tools.js +19 -4
  68. package/src/index.js +1 -0
  69. package/src/transport/batch.js +28 -12
  70. package/src/transport/httpRequest.js +46 -11
  71. package/src/transport/startBatchWithReplica.js +3 -1
@@ -0,0 +1,56 @@
1
+ import { computeBytesCount } from '../byteUtils'
2
+ import { DOM_EVENT } from '../enums'
3
+ import { map } from '../tools'
4
+ import { addEventListener } from '../../browser/addEventListener'
5
+ import { createContextManager } from './contextManager'
6
+ var CONTEXT_STORE_KEY_PREFIX = '_gc_s'
7
+
8
+ var storageListeners = []
9
+
10
+ export function createStoredContextManager(
11
+ productKey,
12
+ customerDataType,
13
+ computeBytesCountImpl
14
+ ) {
15
+ if (computeBytesCountImpl === undefined) {
16
+ computeBytesCountImpl = computeBytesCount
17
+ }
18
+ var storageKey = buildStorageKey(productKey, customerDataType)
19
+ var contextManager = createContextManager(
20
+ customerDataType,
21
+ computeBytesCountImpl
22
+ )
23
+
24
+ synchronizeWithStorage()
25
+ storageListeners.push(
26
+ addEventListener(window, DOM_EVENT.STORAGE, function (params) {
27
+ if (storageKey === params.key) {
28
+ synchronizeWithStorage()
29
+ }
30
+ })
31
+ )
32
+ contextManager.changeObservable.subscribe(dumpToStorage)
33
+ function synchronizeWithStorage() {
34
+ var rawContext = localStorage.getItem(storageKey)
35
+ var context = rawContext !== null ? JSON.parse(rawContext) : {}
36
+ contextManager.setContext(context)
37
+ }
38
+
39
+ function dumpToStorage() {
40
+ localStorage.setItem(
41
+ storageKey,
42
+ JSON.stringify(contextManager.getContext())
43
+ )
44
+ }
45
+ return contextManager
46
+ }
47
+
48
+ export function buildStorageKey(productKey, customerDataType) {
49
+ return CONTEXT_STORE_KEY_PREFIX + '_' + productKey + '_' + customerDataType
50
+ }
51
+
52
+ export function removeStorageListeners() {
53
+ map(storageListeners, function (listener) {
54
+ listener.stop()
55
+ })
56
+ }
@@ -228,6 +228,7 @@ export var matchList = function (list, value, useStartsWith) {
228
228
  } catch (e) {
229
229
  display.error(e)
230
230
  }
231
+ return false
231
232
  })
232
233
  }
233
234
  // https://github.com/jquery/jquery/blob/a684e6ba836f7c553968d7d026ed7941e1a612d8/src/selector/escapeSelector.js
@@ -1594,14 +1595,28 @@ export function getLocationOrigin() {
1594
1595
  return getLinkElementOrigin(window.location)
1595
1596
  }
1596
1597
 
1598
+ var browserIsIE
1597
1599
  export function isIE() {
1598
- return Boolean(document.documentMode)
1600
+ if (browserIsIE === undefined) {
1601
+ browserIsIE = Boolean(document.documentMode)
1602
+ }
1603
+ return browserIsIE
1599
1604
  }
1600
-
1605
+ var browserIsChromium
1601
1606
  export function isChromium() {
1602
- return !!window.chrome || /HeadlessChrome/.test(window.navigator.userAgent)
1607
+ if (browserIsChromium === undefined) {
1608
+ browserIsChromium =
1609
+ !!window.chrome || /HeadlessChrome/.test(window.navigator.userAgent)
1610
+ }
1611
+ return browserIsChromium
1612
+ }
1613
+ var browserIsSafari
1614
+ export function isSafari() {
1615
+ if (browserIsSafari === undefined) {
1616
+ browserIsSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
1617
+ }
1618
+ return browserIsSafari
1603
1619
  }
1604
-
1605
1620
  /**
1606
1621
  * IE fallback
1607
1622
  * https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/origin
package/src/index.js CHANGED
@@ -47,6 +47,7 @@ export * from './helper/serialisation/contextManager'
47
47
  export * from './helper/serialisation/heavyCustomerDataWarning'
48
48
  export * from './helper/serialisation/jsonStringify'
49
49
  export * from './helper/serialisation/rowData'
50
+ export * from './helper/serialisation/storedContextManager'
50
51
  export * from './user'
51
52
 
52
53
  export * from './telemetry/telemetry'
@@ -7,8 +7,6 @@ import {
7
7
  isArray,
8
8
  extend,
9
9
  isString,
10
- toServerDuration,
11
- isBoolean,
12
10
  isEmptyObject,
13
11
  isObject
14
12
  } from '../helper/tools'
@@ -21,6 +19,7 @@ import { commonTags, dataMap, commonFields } from '../dataMap'
21
19
  import { RumEventType } from '../helper/enums'
22
20
  import { computeBytesCount } from '../helper/byteUtils'
23
21
  import { isPageExitReason } from '../browser/pageExitObservable'
22
+ import { jsonStringify } from '../helper/serialisation/jsonStringify'
24
23
  // https://en.wikipedia.org/wiki/UTF-8
25
24
  // eslint-disable-next-line no-control-regex
26
25
  var HAS_MULTI_BYTES_CHARACTERS = /[^\u0000-\u007F]/
@@ -46,7 +45,7 @@ export var processedMessageByDataMap = function (message) {
46
45
  var _value = findByPath(message, value_path)
47
46
  filterFileds.push(_key)
48
47
  if (_value || isNumber(_value)) {
49
- rowData.tags[_key] = escapeJsonValue(_value)
48
+ rowData.tags[_key] = escapeJsonValue(_value, true)
50
49
  tagsStr.push(escapeRowData(_key) + '=' + escapeRowData(_value))
51
50
  }
52
51
  })
@@ -59,7 +58,7 @@ export var processedMessageByDataMap = function (message) {
59
58
  var _valueData = findByPath(message, value_path)
60
59
  filterFileds.push(_key)
61
60
  if (_valueData !== undefined && _valueData !== null) {
62
- rowData.fields[_key] = _valueData // 这里不需要转译
61
+ rowData.fields[_key] = escapeJsonValue(_valueData) // 这里不需要转译
63
62
  fieldsStr.push(
64
63
  escapeRowData(_key) + '=' + escapeRowField(_valueData)
65
64
  )
@@ -68,7 +67,7 @@ export var processedMessageByDataMap = function (message) {
68
67
  var _valueData = findByPath(message, _value)
69
68
  filterFileds.push(_key)
70
69
  if (_valueData !== undefined && _valueData !== null) {
71
- rowData.fields[_key] = _valueData // 这里不需要转译
70
+ rowData.fields[_key] = escapeJsonValue(_valueData) // 这里不需要转译
72
71
  fieldsStr.push(
73
72
  escapeRowData(_key) + '=' + escapeRowField(_valueData)
74
73
  )
@@ -88,12 +87,12 @@ export var processedMessageByDataMap = function (message) {
88
87
  filterFileds.push(_key)
89
88
  if (_value !== undefined && _value !== null) {
90
89
  _tagKeys.push(_key)
91
- rowData.fields[_key] = _value // 这里不需要转译
90
+ rowData.fields[_key] = escapeJsonValue(_value) // 这里不需要转译
92
91
  fieldsStr.push(escapeRowData(_key) + '=' + escapeRowField(_value))
93
92
  }
94
93
  })
95
94
  if (_tagKeys.length) {
96
- rowData.fields[CUSTOM_KEYS] = escapeRowField(_tagKeys)
95
+ rowData.fields[CUSTOM_KEYS] = escapeJsonValue(_tagKeys)
97
96
  fieldsStr.push(
98
97
  escapeRowData(CUSTOM_KEYS) + '=' + escapeRowField(_tagKeys)
99
98
  )
@@ -107,7 +106,7 @@ export var processedMessageByDataMap = function (message) {
107
106
  value !== undefined &&
108
107
  value !== null
109
108
  ) {
110
- rowData.fields[key] = value // 这里不需要转译
109
+ rowData.fields[key] = escapeJsonValue(value) // 这里不需要转译
111
110
  fieldsStr.push(escapeRowData(key) + '=' + escapeRowField(value))
112
111
  }
113
112
  })
@@ -121,7 +120,7 @@ export var processedMessageByDataMap = function (message) {
121
120
  hasFileds = true
122
121
  }
123
122
  rowStr = rowStr + ' ' + message.date
124
- rowData.time = toServerDuration(message.date) // 这里不需要转译
123
+ rowData.time = message.date // 这里不需要转译
125
124
  }
126
125
  })
127
126
  return {
@@ -129,12 +128,18 @@ export var processedMessageByDataMap = function (message) {
129
128
  rowData: hasFileds ? rowData : undefined
130
129
  }
131
130
  }
132
- var batch = function (request, flushController, messageBytesLimit) {
131
+ var batch = function (
132
+ request,
133
+ flushController,
134
+ messageBytesLimit,
135
+ sendContentTypeByJson
136
+ ) {
133
137
  this.pushOnlyBuffer = []
134
138
  this.upsertBuffer = {}
135
139
  this.request = request
136
140
  this.flushController = flushController
137
141
  this.messageBytesLimit = messageBytesLimit
142
+ this.sendContentTypeByJson = sendContentTypeByJson
138
143
  var _this = this
139
144
  this.flushController.flushObservable.subscribe(function (event) {
140
145
  _this.flush(event)
@@ -151,8 +156,14 @@ batch.prototype.flush = function (event) {
151
156
  this.pushOnlyBuffer = []
152
157
  this.upsertBuffer = {}
153
158
  if (messages.length > 0) {
159
+ var payloadData = ''
160
+ if (this.sendContentTypeByJson) {
161
+ payloadData = '[' + messages.join(',') + ']'
162
+ } else {
163
+ payloadData = messages.join('\n')
164
+ }
154
165
  var payload = {
155
- data: messages.join('\n'),
166
+ data: payloadData,
156
167
  bytesCount: event.bytesCount,
157
168
  flushReason: event.reason
158
169
  }
@@ -182,7 +193,12 @@ batch.prototype.addOrUpdate = function (message, key) {
182
193
  this.push(processedMessage, messageBytesCount, key)
183
194
  }
184
195
  batch.prototype.process = function (message) {
185
- var processedMessage = processedMessageByDataMap(message).rowStr
196
+ var processedMessage = ''
197
+ if (this.sendContentTypeByJson) {
198
+ processedMessage = jsonStringify(processedMessageByDataMap(message).rowData)
199
+ } else {
200
+ processedMessage = processedMessageByDataMap(message).rowStr
201
+ }
186
202
  var messageBytesCount = computeBytesCount(processedMessage)
187
203
  return {
188
204
  processedMessage: processedMessage,
@@ -13,10 +13,24 @@ function addBatchPrecision(url) {
13
13
  if (!url) return url
14
14
  return url + (url.indexOf('?') === -1 ? '?' : '&') + 'precision=ms'
15
15
  }
16
- export function createHttpRequest(endpointUrl, bytesLimit, reportError) {
16
+ export function createHttpRequest(
17
+ endpointUrl,
18
+ bytesLimit,
19
+ sendContentTypeByJson,
20
+ reportError
21
+ ) {
22
+ var contentType = sendContentTypeByJson
23
+ ? 'application/json; charset=UTF-8'
24
+ : undefined
17
25
  var retryState = newRetryState()
18
26
  var sendStrategyForRetry = function (payload, onResponse) {
19
- return fetchKeepAliveStrategy(endpointUrl, bytesLimit, payload, onResponse)
27
+ return fetchKeepAliveStrategy(
28
+ endpointUrl,
29
+ bytesLimit,
30
+ contentType,
31
+ payload,
32
+ onResponse
33
+ )
20
34
  }
21
35
 
22
36
  return {
@@ -34,19 +48,28 @@ export function createHttpRequest(endpointUrl, bytesLimit, reportError) {
34
48
  * keep using sendBeaconStrategy on exit
35
49
  */
36
50
  sendOnExit: function (payload) {
37
- sendBeaconStrategy(endpointUrl, bytesLimit, payload)
51
+ sendBeaconStrategy(endpointUrl, bytesLimit, contentType, payload)
38
52
  }
39
53
  }
40
54
  }
41
55
 
42
- function sendBeaconStrategy(endpointUrl, bytesLimit, payload) {
56
+ function sendBeaconStrategy(endpointUrl, bytesLimit, contentType, payload) {
43
57
  var data = payload.data
44
58
  var bytesCount = payload.bytesCount
45
59
  var url = addBatchPrecision(endpointUrl)
46
60
  var canUseBeacon = !!navigator.sendBeacon && bytesCount < bytesLimit
47
61
  if (canUseBeacon) {
48
62
  try {
49
- var isQueued = navigator.sendBeacon(url, data)
63
+ var beaconData
64
+ if (contentType) {
65
+ beaconData = new Blob([data], {
66
+ type: contentType
67
+ })
68
+ } else {
69
+ beaconData = data
70
+ }
71
+
72
+ var isQueued = navigator.sendBeacon(url, beaconData)
50
73
 
51
74
  if (isQueued) {
52
75
  return
@@ -55,12 +78,13 @@ function sendBeaconStrategy(endpointUrl, bytesLimit, payload) {
55
78
  // reportBeaconError(e)
56
79
  }
57
80
  }
58
- sendXHR(url, data)
81
+ sendXHR(url, contentType, data)
59
82
  }
60
83
 
61
84
  export function fetchKeepAliveStrategy(
62
85
  endpointUrl,
63
86
  bytesLimit,
87
+ contentType,
64
88
  payload,
65
89
  onResponse
66
90
  ) {
@@ -69,12 +93,18 @@ export function fetchKeepAliveStrategy(
69
93
  var url = addBatchPrecision(endpointUrl)
70
94
  var canUseKeepAlive = isKeepAliveSupported() && bytesCount < bytesLimit
71
95
  if (canUseKeepAlive) {
72
- fetch(url, {
96
+ var fetchOption = {
73
97
  method: 'POST',
74
98
  body: data,
75
99
  keepalive: true,
76
100
  mode: 'cors'
77
- }).then(
101
+ }
102
+ if (contentType) {
103
+ fetchOption.headers = {
104
+ 'Content-Type': contentType
105
+ }
106
+ }
107
+ fetch(url, fetchOption).then(
78
108
  monitor(function (response) {
79
109
  if (typeof onResponse === 'function') {
80
110
  onResponse({ status: response.status, type: response.type })
@@ -82,11 +112,11 @@ export function fetchKeepAliveStrategy(
82
112
  }),
83
113
  monitor(function () {
84
114
  // failed to queue the request
85
- sendXHR(url, data, onResponse)
115
+ sendXHR(url, contentType, data, onResponse)
86
116
  })
87
117
  )
88
118
  } else {
89
- sendXHR(url, data, onResponse)
119
+ sendXHR(url, contentType, data, onResponse)
90
120
  }
91
121
  }
92
122
 
@@ -99,9 +129,14 @@ function isKeepAliveSupported() {
99
129
  }
100
130
  }
101
131
 
102
- function sendXHR(url, data, onResponse) {
132
+ function sendXHR(url, contentType, data, onResponse) {
103
133
  const request = new XMLHttpRequest()
104
134
  request.open('POST', url, true)
135
+ if (contentType) {
136
+ //application/json; charset=UTF-8
137
+ request.setRequestHeader('Content-Type', contentType)
138
+ }
139
+
105
140
  addEventListener(
106
141
  request,
107
142
  'loadend',
@@ -15,6 +15,7 @@ export function startBatchWithReplica(
15
15
  createHttpRequest(
16
16
  endpointUrl,
17
17
  configuration.batchBytesLimit,
18
+ configuration.sendContentTypeByJson,
18
19
  reportError
19
20
  ),
20
21
  createFlushController({
@@ -24,7 +25,8 @@ export function startBatchWithReplica(
24
25
  pageExitObservable: pageExitObservable,
25
26
  sessionExpireObservable: sessionExpireObservable
26
27
  }),
27
- configuration.messageBytesLimit
28
+ configuration.messageBytesLimit,
29
+ configuration.sendContentTypeByJson
28
30
  )
29
31
  }
30
32