@cloudcare/browser-core 1.0.25 → 1.1.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.
@@ -51,6 +51,9 @@ var DEFAULT_CONFIGURATION = {
51
51
  // 新增
52
52
  isServiceSampling: false,
53
53
  // 是否不抛弃采样是数据, 采用在服务端菜样的方式
54
+ isJsBirdge: false,
55
+ // 是否需要对webview 发送数据,需要装我们对应ios sdk
56
+ isLineProtocolToJson: false,
54
57
  beforeSend: function beforeSend(event) {},
55
58
  isServerError: function isServerError(request) {
56
59
  return false;
@@ -102,6 +105,14 @@ function commonInit(userConfiguration, buildEnv) {
102
105
  cookieOptions: buildCookieOptions(userConfiguration)
103
106
  };
104
107
 
108
+ if ('isJsBirdge' in userConfiguration) {
109
+ transportConfiguration.isJsBirdge = userConfiguration.isJsBirdge;
110
+ }
111
+
112
+ if ('isLineProtocolToJson' in userConfiguration) {
113
+ transportConfiguration.isLineProtocolToJson = userConfiguration.isLineProtocolToJson;
114
+ }
115
+
105
116
  if ('allowedDDTracingOrigins' in userConfiguration) {
106
117
  transportConfiguration.allowedTracingOrigins = userConfiguration.allowedDDTracingOrigins;
107
118
  }
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.userAgent = exports.jsBirdge = exports.isIos = exports.isAndroid = void 0;
6
+ exports.userAgent = exports.isIos = exports.isAndroid = exports.JsBirdge = void 0;
7
7
  var userAgent = navigator.userAgent.toLowerCase();
8
8
  exports.userAgent = userAgent;
9
9
 
@@ -29,6 +29,7 @@ var JsBirdge = function JsBirdge() {
29
29
  } catch (err) {}
30
30
  };
31
31
 
32
+ exports.JsBirdge = JsBirdge;
32
33
  JsBirdge.prototype = {
33
34
  initBridge: function initBridge() {
34
35
  var _this = this;
@@ -116,5 +117,5 @@ JsBirdge.prototype = {
116
117
  }
117
118
  }
118
119
  };
119
- var jsBirdge = new JsBirdge();
120
- exports.jsBirdge = jsBirdge;
120
+ var JsBirdge = JsBirdge;
121
+ exports.JsBirdge = JsBirdge;
@@ -8,7 +8,9 @@ exports.UUID = UUID;
8
8
  exports.addEvent = exports._URL = void 0;
9
9
  exports.addEventListener = addEventListener;
10
10
  exports.addEventListeners = addEventListeners;
11
- exports.base64Encode = exports.autoExeQueue = exports.ajax = exports.addSinglePageEvent = exports.addHashEvent = void 0;
11
+ exports.ajax = exports.addSinglePageEvent = exports.addHashEvent = void 0;
12
+ exports.assign = assign;
13
+ exports.base64Encode = exports.autoExeQueue = void 0;
12
14
  exports.clocksNow = clocksNow;
13
15
  exports.clocksOrigin = clocksOrigin;
14
16
  exports.coverExtend = exports.cookie = void 0;
@@ -19,6 +21,7 @@ exports.deepSnakeCase = deepSnakeCase;
19
21
  exports.each = void 0;
20
22
  exports.elapsed = elapsed;
21
23
  exports.encodeDates = void 0;
24
+ exports.escapeJsonValue = escapeJsonValue;
22
25
  exports.escapeRowData = escapeRowData;
23
26
  exports.filter = exports.extend2Lev = exports.extend = void 0;
24
27
  exports.find = find;
@@ -57,7 +60,10 @@ exports.replaceNumberCharByPath = replaceNumberCharByPath;
57
60
  exports.round = round;
58
61
  exports.safeJSONParse = void 0;
59
62
  exports.safeTruncate = safeTruncate;
60
- exports.throttle = exports.strip_sa_properties = exports.strip_empty_properties = exports.stringSplice = exports.strToUnicode = exports.sessionStorage = exports.searchObjString = exports.searchObjDate = exports.searchConfigData = void 0;
63
+ exports.sessionStorage = exports.searchObjString = exports.searchObjDate = exports.searchConfigData = void 0;
64
+ exports.shallowClone = shallowClone;
65
+ exports.strip_empty_properties = exports.stringSplice = exports.strToUnicode = void 0;
66
+ exports.throttle = exports.strip_sa_properties = void 0;
61
67
  exports.timeStampNow = timeStampNow;
62
68
  exports.toArray = exports.tirm = void 0;
63
69
  exports.toServerDuration = toServerDuration;
@@ -104,6 +110,21 @@ var each = function each(obj, iterator, context) {
104
110
 
105
111
  exports.each = each;
106
112
 
113
+ function assign(target) {
114
+ each(slice.call(arguments, 1), function (source) {
115
+ for (var prop in source) {
116
+ if (Object.prototype.hasOwnProperty.call(source, prop)) {
117
+ target[prop] = source[prop];
118
+ }
119
+ }
120
+ });
121
+ return target;
122
+ }
123
+
124
+ function shallowClone(object) {
125
+ return assign({}, object);
126
+ }
127
+
107
128
  var extend = function extend(obj) {
108
129
  each(slice.call(arguments, 1), function (source) {
109
130
  for (var prop in source) {
@@ -2033,4 +2054,12 @@ function escapeRowData(str) {
2033
2054
  return String(str).replace(reg, function (word) {
2034
2055
  return '\\' + word;
2035
2056
  });
2057
+ }
2058
+
2059
+ function escapeJsonValue(value) {
2060
+ if (isString(value)) {
2061
+ return value;
2062
+ } else {
2063
+ return jsonStringify(value);
2064
+ }
2036
2065
  }
package/cjs/transport.js CHANGED
@@ -11,6 +11,8 @@ var _enums = require("./helper/enums");
11
11
 
12
12
  var _dataMap = require("./dataMap");
13
13
 
14
+ var _init = require("./init");
15
+
14
16
  // https://en.wikipedia.org/wiki/UTF-8
15
17
  var HAS_MULTI_BYTES_CHARACTERS = /[^\u0000-\u007F]/;
16
18
  var CUSTOM_KEYS = 'custom_keys';
@@ -20,17 +22,37 @@ function addBatchPrecision(url) {
20
22
  return url + (url.indexOf('?') === -1 ? '?' : '&') + 'precision=ms';
21
23
  }
22
24
 
23
- var httpRequest = function httpRequest(endpointUrl, bytesLimit) {
25
+ var global = (0, _init.getGlobalObject)();
26
+
27
+ var httpRequest = function httpRequest(endpointUrl, bytesLimit, isLineProtocolToJson) {
24
28
  this.endpointUrl = endpointUrl;
25
29
  this.bytesLimit = bytesLimit;
30
+ this.isLineProtocolToJson = isLineProtocolToJson;
31
+ var isRealNavigator = Object.prototype.toString.call(global && global.navigator) === '[object Navigator]';
32
+ var hasSendBeacon = isRealNavigator && typeof global.navigator.sendBeacon === 'function';
33
+
34
+ if (hasSendBeacon) {
35
+ this.sendBeacon = global.navigator.sendBeacon.bind(global.navigator);
36
+ } else {
37
+ this.sendBeacon = undefined;
38
+ }
26
39
  };
27
40
 
28
41
  httpRequest.prototype = {
29
42
  send: function send(data, size) {
30
43
  var url = addBatchPrecision(this.endpointUrl);
31
44
 
32
- if (navigator.sendBeacon && size < this.bytesLimit) {
33
- var isQueued = navigator.sendBeacon(url, data);
45
+ if (this.sendBeacon && size < this.bytesLimit && !this.isLineProtocolToJson) {
46
+ var isQueued = this.sendBeacon(url, data);
47
+
48
+ if (isQueued) {
49
+ return;
50
+ }
51
+ } else if (this.sendBeacon && size < this.bytesLimit && this.isLineProtocolToJson) {
52
+ var blob = new Blob([JSON.stringify(data)], {
53
+ type: 'application/json'
54
+ });
55
+ var isQueued = this.sendBeacon(url, blob);
34
56
 
35
57
  if (isQueued) {
36
58
  return;
@@ -40,7 +62,14 @@ httpRequest.prototype = {
40
62
  var request = new XMLHttpRequest();
41
63
  request.open('POST', url, true);
42
64
  request.withCredentials = true;
43
- request.send(data);
65
+
66
+ if (this.isLineProtocolToJson) {
67
+ request.setRequestHeader('Content-type', 'application/json');
68
+ request.send(JSON.stringify(data));
69
+ } else {
70
+ request.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');
71
+ request.send(data);
72
+ }
44
73
  }
45
74
  };
46
75
  var HttpRequest = httpRequest;
@@ -71,33 +100,10 @@ var processedMessageByDataMap = function processedMessageByDataMap(message) {
71
100
  filterFileds.push(_key);
72
101
 
73
102
  if (_value || (0, _tools.isNumber)(_value)) {
74
- rowData.tags[_key] = _value;
103
+ rowData.tags[_key] = (0, _tools.escapeJsonValue)(_value);
75
104
  tagsStr.push((0, _tools.escapeRowData)(_key) + '=' + (0, _tools.escapeRowData)(_value));
76
105
  }
77
106
  });
78
-
79
- if (message.tags && (0, _tools.isObject)(message.tags) && !(0, _tools.isEmptyObject)(message.tags)) {
80
- // 自定义tag
81
- var _tagKeys = [];
82
- (0, _tools.each)(message.tags, function (_value, _key) {
83
- // 如果和之前tag重名,则舍弃
84
- if (filterFileds.indexOf(_key) > -1) return;
85
- filterFileds.push(_key);
86
-
87
- if (_value || (0, _tools.isNumber)(_value)) {
88
- _tagKeys.push(_key);
89
-
90
- rowData.tags[_key] = _value;
91
- tagsStr.push((0, _tools.escapeRowData)(_key) + '=' + (0, _tools.escapeRowData)(_value));
92
- }
93
- });
94
-
95
- if (_tagKeys.length) {
96
- rowData.tags[CUSTOM_KEYS] = _tagKeys;
97
- tagsStr.push((0, _tools.escapeRowData)(CUSTOM_KEYS) + '=' + (0, _tools.escapeRowData)(_tagKeys));
98
- }
99
- }
100
-
101
107
  var fieldsStr = [];
102
108
  (0, _tools.each)(value.fields, function (_value, _key) {
103
109
  if ((0, _tools.isArray)(_value) && _value.length === 2) {
@@ -128,10 +134,33 @@ var processedMessageByDataMap = function processedMessageByDataMap(message) {
128
134
  }
129
135
  });
130
136
 
137
+ if (message.tags && (0, _tools.isObject)(message.tags) && !(0, _tools.isEmptyObject)(message.tags)) {
138
+ // 自定义tag
139
+ var _tagKeys = [];
140
+ (0, _tools.each)(message.tags, function (_value, _key) {
141
+ // 如果和之前tag重名,则舍弃
142
+ if (filterFileds.indexOf(_key) > -1) return;
143
+ filterFileds.push(_key);
144
+
145
+ if (_value || (0, _tools.isNumber)(_value)) {
146
+ _tagKeys.push(_key);
147
+
148
+ rowData.tags[_key] = (0, _tools.escapeJsonValue)(_value);
149
+ tagsStr.push((0, _tools.escapeRowData)(_key) + '=' + (0, _tools.escapeRowData)(_value));
150
+ }
151
+ });
152
+
153
+ if (_tagKeys.length) {
154
+ rowData.tags[CUSTOM_KEYS] = (0, _tools.escapeJsonValue)(_tagKeys);
155
+ tagsStr.push((0, _tools.escapeRowData)(CUSTOM_KEYS) + '=' + (0, _tools.escapeRowData)(_tagKeys));
156
+ }
157
+ }
158
+
131
159
  if (message.type === _enums.RumEventType.LOGGER) {
132
160
  // 这里处理日志类型数据自定义字段
133
161
  (0, _tools.each)(message, function (value, key) {
134
162
  if (filterFileds.indexOf(key) === -1 && ((0, _tools.isNumber)(value) || (0, _tools.isString)(value) || (0, _tools.isBoolean)(value))) {
163
+ rowData.tags[key] = (0, _tools.escapeJsonValue)(value);
135
164
  tagsStr.push((0, _tools.escapeRowData)(key) + '=' + (0, _tools.escapeRowData)(value));
136
165
  }
137
166
  });
@@ -159,12 +188,13 @@ var processedMessageByDataMap = function processedMessageByDataMap(message) {
159
188
 
160
189
  exports.processedMessageByDataMap = processedMessageByDataMap;
161
190
 
162
- function batch(request, maxSize, bytesLimit, maxMessageSize, flushTimeout, beforeUnloadCallback) {
191
+ var batch = function batch(request, maxSize, bytesLimit, maxMessageSize, flushTimeout, isLineProtocolToJson, beforeUnloadCallback) {
163
192
  this.request = request;
164
193
  this.maxSize = maxSize;
165
194
  this.bytesLimit = bytesLimit;
166
195
  this.maxMessageSize = maxMessageSize;
167
196
  this.flushTimeout = flushTimeout;
197
+ this.isLineProtocolToJson = isLineProtocolToJson;
168
198
  this.beforeUnloadCallback = beforeUnloadCallback;
169
199
  this.pushOnlyBuffer = [];
170
200
  this.upsertBuffer = {};
@@ -172,7 +202,7 @@ function batch(request, maxSize, bytesLimit, maxMessageSize, flushTimeout, befor
172
202
  this.bufferMessageCount = 0;
173
203
  this.flushOnVisibilityHidden();
174
204
  this.flushPeriodically();
175
- }
205
+ };
176
206
 
177
207
  batch.prototype = {
178
208
  add: function add(message) {
@@ -184,7 +214,16 @@ batch.prototype = {
184
214
  flush: function flush() {
185
215
  if (this.bufferMessageCount !== 0) {
186
216
  var messages = this.pushOnlyBuffer.concat((0, _tools.values)(this.upsertBuffer));
187
- this.request.send(messages.join('\n'), this.bufferBytesSize);
217
+ if (messages.length === 0) return;
218
+
219
+ if (this.isLineProtocolToJson) {
220
+ this.request.send((0, _tools.map)(messages, function (rowdataStr) {
221
+ return JSON.parse(rowdataStr);
222
+ }), this.bufferBytesSize);
223
+ } else {
224
+ this.request.send(messages.join('\n'), this.bufferBytesSize);
225
+ }
226
+
188
227
  this.pushOnlyBuffer = [];
189
228
  this.upsertBuffer = {};
190
229
  this.bufferBytesSize = 0;
@@ -192,6 +231,10 @@ batch.prototype = {
192
231
  }
193
232
  },
194
233
  processSendData: function processSendData(message) {
234
+ if (this.isLineProtocolToJson) {
235
+ return JSON.stringify(processedMessageByDataMap(message).rowData);
236
+ }
237
+
195
238
  return processedMessageByDataMap(message).rowStr;
196
239
  },
197
240
  sizeInBytes: function sizeInBytes(candidate) {
@@ -291,7 +334,7 @@ batch.prototype = {
291
334
  // @ts-ignore this function is not always defined
292
335
 
293
336
 
294
- if (navigator.sendBeacon) {
337
+ if (global.navigator.sendBeacon) {
295
338
  /**
296
339
  * beforeunload is called before visibilitychange
297
340
  * register first to be sure to be called before flush on beforeunload
@@ -37,6 +37,9 @@ export var DEFAULT_CONFIGURATION = {
37
37
  // 新增
38
38
  isServiceSampling: false,
39
39
  // 是否不抛弃采样是数据, 采用在服务端菜样的方式
40
+ isJsBirdge: false,
41
+ // 是否需要对webview 发送数据,需要装我们对应ios sdk
42
+ isLineProtocolToJson: false,
40
43
  beforeSend: function beforeSend(event) {},
41
44
  isServerError: function isServerError(request) {
42
45
  return false;
@@ -87,6 +90,14 @@ export function commonInit(userConfiguration, buildEnv) {
87
90
  cookieOptions: buildCookieOptions(userConfiguration)
88
91
  };
89
92
 
93
+ if ('isJsBirdge' in userConfiguration) {
94
+ transportConfiguration.isJsBirdge = userConfiguration.isJsBirdge;
95
+ }
96
+
97
+ if ('isLineProtocolToJson' in userConfiguration) {
98
+ transportConfiguration.isLineProtocolToJson = userConfiguration.isLineProtocolToJson;
99
+ }
100
+
90
101
  if ('allowedDDTracingOrigins' in userConfiguration) {
91
102
  transportConfiguration.allowedTracingOrigins = userConfiguration.allowedDDTracingOrigins;
92
103
  }
@@ -103,4 +103,4 @@ JsBirdge.prototype = {
103
103
  }
104
104
  }
105
105
  };
106
- export var jsBirdge = new JsBirdge();
106
+ export var JsBirdge = JsBirdge;
@@ -30,6 +30,19 @@ export var each = function each(obj, iterator, context) {
30
30
  }
31
31
  }
32
32
  };
33
+ export function assign(target) {
34
+ each(slice.call(arguments, 1), function (source) {
35
+ for (var prop in source) {
36
+ if (Object.prototype.hasOwnProperty.call(source, prop)) {
37
+ target[prop] = source[prop];
38
+ }
39
+ }
40
+ });
41
+ return target;
42
+ }
43
+ export function shallowClone(object) {
44
+ return assign({}, object);
45
+ }
33
46
  export var extend = function extend(obj) {
34
47
  each(slice.call(arguments, 1), function (source) {
35
48
  for (var prop in source) {
@@ -1726,4 +1739,11 @@ export function escapeRowData(str) {
1726
1739
  return String(str).replace(reg, function (word) {
1727
1740
  return '\\' + word;
1728
1741
  });
1742
+ }
1743
+ export function escapeJsonValue(value) {
1744
+ if (isString(value)) {
1745
+ return value;
1746
+ } else {
1747
+ return jsonStringify(value);
1748
+ }
1729
1749
  }
package/esm/transport.js CHANGED
@@ -1,6 +1,7 @@
1
- import { addEventListener, values, findByPath, escapeRowData, each, isNumber, isArray, extend, isString, toServerDuration, isBoolean, isEmptyObject, isObject } from './helper/tools';
1
+ import { addEventListener, values, findByPath, escapeRowData, each, isNumber, isArray, extend, isString, toServerDuration, isBoolean, isEmptyObject, isObject, map, escapeJsonValue } from './helper/tools';
2
2
  import { DOM_EVENT, RumEventType } from './helper/enums';
3
- import { commonTags, dataMap } from './dataMap'; // https://en.wikipedia.org/wiki/UTF-8
3
+ import { commonTags, dataMap } from './dataMap';
4
+ import { getGlobalObject } from './init'; // https://en.wikipedia.org/wiki/UTF-8
4
5
 
5
6
  var HAS_MULTI_BYTES_CHARACTERS = /[^\u0000-\u007F]/;
6
7
  var CUSTOM_KEYS = 'custom_keys';
@@ -10,17 +11,37 @@ function addBatchPrecision(url) {
10
11
  return url + (url.indexOf('?') === -1 ? '?' : '&') + 'precision=ms';
11
12
  }
12
13
 
13
- var httpRequest = function httpRequest(endpointUrl, bytesLimit) {
14
+ var global = getGlobalObject();
15
+
16
+ var httpRequest = function httpRequest(endpointUrl, bytesLimit, isLineProtocolToJson) {
14
17
  this.endpointUrl = endpointUrl;
15
18
  this.bytesLimit = bytesLimit;
19
+ this.isLineProtocolToJson = isLineProtocolToJson;
20
+ var isRealNavigator = Object.prototype.toString.call(global && global.navigator) === '[object Navigator]';
21
+ var hasSendBeacon = isRealNavigator && typeof global.navigator.sendBeacon === 'function';
22
+
23
+ if (hasSendBeacon) {
24
+ this.sendBeacon = global.navigator.sendBeacon.bind(global.navigator);
25
+ } else {
26
+ this.sendBeacon = undefined;
27
+ }
16
28
  };
17
29
 
18
30
  httpRequest.prototype = {
19
31
  send: function send(data, size) {
20
32
  var url = addBatchPrecision(this.endpointUrl);
21
33
 
22
- if (navigator.sendBeacon && size < this.bytesLimit) {
23
- var isQueued = navigator.sendBeacon(url, data);
34
+ if (this.sendBeacon && size < this.bytesLimit && !this.isLineProtocolToJson) {
35
+ var isQueued = this.sendBeacon(url, data);
36
+
37
+ if (isQueued) {
38
+ return;
39
+ }
40
+ } else if (this.sendBeacon && size < this.bytesLimit && this.isLineProtocolToJson) {
41
+ var blob = new Blob([JSON.stringify(data)], {
42
+ type: 'application/json'
43
+ });
44
+ var isQueued = this.sendBeacon(url, blob);
24
45
 
25
46
  if (isQueued) {
26
47
  return;
@@ -30,7 +51,14 @@ httpRequest.prototype = {
30
51
  var request = new XMLHttpRequest();
31
52
  request.open('POST', url, true);
32
53
  request.withCredentials = true;
33
- request.send(data);
54
+
55
+ if (this.isLineProtocolToJson) {
56
+ request.setRequestHeader('Content-type', 'application/json');
57
+ request.send(JSON.stringify(data));
58
+ } else {
59
+ request.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');
60
+ request.send(data);
61
+ }
34
62
  }
35
63
  };
36
64
  export var HttpRequest = httpRequest;
@@ -59,33 +87,10 @@ export var processedMessageByDataMap = function processedMessageByDataMap(messag
59
87
  filterFileds.push(_key);
60
88
 
61
89
  if (_value || isNumber(_value)) {
62
- rowData.tags[_key] = _value;
90
+ rowData.tags[_key] = escapeJsonValue(_value);
63
91
  tagsStr.push(escapeRowData(_key) + '=' + escapeRowData(_value));
64
92
  }
65
93
  });
66
-
67
- if (message.tags && isObject(message.tags) && !isEmptyObject(message.tags)) {
68
- // 自定义tag
69
- var _tagKeys = [];
70
- each(message.tags, function (_value, _key) {
71
- // 如果和之前tag重名,则舍弃
72
- if (filterFileds.indexOf(_key) > -1) return;
73
- filterFileds.push(_key);
74
-
75
- if (_value || isNumber(_value)) {
76
- _tagKeys.push(_key);
77
-
78
- rowData.tags[_key] = _value;
79
- tagsStr.push(escapeRowData(_key) + '=' + escapeRowData(_value));
80
- }
81
- });
82
-
83
- if (_tagKeys.length) {
84
- rowData.tags[CUSTOM_KEYS] = _tagKeys;
85
- tagsStr.push(escapeRowData(CUSTOM_KEYS) + '=' + escapeRowData(_tagKeys));
86
- }
87
- }
88
-
89
94
  var fieldsStr = [];
90
95
  each(value.fields, function (_value, _key) {
91
96
  if (isArray(_value) && _value.length === 2) {
@@ -116,10 +121,33 @@ export var processedMessageByDataMap = function processedMessageByDataMap(messag
116
121
  }
117
122
  });
118
123
 
124
+ if (message.tags && isObject(message.tags) && !isEmptyObject(message.tags)) {
125
+ // 自定义tag
126
+ var _tagKeys = [];
127
+ each(message.tags, function (_value, _key) {
128
+ // 如果和之前tag重名,则舍弃
129
+ if (filterFileds.indexOf(_key) > -1) return;
130
+ filterFileds.push(_key);
131
+
132
+ if (_value || isNumber(_value)) {
133
+ _tagKeys.push(_key);
134
+
135
+ rowData.tags[_key] = escapeJsonValue(_value);
136
+ tagsStr.push(escapeRowData(_key) + '=' + escapeRowData(_value));
137
+ }
138
+ });
139
+
140
+ if (_tagKeys.length) {
141
+ rowData.tags[CUSTOM_KEYS] = escapeJsonValue(_tagKeys);
142
+ tagsStr.push(escapeRowData(CUSTOM_KEYS) + '=' + escapeRowData(_tagKeys));
143
+ }
144
+ }
145
+
119
146
  if (message.type === RumEventType.LOGGER) {
120
147
  // 这里处理日志类型数据自定义字段
121
148
  each(message, function (value, key) {
122
149
  if (filterFileds.indexOf(key) === -1 && (isNumber(value) || isString(value) || isBoolean(value))) {
150
+ rowData.tags[key] = escapeJsonValue(value);
123
151
  tagsStr.push(escapeRowData(key) + '=' + escapeRowData(value));
124
152
  }
125
153
  });
@@ -145,12 +173,13 @@ export var processedMessageByDataMap = function processedMessageByDataMap(messag
145
173
  };
146
174
  };
147
175
 
148
- function batch(request, maxSize, bytesLimit, maxMessageSize, flushTimeout, beforeUnloadCallback) {
176
+ var batch = function batch(request, maxSize, bytesLimit, maxMessageSize, flushTimeout, isLineProtocolToJson, beforeUnloadCallback) {
149
177
  this.request = request;
150
178
  this.maxSize = maxSize;
151
179
  this.bytesLimit = bytesLimit;
152
180
  this.maxMessageSize = maxMessageSize;
153
181
  this.flushTimeout = flushTimeout;
182
+ this.isLineProtocolToJson = isLineProtocolToJson;
154
183
  this.beforeUnloadCallback = beforeUnloadCallback;
155
184
  this.pushOnlyBuffer = [];
156
185
  this.upsertBuffer = {};
@@ -158,7 +187,7 @@ function batch(request, maxSize, bytesLimit, maxMessageSize, flushTimeout, befor
158
187
  this.bufferMessageCount = 0;
159
188
  this.flushOnVisibilityHidden();
160
189
  this.flushPeriodically();
161
- }
190
+ };
162
191
 
163
192
  batch.prototype = {
164
193
  add: function add(message) {
@@ -170,7 +199,16 @@ batch.prototype = {
170
199
  flush: function flush() {
171
200
  if (this.bufferMessageCount !== 0) {
172
201
  var messages = this.pushOnlyBuffer.concat(values(this.upsertBuffer));
173
- this.request.send(messages.join('\n'), this.bufferBytesSize);
202
+ if (messages.length === 0) return;
203
+
204
+ if (this.isLineProtocolToJson) {
205
+ this.request.send(map(messages, function (rowdataStr) {
206
+ return JSON.parse(rowdataStr);
207
+ }), this.bufferBytesSize);
208
+ } else {
209
+ this.request.send(messages.join('\n'), this.bufferBytesSize);
210
+ }
211
+
174
212
  this.pushOnlyBuffer = [];
175
213
  this.upsertBuffer = {};
176
214
  this.bufferBytesSize = 0;
@@ -178,6 +216,10 @@ batch.prototype = {
178
216
  }
179
217
  },
180
218
  processSendData: function processSendData(message) {
219
+ if (this.isLineProtocolToJson) {
220
+ return JSON.stringify(processedMessageByDataMap(message).rowData);
221
+ }
222
+
181
223
  return processedMessageByDataMap(message).rowStr;
182
224
  },
183
225
  sizeInBytes: function sizeInBytes(candidate) {
@@ -277,7 +319,7 @@ batch.prototype = {
277
319
  // @ts-ignore this function is not always defined
278
320
 
279
321
 
280
- if (navigator.sendBeacon) {
322
+ if (global.navigator.sendBeacon) {
281
323
  /**
282
324
  * beforeunload is called before visibilitychange
283
325
  * register first to be sure to be called before flush on beforeunload
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudcare/browser-core",
3
- "version": "1.0.25",
3
+ "version": "1.1.0",
4
4
  "main": "cjs/index.js",
5
5
  "module": "esm/index.js",
6
6
  "scripts": {
@@ -20,5 +20,5 @@
20
20
  "author": "dataflux",
21
21
  "license": "MIT",
22
22
  "description": "DataFlux RUM Web 端数据指标监控",
23
- "gitHead": "71b933526e868e57c1ebf943f337bda9a19fe7ed"
23
+ "gitHead": "f952b9eeba6f5cfe85fe0073700a35cfdc35454b"
24
24
  }
@@ -40,6 +40,8 @@ export var DEFAULT_CONFIGURATION = {
40
40
  allowedDDTracingOrigins: [], //废弃
41
41
  allowedTracingOrigins:[], // 新增
42
42
  isServiceSampling: false, // 是否不抛弃采样是数据, 采用在服务端菜样的方式
43
+ isJsBirdge: false,// 是否需要对webview 发送数据,需要装我们对应ios sdk
44
+ isLineProtocolToJson: false,
43
45
  beforeSend: function (event) {},
44
46
  isServerError: function(request) {return false} // 判断请求是否为error 请求
45
47
  }
@@ -87,6 +89,12 @@ export function commonInit(userConfiguration, buildEnv) {
87
89
  isEnabled: function(feature) {return includes(enableExperimentalFeatures, feature)},
88
90
  cookieOptions: buildCookieOptions(userConfiguration)
89
91
  }
92
+ if ('isJsBirdge' in userConfiguration) {
93
+ transportConfiguration.isJsBirdge = userConfiguration.isJsBirdge
94
+ }
95
+ if ('isLineProtocolToJson' in userConfiguration) {
96
+ transportConfiguration.isLineProtocolToJson = userConfiguration.isLineProtocolToJson
97
+ }
90
98
  if ('allowedDDTracingOrigins' in userConfiguration) {
91
99
  transportConfiguration.allowedTracingOrigins =
92
100
  userConfiguration.allowedDDTracingOrigins
@@ -99,4 +99,4 @@ JsBirdge.prototype = {
99
99
  }
100
100
  }
101
101
 
102
- export var jsBirdge = new JsBirdge()
102
+ export var JsBirdge = JsBirdge
@@ -29,6 +29,20 @@ export var each = function (obj, iterator, context) {
29
29
  }
30
30
  }
31
31
  }
32
+ export function assign(target) {
33
+ each(slice.call(arguments, 1), function (source) {
34
+ for (var prop in source) {
35
+ if (Object.prototype.hasOwnProperty.call(source, prop)) {
36
+ target[prop] = source[prop]
37
+ }
38
+ }
39
+ })
40
+ return target
41
+ }
42
+
43
+ export function shallowClone(object){
44
+ return assign({}, object)
45
+ }
32
46
  export var extend = function (obj) {
33
47
  each(slice.call(arguments, 1), function (source) {
34
48
  for (var prop in source) {
@@ -1702,3 +1716,11 @@ export function escapeRowData(str) {
1702
1716
  return '\\' + word
1703
1717
  })
1704
1718
  }
1719
+
1720
+ export function escapeJsonValue(value) {
1721
+ if (isString(value)) {
1722
+ return value
1723
+ } else {
1724
+ return jsonStringify(value)
1725
+ }
1726
+ }
package/src/transport.js CHANGED
@@ -11,10 +11,13 @@ import {
11
11
  toServerDuration,
12
12
  isBoolean,
13
13
  isEmptyObject,
14
- isObject
14
+ isObject,
15
+ map,
16
+ escapeJsonValue
15
17
  } from './helper/tools'
16
18
  import { DOM_EVENT, RumEventType } from './helper/enums'
17
19
  import { commonTags, dataMap } from './dataMap'
20
+ import { getGlobalObject } from'./init'
18
21
  // https://en.wikipedia.org/wiki/UTF-8
19
22
  var HAS_MULTI_BYTES_CHARACTERS = /[^\u0000-\u007F]/
20
23
  var CUSTOM_KEYS = 'custom_keys'
@@ -22,27 +25,59 @@ function addBatchPrecision(url) {
22
25
  if (!url) return url
23
26
  return url + (url.indexOf('?') === -1 ? '?' : '&') + 'precision=ms'
24
27
  }
25
- var httpRequest = function (endpointUrl, bytesLimit) {
28
+ var global = getGlobalObject()
29
+ var httpRequest = function (endpointUrl, bytesLimit, isLineProtocolToJson) {
26
30
  this.endpointUrl = endpointUrl
27
31
  this.bytesLimit = bytesLimit
32
+ this.isLineProtocolToJson = isLineProtocolToJson
33
+ var isRealNavigator = Object.prototype.toString.call(global && global.navigator) === '[object Navigator]';
34
+ var hasSendBeacon = isRealNavigator && typeof global.navigator.sendBeacon === 'function';
35
+ if (hasSendBeacon) {
36
+ this.sendBeacon = global.navigator.sendBeacon.bind(global.navigator);
37
+ } else {
38
+ this.sendBeacon = undefined
39
+ }
40
+
28
41
  }
29
42
  httpRequest.prototype = {
30
43
  send: function (data, size) {
44
+
31
45
  var url = addBatchPrecision(this.endpointUrl)
32
- if (navigator.sendBeacon && size < this.bytesLimit) {
33
- var isQueued = navigator.sendBeacon(url, data)
46
+
47
+ if (this.sendBeacon && size < this.bytesLimit && !this.isLineProtocolToJson) {
48
+ var isQueued = this.sendBeacon(url, data)
49
+ if (isQueued) {
50
+ return
51
+ }
52
+ } else if (this.sendBeacon && size < this.bytesLimit && this.isLineProtocolToJson) {
53
+ const blob = new Blob([JSON.stringify(data)], {
54
+ type: 'application/json',
55
+ });
56
+ var isQueued = this.sendBeacon(url, blob)
34
57
  if (isQueued) {
35
58
  return
36
59
  }
37
60
  }
61
+
38
62
  var request = new XMLHttpRequest()
39
63
  request.open('POST', url, true)
40
64
  request.withCredentials = true
41
- request.send(data)
65
+ if (this.isLineProtocolToJson) {
66
+ request.setRequestHeader('Content-type', 'application/json')
67
+ request.send(JSON.stringify(data))
68
+ } else {
69
+
70
+ request.setRequestHeader('Content-type', 'text/plain;charset=UTF-8')
71
+ request.send(data)
72
+ }
73
+
74
+
75
+
42
76
  }
43
77
  }
44
78
 
45
79
  export var HttpRequest = httpRequest
80
+
46
81
  export var processedMessageByDataMap = function (message) {
47
82
  if (!message || !message.type) return {
48
83
  rowStr: '',
@@ -63,28 +98,11 @@ export var processedMessageByDataMap = function (message) {
63
98
  var _value = findByPath(message, value_path)
64
99
  filterFileds.push(_key)
65
100
  if (_value || isNumber(_value)) {
66
- rowData.tags[_key] = _value
101
+ rowData.tags[_key] = escapeJsonValue(_value)
67
102
  tagsStr.push(escapeRowData(_key) + '=' + escapeRowData(_value))
68
103
  }
69
104
  })
70
- if (message.tags && isObject(message.tags) && !isEmptyObject(message.tags)) {
71
- // 自定义tag
72
- const _tagKeys = []
73
- each(message.tags, function (_value, _key) {
74
- // 如果和之前tag重名,则舍弃
75
- if (filterFileds.indexOf(_key) > -1) return
76
- filterFileds.push(_key)
77
- if (_value || isNumber(_value)) {
78
- _tagKeys.push(_key)
79
- rowData.tags[_key] = _value
80
- tagsStr.push(escapeRowData(_key) + '=' + escapeRowData(_value))
81
- }
82
- })
83
- if (_tagKeys.length) {
84
- rowData.tags[CUSTOM_KEYS] = _tagKeys
85
- tagsStr.push(escapeRowData(CUSTOM_KEYS) + '=' + escapeRowData(_tagKeys))
86
- }
87
- }
105
+
88
106
  var fieldsStr = []
89
107
  each(value.fields, function (_value, _key) {
90
108
  if (isArray(_value) && _value.length === 2) {
@@ -112,6 +130,24 @@ export var processedMessageByDataMap = function (message) {
112
130
  }
113
131
  }
114
132
  })
133
+ if (message.tags && isObject(message.tags) && !isEmptyObject(message.tags)) {
134
+ // 自定义tag
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.tags[_key] = escapeJsonValue(_value)
143
+ tagsStr.push(escapeRowData(_key) + '=' + escapeRowData(_value))
144
+ }
145
+ })
146
+ if (_tagKeys.length) {
147
+ rowData.tags[CUSTOM_KEYS] = escapeJsonValue(_tagKeys)
148
+ tagsStr.push(escapeRowData(CUSTOM_KEYS) + '=' + escapeRowData(_tagKeys))
149
+ }
150
+ }
115
151
  if (message.type === RumEventType.LOGGER) {
116
152
  // 这里处理日志类型数据自定义字段
117
153
 
@@ -120,6 +156,7 @@ export var processedMessageByDataMap = function (message) {
120
156
  filterFileds.indexOf(key) === -1 &&
121
157
  (isNumber(value) || isString(value) || isBoolean(value))
122
158
  ) {
159
+ rowData.tags[key] = escapeJsonValue(value)
123
160
  tagsStr.push(escapeRowData(key) + '=' + escapeRowData(value))
124
161
  }
125
162
  })
@@ -141,40 +178,58 @@ export var processedMessageByDataMap = function (message) {
141
178
  rowData: hasFileds ? rowData : undefined
142
179
  }
143
180
  }
144
- function batch(
181
+ var batch = function(
145
182
  request,
146
183
  maxSize,
147
184
  bytesLimit,
148
185
  maxMessageSize,
149
186
  flushTimeout,
187
+ isLineProtocolToJson,
150
188
  beforeUnloadCallback
151
189
  ) {
190
+
152
191
  this.request = request
153
192
  this.maxSize = maxSize
154
193
  this.bytesLimit = bytesLimit
155
194
  this.maxMessageSize = maxMessageSize
156
195
  this.flushTimeout = flushTimeout
196
+ this.isLineProtocolToJson = isLineProtocolToJson
157
197
  this.beforeUnloadCallback = beforeUnloadCallback
198
+
158
199
  this.pushOnlyBuffer = []
159
200
  this.upsertBuffer = {}
160
201
  this.bufferBytesSize = 0
161
202
  this.bufferMessageCount = 0
203
+
162
204
  this.flushOnVisibilityHidden()
163
205
  this.flushPeriodically()
164
206
  }
165
207
  batch.prototype = {
208
+
166
209
  add: function (message) {
210
+
167
211
  this.addOrUpdate(message)
168
212
  },
169
213
 
170
214
  upsert: function (message, key) {
215
+
171
216
  this.addOrUpdate(message, key)
172
217
  },
173
218
 
174
219
  flush: function () {
220
+
175
221
  if (this.bufferMessageCount !== 0) {
176
222
  var messages = this.pushOnlyBuffer.concat(values(this.upsertBuffer))
177
- this.request.send(messages.join('\n'), this.bufferBytesSize)
223
+ if (messages.length === 0) return
224
+ if (this.isLineProtocolToJson) {
225
+ this.request.send(map(messages, function(rowdataStr) {
226
+ return JSON.parse(rowdataStr)
227
+ }), this.bufferBytesSize)
228
+ } else {
229
+
230
+ this.request.send(messages.join('\n'), this.bufferBytesSize)
231
+ }
232
+
178
233
  this.pushOnlyBuffer = []
179
234
  this.upsertBuffer = {}
180
235
  this.bufferBytesSize = 0
@@ -183,6 +238,10 @@ batch.prototype = {
183
238
  },
184
239
 
185
240
  processSendData: function (message) {
241
+ if (this.isLineProtocolToJson) {
242
+ return JSON.stringify(processedMessageByDataMap(message).rowData)
243
+ }
244
+
186
245
  return processedMessageByDataMap(message).rowStr
187
246
  },
188
247
  sizeInBytes: function (candidate) {
@@ -286,7 +345,7 @@ batch.prototype = {
286
345
  * With sendBeacon, requests are guaranteed to be successfully sent during document unload
287
346
  */
288
347
  // @ts-ignore this function is not always defined
289
- if (navigator.sendBeacon) {
348
+ if (global.navigator.sendBeacon) {
290
349
  /**
291
350
  * beforeunload is called before visibilitychange
292
351
  * register first to be sure to be called before flush on beforeunload